From bce08ba2206668ad5c962903e29777bb7afa2de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 1 Dec 2011 15:17:10 +0100 Subject: Introducing QArrayData Modeled on QByteArrayData/QStringData/QVectorData, the intent is to unify book-keeping structs for array-like data and enable sharing of code among them. As in those structures, size (and alloc) data member(s) specify the number of *typed* elements the array does (and can) hold. The size or alignment requirements of those objects is not tracked in this data structure and needs to be maintained by its users. Contrary to QByteArrayData and QStringData, QArrayData's offset member keeps a *byte* offset to the actual data array and is computed from the beginning of the struct. Shared-null and -empty functionality is provided by QArrayData and shared among all users. Planned features include setSharable (force deep copies), fromRawData (detached header and data allocations) and literals a la QStringLiteral (static immutable instances), thus covering the functionality needed for QByteArray, QString and QVector. Change-Id: I9aa709dbb675442e6d06965efb8138ab84602bbd Reviewed-by: Bradley T. Hughes Reviewed-by: Olivier Goffart --- tests/auto/corelib/tools/qarraydata/qarraydata.pro | 4 + .../corelib/tools/qarraydata/tst_qarraydata.cpp | 152 +++++++++++++++++++++ tests/auto/corelib/tools/tools.pro | 1 + 3 files changed, 157 insertions(+) create mode 100644 tests/auto/corelib/tools/qarraydata/qarraydata.pro create mode 100644 tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/qarraydata.pro b/tests/auto/corelib/tools/qarraydata/qarraydata.pro new file mode 100644 index 0000000000..d384408d3b --- /dev/null +++ b/tests/auto/corelib/tools/qarraydata/qarraydata.pro @@ -0,0 +1,4 @@ +TARGET = tst_qarraydata +SOURCES += tst_qarraydata.cpp +QT = core testlib +CONFIG += testcase parallel_test diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp new file mode 100644 index 0000000000..31006c64ee --- /dev/null +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include + +class tst_QArrayData : public QObject +{ + Q_OBJECT + +private slots: + void referenceCounting(); + void sharedNullEmpty(); + void staticData(); +}; + +void tst_QArrayData::referenceCounting() +{ + { + // Reference counting initialized to 1 (owned) + QArrayData array = { Q_REFCOUNT_INITIALIZER(1), 0, 0, 0, 0 }; + + QCOMPARE(int(array.ref), 1); + + array.ref.ref(); + QCOMPARE(int(array.ref), 2); + + QVERIFY(array.ref.deref()); + QCOMPARE(int(array.ref), 1); + + array.ref.ref(); + QCOMPARE(int(array.ref), 2); + + QVERIFY(array.ref.deref()); + QCOMPARE(int(array.ref), 1); + + QVERIFY(!array.ref.deref()); + QCOMPARE(int(array.ref), 0); + + // Now would be a good time to free/release allocated data + } + + { + // Reference counting initialized to -1 (static read-only data) + QArrayData array = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, 0 }; + + QCOMPARE(int(array.ref), -1); + + array.ref.ref(); + QCOMPARE(int(array.ref), -1); + + QVERIFY(array.ref.deref()); + QCOMPARE(int(array.ref), -1); + } +} + +void tst_QArrayData::sharedNullEmpty() +{ + QArrayData *null = const_cast(&QArrayData::shared_null); + QArrayData *empty = const_cast(&QArrayData::shared_empty); + + QCOMPARE(int(null->ref), -1); + QCOMPARE(int(empty->ref), -1); + + null->ref.ref(); + empty->ref.ref(); + + QCOMPARE(int(null->ref), -1); + QCOMPARE(int(empty->ref), -1); + + QVERIFY(null->ref.deref()); + QVERIFY(empty->ref.deref()); + + QCOMPARE(int(null->ref), -1); + QCOMPARE(int(empty->ref), -1); + + QVERIFY(null != empty); + + QCOMPARE(null->size, 0); + QCOMPARE(null->alloc, 0u); + QCOMPARE(null->capacityReserved, 0u); + + QCOMPARE(empty->size, 0); + QCOMPARE(empty->alloc, 0u); + QCOMPARE(empty->capacityReserved, 0u); +} + +void tst_QArrayData::staticData() +{ + QStaticArrayData charArray = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(char, 10), + { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } + }; + QStaticArrayData intArray = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10), + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } + }; + QStaticArrayData doubleArray = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(double, 10), + { 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f } + }; + + QCOMPARE(charArray.header.size, 10); + QCOMPARE(intArray.header.size, 10); + QCOMPARE(doubleArray.header.size, 10); + + QCOMPARE(charArray.header.data(), reinterpret_cast(&charArray.data)); + QCOMPARE(intArray.header.data(), reinterpret_cast(&intArray.data)); + QCOMPARE(doubleArray.header.data(), reinterpret_cast(&doubleArray.data)); +} + +QTEST_APPLESS_MAIN(tst_QArrayData) +#include "tst_qarraydata.moc" diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro index 930799e3b3..e2002a98b6 100644 --- a/tests/auto/corelib/tools/tools.pro +++ b/tests/auto/corelib/tools/tools.pro @@ -1,6 +1,7 @@ TEMPLATE=subdirs SUBDIRS=\ qalgorithms \ + qarraydata \ qbitarray \ qbytearray \ qbytearraymatcher \ -- cgit v1.2.3 From d5d073f87434fbe0f80269e9948b644f5ced1faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 2 Nov 2011 11:22:14 +0100 Subject: SimpleVector as a test case for QArrayData SimpleVector is meant solely as a test case and reference container implementation based on QArrayData functionality. It shall not replace QVector or friends. Change-Id: I5c66777c720f252c8e073a2884c6d5f1ac836d0e Reviewed-by: Olivier Goffart --- tests/auto/corelib/tools/qarraydata/qarraydata.pro | 1 + tests/auto/corelib/tools/qarraydata/simplevector.h | 183 +++++++++++++++++++++ .../corelib/tools/qarraydata/tst_qarraydata.cpp | 105 ++++++++++++ 3 files changed, 289 insertions(+) create mode 100644 tests/auto/corelib/tools/qarraydata/simplevector.h (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/qarraydata.pro b/tests/auto/corelib/tools/qarraydata/qarraydata.pro index d384408d3b..8e368117fa 100644 --- a/tests/auto/corelib/tools/qarraydata/qarraydata.pro +++ b/tests/auto/corelib/tools/qarraydata/qarraydata.pro @@ -1,4 +1,5 @@ TARGET = tst_qarraydata SOURCES += tst_qarraydata.cpp +HEADERS += simplevector.h QT = core testlib CONFIG += testcase parallel_test diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h new file mode 100644 index 0000000000..ad08ad5fdb --- /dev/null +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QARRAY_TEST_SIMPLE_VECTOR_H +#define QARRAY_TEST_SIMPLE_VECTOR_H + +#include +#include + +template +struct SimpleVector +{ +private: + typedef QArrayData Data; + +public: + typedef T value_type; + typedef T *iterator; + typedef const T *const_iterator; + + SimpleVector() + : d(const_cast(&Data::shared_null)) + { + } + + SimpleVector(const SimpleVector &vec) + : d(vec.d) + { + d->ref.ref(); + } + + explicit SimpleVector(Data *ptr) + : d(ptr) + { + } + + ~SimpleVector() + { + if (!d->ref.deref()) + // Not implemented + Q_ASSERT(false); + } + + SimpleVector &operator=(const SimpleVector &vec) + { + SimpleVector temp(vec); + this->swap(temp); + return *this; + } + + bool empty() const { return d->size == 0; } + bool isNull() const { return d == &Data::shared_null; } + bool isEmpty() const { return this->empty(); } + + bool isSharedWith(const SimpleVector &other) const { return d == other.d; } + + size_t size() const { return d->size; } + size_t capacity() const { return d->alloc; } + + const_iterator begin() const { return static_cast(d->data()); } + const_iterator end() const { return static_cast(d->data()) + d->size; } + + const_iterator constBegin() const { return begin(); } + const_iterator constEnd() const { return end(); } + + const T &operator[](size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; } + const T &at(size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; } + + const T &front() const + { + Q_ASSERT(!isEmpty()); + return *begin(); + } + + const T &back() const + { + Q_ASSERT(!isEmpty()); + return *(end() - 1); + } + + void swap(SimpleVector &other) + { + qSwap(d, other.d); + } + + void clear() + { + SimpleVector tmp(d); + d = const_cast(&Data::shared_empty); + } + +private: + Data *d; +}; + +template +bool operator==(const SimpleVector &lhs, const SimpleVector &rhs) +{ + if (lhs.isSharedWith(rhs)) + return true; + if (lhs.size() != rhs.size()) + return false; + return std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +template +bool operator!=(const SimpleVector &lhs, const SimpleVector &rhs) +{ + return !(lhs == rhs); +} + +template +bool operator<(const SimpleVector &lhs, const SimpleVector &rhs) +{ + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +} + +template +bool operator>(const SimpleVector &lhs, const SimpleVector &rhs) +{ + return rhs < lhs; +} + +template +bool operator<=(const SimpleVector &lhs, const SimpleVector &rhs) +{ + return !(rhs < lhs); +} + +template +bool operator>=(const SimpleVector &lhs, const SimpleVector &rhs) +{ + return !(lhs < rhs); +} + +namespace std { + template + void swap(SimpleVector &v1, SimpleVector &v2) + { + v1.swap(v2); + } +} + +#endif // include guard diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 31006c64ee..1265876eb3 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -43,6 +43,8 @@ #include #include +#include "simplevector.h" + class tst_QArrayData : public QObject { Q_OBJECT @@ -51,6 +53,7 @@ private slots: void referenceCounting(); void sharedNullEmpty(); void staticData(); + void simpleVector(); }; void tst_QArrayData::referenceCounting() @@ -148,5 +151,107 @@ void tst_QArrayData::staticData() QCOMPARE(doubleArray.header.data(), reinterpret_cast(&doubleArray.data)); } +void tst_QArrayData::simpleVector() +{ + QArrayData data0 = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, 0 }; + QStaticArrayData data1 = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 7), + { 0, 1, 2, 3, 4, 5, 6 } + }; + + SimpleVector v1; + SimpleVector v2(v1); + SimpleVector v3(&data0); + SimpleVector v4(&data1.header); + SimpleVector v5(&data0); + SimpleVector v6(&data1.header); + + v3 = v1; + v1.swap(v3); + v4.clear(); + + QVERIFY(v1.isNull()); + QVERIFY(v2.isNull()); + QVERIFY(v3.isNull()); + QVERIFY(!v4.isNull()); + QVERIFY(!v5.isNull()); + QVERIFY(!v6.isNull()); + + QVERIFY(v1.isEmpty()); + QVERIFY(v2.isEmpty()); + QVERIFY(v3.isEmpty()); + QVERIFY(v4.isEmpty()); + QVERIFY(v5.isEmpty()); + QVERIFY(!v6.isEmpty()); + + QCOMPARE(v1.size(), size_t(0)); + QCOMPARE(v2.size(), size_t(0)); + QCOMPARE(v3.size(), size_t(0)); + QCOMPARE(v4.size(), size_t(0)); + QCOMPARE(v5.size(), size_t(0)); + QCOMPARE(v6.size(), size_t(7)); + + QCOMPARE(v1.capacity(), size_t(0)); + QCOMPARE(v2.capacity(), size_t(0)); + QCOMPARE(v3.capacity(), size_t(0)); + QCOMPARE(v4.capacity(), size_t(0)); + QCOMPARE(v5.capacity(), size_t(0)); + // v6.capacity() is unspecified, for now + + QVERIFY(v1.isSharedWith(v2)); + QVERIFY(v1.isSharedWith(v3)); + QVERIFY(!v1.isSharedWith(v4)); + QVERIFY(!v1.isSharedWith(v5)); + QVERIFY(!v1.isSharedWith(v6)); + + QVERIFY(v1.constBegin() == v1.constEnd()); + QVERIFY(v4.constBegin() == v4.constEnd()); + QVERIFY(v6.constBegin() + v6.size() == v6.constEnd()); + + QVERIFY(v1 == v2); + QVERIFY(v1 == v3); + QVERIFY(v1 == v4); + QVERIFY(v1 == v5); + QVERIFY(!(v1 == v6)); + + QVERIFY(v1 != v6); + QVERIFY(v4 != v6); + QVERIFY(v5 != v6); + QVERIFY(!(v1 != v5)); + + QVERIFY(v1 < v6); + QVERIFY(!(v6 < v1)); + QVERIFY(v6 > v1); + QVERIFY(!(v1 > v6)); + QVERIFY(v1 <= v6); + QVERIFY(!(v6 <= v1)); + QVERIFY(v6 >= v1); + QVERIFY(!(v1 >= v6)); + + QCOMPARE(v6.front(), 0); + QCOMPARE(v6.back(), 6); + + for (size_t i = 0; i < v6.size(); ++i) { + QCOMPARE(v6[i], int(i)); + QCOMPARE(v6.at(i), int(i)); + QCOMPARE(&v6[i], &v6.at(i)); + } + + v5 = v6; + QVERIFY(v5.isSharedWith(v6)); + QVERIFY(!v1.isSharedWith(v5)); + + v1.swap(v6); + QVERIFY(v6.isNull()); + QVERIFY(v1.isSharedWith(v5)); + + { + using std::swap; + swap(v1, v6); + QVERIFY(v5.isSharedWith(v6)); + QVERIFY(!v1.isSharedWith(v5)); + } +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From 0806bc2d1b518b53681b3d8023def95ba8122630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 29 Nov 2011 18:12:05 +0100 Subject: Allocate/free support in QArrayData Centralizing QArrayData memory management decisions in one place will allow us to be smarter in how we allocate header and data. At the moment, these are allocated as a single block. In the future we may decide to allocate them separately for "large" data or specific alignment requirements. For users of QArrayData this remains transparent and not part of the ABI. The offset field in QArrayDataHeader enables this. This also hard-wires allocation of empty arrays to return shared_empty. Allocating detached headers (e.g., to support fromRawData) will thus require explicit support. Change-Id: Icac5a1f51ee7e468c76b4493d29debc18780e5dc Reviewed-by: Bradley T. Hughes --- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 1265876eb3..7dfbd654a7 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -54,6 +54,10 @@ private slots: void sharedNullEmpty(); void staticData(); void simpleVector(); + void allocate_data(); + void allocate(); + void alignment_data(); + void alignment(); }; void tst_QArrayData::referenceCounting() @@ -253,5 +257,145 @@ void tst_QArrayData::simpleVector() } } +struct Deallocator +{ + Deallocator(size_t objectSize, size_t alignment) + : objectSize(objectSize) + , alignment(alignment) + { + } + + ~Deallocator() + { + Q_FOREACH (QArrayData *data, headers) + QArrayData::deallocate(data, objectSize, alignment); + } + + size_t objectSize; + size_t alignment; + QVector headers; +}; + +Q_DECLARE_METATYPE(const QArrayData *) + +void tst_QArrayData::allocate_data() +{ + QTest::addColumn("objectSize"); + QTest::addColumn("alignment"); + QTest::addColumn("isCapacityReserved"); + QTest::addColumn("commonEmpty"); + + struct { + char const *typeName; + size_t objectSize; + size_t alignment; + } types[] = { + { "char", sizeof(char), Q_ALIGNOF(char) }, + { "short", sizeof(short), Q_ALIGNOF(short) }, + { "void *", sizeof(void *), Q_ALIGNOF(void *) } + }; + + struct { + char const *description; + bool isCapacityReserved; + const QArrayData *commonEmpty; + } options[] = { + { "Default", false, &QArrayData::shared_empty }, + { "Reserved", true, &QArrayData::shared_empty }, + }; + + for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i) + for (size_t j = 0; j < sizeof(options)/sizeof(options[0]); ++j) + QTest::newRow(qPrintable( + QLatin1String(types[i].typeName) + + QLatin1String(": ") + + QLatin1String(options[j].description))) + << types[i].objectSize << types[i].alignment + << options[j].isCapacityReserved << options[j].commonEmpty; +} + +void tst_QArrayData::allocate() +{ + QFETCH(size_t, objectSize); + QFETCH(size_t, alignment); + QFETCH(bool, isCapacityReserved); + QFETCH(const QArrayData *, commonEmpty); + + // Minimum alignment that can be requested is that of QArrayData. + // Typically, this alignment is sizeof(void *) and ensured by malloc. + size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData)); + + // Shared Empty + QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0, + isCapacityReserved), commonEmpty); + + Deallocator keeper(objectSize, minAlignment); + keeper.headers.reserve(1024); + + for (int capacity = 1; capacity <= 1024; capacity <<= 1) { + QArrayData *data = QArrayData::allocate(objectSize, minAlignment, + capacity, isCapacityReserved); + keeper.headers.append(data); + + QCOMPARE(data->size, 0); + QVERIFY(data->alloc >= uint(capacity)); + QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); + + // Check that the allocated array can be used. Best tested with a + // memory checker, such as valgrind, running. + ::memset(data->data(), 'A', objectSize * capacity); + } +} + +class Unaligned +{ + char dummy[8]; +}; + +void tst_QArrayData::alignment_data() +{ + QTest::addColumn("alignment"); + + for (int i = 1; i < 10; ++i) { + size_t alignment = 1u << i; + QTest::newRow(qPrintable(QString::number(alignment))) << alignment; + } +} + +void tst_QArrayData::alignment() +{ + QFETCH(size_t, alignment); + + // Minimum alignment that can be requested is that of QArrayData. + // Typically, this alignment is sizeof(void *) and ensured by malloc. + size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData)); + + Deallocator keeper(sizeof(Unaligned), minAlignment); + keeper.headers.reserve(100); + + for (int i = 0; i < 100; ++i) { + QArrayData *data = QArrayData::allocate(sizeof(Unaligned), + minAlignment, 8, false); + keeper.headers.append(data); + + QVERIFY(data); + QCOMPARE(data->size, 0); + QVERIFY(data->alloc >= uint(8)); + + // These conditions should hold as long as header and array are + // allocated together + QVERIFY(data->offset >= qptrdiff(sizeof(QArrayData))); + QVERIFY(data->offset <= qptrdiff(sizeof(QArrayData) + + minAlignment - Q_ALIGNOF(QArrayData))); + + // Data is aligned + QCOMPARE(quintptr(data->data()) % alignment, quintptr(0u)); + + // Check that the allocated array can be used. Best tested with a + // memory checker, such as valgrind, running. + ::memset(data->data(), 'A', sizeof(Unaligned) * 8); + } +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From 390eec325b25a142ce2204f1d1950621d4a519e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 29 Nov 2011 17:53:57 +0100 Subject: template struct QTypedArrayData MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QTypedArrayData is a typed overlay for QArrayData, providing convenience and type-safety. It adds no data members to QArrayData, thus avoiding compiler-generated warnings for aliasing issues when casting back and forth. Change-Id: I969342a30989c4c14b3d03d0602e3d60a4cc0e9d Reviewed-by: João Abecasis --- tests/auto/corelib/tools/qarraydata/simplevector.h | 34 ++++-- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 133 ++++++++++++++++++++- 2 files changed, 152 insertions(+), 15 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index ad08ad5fdb..099045dfbb 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -50,15 +50,15 @@ template struct SimpleVector { private: - typedef QArrayData Data; + typedef QTypedArrayData Data; public: typedef T value_type; - typedef T *iterator; - typedef const T *const_iterator; + typedef typename Data::iterator iterator; + typedef typename Data::const_iterator const_iterator; SimpleVector() - : d(const_cast(&Data::shared_null)) + : d(Data::sharedNull()) { } @@ -68,6 +68,15 @@ public: d->ref.ref(); } + SimpleVector(size_t n, const T &t) + : d(Data::allocate(n)) + { + for (size_t i = 0; i < n; ++i) { + new (d->end()) T(t); + ++d->size; + } + } + explicit SimpleVector(Data *ptr) : d(ptr) { @@ -75,9 +84,12 @@ public: ~SimpleVector() { - if (!d->ref.deref()) - // Not implemented - Q_ASSERT(false); + if (!d->ref.deref()) { + const T *const data = d->data(); + while (d->size--) + data[d->size].~T(); + Data::deallocate(d); + } } SimpleVector &operator=(const SimpleVector &vec) @@ -88,7 +100,7 @@ public: } bool empty() const { return d->size == 0; } - bool isNull() const { return d == &Data::shared_null; } + bool isNull() const { return d == Data::sharedNull(); } bool isEmpty() const { return this->empty(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } @@ -96,8 +108,8 @@ public: size_t size() const { return d->size; } size_t capacity() const { return d->alloc; } - const_iterator begin() const { return static_cast(d->data()); } - const_iterator end() const { return static_cast(d->data()) + d->size; } + const_iterator begin() const { return d->begin(); } + const_iterator end() const { return d->end(); } const_iterator constBegin() const { return begin(); } const_iterator constEnd() const { return end(); } @@ -125,7 +137,7 @@ public: void clear() { SimpleVector tmp(d); - d = const_cast(&Data::shared_empty); + d = Data::sharedEmpty(); } private: diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 7dfbd654a7..8bbef9bac9 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -58,6 +58,7 @@ private slots: void allocate(); void alignment_data(); void alignment(); + void typedData(); }; void tst_QArrayData::referenceCounting() @@ -165,10 +166,11 @@ void tst_QArrayData::simpleVector() SimpleVector v1; SimpleVector v2(v1); - SimpleVector v3(&data0); - SimpleVector v4(&data1.header); - SimpleVector v5(&data0); - SimpleVector v6(&data1.header); + SimpleVector v3(static_cast *>(&data0)); + SimpleVector v4(static_cast *>(&data1.header)); + SimpleVector v5(static_cast *>(&data0)); + SimpleVector v6(static_cast *>(&data1.header)); + SimpleVector v7(10, 5); v3 = v1; v1.swap(v3); @@ -180,6 +182,7 @@ void tst_QArrayData::simpleVector() QVERIFY(!v4.isNull()); QVERIFY(!v5.isNull()); QVERIFY(!v6.isNull()); + QVERIFY(!v7.isNull()); QVERIFY(v1.isEmpty()); QVERIFY(v2.isEmpty()); @@ -187,6 +190,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v4.isEmpty()); QVERIFY(v5.isEmpty()); QVERIFY(!v6.isEmpty()); + QVERIFY(!v7.isEmpty()); QCOMPARE(v1.size(), size_t(0)); QCOMPARE(v2.size(), size_t(0)); @@ -194,6 +198,7 @@ void tst_QArrayData::simpleVector() QCOMPARE(v4.size(), size_t(0)); QCOMPARE(v5.size(), size_t(0)); QCOMPARE(v6.size(), size_t(7)); + QCOMPARE(v7.size(), size_t(10)); QCOMPARE(v1.capacity(), size_t(0)); QCOMPARE(v2.capacity(), size_t(0)); @@ -201,6 +206,7 @@ void tst_QArrayData::simpleVector() QCOMPARE(v4.capacity(), size_t(0)); QCOMPARE(v5.capacity(), size_t(0)); // v6.capacity() is unspecified, for now + QVERIFY(v7.capacity() >= size_t(10)); QVERIFY(v1.isSharedWith(v2)); QVERIFY(v1.isSharedWith(v3)); @@ -211,6 +217,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v1.constBegin() == v1.constEnd()); QVERIFY(v4.constBegin() == v4.constEnd()); QVERIFY(v6.constBegin() + v6.size() == v6.constEnd()); + QVERIFY(v7.constBegin() + v7.size() == v7.constEnd()); QVERIFY(v1 == v2); QVERIFY(v1 == v3); @@ -241,6 +248,16 @@ void tst_QArrayData::simpleVector() QCOMPARE(&v6[i], &v6.at(i)); } + { + int count = 0; + Q_FOREACH (int value, v7) { + QCOMPARE(value, 5); + ++count; + } + + QCOMPARE(count, 10); + } + v5 = v6; QVERIFY(v5.isSharedWith(v6)); QVERIFY(!v1.isSharedWith(v5)); @@ -397,5 +414,113 @@ void tst_QArrayData::alignment() } } +void tst_QArrayData::typedData() +{ + QStaticArrayData data = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10), + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } + }; + QCOMPARE(data.header.size, 10); + + { + QTypedArrayData *array = + static_cast *>(&data.header); + QCOMPARE(array->data(), data.data); + + int j = 0; + for (QTypedArrayData::iterator iter = array->begin(); + iter != array->end(); ++iter, ++j) + QCOMPARE(iter, data.data + j); + QCOMPARE(j, 10); + } + + { + const QTypedArrayData *array = + static_cast *>(&data.header); + + QCOMPARE(array->data(), data.data); + + int j = 0; + for (QTypedArrayData::const_iterator iter = array->begin(); + iter != array->end(); ++iter, ++j) + QCOMPARE(iter, data.data + j); + QCOMPARE(j, 10); + } + + { + QTypedArrayData *null = QTypedArrayData::sharedNull(); + QTypedArrayData *empty = QTypedArrayData::sharedEmpty(); + + QVERIFY(null != empty); + + QCOMPARE(null->size, 0); + QCOMPARE(empty->size, 0); + + QCOMPARE(null->begin(), null->end()); + QCOMPARE(empty->begin(), empty->end()); + } + + + { + Deallocator keeper(sizeof(char), + Q_ALIGNOF(QTypedArrayData::AlignmentDummy)); + QArrayData *array = QTypedArrayData::allocate(10, false); + keeper.headers.append(array); + + QVERIFY(array); + QCOMPARE(array->size, 0); + QCOMPARE(array->alloc, 10u); + + // Check that the allocated array can be used. Best tested with a + // memory checker, such as valgrind, running. + ::memset(array->data(), 0, 10 * sizeof(char)); + + keeper.headers.clear(); + QTypedArrayData::deallocate(array); + + QVERIFY(true); + } + + { + Deallocator keeper(sizeof(short), + Q_ALIGNOF(QTypedArrayData::AlignmentDummy)); + QArrayData *array = QTypedArrayData::allocate(10, false); + keeper.headers.append(array); + + QVERIFY(array); + QCOMPARE(array->size, 0); + QCOMPARE(array->alloc, 10u); + + // Check that the allocated array can be used. Best tested with a + // memory checker, such as valgrind, running. + ::memset(array->data(), 0, 10 * sizeof(short)); + + keeper.headers.clear(); + QTypedArrayData::deallocate(array); + + QVERIFY(true); + } + + { + Deallocator keeper(sizeof(double), + Q_ALIGNOF(QTypedArrayData::AlignmentDummy)); + QArrayData *array = QTypedArrayData::allocate(10, false); + keeper.headers.append(array); + + QVERIFY(array); + QCOMPARE(array->size, 0); + QCOMPARE(array->alloc, 10u); + + // Check that the allocated array can be used. Best tested with a + // memory checker, such as valgrind, running. + ::memset(array->data(), 0, 10 * sizeof(double)); + + keeper.headers.clear(); + QTypedArrayData::deallocate(array); + + QVERIFY(true); + } +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From bd0b49efe0bf63b359fc315757a9de547d557802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 1 Dec 2011 12:54:50 +0100 Subject: Add test for GCC bug #43247 A bug has been reported against GCC 4.4.3 (present in other version as well), where the use of an array of size 1 to implement dynamic arrays (such as QVector) leads to incorrect results in optimized builds as the compiler assumes the index to be 0. This test tries to ensure QArrayDataHeader is not affected by this bug, as QVector currently is. Change-Id: Id701496bae4d74170de43399c1062da40eb078e7 Reviewed-by: Olivier Goffart --- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 8bbef9bac9..f7a2fa7979 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -59,6 +59,7 @@ private slots: void alignment_data(); void alignment(); void typedData(); + void gccBug43247(); }; void tst_QArrayData::referenceCounting() @@ -522,5 +523,32 @@ void tst_QArrayData::typedData() } } +void tst_QArrayData::gccBug43247() +{ + // This test tries to verify QArrayData is not affected by GCC optimizer + // bug #43247. + // Reported on GCC 4.4.3, Linux, affects QVector + + QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (3)"); + QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (4)"); + QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (5)"); + QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (6)"); + QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (7)"); + + SimpleVector array(10, 0); + // QVector vector(10, 0); + + for (int i = 0; i < 10; ++i) { + if (i >= 3 && i < 8) + qDebug("GCC Optimization bug #43247 not triggered (%i)", i); + + // When access to data is implemented through an array of size 1, this + // line lets the compiler assume i == 0, and the conditional above is + // skipped. + QVERIFY(array.at(i) == 0); + // QVERIFY(vector.at(i) == 0); + } +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From 4da0b5fc02fe3a647d32892905c42928841d6487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 3 Nov 2011 12:52:26 +0100 Subject: QArrayDataOps: generic array operations This class, the selector and underlying implementations provide specialized operations on QArrayData, while allowing for optimized implementations that benefit from type-specific information. Currently, offering a generic implementation and specializations for PODs (trivial ctor, dtor and move operations) and movable types (can be trivially moved in memory). Change-Id: I2c5829b66c2aea79f12f21debe5c01f7104c7ea3 Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qarraydata/simplevector.h | 20 ++-- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 127 +++++++++++++++++++++ 2 files changed, 140 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 099045dfbb..36c9b7bc50 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -44,6 +44,8 @@ #define QARRAY_TEST_SIMPLE_VECTOR_H #include +#include + #include template @@ -51,6 +53,7 @@ struct SimpleVector { private: typedef QTypedArrayData Data; + typedef QArrayDataOps DataOps; public: typedef T value_type; @@ -71,10 +74,15 @@ public: SimpleVector(size_t n, const T &t) : d(Data::allocate(n)) { - for (size_t i = 0; i < n; ++i) { - new (d->end()) T(t); - ++d->size; - } + if (n) + static_cast(d)->copyAppend(n, t); + } + + SimpleVector(const T *begin, const T *end) + : d(Data::allocate(end - begin)) + { + if (end - begin) + static_cast(d)->copyAppend(begin, end); } explicit SimpleVector(Data *ptr) @@ -85,9 +93,7 @@ public: ~SimpleVector() { if (!d->ref.deref()) { - const T *const data = d->data(); - while (d->size--) - data[d->size].~T(); + static_cast(d)->destroyAll(); Data::deallocate(d); } } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index f7a2fa7979..2972f0a678 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -41,6 +41,7 @@ #include +#include #include #include "simplevector.h" @@ -60,6 +61,7 @@ private slots: void alignment(); void typedData(); void gccBug43247(); + void arrayOps(); }; void tst_QArrayData::referenceCounting() @@ -165,6 +167,8 @@ void tst_QArrayData::simpleVector() { 0, 1, 2, 3, 4, 5, 6 } }; + int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + SimpleVector v1; SimpleVector v2(v1); SimpleVector v3(static_cast *>(&data0)); @@ -172,6 +176,7 @@ void tst_QArrayData::simpleVector() SimpleVector v5(static_cast *>(&data0)); SimpleVector v6(static_cast *>(&data1.header)); SimpleVector v7(10, 5); + SimpleVector v8(array, array + sizeof(array)/sizeof(*array)); v3 = v1; v1.swap(v3); @@ -184,6 +189,7 @@ void tst_QArrayData::simpleVector() QVERIFY(!v5.isNull()); QVERIFY(!v6.isNull()); QVERIFY(!v7.isNull()); + QVERIFY(!v8.isNull()); QVERIFY(v1.isEmpty()); QVERIFY(v2.isEmpty()); @@ -192,6 +198,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v5.isEmpty()); QVERIFY(!v6.isEmpty()); QVERIFY(!v7.isEmpty()); + QVERIFY(!v8.isEmpty()); QCOMPARE(v1.size(), size_t(0)); QCOMPARE(v2.size(), size_t(0)); @@ -200,6 +207,7 @@ void tst_QArrayData::simpleVector() QCOMPARE(v5.size(), size_t(0)); QCOMPARE(v6.size(), size_t(7)); QCOMPARE(v7.size(), size_t(10)); + QCOMPARE(v8.size(), size_t(10)); QCOMPARE(v1.capacity(), size_t(0)); QCOMPARE(v2.capacity(), size_t(0)); @@ -208,6 +216,7 @@ void tst_QArrayData::simpleVector() QCOMPARE(v5.capacity(), size_t(0)); // v6.capacity() is unspecified, for now QVERIFY(v7.capacity() >= size_t(10)); + QVERIFY(v8.capacity() >= size_t(10)); QVERIFY(v1.isSharedWith(v2)); QVERIFY(v1.isSharedWith(v3)); @@ -219,6 +228,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v4.constBegin() == v4.constEnd()); QVERIFY(v6.constBegin() + v6.size() == v6.constEnd()); QVERIFY(v7.constBegin() + v7.size() == v7.constEnd()); + QVERIFY(v8.constBegin() + v8.size() == v8.constEnd()); QVERIFY(v1 == v2); QVERIFY(v1 == v3); @@ -259,6 +269,16 @@ void tst_QArrayData::simpleVector() QCOMPARE(count, 10); } + { + int count = 0; + Q_FOREACH (int value, v8) { + QCOMPARE(value, count); + ++count; + } + + QCOMPARE(count, 10); + } + v5 = v6; QVERIFY(v5.isSharedWith(v6)); QVERIFY(!v1.isSharedWith(v5)); @@ -550,5 +570,112 @@ void tst_QArrayData::gccBug43247() } } +struct CountedObject +{ + CountedObject() + : id(liveCount++) + { + } + + CountedObject(const CountedObject &other) + : id(other.id) + { + ++liveCount; + } + + ~CountedObject() + { + --liveCount; + } + + CountedObject &operator=(const CountedObject &other) + { + id = other.id; + return *this; + } + + struct LeakChecker + { + LeakChecker() + : previousLiveCount(liveCount) + { + } + + ~LeakChecker() + { + QCOMPARE(liveCount, previousLiveCount); + } + + private: + const size_t previousLiveCount; + }; + + size_t id; // not unique + static size_t liveCount; +}; + +size_t CountedObject::liveCount = 0; + +void tst_QArrayData::arrayOps() +{ + CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker) + + const int intArray[5] = { 80, 101, 100, 114, 111 }; + const QString stringArray[5] = { + QLatin1String("just"), + QLatin1String("for"), + QLatin1String("testing"), + QLatin1String("a"), + QLatin1String("vector") + }; + const CountedObject objArray[5]; + + QVERIFY(!QTypeInfo::isComplex && !QTypeInfo::isStatic); + QVERIFY(QTypeInfo::isComplex && !QTypeInfo::isStatic); + QVERIFY(QTypeInfo::isComplex && QTypeInfo::isStatic); + + QCOMPARE(CountedObject::liveCount, size_t(5)); + for (size_t i = 0; i < 5; ++i) + QCOMPARE(objArray[i].id, i); + + //////////////////////////////////////////////////////////////////////////// + // copyAppend (I) + SimpleVector vi(intArray, intArray + 5); + SimpleVector vs(stringArray, stringArray + 5); + SimpleVector vo(objArray, objArray + 5); + + QCOMPARE(CountedObject::liveCount, size_t(10)); + for (int i = 0; i < 5; ++i) { + QCOMPARE(vi[i], intArray[i]); + QVERIFY(vs[i].isSharedWith(stringArray[i])); + QCOMPARE(vo[i].id, objArray[i].id); + } + + //////////////////////////////////////////////////////////////////////////// + // destroyAll + vi.clear(); + vs.clear(); + vo.clear(); + + QCOMPARE(CountedObject::liveCount, size_t(5)); + + //////////////////////////////////////////////////////////////////////////// + // copyAppend (II) + int referenceInt = 7; + QString referenceString = QLatin1String("reference"); + CountedObject referenceObject; + + vi = SimpleVector(5, referenceInt); + vs = SimpleVector(5, referenceString); + vo = SimpleVector(5, referenceObject); + + QCOMPARE(CountedObject::liveCount, size_t(11)); + for (int i = 0; i < 5; ++i) { + QCOMPARE(vi[i], referenceInt); + QVERIFY(vs[i].isSharedWith(referenceString)); + QCOMPARE(vo[i].id, referenceObject.id); + } +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From 9c04f721a6b0521f596950771e9d88a5d00a29ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 22 Nov 2011 12:16:24 +0100 Subject: QArrayDataOps::insert Inserting elements anywhere in the array requires moving the elements that follow out of the way and writing in the new ones. Trivial for PODs and almost as much for movable types. For "complex" types, we start by extending the array with placement new and copy constructing elements. Then, copy assignment resets the elements that were previously part of the array. QPodArrayOps uses non-throwing operations. QMovableArrayOps provides full rollback in the face of exceptions (strong guarantee). QGenericArrayOps enforces that no data is leaked (all destructors called) and invariants are maintained on exceptions -- the basic guarantee. With 3 different implementations, 2 of which are non-trivial, this operation is a good showcase for QArrayOpsSelector and the different implementations. As such, it warrants its own commit. Change-Id: I21d9b4cb8e810db82623bcd1d78f583ebf3b6cb7 Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qarraydata/simplevector.h | 107 +++++++++++++++++ .../corelib/tools/qarraydata/tst_qarraydata.cpp | 131 +++++++++++++++++++++ 2 files changed, 238 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 36c9b7bc50..4aa3ab09c8 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -135,6 +135,113 @@ public: return *(end() - 1); } + void reserve(size_t n) + { + if (n > capacity() + || (n + && !d->capacityReserved + && (d->ref != 1 || (d->capacityReserved = 1, false)))) { + SimpleVector detached(Data::allocate(n, true)); + static_cast(detached.d)->copyAppend(constBegin(), constEnd()); + detached.swap(*this); + } + } + + void prepend(const_iterator first, const_iterator last) + { + if (!d->size) { + append(first, last); + return; + } + + if (first == last) + return; + + T *const begin = d->begin(); + if (d->ref != 1 + || capacity() - size() < size_t(last - first)) { + SimpleVector detached(Data::allocate( + qMax(capacity(), size() + (last - first)), d->capacityReserved)); + + static_cast(detached.d)->copyAppend(first, last); + static_cast(detached.d)->copyAppend(begin, begin + d->size); + detached.swap(*this); + + return; + } + + static_cast(d)->insert(begin, first, last); + } + + void append(const_iterator first, const_iterator last) + { + if (first == last) + return; + + if (d->ref != 1 + || capacity() - size() < size_t(last - first)) { + SimpleVector detached(Data::allocate( + qMax(capacity(), size() + (last - first)), d->capacityReserved)); + + if (d->size) { + const T *const begin = constBegin(); + static_cast(detached.d)->copyAppend(begin, begin + d->size); + } + static_cast(detached.d)->copyAppend(first, last); + detached.swap(*this); + + return; + } + + static_cast(d)->copyAppend(first, last); + } + + void insert(int position, const_iterator first, const_iterator last) + { + if (position < 0) + position += d->size + 1; + + if (position <= 0) { + prepend(first, last); + return; + } + + if (size_t(position) >= size()) { + append(first, last); + return; + } + + if (first == last) + return; + + T *const begin = d->begin(); + T *const where = begin + position; + const T *const end = begin + d->size; + if (d->ref != 1 + || capacity() - size() < size_t(last - first)) { + SimpleVector detached(Data::allocate( + qMax(capacity(), size() + (last - first)), d->capacityReserved)); + + if (position) + static_cast(detached.d)->copyAppend(begin, where); + static_cast(detached.d)->copyAppend(first, last); + static_cast(detached.d)->copyAppend(where, end); + detached.swap(*this); + + return; + } + + // Temporarily copy overlapping data, if needed + if ((first >= where && first < end) + || (last > where && last <= end)) { + SimpleVector tmp(first, last); + static_cast(d)->insert(where, tmp.constBegin(), tmp.constEnd()); + return; + } + + static_cast(d)->insert(where, first, last); + } + void swap(SimpleVector &other) { qSwap(d, other.d); diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 2972f0a678..808aa73c98 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -293,6 +293,67 @@ void tst_QArrayData::simpleVector() QVERIFY(v5.isSharedWith(v6)); QVERIFY(!v1.isSharedWith(v5)); } + + v1.prepend(array, array + sizeof(array)/sizeof(array[0])); + QCOMPARE(v1.size(), size_t(10)); + QVERIFY(v1 == v8); + + v6 = v1; + QVERIFY(v1.isSharedWith(v6)); + + v1.prepend(array, array + sizeof(array)/sizeof(array[0])); + QVERIFY(!v1.isSharedWith(v6)); + QCOMPARE(v1.size(), size_t(20)); + QCOMPARE(v6.size(), size_t(10)); + + for (int i = 0; i < 20; ++i) + QCOMPARE(v1[i], v6[i % 10]); + + v1.clear(); + + v1.append(array, array + sizeof(array)/sizeof(array[0])); + QCOMPARE(v1.size(), size_t(10)); + QVERIFY(v1 == v8); + + v6 = v1; + QVERIFY(v1.isSharedWith(v6)); + + v1.append(array, array + sizeof(array)/sizeof(array[0])); + QVERIFY(!v1.isSharedWith(v6)); + QCOMPARE(v1.size(), size_t(20)); + QCOMPARE(v6.size(), size_t(10)); + + for (int i = 0; i < 20; ++i) + QCOMPARE(v1[i], v6[i % 10]); + + v1.insert(0, v6.constBegin(), v6.constEnd()); + QCOMPARE(v1.size(), size_t(30)); + + v6 = v1; + QVERIFY(v1.isSharedWith(v6)); + + v1.insert(10, v6.constBegin(), v6.constEnd()); + QVERIFY(!v1.isSharedWith(v6)); + QCOMPARE(v1.size(), size_t(60)); + QCOMPARE(v6.size(), size_t(30)); + + for (int i = 0; i < 30; ++i) + QCOMPARE(v6[i], v8[i % 10]); + + v1.insert(v1.size(), v6.constBegin(), v6.constEnd()); + QCOMPARE(v1.size(), size_t(90)); + + v1.insert(-1, v8.constBegin(), v8.constEnd()); + QCOMPARE(v1.size(), size_t(100)); + + v1.insert(-11, v8.constBegin(), v8.constEnd()); + QCOMPARE(v1.size(), size_t(110)); + + v1.insert(-200, v8.constBegin(), v8.constEnd()); + QCOMPARE(v1.size(), size_t(120)); + + for (int i = 0; i < 120; ++i) + QCOMPARE(v1[i], v8[i % 10]); } struct Deallocator @@ -669,12 +730,82 @@ void tst_QArrayData::arrayOps() vs = SimpleVector(5, referenceString); vo = SimpleVector(5, referenceObject); + QCOMPARE(vi.size(), size_t(5)); + QCOMPARE(vs.size(), size_t(5)); + QCOMPARE(vo.size(), size_t(5)); + QCOMPARE(CountedObject::liveCount, size_t(11)); for (int i = 0; i < 5; ++i) { QCOMPARE(vi[i], referenceInt); QVERIFY(vs[i].isSharedWith(referenceString)); QCOMPARE(vo[i].id, referenceObject.id); } + + //////////////////////////////////////////////////////////////////////////// + // insert + vi.reserve(30); + vs.reserve(30); + vo.reserve(30); + + QCOMPARE(vi.size(), size_t(5)); + QCOMPARE(vs.size(), size_t(5)); + QCOMPARE(vo.size(), size_t(5)); + + QVERIFY(vi.capacity() >= 30); + QVERIFY(vs.capacity() >= 30); + QVERIFY(vo.capacity() >= 30); + + // Displace as many elements as array is extended by + vi.insert(0, intArray, intArray + 5); + vs.insert(0, stringArray, stringArray + 5); + vo.insert(0, objArray, objArray + 5); + + QCOMPARE(vi.size(), size_t(10)); + QCOMPARE(vs.size(), size_t(10)); + QCOMPARE(vo.size(), size_t(10)); + + // Displace more elements than array is extended by + vi.insert(0, intArray, intArray + 5); + vs.insert(0, stringArray, stringArray + 5); + vo.insert(0, objArray, objArray + 5); + + QCOMPARE(vi.size(), size_t(15)); + QCOMPARE(vs.size(), size_t(15)); + QCOMPARE(vo.size(), size_t(15)); + + // Displace less elements than array is extended by + vi.insert(5, vi.constBegin(), vi.constEnd()); + vs.insert(5, vs.constBegin(), vs.constEnd()); + vo.insert(5, vo.constBegin(), vo.constEnd()); + + QCOMPARE(vi.size(), size_t(30)); + QCOMPARE(vs.size(), size_t(30)); + QCOMPARE(vo.size(), size_t(30)); + + QCOMPARE(CountedObject::liveCount, size_t(36)); + for (int i = 0; i < 15; ++i) { + QCOMPARE(vi[i], intArray[i % 5]); + QVERIFY(vs[i].isSharedWith(stringArray[i % 5])); + QCOMPARE(vo[i].id, objArray[i % 5].id); + } + + for (int i = 15; i < 20; ++i) { + QCOMPARE(vi[i], referenceInt); + QVERIFY(vs[i].isSharedWith(referenceString)); + QCOMPARE(vo[i].id, referenceObject.id); + } + + for (int i = 20; i < 25; ++i) { + QCOMPARE(vi[i], intArray[i % 5]); + QVERIFY(vs[i].isSharedWith(stringArray[i % 5])); + QCOMPARE(vo[i].id, objArray[i % 5].id); + } + + for (int i = 25; i < 30; ++i) { + QCOMPARE(vi[i], referenceInt); + QVERIFY(vs[i].isSharedWith(referenceString)); + QCOMPARE(vo[i].id, referenceObject.id); + } } QTEST_APPLESS_MAIN(tst_QArrayData) -- cgit v1.2.3 From 7d16ea40331dc4480af823288e6ed3ca58a677d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 2 Nov 2011 12:10:17 +0100 Subject: Introducing QArrayDataPointer This class provides RAII functionality for handling QArrayData pointers. Together with QArrayDataHeader and QArrayDataOps, this offers common boilerplate code for implementing a container which, itself, defines its own interface. Change-Id: If38eba22fbe8f69038a06fff4acb50af434d229e Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qarraydata/simplevector.h | 60 +++++++--------------- 1 file changed, 18 insertions(+), 42 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 4aa3ab09c8..38f61189da 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -44,7 +44,7 @@ #define QARRAY_TEST_SIMPLE_VECTOR_H #include -#include +#include #include @@ -53,7 +53,6 @@ struct SimpleVector { private: typedef QTypedArrayData Data; - typedef QArrayDataOps DataOps; public: typedef T value_type; @@ -61,28 +60,21 @@ public: typedef typename Data::const_iterator const_iterator; SimpleVector() - : d(Data::sharedNull()) { } - SimpleVector(const SimpleVector &vec) - : d(vec.d) - { - d->ref.ref(); - } - SimpleVector(size_t n, const T &t) : d(Data::allocate(n)) { if (n) - static_cast(d)->copyAppend(n, t); + d->copyAppend(n, t); } SimpleVector(const T *begin, const T *end) : d(Data::allocate(end - begin)) { if (end - begin) - static_cast(d)->copyAppend(begin, end); + d->copyAppend(begin, end); } explicit SimpleVector(Data *ptr) @@ -90,23 +82,8 @@ public: { } - ~SimpleVector() - { - if (!d->ref.deref()) { - static_cast(d)->destroyAll(); - Data::deallocate(d); - } - } - - SimpleVector &operator=(const SimpleVector &vec) - { - SimpleVector temp(vec); - this->swap(temp); - return *this; - } - bool empty() const { return d->size == 0; } - bool isNull() const { return d == Data::sharedNull(); } + bool isNull() const { return d.isNull(); } bool isEmpty() const { return this->empty(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } @@ -142,7 +119,7 @@ public: && !d->capacityReserved && (d->ref != 1 || (d->capacityReserved = 1, false)))) { SimpleVector detached(Data::allocate(n, true)); - static_cast(detached.d)->copyAppend(constBegin(), constEnd()); + detached.d->copyAppend(constBegin(), constEnd()); detached.swap(*this); } } @@ -163,14 +140,14 @@ public: SimpleVector detached(Data::allocate( qMax(capacity(), size() + (last - first)), d->capacityReserved)); - static_cast(detached.d)->copyAppend(first, last); - static_cast(detached.d)->copyAppend(begin, begin + d->size); + detached.d->copyAppend(first, last); + detached.d->copyAppend(begin, begin + d->size); detached.swap(*this); return; } - static_cast(d)->insert(begin, first, last); + d->insert(begin, first, last); } void append(const_iterator first, const_iterator last) @@ -185,15 +162,15 @@ public: if (d->size) { const T *const begin = constBegin(); - static_cast(detached.d)->copyAppend(begin, begin + d->size); + detached.d->copyAppend(begin, begin + d->size); } - static_cast(detached.d)->copyAppend(first, last); + detached.d->copyAppend(first, last); detached.swap(*this); return; } - static_cast(d)->copyAppend(first, last); + d->copyAppend(first, last); } void insert(int position, const_iterator first, const_iterator last) @@ -223,9 +200,9 @@ public: qMax(capacity(), size() + (last - first)), d->capacityReserved)); if (position) - static_cast(detached.d)->copyAppend(begin, where); - static_cast(detached.d)->copyAppend(first, last); - static_cast(detached.d)->copyAppend(where, end); + detached.d->copyAppend(begin, where); + detached.d->copyAppend(first, last); + detached.d->copyAppend(where, end); detached.swap(*this); return; @@ -235,11 +212,11 @@ public: if ((first >= where && first < end) || (last > where && last <= end)) { SimpleVector tmp(first, last); - static_cast(d)->insert(where, tmp.constBegin(), tmp.constEnd()); + d->insert(where, tmp.constBegin(), tmp.constEnd()); return; } - static_cast(d)->insert(where, first, last); + d->insert(where, first, last); } void swap(SimpleVector &other) @@ -249,12 +226,11 @@ public: void clear() { - SimpleVector tmp(d); - d = Data::sharedEmpty(); + d.clear(); } private: - Data *d; + QArrayDataPointer d; }; template -- cgit v1.2.3 From 7fadc3ce322706ed6c36ad907e83fed1992b490e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 16 Dec 2011 17:22:45 +0100 Subject: Get rid of assignment operators in RefCount , and make it strictly a POD struct. Since this operator was only being used to set the initial (owned) value of the reference count, the name of the function introduced here to replace it makes that use case explicit. Change-Id: I2feadd2ac35dcb75ca211471baf5044a5f57cd62 Reviewed-by: Olivier Goffart Reviewed-by: Thiago Macieira --- tests/benchmarks/corelib/tools/qvector/qrawvector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index eb12a25403..f786d83a53 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -289,7 +289,7 @@ public: QVector mutateToVector() { Data *d = toBase(m_begin); - d->ref = 1; + d->ref.initializeOwned(); d->alloc = m_alloc; d->size = m_size; d->sharable = 0; -- cgit v1.2.3 From 3fad9a846f6a89bd342b25c319d0263794bda575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 16 Dec 2011 16:21:29 +0100 Subject: Retire the generic Q_REFCOUNT_INITIALIZER macro This was only being used to initialize static read-only RefCount instances, where the value is hard-wired to -1. Instead of allowing initialization with arbitrary values (which for a reference count can be error prone) the intent of the macro is made explicit with its replacement Q_REFCOUNT_INITIALIZE_STATIC. Change-Id: I5b0f3f1eb58c3d010e49e9259ff4d06cbab2fd35 Reviewed-by: Olivier Goffart Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 808aa73c98..241ef3b3e0 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -68,7 +68,7 @@ void tst_QArrayData::referenceCounting() { { // Reference counting initialized to 1 (owned) - QArrayData array = { Q_REFCOUNT_INITIALIZER(1), 0, 0, 0, 0 }; + QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(1) }, 0, 0, 0, 0 }; QCOMPARE(int(array.ref), 1); @@ -92,7 +92,7 @@ void tst_QArrayData::referenceCounting() { // Reference counting initialized to -1 (static read-only data) - QArrayData array = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, 0 }; + QArrayData array = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 }; QCOMPARE(int(array.ref), -1); @@ -161,7 +161,7 @@ void tst_QArrayData::staticData() void tst_QArrayData::simpleVector() { - QArrayData data0 = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, 0 }; + QArrayData data0 = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 }; QStaticArrayData data1 = { Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 7), { 0, 1, 2, 3, 4, 5, 6 } -- cgit v1.2.3 From 9a890a519e9e314b99ca765a7127aa8bdc5b8870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 25 Nov 2011 11:09:09 +0100 Subject: Add support for setSharable in RefCount A reference count of 0 (zero) would never change. RefCount::deref to zero would return false (resource should be freed), subsequent calls on the same state would return true and not change state. While safe from RefCount's side, calling deref on a reference count of zero potentially indicated a dangling reference. With this change, a reference count of 0 is now abused to imply a non-sharable instance (cf. QVector::setSharable). This instance is to be deleted upon deref(), as the data is not shared and has a single owner. In practice, this means an (intentional) change in behaviour in that deref'ing zero still won't change state, but will return false, turning previous access to dangling references into double free errors. Users of RefCount wanting to support non-sharable instances are required to check the return of RefCount::ref() and use RefCount::isShared() to determine whether to detach (instead of directly checking count == 1). New functions are introduced to determine whether RefCount indicates a "Static" (permanent, typically read-only) or "Sharable" instance and whether the instance is currently "Shared" and requires detaching prior to accepting modifications.. This change formalizes -1 as the value used to flag persistent, read-only instances, no longer reserving the full negative domain. The concrete value is part of the ABI, but not of the API. (isStatic and Q_REFCOUNT_INITIALIZE_STATIC are part of the API, instead) Change-Id: I9a63c844155319bef0411e02b47f9d92476afefe Reviewed-by: Thiago Macieira Reviewed-by: Bradley T. Hughes Reviewed-by: Robin Burchell --- tests/auto/corelib/tools/qarraydata/simplevector.h | 2 + .../corelib/tools/qarraydata/tst_qarraydata.cpp | 63 ++++++++++++++++++++-- 2 files changed, 60 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 38f61189da..c5e19f3c55 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -86,6 +86,8 @@ public: bool isNull() const { return d.isNull(); } bool isEmpty() const { return this->empty(); } + bool isStatic() const { return d->ref.isStatic(); } + bool isShared() const { return d->ref.isShared(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } size_t size() const { return d->size; } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 241ef3b3e0..89a1f8bc75 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -72,13 +72,16 @@ void tst_QArrayData::referenceCounting() QCOMPARE(int(array.ref), 1); - array.ref.ref(); + QVERIFY(!array.ref.isStatic()); + QVERIFY(array.ref.isSharable()); + + QVERIFY(array.ref.ref()); QCOMPARE(int(array.ref), 2); QVERIFY(array.ref.deref()); QCOMPARE(int(array.ref), 1); - array.ref.ref(); + QVERIFY(array.ref.ref()); QCOMPARE(int(array.ref), 2); QVERIFY(array.ref.deref()); @@ -90,13 +93,35 @@ void tst_QArrayData::referenceCounting() // Now would be a good time to free/release allocated data } + { + // Reference counting initialized to 0 (non-sharable) + QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 }; + + QCOMPARE(int(array.ref), 0); + + QVERIFY(!array.ref.isStatic()); + QVERIFY(!array.ref.isSharable()); + + QVERIFY(!array.ref.ref()); + // Reference counting fails, data should be copied + QCOMPARE(int(array.ref), 0); + + QVERIFY(!array.ref.deref()); + QCOMPARE(int(array.ref), 0); + + // Free/release data + } + { // Reference counting initialized to -1 (static read-only data) QArrayData array = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 }; QCOMPARE(int(array.ref), -1); - array.ref.ref(); + QVERIFY(array.ref.isStatic()); + QVERIFY(array.ref.isSharable()); + + QVERIFY(array.ref.ref()); QCOMPARE(int(array.ref), -1); QVERIFY(array.ref.deref()); @@ -109,11 +134,19 @@ void tst_QArrayData::sharedNullEmpty() QArrayData *null = const_cast(&QArrayData::shared_null); QArrayData *empty = const_cast(&QArrayData::shared_empty); + QVERIFY(null->ref.isStatic()); + QVERIFY(null->ref.isSharable()); + QVERIFY(null->ref.isShared()); + + QVERIFY(empty->ref.isStatic()); + QVERIFY(empty->ref.isSharable()); + QVERIFY(empty->ref.isShared()); + QCOMPARE(int(null->ref), -1); QCOMPARE(int(empty->ref), -1); - null->ref.ref(); - empty->ref.ref(); + QVERIFY(null->ref.ref()); + QVERIFY(empty->ref.ref()); QCOMPARE(int(null->ref), -1); QCOMPARE(int(empty->ref), -1); @@ -218,6 +251,26 @@ void tst_QArrayData::simpleVector() QVERIFY(v7.capacity() >= size_t(10)); QVERIFY(v8.capacity() >= size_t(10)); + QVERIFY(v1.isStatic()); + QVERIFY(v2.isStatic()); + QVERIFY(v3.isStatic()); + QVERIFY(v4.isStatic()); + QVERIFY(v5.isStatic()); + QVERIFY(v6.isStatic()); + QVERIFY(!v7.isStatic()); + QVERIFY(!v8.isStatic()); + + QVERIFY(v1.isShared()); + QVERIFY(v2.isShared()); + QVERIFY(v3.isShared()); + QVERIFY(v4.isShared()); + QVERIFY(v5.isShared()); + QVERIFY(v6.isShared()); + QVERIFY(!v7.isShared()); + QVERIFY((SimpleVector(v7), v7.isShared())); + QVERIFY(!v7.isShared()); + QVERIFY(!v8.isShared()); + QVERIFY(v1.isSharedWith(v2)); QVERIFY(v1.isSharedWith(v3)); QVERIFY(!v1.isSharedWith(v4)); -- cgit v1.2.3 From fed603fde515339ec520accefded211ac6f69982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 4 Jan 2012 14:30:42 +0100 Subject: Ensure shared_null(s) are statically initialized on VS 2010 This removes const qualification on data members of QConst*Data, which was subjecting QString's and QByteArray's shared_null to the "order of static initialization fiasco", with up-to-date VS 2010. Furthermore, the const qualification in the places where it was removed had little meaning and no value. It was unnecessary. As such, "Const" was removed from the struct's names and "Static" used in its place, to imply their usefulness in supporting statically-initialized fixed-size (string and byte) containers. A test case was added to QArrayData as that is meant to replace both QStringData and QByteArrayData in the near future. VS issue reported at: https://connect.microsoft.com/VisualStudio/feedback/details/716461 Change-Id: I3d86f2a387a68f359bb3d8f4d10cf3da51c6ecf7 Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 89a1f8bc75..63a26ed926 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -46,6 +46,23 @@ #include "simplevector.h" +struct SharedNullVerifier +{ + SharedNullVerifier() + { + Q_ASSERT(QArrayData::shared_null.ref.isStatic()); + Q_ASSERT(QArrayData::shared_null.ref.isShared()); + Q_ASSERT(QArrayData::shared_null.ref.isSharable()); + } +}; + +// This is meant to verify/ensure that shared_null is not being dynamically +// initialized and stays away from the order-of-static-initialization fiasco. +// +// Of course, if this was to fail, qmake and the build should have crashed and +// burned before we ever got to this point :-) +SharedNullVerifier globalInit; + class tst_QArrayData : public QObject { Q_OBJECT -- cgit v1.2.3 From b29338e80588b97efdb57d62cd3ca474f16db965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 25 Nov 2011 13:16:24 +0100 Subject: Add test for QVector::setSharable Change-Id: Id31761bfb642d4ce515768c1ffe1e3088d883353 Reviewed-by: Bradley T. Hughes Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qvector/tst_qvector.cpp | 94 ++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index acf3756258..704d75b709 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -85,6 +85,8 @@ private slots: void initializeList(); void const_shared_null(); + void setSharable_data(); + void setSharable(); }; void tst_QVector::constructors() const @@ -946,5 +948,97 @@ void tst_QVector::const_shared_null() QVERIFY(!v2.isDetached()); } +Q_DECLARE_METATYPE(QVector); + +void tst_QVector::setSharable_data() +{ + QTest::addColumn >("vector"); + QTest::addColumn("size"); + QTest::addColumn("capacity"); + QTest::addColumn("isCapacityReserved"); + + QVector null; + QVector empty(0, 5); + QVector emptyReserved; + QVector nonEmpty; + QVector nonEmptyReserved; + + emptyReserved.reserve(10); + nonEmptyReserved.reserve(15); + + nonEmpty << 0 << 1 << 2 << 3 << 4; + nonEmptyReserved << 0 << 1 << 2 << 3 << 4 << 5 << 6; + + QVERIFY(emptyReserved.capacity() >= 10); + QVERIFY(nonEmptyReserved.capacity() >= 15); + + QTest::newRow("null") << null << 0 << 0 << false; + QTest::newRow("empty") << empty << 0 << 0 << false; + QTest::newRow("empty, Reserved") << emptyReserved << 0 << 10 << true; + QTest::newRow("non-empty") << nonEmpty << 5 << 0 << false; + QTest::newRow("non-empty, Reserved") << nonEmptyReserved << 7 << 15 << true; +} + +void tst_QVector::setSharable() +{ + QFETCH(QVector, vector); + QFETCH(int, size); + QFETCH(int, capacity); + QFETCH(bool, isCapacityReserved); + + QVERIFY(!vector.isDetached()); // Shared with QTest + + vector.setSharable(true); + + QCOMPARE(vector.size(), size); + if (isCapacityReserved) + QVERIFY2(vector.capacity() >= capacity, + qPrintable(QString("Capacity is %1, expected at least %2.") + .arg(vector.capacity()) + .arg(capacity))); + + { + QVector copy(vector); + + QVERIFY(!copy.isDetached()); + QVERIFY(copy.isSharedWith(vector)); + } + + vector.setSharable(false); + QVERIFY(vector.isDetached() || vector.isSharedWith(QVector())); + + { + QVector copy(vector); + + QVERIFY(copy.isDetached() || copy.isSharedWith(QVector())); + QCOMPARE(copy.size(), size); + if (isCapacityReserved) + QVERIFY2(copy.capacity() >= capacity, + qPrintable(QString("Capacity is %1, expected at least %2.") + .arg(vector.capacity()) + .arg(capacity))); + QCOMPARE(copy, vector); + } + + vector.setSharable(true); + + { + QVector copy(vector); + + QVERIFY(!copy.isDetached()); + QVERIFY(copy.isSharedWith(vector)); + } + + for (int i = 0; i < vector.size(); ++i) + QCOMPARE(vector[i], i); + + QCOMPARE(vector.size(), size); + if (isCapacityReserved) + QVERIFY2(vector.capacity() >= capacity, + qPrintable(QString("Capacity is %1, expected at least %2.") + .arg(vector.capacity()) + .arg(capacity))); +} + QTEST_APPLESS_MAIN(tst_QVector) #include "tst_qvector.moc" -- cgit v1.2.3 From 51048e1f31df5be45e71a75fc535111dd36c4c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 24 Nov 2011 17:22:37 +0100 Subject: Adding detach to QArrayDataPointer Detaching operations added to SimpleVector Change-Id: I5f549582cf579569f08cb8d53a6d12fe32b862e6 Reviewed-by: Bradley T. Hughes Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 25 +++++++++++++++ .../corelib/tools/qarraydata/tst_qarraydata.cpp | 37 ++++++++++++++++++---- 2 files changed, 56 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index c5e19f3c55..9ab28a9ddd 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -93,15 +93,35 @@ public: size_t size() const { return d->size; } size_t capacity() const { return d->alloc; } + iterator begin() { detach(); return d->begin(); } + iterator end() { detach(); return d->end(); } + const_iterator begin() const { return d->begin(); } const_iterator end() const { return d->end(); } const_iterator constBegin() const { return begin(); } const_iterator constEnd() const { return end(); } + T &operator[](size_t i) { Q_ASSERT(i < size_t(d->size)); detach(); return begin()[i]; } + T &at(size_t i) { Q_ASSERT(i < size_t(d->size)); detach(); return begin()[i]; } + const T &operator[](size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; } const T &at(size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; } + T &front() + { + Q_ASSERT(!isEmpty()); + detach(); + return *begin(); + } + + T &back() + { + Q_ASSERT(!isEmpty()); + detach(); + return *(end() - 1); + } + const T &front() const { Q_ASSERT(!isEmpty()); @@ -231,6 +251,11 @@ public: d.clear(); } + void detach() + { + d.detach(); + } + private: QArrayDataPointer d; }; diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 63a26ed926..e9a3218331 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -81,6 +81,8 @@ private slots: void arrayOps(); }; +template const T &const_(const T &t) { return t; } + void tst_QArrayData::referenceCounting() { { @@ -320,13 +322,36 @@ void tst_QArrayData::simpleVector() QVERIFY(v6 >= v1); QVERIFY(!(v1 >= v6)); - QCOMPARE(v6.front(), 0); - QCOMPARE(v6.back(), 6); + { + SimpleVector temp(v6); + + QCOMPARE(const_(v6).front(), 0); + QCOMPARE(const_(v6).back(), 6); + + QVERIFY(temp.isShared()); + QVERIFY(temp.isSharedWith(v6)); + + QCOMPARE(temp.front(), 0); + QCOMPARE(temp.back(), 6); + + // Detached + QVERIFY(!temp.isShared()); + const int *const tempBegin = temp.begin(); + + for (size_t i = 0; i < v6.size(); ++i) { + QCOMPARE(const_(v6)[i], int(i)); + QCOMPARE(const_(v6).at(i), int(i)); + QCOMPARE(&const_(v6)[i], &const_(v6).at(i)); + + QCOMPARE(const_(v8)[i], const_(v6)[i]); + + QCOMPARE(temp[i], int(i)); + QCOMPARE(temp.at(i), int(i)); + QCOMPARE(&temp[i], &temp.at(i)); + } - for (size_t i = 0; i < v6.size(); ++i) { - QCOMPARE(v6[i], int(i)); - QCOMPARE(v6.at(i), int(i)); - QCOMPARE(&v6[i], &v6.at(i)); + // A single detach should do + QCOMPARE(temp.begin(), tempBegin); } { -- cgit v1.2.3 From 3d61c5ca8f00b489435d5bea776b4a4c97c39793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 24 Nov 2011 17:15:11 +0100 Subject: Add setSharable support in QArrayData stack Making use of the same feature added in RefCount. To keep with the intention of avoiding the allocation of "empty" array headers, this introduces an unsharable_empty, which allows users to maintain the "unsharable bit" on empty containers, without imposing any actual allocations. (Before anyone asks, there is no point to a zero-sized capacity-reserved container so no other combinations are needed for now.) Change-Id: Icaa40ac3100ad954fdc20dee0c991861136a5b19 Reviewed-by: Bradley T. Hughes --- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 152 ++++++++++++++++++++- 1 file changed, 146 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index e9a3218331..e8edab20e4 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -79,6 +79,8 @@ private slots: void typedData(); void gccBug43247(); void arrayOps(); + void setSharable_data(); + void setSharable(); }; template const T &const_(const T &t) { return t; } @@ -477,6 +479,7 @@ void tst_QArrayData::allocate_data() QTest::addColumn("objectSize"); QTest::addColumn("alignment"); QTest::addColumn("isCapacityReserved"); + QTest::addColumn("isSharable"); QTest::addColumn("commonEmpty"); struct { @@ -492,10 +495,13 @@ void tst_QArrayData::allocate_data() struct { char const *description; bool isCapacityReserved; + bool isSharable; const QArrayData *commonEmpty; } options[] = { - { "Default", false, &QArrayData::shared_empty }, - { "Reserved", true, &QArrayData::shared_empty }, + { "Default", false, true, &QArrayData::shared_empty }, + { "Reserved", true, true, &QArrayData::shared_empty }, + { "Reserved | Unsharable", true, false, &QArrayData::unsharable_empty }, + { "Unsharable", false, false, &QArrayData::unsharable_empty }, }; for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i) @@ -505,7 +511,8 @@ void tst_QArrayData::allocate_data() + QLatin1String(": ") + QLatin1String(options[j].description))) << types[i].objectSize << types[i].alignment - << options[j].isCapacityReserved << options[j].commonEmpty; + << options[j].isCapacityReserved << options[j].isSharable + << options[j].commonEmpty; } void tst_QArrayData::allocate() @@ -513,6 +520,7 @@ void tst_QArrayData::allocate() QFETCH(size_t, objectSize); QFETCH(size_t, alignment); QFETCH(bool, isCapacityReserved); + QFETCH(bool, isSharable); QFETCH(const QArrayData *, commonEmpty); // Minimum alignment that can be requested is that of QArrayData. @@ -521,19 +529,20 @@ void tst_QArrayData::allocate() // Shared Empty QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0, - isCapacityReserved), commonEmpty); + isCapacityReserved, isSharable), commonEmpty); Deallocator keeper(objectSize, minAlignment); keeper.headers.reserve(1024); for (int capacity = 1; capacity <= 1024; capacity <<= 1) { QArrayData *data = QArrayData::allocate(objectSize, minAlignment, - capacity, isCapacityReserved); + capacity, isCapacityReserved, isSharable); keeper.headers.append(data); QCOMPARE(data->size, 0); QVERIFY(data->alloc >= uint(capacity)); QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); + QCOMPARE(data->ref.isSharable(), isSharable); // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. @@ -569,7 +578,7 @@ void tst_QArrayData::alignment() for (int i = 0; i < 100; ++i) { QArrayData *data = QArrayData::allocate(sizeof(Unaligned), - minAlignment, 8, false); + minAlignment, 8, false, true); keeper.headers.append(data); QVERIFY(data); @@ -903,5 +912,136 @@ void tst_QArrayData::arrayOps() } } +Q_DECLARE_METATYPE(QArrayDataPointer) + +static inline bool arrayIsFilledWith(const QArrayDataPointer &array, + int fillValue, size_t size) +{ + const int *iter = array->begin(); + const int *const end = array->end(); + + for (size_t i = 0; i < size; ++i, ++iter) + if (*iter != fillValue) + return false; + + if (iter != end) + return false; + + return true; +} + +void tst_QArrayData::setSharable_data() +{ + QTest::addColumn >("array"); + QTest::addColumn("size"); + QTest::addColumn("capacity"); + QTest::addColumn("isCapacityReserved"); + QTest::addColumn("fillValue"); + + QArrayDataPointer null; + QArrayDataPointer empty; empty.clear(); + + static QStaticArrayData staticArrayData = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10), + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } + }; + + QArrayDataPointer emptyReserved(QTypedArrayData::allocate(5, true, true)); + QArrayDataPointer nonEmpty(QTypedArrayData::allocate(10, false, true)); + QArrayDataPointer nonEmptyReserved(QTypedArrayData::allocate(15, true, true)); + QArrayDataPointer staticArray(static_cast *>(&staticArrayData.header)); + + nonEmpty->copyAppend(5, 1); + nonEmptyReserved->copyAppend(7, 2); + + QTest::newRow("shared-null") << null << size_t(0) << size_t(0) << false << 0; + QTest::newRow("shared-empty") << empty << size_t(0) << size_t(0) << false << 0; + // unsharable-empty implicitly tested in shared-empty + QTest::newRow("empty-reserved") << emptyReserved << size_t(0) << size_t(5) << true << 0; + QTest::newRow("non-empty") << nonEmpty << size_t(5) << size_t(10) << false << 1; + QTest::newRow("non-empty-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2; + QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3; +} + +void tst_QArrayData::setSharable() +{ + QFETCH(QArrayDataPointer, array); + QFETCH(size_t, size); + QFETCH(size_t, capacity); + QFETCH(bool, isCapacityReserved); + QFETCH(int, fillValue); + + QVERIFY(array->ref.isShared()); // QTest has a copy + QVERIFY(array->ref.isSharable()); + + QCOMPARE(size_t(array->size), size); + QCOMPARE(size_t(array->alloc), capacity); + QCOMPARE(bool(array->capacityReserved), isCapacityReserved); + QVERIFY(arrayIsFilledWith(array, fillValue, size)); + + // shared-null becomes shared-empty, may otherwise detach + array.setSharable(true); + + QVERIFY(array->ref.isSharable()); + QVERIFY(arrayIsFilledWith(array, fillValue, size)); + + { + QArrayDataPointer copy(array); + QVERIFY(array->ref.isShared()); + QVERIFY(array->ref.isSharable()); + QCOMPARE(copy.data(), array.data()); + } + + // Unshare, must detach + array.setSharable(false); + + // Immutability (alloc == 0) is lost on detach + if (capacity == 0 && size != 0) + capacity = size; + + QVERIFY(!array->ref.isShared()); + QVERIFY(!array->ref.isSharable()); + + QCOMPARE(size_t(array->size), size); + QCOMPARE(size_t(array->alloc), capacity); + QCOMPARE(bool(array->capacityReserved), isCapacityReserved); + QVERIFY(arrayIsFilledWith(array, fillValue, size)); + + { + QArrayDataPointer copy(array); + QVERIFY(!array->ref.isShared()); + QVERIFY(!array->ref.isSharable()); + + // Null/empty is always shared + QCOMPARE(copy->ref.isShared(), !(size || isCapacityReserved)); + QVERIFY(copy->ref.isSharable()); + + QCOMPARE(size_t(copy->size), size); + QCOMPARE(size_t(copy->alloc), capacity); + QCOMPARE(bool(copy->capacityReserved), isCapacityReserved); + QVERIFY(arrayIsFilledWith(copy, fillValue, size)); + } + + // Make sharable, again + array.setSharable(true); + + QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved)); + QVERIFY(array->ref.isSharable()); + + QCOMPARE(size_t(array->size), size); + QCOMPARE(size_t(array->alloc), capacity); + QCOMPARE(bool(array->capacityReserved), isCapacityReserved); + QVERIFY(arrayIsFilledWith(array, fillValue, size)); + + { + QArrayDataPointer copy(array); + QVERIFY(array->ref.isShared()); + QCOMPARE(copy.data(), array.data()); + } + + QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved)); + QVERIFY(array->ref.isSharable()); +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From d91b4f0b13926a0861d7e172f14437d20d06332e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 5 Jan 2012 16:29:42 +0100 Subject: Remove shared_empty and unsharable_empty from API They still exist and help avoid allocation of "empty" array headers, but they're no longer part of the public API, thus reducing relocatable symbols and relocations in inline code. This means an extra non-inline call on QArrayDataPointer::clear and setSharable operations, which are (expensive) detaching operations, anyway. Change-Id: Iea804e5ddc8af55ebc0951ca17a7a4e8401abc55 Reviewed-by: Bradley T. Hughes Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index e8edab20e4..47d5e2a32b 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -153,7 +153,7 @@ void tst_QArrayData::referenceCounting() void tst_QArrayData::sharedNullEmpty() { QArrayData *null = const_cast(&QArrayData::shared_null); - QArrayData *empty = const_cast(&QArrayData::shared_empty); + QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0, false, true); QVERIFY(null->ref.isStatic()); QVERIFY(null->ref.isSharable()); @@ -492,16 +492,22 @@ void tst_QArrayData::allocate_data() { "void *", sizeof(void *), Q_ALIGNOF(void *) } }; + QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, false, true); + QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, false, false); + + QVERIFY(shared_empty); + QVERIFY(unsharable_empty); + struct { char const *description; bool isCapacityReserved; bool isSharable; const QArrayData *commonEmpty; } options[] = { - { "Default", false, true, &QArrayData::shared_empty }, - { "Reserved", true, true, &QArrayData::shared_empty }, - { "Reserved | Unsharable", true, false, &QArrayData::unsharable_empty }, - { "Unsharable", false, false, &QArrayData::unsharable_empty }, + { "Default", false, true, shared_empty }, + { "Reserved", true, true, shared_empty }, + { "Reserved | Unsharable", true, false, unsharable_empty }, + { "Unsharable", false, false, unsharable_empty }, }; for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i) @@ -635,7 +641,7 @@ void tst_QArrayData::typedData() { QTypedArrayData *null = QTypedArrayData::sharedNull(); - QTypedArrayData *empty = QTypedArrayData::sharedEmpty(); + QTypedArrayData *empty = QTypedArrayData::allocate(0); QVERIFY(null != empty); -- cgit v1.2.3 From f1e48d48fd58b28b1dc18652af3fc74da5e112fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 22 Nov 2011 17:28:14 +0100 Subject: Add AllocateOptions to QArrayData MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This approach is better for future ABI evolution than using individual bool parameters. QArrayData now also offers to calculate allocate options for typical detach and clone operations: the CapacityReserved flag is preserved, while cloning resets the Unsharable state. Change-Id: I256e135adcf27a52a5c7d6130069c35c8b946bc3 Reviewed-by: João Abecasis --- tests/auto/corelib/tools/qarraydata/simplevector.h | 12 ++++--- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 42 +++++++++++++--------- 2 files changed, 34 insertions(+), 20 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 9ab28a9ddd..4f02df1c40 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -140,7 +140,8 @@ public: || (n && !d->capacityReserved && (d->ref != 1 || (d->capacityReserved = 1, false)))) { - SimpleVector detached(Data::allocate(n, true)); + SimpleVector detached(Data::allocate(n, + d->detachFlags() | Data::CapacityReserved)); detached.d->copyAppend(constBegin(), constEnd()); detached.swap(*this); } @@ -160,7 +161,8 @@ public: if (d->ref != 1 || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( - qMax(capacity(), size() + (last - first)), d->capacityReserved)); + qMax(capacity(), size() + (last - first)), + d->detachFlags())); detached.d->copyAppend(first, last); detached.d->copyAppend(begin, begin + d->size); @@ -180,7 +182,8 @@ public: if (d->ref != 1 || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( - qMax(capacity(), size() + (last - first)), d->capacityReserved)); + qMax(capacity(), size() + (last - first)), + d->detachFlags())); if (d->size) { const T *const begin = constBegin(); @@ -219,7 +222,8 @@ public: if (d->ref != 1 || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( - qMax(capacity(), size() + (last - first)), d->capacityReserved)); + qMax(capacity(), size() + (last - first)), + d->detachFlags())); if (position) detached.d->copyAppend(begin, where); diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 47d5e2a32b..2df4131f4a 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -153,7 +153,7 @@ void tst_QArrayData::referenceCounting() void tst_QArrayData::sharedNullEmpty() { QArrayData *null = const_cast(&QArrayData::shared_null); - QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0, false, true); + QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0); QVERIFY(null->ref.isStatic()); QVERIFY(null->ref.isSharable()); @@ -473,11 +473,13 @@ struct Deallocator }; Q_DECLARE_METATYPE(const QArrayData *) +Q_DECLARE_METATYPE(QArrayData::AllocateOptions) void tst_QArrayData::allocate_data() { QTest::addColumn("objectSize"); QTest::addColumn("alignment"); + QTest::addColumn("allocateOptions"); QTest::addColumn("isCapacityReserved"); QTest::addColumn("isSharable"); QTest::addColumn("commonEmpty"); @@ -492,22 +494,25 @@ void tst_QArrayData::allocate_data() { "void *", sizeof(void *), Q_ALIGNOF(void *) } }; - QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, false, true); - QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, false, false); + QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0); + QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable); QVERIFY(shared_empty); QVERIFY(unsharable_empty); struct { char const *description; + QArrayData::AllocateOptions allocateOptions; bool isCapacityReserved; bool isSharable; const QArrayData *commonEmpty; } options[] = { - { "Default", false, true, shared_empty }, - { "Reserved", true, true, shared_empty }, - { "Reserved | Unsharable", true, false, unsharable_empty }, - { "Unsharable", false, false, unsharable_empty }, + { "Default", QArrayData::Default, false, true, shared_empty }, + { "Reserved", QArrayData::CapacityReserved, true, true, shared_empty }, + { "Reserved | Unsharable", + QArrayData::CapacityReserved | QArrayData::Unsharable, true, false, + unsharable_empty }, + { "Unsharable", QArrayData::Unsharable, false, false, unsharable_empty }, }; for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i) @@ -517,14 +522,15 @@ void tst_QArrayData::allocate_data() + QLatin1String(": ") + QLatin1String(options[j].description))) << types[i].objectSize << types[i].alignment - << options[j].isCapacityReserved << options[j].isSharable - << options[j].commonEmpty; + << options[j].allocateOptions << options[j].isCapacityReserved + << options[j].isSharable << options[j].commonEmpty; } void tst_QArrayData::allocate() { QFETCH(size_t, objectSize); QFETCH(size_t, alignment); + QFETCH(QArrayData::AllocateOptions, allocateOptions); QFETCH(bool, isCapacityReserved); QFETCH(bool, isSharable); QFETCH(const QArrayData *, commonEmpty); @@ -535,14 +541,14 @@ void tst_QArrayData::allocate() // Shared Empty QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0, - isCapacityReserved, isSharable), commonEmpty); + QArrayData::AllocateOptions(allocateOptions)), commonEmpty); Deallocator keeper(objectSize, minAlignment); keeper.headers.reserve(1024); for (int capacity = 1; capacity <= 1024; capacity <<= 1) { QArrayData *data = QArrayData::allocate(objectSize, minAlignment, - capacity, isCapacityReserved, isSharable); + capacity, QArrayData::AllocateOptions(allocateOptions)); keeper.headers.append(data); QCOMPARE(data->size, 0); @@ -584,7 +590,7 @@ void tst_QArrayData::alignment() for (int i = 0; i < 100; ++i) { QArrayData *data = QArrayData::allocate(sizeof(Unaligned), - minAlignment, 8, false, true); + minAlignment, 8, QArrayData::Default); keeper.headers.append(data); QVERIFY(data); @@ -952,10 +958,14 @@ void tst_QArrayData::setSharable_data() { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } }; - QArrayDataPointer emptyReserved(QTypedArrayData::allocate(5, true, true)); - QArrayDataPointer nonEmpty(QTypedArrayData::allocate(10, false, true)); - QArrayDataPointer nonEmptyReserved(QTypedArrayData::allocate(15, true, true)); - QArrayDataPointer staticArray(static_cast *>(&staticArrayData.header)); + QArrayDataPointer emptyReserved(QTypedArrayData::allocate(5, + QArrayData::CapacityReserved)); + QArrayDataPointer nonEmpty(QTypedArrayData::allocate(10, + QArrayData::Default)); + QArrayDataPointer nonEmptyReserved(QTypedArrayData::allocate(15, + QArrayData::CapacityReserved)); + QArrayDataPointer staticArray( + static_cast *>(&staticArrayData.header)); nonEmpty->copyAppend(5, 1); nonEmptyReserved->copyAppend(7, 2); -- cgit v1.2.3 From cb0cdf6c0835c7cdff341c285cd0708aa2f4cb0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 31 Oct 2011 15:30:20 +0100 Subject: Use RefCount::setSharable feature in QVector Note: This constitutes a break in Binary Compatibility. Change-Id: I050587901725b701f20dd46475ae48aec28aa54d Reviewed-by: Bradley T. Hughes --- tests/benchmarks/corelib/tools/qvector/qrawvector.h | 1 - 1 file changed, 1 deletion(-) (limited to 'tests') diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index f786d83a53..2cdabb30c5 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -292,7 +292,6 @@ public: d->ref.initializeOwned(); d->alloc = m_alloc; d->size = m_size; - d->sharable = 0; d->capacity = 0; QVector v; -- cgit v1.2.3 From 25b8b2437ca4dc2d77ab985f491867bdbe2fff32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 25 Nov 2011 14:12:54 +0100 Subject: Add setSharable support to SimpleVector Change-Id: I606064d86b58be1a6a57f64f4eb55a4a751a0811 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 11 ++-- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 72 ++++++++++++++++++++++ 2 files changed, 79 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 4f02df1c40..e7032f0608 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -89,6 +89,9 @@ public: bool isStatic() const { return d->ref.isStatic(); } bool isShared() const { return d->ref.isShared(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } + bool isSharable() const { return d->ref.isSharable(); } + + void setSharable(bool sharable) { d.setSharable(sharable); } size_t size() const { return d->size; } size_t capacity() const { return d->alloc; } @@ -139,7 +142,7 @@ public: if (n > capacity() || (n && !d->capacityReserved - && (d->ref != 1 || (d->capacityReserved = 1, false)))) { + && (d->ref.isShared() || (d->capacityReserved = 1, false)))) { SimpleVector detached(Data::allocate(n, d->detachFlags() | Data::CapacityReserved)); detached.d->copyAppend(constBegin(), constEnd()); @@ -158,7 +161,7 @@ public: return; T *const begin = d->begin(); - if (d->ref != 1 + if (d->ref.isShared() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( qMax(capacity(), size() + (last - first)), @@ -179,7 +182,7 @@ public: if (first == last) return; - if (d->ref != 1 + if (d->ref.isShared() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( qMax(capacity(), size() + (last - first)), @@ -219,7 +222,7 @@ public: T *const begin = d->begin(); T *const where = begin + position; const T *const end = begin + d->size; - if (d->ref != 1 + if (d->ref.isShared() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( qMax(capacity(), size() + (last - first)), diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 2df4131f4a..90c865c9e7 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -292,6 +292,15 @@ void tst_QArrayData::simpleVector() QVERIFY(!v7.isShared()); QVERIFY(!v8.isShared()); + QVERIFY(v1.isSharable()); + QVERIFY(v2.isSharable()); + QVERIFY(v3.isSharable()); + QVERIFY(v4.isSharable()); + QVERIFY(v5.isSharable()); + QVERIFY(v6.isSharable()); + QVERIFY(v7.isSharable()); + QVERIFY(v8.isSharable()); + QVERIFY(v1.isSharedWith(v2)); QVERIFY(v1.isSharedWith(v3)); QVERIFY(!v1.isSharedWith(v4)); @@ -451,6 +460,69 @@ void tst_QArrayData::simpleVector() for (int i = 0; i < 120; ++i) QCOMPARE(v1[i], v8[i % 10]); + + { + v7.setSharable(true); + QVERIFY(v7.isSharable()); + + SimpleVector copy1(v7); + QVERIFY(copy1.isSharedWith(v7)); + + v7.setSharable(false); + QVERIFY(!v7.isSharable()); + + QVERIFY(!copy1.isSharedWith(v7)); + QCOMPARE(v7.size(), copy1.size()); + for (size_t i = 0; i < copy1.size(); ++i) + QCOMPARE(v7[i], copy1[i]); + + SimpleVector clone(v7); + QVERIFY(!clone.isSharedWith(v7)); + QCOMPARE(clone.size(), copy1.size()); + for (size_t i = 0; i < copy1.size(); ++i) + QCOMPARE(clone[i], copy1[i]); + + v7.setSharable(true); + QVERIFY(v7.isSharable()); + + SimpleVector copy2(v7); + QVERIFY(copy2.isSharedWith(v7)); + } + + { + SimpleVector null; + SimpleVector empty(0, 5); + + QVERIFY(null.isSharable()); + QVERIFY(empty.isSharable()); + + null.setSharable(true); + empty.setSharable(true); + + QVERIFY(null.isSharable()); + QVERIFY(empty.isSharable()); + + QVERIFY(null.isEmpty()); + QVERIFY(empty.isEmpty()); + + null.setSharable(false); + empty.setSharable(false); + + QVERIFY(!null.isSharable()); + QVERIFY(!empty.isSharable()); + + QVERIFY(null.isEmpty()); + QVERIFY(empty.isEmpty()); + + null.setSharable(true); + empty.setSharable(true); + + QVERIFY(null.isSharable()); + QVERIFY(empty.isSharable()); + + QVERIFY(null.isEmpty()); + QVERIFY(empty.isEmpty()); + } } struct Deallocator -- cgit v1.2.3 From 5a92bc9760eb0bff73ac312850f81059f05eb5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 6 Jan 2012 14:38:57 +0100 Subject: Don't allocate when inserting overlapping data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (This is only for a test case, but still...) Change-Id: Ied205860e5469000249e15a5478c10db53f1fdaa Reviewed-by: Thiago Macieira Reviewed-by: Jędrzej Nowacki --- tests/auto/corelib/tools/qarraydata/simplevector.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index e7032f0608..54c5fd2f61 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -237,11 +237,15 @@ public: return; } - // Temporarily copy overlapping data, if needed if ((first >= where && first < end) || (last > where && last <= end)) { - SimpleVector tmp(first, last); - d->insert(where, tmp.constBegin(), tmp.constEnd()); + // Copy overlapping data first and only then shuffle it into place + T *start = d->begin() + position; + T *middle = d->end(); + + d->copyAppend(first, last); + std::rotate(start, middle, d->end()); + return; } -- cgit v1.2.3 From 2c52e9a5c1d6ef6cbf4577430e14027375465c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 10 Jan 2012 16:03:30 +0100 Subject: Expand if condition for readability Change-Id: I5057c236457587ad03b55019cb340cf59d9ecdb5 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 54c5fd2f61..a1eb2dac48 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -139,15 +139,22 @@ public: void reserve(size_t n) { - if (n > capacity() - || (n - && !d->capacityReserved - && (d->ref.isShared() || (d->capacityReserved = 1, false)))) { - SimpleVector detached(Data::allocate(n, - d->detachFlags() | Data::CapacityReserved)); - detached.d->copyAppend(constBegin(), constEnd()); - detached.swap(*this); + if (n == 0) + return; + + if (n <= capacity()) { + if (d->capacityReserved) + return; + if (!d->ref.isShared()) { + d->capacityReserved = 1; + return; + } } + + SimpleVector detached(Data::allocate(n, + d->detachFlags() | Data::CapacityReserved)); + detached.d->copyAppend(constBegin(), constEnd()); + detached.swap(*this); } void prepend(const_iterator first, const_iterator last) -- cgit v1.2.3 From f4c1e2c40fcc1285ea24d55ed4eac036d8bbdf1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 11 Jan 2012 17:16:04 +0100 Subject: Enable QArrayData to reference external array data By default, QTypedArrayData::fromRawData provides the same semantics as already exist in QByteArray and QString (immutable, sharable data), but more combinations are possible. In particular, immutable-unsharable leaves the data owner in control of its lifetime by forcing deep copies. As part of this, a new isMutable property is introduced in QArrayData. This could be taken to be implicit in statics that are initialized with a proper size but with alloc set to 0. QStringLiteral and QByteLiteral already did this, forcing re-allocations on resize even before the (static, thus shared) ref-count is considered. The isMutable property detaches data mutability and shared status, which are orthogonal concepts (at least in the unshared state). For the time being, there is no API to explicitly (re)set mutability, but statics and RawData mark data immutable. Change-Id: I33a995a35e1c3d7a12391b1d7c36095aa28e221a Reviewed-by: Robin Burchell Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 6 +++ .../corelib/tools/qarraydata/tst_qarraydata.cpp | 51 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index a1eb2dac48..3fa7905a39 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -274,6 +274,12 @@ public: d.detach(); } + static SimpleVector fromRawData(const T *data, size_t size, + QArrayData::AllocateOptions options = Data::Default) + { + return SimpleVector(Data::fromRawData(data, size, options)); + } + private: QArrayDataPointer d; }; diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 90c865c9e7..4dba02cc70 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -81,6 +81,7 @@ private slots: void arrayOps(); void setSharable_data(); void setSharable(); + void fromRawData(); }; template const T &const_(const T &t) { return t; } @@ -1131,5 +1132,55 @@ void tst_QArrayData::setSharable() QVERIFY(array->ref.isSharable()); } +void tst_QArrayData::fromRawData() +{ + static const int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + { + // Default: Immutable, sharable + SimpleVector raw = SimpleVector::fromRawData(array, + sizeof(array)/sizeof(array[0]), QArrayData::Default); + + QCOMPARE(raw.size(), size_t(11)); + QCOMPARE(raw.constBegin(), array); + QCOMPARE(raw.constEnd(), array + sizeof(array)/sizeof(array[0])); + + QVERIFY(!raw.isShared()); + QVERIFY(SimpleVector(raw).isSharedWith(raw)); + QVERIFY(!raw.isShared()); + + // Detach + QCOMPARE(raw.back(), 11); + QVERIFY(raw.constBegin() != array); + } + + { + // Immutable, unsharable + SimpleVector raw = SimpleVector::fromRawData(array, + sizeof(array)/sizeof(array[0]), QArrayData::Unsharable); + + QCOMPARE(raw.size(), size_t(11)); + QCOMPARE(raw.constBegin(), array); + QCOMPARE(raw.constEnd(), array + sizeof(array)/sizeof(array[0])); + + SimpleVector copy(raw); + QVERIFY(!copy.isSharedWith(raw)); + QVERIFY(!raw.isShared()); + + QCOMPARE(copy.size(), size_t(11)); + + for (size_t i = 0; i < 11; ++i) + QCOMPARE(const_(copy)[i], const_(raw)[i]); + + QCOMPARE(raw.size(), size_t(11)); + QCOMPARE(raw.constBegin(), array); + QCOMPARE(raw.constEnd(), array + sizeof(array)/sizeof(array[0])); + + // Detach + QCOMPARE(raw.back(), 11); + QVERIFY(raw.constBegin() != array); + } +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From b3a4d3e328a3d80d4728716f2e5e68817b82cbb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 12 Jan 2012 16:08:54 +0100 Subject: Rename QArrayData::AllocateOption to AllocationOption Change-Id: Id3e7c748b4b40d703ad1785c903c96bdd968390e Reviewed-by: Oswald Buddenhagen --- tests/auto/corelib/tools/qarraydata/simplevector.h | 2 +- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 3fa7905a39..d53b90d8a4 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -275,7 +275,7 @@ public: } static SimpleVector fromRawData(const T *data, size_t size, - QArrayData::AllocateOptions options = Data::Default) + QArrayData::AllocationOptions options = Data::Default) { return SimpleVector(Data::fromRawData(data, size, options)); } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 4dba02cc70..4d121a823f 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -546,13 +546,13 @@ struct Deallocator }; Q_DECLARE_METATYPE(const QArrayData *) -Q_DECLARE_METATYPE(QArrayData::AllocateOptions) +Q_DECLARE_METATYPE(QArrayData::AllocationOptions) void tst_QArrayData::allocate_data() { QTest::addColumn("objectSize"); QTest::addColumn("alignment"); - QTest::addColumn("allocateOptions"); + QTest::addColumn("allocateOptions"); QTest::addColumn("isCapacityReserved"); QTest::addColumn("isSharable"); QTest::addColumn("commonEmpty"); @@ -575,7 +575,7 @@ void tst_QArrayData::allocate_data() struct { char const *description; - QArrayData::AllocateOptions allocateOptions; + QArrayData::AllocationOptions allocateOptions; bool isCapacityReserved; bool isSharable; const QArrayData *commonEmpty; @@ -603,7 +603,7 @@ void tst_QArrayData::allocate() { QFETCH(size_t, objectSize); QFETCH(size_t, alignment); - QFETCH(QArrayData::AllocateOptions, allocateOptions); + QFETCH(QArrayData::AllocationOptions, allocateOptions); QFETCH(bool, isCapacityReserved); QFETCH(bool, isSharable); QFETCH(const QArrayData *, commonEmpty); @@ -614,14 +614,14 @@ void tst_QArrayData::allocate() // Shared Empty QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0, - QArrayData::AllocateOptions(allocateOptions)), commonEmpty); + QArrayData::AllocationOptions(allocateOptions)), commonEmpty); Deallocator keeper(objectSize, minAlignment); keeper.headers.reserve(1024); for (int capacity = 1; capacity <= 1024; capacity <<= 1) { QArrayData *data = QArrayData::allocate(objectSize, minAlignment, - capacity, QArrayData::AllocateOptions(allocateOptions)); + capacity, QArrayData::AllocationOptions(allocateOptions)); keeper.headers.append(data); QCOMPARE(data->size, 0); -- cgit v1.2.3 From 9e9f7a482abbfc862c9a5cc292139a36b5f25700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 11 Jan 2012 16:01:10 +0100 Subject: Don't use RefCount int operations , as those are going away. This cleans use of those operations in the QArrayData stack. Change-Id: I67705fe0a2f8d99ea13739b675021356a5736f83 Reviewed-by: Robin Burchell Reviewed-by: hjk --- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 4d121a823f..d1da18d4e1 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -92,25 +92,25 @@ void tst_QArrayData::referenceCounting() // Reference counting initialized to 1 (owned) QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(1) }, 0, 0, 0, 0 }; - QCOMPARE(int(array.ref), 1); + QCOMPARE(array.ref.atomic.load(), 1); QVERIFY(!array.ref.isStatic()); QVERIFY(array.ref.isSharable()); QVERIFY(array.ref.ref()); - QCOMPARE(int(array.ref), 2); + QCOMPARE(array.ref.atomic.load(), 2); QVERIFY(array.ref.deref()); - QCOMPARE(int(array.ref), 1); + QCOMPARE(array.ref.atomic.load(), 1); QVERIFY(array.ref.ref()); - QCOMPARE(int(array.ref), 2); + QCOMPARE(array.ref.atomic.load(), 2); QVERIFY(array.ref.deref()); - QCOMPARE(int(array.ref), 1); + QCOMPARE(array.ref.atomic.load(), 1); QVERIFY(!array.ref.deref()); - QCOMPARE(int(array.ref), 0); + QCOMPARE(array.ref.atomic.load(), 0); // Now would be a good time to free/release allocated data } @@ -119,17 +119,17 @@ void tst_QArrayData::referenceCounting() // Reference counting initialized to 0 (non-sharable) QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 }; - QCOMPARE(int(array.ref), 0); + QCOMPARE(array.ref.atomic.load(), 0); QVERIFY(!array.ref.isStatic()); QVERIFY(!array.ref.isSharable()); QVERIFY(!array.ref.ref()); // Reference counting fails, data should be copied - QCOMPARE(int(array.ref), 0); + QCOMPARE(array.ref.atomic.load(), 0); QVERIFY(!array.ref.deref()); - QCOMPARE(int(array.ref), 0); + QCOMPARE(array.ref.atomic.load(), 0); // Free/release data } @@ -138,16 +138,16 @@ void tst_QArrayData::referenceCounting() // Reference counting initialized to -1 (static read-only data) QArrayData array = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 }; - QCOMPARE(int(array.ref), -1); + QCOMPARE(array.ref.atomic.load(), -1); QVERIFY(array.ref.isStatic()); QVERIFY(array.ref.isSharable()); QVERIFY(array.ref.ref()); - QCOMPARE(int(array.ref), -1); + QCOMPARE(array.ref.atomic.load(), -1); QVERIFY(array.ref.deref()); - QCOMPARE(int(array.ref), -1); + QCOMPARE(array.ref.atomic.load(), -1); } } @@ -164,20 +164,20 @@ void tst_QArrayData::sharedNullEmpty() QVERIFY(empty->ref.isSharable()); QVERIFY(empty->ref.isShared()); - QCOMPARE(int(null->ref), -1); - QCOMPARE(int(empty->ref), -1); + QCOMPARE(null->ref.atomic.load(), -1); + QCOMPARE(empty->ref.atomic.load(), -1); QVERIFY(null->ref.ref()); QVERIFY(empty->ref.ref()); - QCOMPARE(int(null->ref), -1); - QCOMPARE(int(empty->ref), -1); + QCOMPARE(null->ref.atomic.load(), -1); + QCOMPARE(empty->ref.atomic.load(), -1); QVERIFY(null->ref.deref()); QVERIFY(empty->ref.deref()); - QCOMPARE(int(null->ref), -1); - QCOMPARE(int(empty->ref), -1); + QCOMPARE(null->ref.atomic.load(), -1); + QCOMPARE(empty->ref.atomic.load(), -1); QVERIFY(null != empty); -- cgit v1.2.3 From 3249aab539b37a98d75329598bd6838082a8158e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 12 Jan 2012 15:39:17 +0100 Subject: Don't use RefCount int operators , as those are going away. The comment in QString/QByteArray::squeeze about shared_null was updated as it also affects other static data, such as that generated by QStringLiteral and QByteArrayLiteral. Change-Id: I26a757d29db62b1e3566a1f7c8d4030918ed8a89 Reviewed-by: Thiago Macieira Reviewed-by: Bradley T. Hughes Reviewed-by: Olivier Goffart --- tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 8767571f6c..5b660ecd3f 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -1504,7 +1504,7 @@ void tst_QByteArray::literals() QVERIFY(str.length() == 4); QVERIFY(str == "abcd"); - QVERIFY(str.data_ptr()->ref == -1); + QVERIFY(str.data_ptr()->ref.isStatic()); QVERIFY(str.data_ptr()->offset == 0); const char *s = str.constData(); -- cgit v1.2.3 From 32240022731f513fc080a6ca3e7ba6a2374fe0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 24 Jan 2012 13:51:41 +0100 Subject: Don't use RefCount int operators The previous patch missed this, which was hidden inside #ifdefs. Change-Id: Iba1417d4191b6931afb549022768f3e3a2cf727d Reviewed-by: Lars Knoll --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index ed525e3429..622d494a06 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -5120,7 +5120,7 @@ void tst_QString::literals() QVERIFY(str.length() == 4); QVERIFY(str == QLatin1String("abcd")); - QVERIFY(str.data_ptr()->ref == -1); + QVERIFY(str.data_ptr()->ref.isStatic()); QVERIFY(str.data_ptr()->offset == 0); const QChar *s = str.constData(); -- cgit v1.2.3 From b59d8319806ff0ed2e340126fd110413301a833b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 2 Nov 2011 13:11:31 +0100 Subject: Introducing Q_ARRAY_LITERAL This provides the same functionality as the specialized QStringLiteral and QByteArrayLiteral, but on top of QArrayData. The macro has two variations, variadic and simple. The variadic version depends on compiler support for (C99) variadic macros and enables static initialization of arrays of any POD data. Use of this macro is not recommended on code or applications that need to work in configurations where variadic macros are not supported. The simple version is more portable and is enough to support the use cases of QStringLiteral and QByteArrayLiteral, also providing a fallback that allocates and copies data when static initialization is not available. Change-Id: I7154a24dcae4bbbd7d5978653f620138467830c5 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 5 ++ .../corelib/tools/qarraydata/tst_qarraydata.cpp | 92 ++++++++++++++++++++++ 2 files changed, 97 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index d53b90d8a4..f210411643 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -77,6 +77,11 @@ public: d->copyAppend(begin, end); } + SimpleVector(QArrayDataPointerRef ptr) + : d(ptr) + { + } + explicit SimpleVector(Data *ptr) : d(ptr) { diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index d1da18d4e1..55aa2e5e75 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -82,6 +82,8 @@ private slots: void setSharable_data(); void setSharable(); void fromRawData(); + void literals(); + void variadicLiterals(); }; template const T &const_(const T &t) { return t; } @@ -1182,5 +1184,95 @@ void tst_QArrayData::fromRawData() } } +void tst_QArrayData::literals() +{ + { + QArrayDataPointer d = Q_ARRAY_LITERAL(char, "ABCDEFGHIJ"); + QCOMPARE(d->size, 10 + 1); + for (int i = 0; i < 10; ++i) + QCOMPARE(d->data()[i], char('A' + i)); + } + + { + // wchar_t is not necessarily 2-bytes + QArrayDataPointer d = Q_ARRAY_LITERAL(wchar_t, L"ABCDEFGHIJ"); + QCOMPARE(d->size, 10 + 1); + for (int i = 0; i < 10; ++i) + QCOMPARE(d->data()[i], wchar_t('A' + i)); + } + + { + SimpleVector v = Q_ARRAY_LITERAL(char, "ABCDEFGHIJ"); + + QVERIFY(!v.isNull()); + QVERIFY(!v.isEmpty()); + QCOMPARE(v.size(), size_t(11)); + // v.capacity() is unspecified, for now + +#if defined(Q_COMPILER_VARIADIC_MACROS) \ + && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU)) + QVERIFY(v.isStatic()); +#endif + + QVERIFY(v.isSharable()); + QVERIFY(v.constBegin() + v.size() == v.constEnd()); + + for (int i = 0; i < 10; ++i) + QCOMPARE(const_(v)[i], char('A' + i)); + QCOMPARE(const_(v)[10], char('\0')); + } +} + +void tst_QArrayData::variadicLiterals() +{ +#if defined(Q_COMPILER_VARIADIC_MACROS) \ + && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU)) + { + QArrayDataPointer d = + Q_ARRAY_LITERAL(int, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + QCOMPARE(d->size, 10); + for (int i = 0; i < 10; ++i) + QCOMPARE(d->data()[i], i); + } + + { + QArrayDataPointer d = Q_ARRAY_LITERAL(char, + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'); + QCOMPARE(d->size, 10); + for (int i = 0; i < 10; ++i) + QCOMPARE(d->data()[i], char('A' + i)); + } + + { + QArrayDataPointer d = Q_ARRAY_LITERAL(const char *, + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J"); + QCOMPARE(d->size, 10); + for (int i = 0; i < 10; ++i) { + QCOMPARE(d->data()[i][0], char('A' + i)); + QCOMPARE(d->data()[i][1], '\0'); + } + } + + { + SimpleVector v = Q_ARRAY_LITERAL(int, 0, 1, 2, 3, 4, 5, 6); + + QVERIFY(!v.isNull()); + QVERIFY(!v.isEmpty()); + QCOMPARE(v.size(), size_t(7)); + // v.capacity() is unspecified, for now + + QVERIFY(v.isStatic()); + + QVERIFY(v.isSharable()); + QVERIFY(v.constBegin() + v.size() == v.constEnd()); + + for (int i = 0; i < 7; ++i) + QCOMPARE(const_(v)[i], i); + } +#else + QSKIP("Variadic Q_ARRAY_LITERAL not available in current configuration."); +#endif // defined(Q_COMPILER_VARIADIC_MACROS) +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From e32d417b5129171be09a32bb3a65dca6f7464d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 24 Jan 2012 18:05:07 +0100 Subject: Fix some warnings with Clang The extra bool arguments weren't needed in the first place as they specify the default, but were left behind when allocate parameters were changed from bools to AllocationOptions. Clang saves the day by pointing out the weird conversion going through void ** (!?) Change-Id: Ia0dafce06bf0ee62bd825a2db819c890343b6342 Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 55aa2e5e75..46985c1e3b 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -737,7 +737,7 @@ void tst_QArrayData::typedData() { Deallocator keeper(sizeof(char), Q_ALIGNOF(QTypedArrayData::AlignmentDummy)); - QArrayData *array = QTypedArrayData::allocate(10, false); + QArrayData *array = QTypedArrayData::allocate(10); keeper.headers.append(array); QVERIFY(array); @@ -757,7 +757,7 @@ void tst_QArrayData::typedData() { Deallocator keeper(sizeof(short), Q_ALIGNOF(QTypedArrayData::AlignmentDummy)); - QArrayData *array = QTypedArrayData::allocate(10, false); + QArrayData *array = QTypedArrayData::allocate(10); keeper.headers.append(array); QVERIFY(array); @@ -777,7 +777,7 @@ void tst_QArrayData::typedData() { Deallocator keeper(sizeof(double), Q_ALIGNOF(QTypedArrayData::AlignmentDummy)); - QArrayData *array = QTypedArrayData::allocate(10, false); + QArrayData *array = QTypedArrayData::allocate(10); keeper.headers.append(array); QVERIFY(array); -- cgit v1.2.3 From 632840cb0f5ad355d87fc040b015d04af86371ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 1 Feb 2012 11:51:08 +0100 Subject: Make clear() use the shared null inline There isn't a good reason to impose the additional library call and using the shared null here matches existing behavior in QByteArray, QString and QVector. Change-Id: Idd0bb9c7411db52630402534a11d87cbf2b1e7ba Reviewed-by: Robin Burchell --- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 46985c1e3b..ff0d8bd6de 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -242,7 +242,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v1.isNull()); QVERIFY(v2.isNull()); QVERIFY(v3.isNull()); - QVERIFY(!v4.isNull()); + QVERIFY(v4.isNull()); QVERIFY(!v5.isNull()); QVERIFY(!v6.isNull()); QVERIFY(!v7.isNull()); @@ -306,7 +306,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v1.isSharedWith(v2)); QVERIFY(v1.isSharedWith(v3)); - QVERIFY(!v1.isSharedWith(v4)); + QVERIFY(v1.isSharedWith(v4)); QVERIFY(!v1.isSharedWith(v5)); QVERIFY(!v1.isSharedWith(v6)); -- cgit v1.2.3 From 475280d5fd13a996ade7a69776fe4d0385114a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 6 Feb 2012 11:18:18 +0100 Subject: Update license headers - Updated copyright year, per 1fdfc2abfe1fa26b86028934d4853432e25b4655 - Updated contact information, 629d6eda5cf67122776981de9073857bbc3dcba2 - Drop "All rights reserved", 5635823e17db3395d9b0fa8cfcc72f82fea583f4 (Empty line added to maintain license header line count) Change-Id: Ie401e2b6e40a4b79f4191377dd50dc60be801e1f Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 6 +++--- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index f210411643..b16025b34a 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -1,8 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ ** ** This file is part of the test suite of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index ff0d8bd6de..6a42f4da59 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -1,8 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ ** ** This file is part of the test suite of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ -- cgit v1.2.3 From f9872d12a6fb81aa0efa995720c7d733bbbdd71b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 10 Feb 2012 16:13:56 +0100 Subject: Add support for rvalue-references in QArrayDataPointer I love how this magically makes SimpleVector move-aware :-) Change-Id: I5cb75954d70cf256863c33e684ebc4551ac94f87 Reviewed-by: Bradley T. Hughes --- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 6a42f4da59..00873a84d1 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -84,6 +84,7 @@ private slots: void fromRawData(); void literals(); void variadicLiterals(); + void rValueReferences(); }; template const T &const_(const T &t) { return t; } @@ -1274,5 +1275,50 @@ void tst_QArrayData::variadicLiterals() #endif // defined(Q_COMPILER_VARIADIC_MACROS) } +#ifdef Q_COMPILER_RVALUE_REFS +// std::remove_reference is in C++11, but requires library support +template struct RemoveReference { typedef T Type; }; +template struct RemoveReference { typedef T Type; }; + +// single-argument std::move is in C++11, but requires library support +template +typename RemoveReference::Type &&cxx11Move(T &&t) +{ + return static_cast::Type &&>(t); +} +#endif + +void tst_QArrayData::rValueReferences() +{ +#ifdef Q_COMPILER_RVALUE_REFS + SimpleVector v1(1, 42); + SimpleVector v2; + + const SimpleVector::const_iterator begin = v1.constBegin(); + + QVERIFY(!v1.isNull()); + QVERIFY(v2.isNull()); + + // move-assign + v2 = cxx11Move(v1); + + QVERIFY(v1.isNull()); + QVERIFY(!v2.isNull()); + QCOMPARE(v2.constBegin(), begin); + + SimpleVector v3(cxx11Move(v2)); + + QVERIFY(v1.isNull()); + QVERIFY(v2.isNull()); + QVERIFY(!v3.isNull()); + QCOMPARE(v3.constBegin(), begin); + + QCOMPARE(v3.size(), size_t(1)); + QCOMPARE(v3.front(), 42); +#else + QSKIP("RValue references are not supported in current configuration"); +#endif +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From 75286739de854d761bbfcababa50d1bc6dfda12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 14 Feb 2012 00:02:08 +0100 Subject: Fix and simplify QString::mid 'position' was being used to initialize 'n' before being fully validated. To compensate for this, the code attempted to fix 'n' once 'position' was found to be invalid (negative). This would, however, also attempt to "fix" a perfectly valid value of 'n'. By fully validating 'position' beforehand we avoid this trap and can safely use it to validate and reset 'n', as needed. Arithmetic for boundary conditions of 'n' was rearranged to avoid triggering integer overflow. Removed explicit check for shared_null, as the same behaviour can be supported without it. Change-Id: Ie9bff7b8137a74f55c7dcfe629bd569045e28f3c Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 70 ++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 37d80afd34..7dd801b50b 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -1429,16 +1429,51 @@ void tst_QString::mid() QVERIFY(a.mid(9999).isNull()); QVERIFY(a.mid(9999,1).isNull()); + QCOMPARE(a.mid(-1, 6), QString("ABCDEF")); + QCOMPARE(a.mid(-100, 6), QString("ABCDEF")); + QVERIFY(a.mid(INT_MAX).isNull()); + QVERIFY(a.mid(INT_MAX, INT_MAX).isNull()); + QCOMPARE(a.mid(-5, INT_MAX), a); + QCOMPARE(a.mid(-1, INT_MAX), a); + QCOMPARE(a.mid(0, INT_MAX), a); + QCOMPARE(a.mid(1, INT_MAX), QString("BCDEFGHIEfGEFG")); + QCOMPARE(a.mid(5, INT_MAX), QString("FGHIEfGEFG")); + QVERIFY(a.mid(20, INT_MAX).isNull()); + QCOMPARE(a.mid(-1, -1), a); + QString n; QVERIFY(n.mid(3,3).isNull()); QVERIFY(n.mid(0,0).isNull()); QVERIFY(n.mid(9999,0).isNull()); QVERIFY(n.mid(9999,1).isNull()); + QVERIFY(n.mid(-1, 6).isNull()); + QVERIFY(n.mid(-100, 6).isNull()); + QVERIFY(n.mid(INT_MAX).isNull()); + QVERIFY(n.mid(INT_MAX, INT_MAX).isNull()); + QVERIFY(n.mid(-5, INT_MAX).isNull()); + QVERIFY(n.mid(-1, INT_MAX).isNull()); + QVERIFY(n.mid(0, INT_MAX).isNull()); + QVERIFY(n.mid(1, INT_MAX).isNull()); + QVERIFY(n.mid(5, INT_MAX).isNull()); + QVERIFY(n.mid(20, INT_MAX).isNull()); + QVERIFY(n.mid(-1, -1).isNull()); + QString x = "Nine pineapples"; QCOMPARE(x.mid(5, 4), QString("pine")); QCOMPARE(x.mid(5), QString("pineapples")); + QCOMPARE(x.mid(-1, 6), QString("Nine p")); + QCOMPARE(x.mid(-100, 6), QString("Nine p")); + QVERIFY(x.mid(INT_MAX).isNull()); + QVERIFY(x.mid(INT_MAX, INT_MAX).isNull()); + QCOMPARE(x.mid(-5, INT_MAX), x); + QCOMPARE(x.mid(-1, INT_MAX), x); + QCOMPARE(x.mid(0, INT_MAX), x); + QCOMPARE(x.mid(1, INT_MAX), QString("ine pineapples")); + QCOMPARE(x.mid(5, INT_MAX), QString("pineapples")); + QVERIFY(x.mid(20, INT_MAX).isNull()); + QCOMPARE(x.mid(-1, -1), x); } void tst_QString::midRef() @@ -1455,16 +1490,51 @@ void tst_QString::midRef() QVERIFY(a.midRef(9999).toString().isEmpty()); QVERIFY(a.midRef(9999,1).toString().isEmpty()); + QCOMPARE(a.midRef(-1, 6).toString(), QString("ABCDEF")); + QCOMPARE(a.midRef(-100, 6).toString(), QString("ABCDEF")); + QVERIFY(a.midRef(INT_MAX).isNull()); + QVERIFY(a.midRef(INT_MAX, INT_MAX).isNull()); + QCOMPARE(a.midRef(-5, INT_MAX).toString(), a); + QCOMPARE(a.midRef(-1, INT_MAX).toString(), a); + QCOMPARE(a.midRef(0, INT_MAX).toString(), a); + QCOMPARE(a.midRef(1, INT_MAX).toString(), QString("BCDEFGHIEfGEFG")); + QCOMPARE(a.midRef(5, INT_MAX).toString(), QString("FGHIEfGEFG")); + QVERIFY(a.midRef(20, INT_MAX).isNull()); + QCOMPARE(a.midRef(-1, -1).toString(), a); + QString n; QVERIFY(n.midRef(3,3).toString().isEmpty()); QVERIFY(n.midRef(0,0).toString().isEmpty()); QVERIFY(n.midRef(9999,0).toString().isEmpty()); QVERIFY(n.midRef(9999,1).toString().isEmpty()); + QVERIFY(n.midRef(-1, 6).isNull()); + QVERIFY(n.midRef(-100, 6).isNull()); + QVERIFY(n.midRef(INT_MAX).isNull()); + QVERIFY(n.midRef(INT_MAX, INT_MAX).isNull()); + QVERIFY(n.midRef(-5, INT_MAX).isNull()); + QVERIFY(n.midRef(-1, INT_MAX).isNull()); + QVERIFY(n.midRef(0, INT_MAX).isNull()); + QVERIFY(n.midRef(1, INT_MAX).isNull()); + QVERIFY(n.midRef(5, INT_MAX).isNull()); + QVERIFY(n.midRef(20, INT_MAX).isNull()); + QVERIFY(n.midRef(-1, -1).isNull()); + QString x = "Nine pineapples"; QCOMPARE(x.midRef(5, 4).toString(), QString("pine")); QCOMPARE(x.midRef(5).toString(), QString("pineapples")); + QCOMPARE(x.midRef(-1, 6).toString(), QString("Nine p")); + QCOMPARE(x.midRef(-100, 6).toString(), QString("Nine p")); + QVERIFY(x.midRef(INT_MAX).isNull()); + QVERIFY(x.midRef(INT_MAX, INT_MAX).isNull()); + QCOMPARE(x.midRef(-5, INT_MAX).toString(), x); + QCOMPARE(x.midRef(-1, INT_MAX).toString(), x); + QCOMPARE(x.midRef(0, INT_MAX).toString(), x); + QCOMPARE(x.midRef(1, INT_MAX).toString(), QString("ine pineapples")); + QCOMPARE(x.midRef(5, INT_MAX).toString(), QString("pineapples")); + QVERIFY(x.midRef(20, INT_MAX).isNull()); + QCOMPARE(x.midRef(-1, -1).toString(), x); } void tst_QString::stringRef() -- cgit v1.2.3 From fb8be9905d5f3216edc3fbb72b8ce1c380737eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Feb 2012 19:59:07 +0100 Subject: qAllocMore: Always grow exponentially qAllocMore is used by growing containers to allocate additional memory for future growth. The previous algorithm would grow linearly in increments of 8 up to 64 and then progress exponentially in powers of two. The new (constant time) algorithm does away with the linear segment and always progresses exponentially. It also has the nice benefit of cleanly avoiding undefined behaviour that the old implementation tried hard to circumvent. Besides always progressing exponentially, the next-power-of-two algorithm was tweaked to always include space for growth. Previously queries at boundary values (powers of two) would return the same value. The test was updated to verify sanity of results. As the algorithm is well behaved, testing of bogus data was dropped. Whatever happens in those cases is irrelevant, anyway: the bug lives elsewhere. Change-Id: I4def473cce4b438734887084e3c3bd8da0ff466b Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- .../corelib/tools/qbytearray/tst_qbytearray.cpp | 31 +++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 585d6afa44..4fb74a2af5 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -1075,18 +1075,25 @@ void tst_QByteArray::toULongLong() // global function defined in qbytearray.cpp void tst_QByteArray::qAllocMore() { - static const int t[] = { - INT_MIN, INT_MIN + 1, -1234567, -66000, -1025, - -3, -1, 0, +1, +3, +1025, +66000, +1234567, INT_MAX - 1, INT_MAX, - INT_MAX/3 - }; - static const int N = sizeof(t)/sizeof(t[0]); - - // make sure qAllocMore() doesn't loop infinitely on any input - for (int i = 0; i < N; ++i) { - for (int j = 0; j < N; ++j) { - ::qAllocMore(t[i], t[j]); - } + using QT_PREPEND_NAMESPACE(qAllocMore); + + // Not very important, but please behave :-) + QVERIFY(qAllocMore(0, 0) >= 0); + + for (int i = 1; i < 1 << 8; i <<= 1) + QVERIFY(qAllocMore(i, 0) >= i); + + for (int i = 1 << 8; i < 1 << 30; i <<= 1) { + const int alloc = qAllocMore(i, 0); + + QVERIFY(alloc >= i); + QCOMPARE(qAllocMore(i - 8, 8), alloc - 8); + QCOMPARE(qAllocMore(i - 16, 16), alloc - 16); + QCOMPARE(qAllocMore(i - 24, 24), alloc - 24); + QCOMPARE(qAllocMore(i - 32, 32), alloc - 32); + + QVERIFY(qAllocMore(i - 1, 0) >= i - 1); + QVERIFY(qAllocMore(i + 1, 0) >= i + 1); } } -- cgit v1.2.3 From fd96115ae8501c2baf591b821bdf6f7d90b62f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Feb 2012 23:53:58 +0100 Subject: QVector: always grow exponentially For non-movable types (QTypeInfo::isStatic), QVector would grow the array linearly, and defer to qAllocMore otherwise. That property, however, gives no indication as to how the vector will grow. By forcing additional allocations for growing containers of such types, this penalized exactly those objects which are more expensive to move. We now let qAllocMore reign in growth decisions. Change-Id: I843a89dcdc21d09868c6b62a846a7e1e4548e399 Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- tests/benchmarks/corelib/tools/qvector/qrawvector.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index 159dfbf8dc..4a4f03ee1b 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -308,7 +308,7 @@ void QRawVector::reserve(int asize) template void QRawVector::resize(int asize) { realloc(asize, (asize > m_alloc || (asize < m_size && asize < (m_alloc >> 1))) - ? QVectorData::grow(sizeOfTypedData(), asize, sizeof(T), QTypeInfo::isStatic) + ? QVectorData::grow(sizeOfTypedData(), asize, sizeof(T)) : m_alloc, false); } template inline void QRawVector::clear() @@ -510,8 +510,7 @@ void QRawVector::append(const T &t) { if (m_size + 1 > m_alloc) { const T copy(t); - realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + 1, sizeof(T), - QTypeInfo::isStatic), false); + realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + 1, sizeof(T)), false); if (QTypeInfo::isComplex) new (m_begin + m_size) T(copy); else @@ -532,8 +531,7 @@ typename QRawVector::iterator QRawVector::insert(iterator before, size_typ if (n != 0) { const T copy(t); if (m_size + n > m_alloc) - realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + n, sizeof(T), - QTypeInfo::isStatic), false); + realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + n, sizeof(T)), false); if (QTypeInfo::isStatic) { T *b = m_begin + m_size; T *i = m_begin + m_size + n; -- cgit v1.2.3 From ebeebe212624b0d6fb87266629dce20ee75391bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Feb 2012 11:23:41 +0100 Subject: Have QVectorData::grow, take size of header w/ padding This includes padding necessary to align the data array, but excludes the first element as was done before. Size of header is the interesting piece of information, anyway. This simplifies calculations in a couple of places, harmonizes code with the QRawVector fork and paves the way for further changes in QVector, namely the memory layout. When Q_ALIGNOF is not available, default to pointer-size alignment. This should be honoured by malloc and won't trigger use of more expensive aligned allocation. Change-Id: I504022ac7595f69089cafd96e47a91b874d5771e Reviewed-by: Thiago Macieira --- .../benchmarks/corelib/tools/qvector/qrawvector.h | 46 ++++++++++------------ 1 file changed, 20 insertions(+), 26 deletions(-) (limited to 'tests') diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index 4a4f03ee1b..1342513a7f 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -73,17 +73,11 @@ class QRawVector int m_alloc; public: - //static Data dummy; - //int headerOffset() { return (char*)&dummy.array - (char*)&dummy; } - inline int headerOffset() const { - // gcc complains about: return offsetof(Data, array); and also - // does not like '0' in the expression below. - return (char *)&(((Data *)(1))->array) - (char *)1; - } - inline Data *toBase(T *begin) const - { return (Data*)((char*)begin - headerOffset()); } - inline T *fromBase(void *d) const - { return (T*)((char*)d + headerOffset()); } + static Data *toBase(T *begin) + { return (Data*)((char*)begin - offsetOfTypedData()); } + static T *fromBase(void *d) + { return (T*)((char*)d + offsetOfTypedData()); } + inline QRawVector() { m_begin = fromBase(0); m_alloc = m_size = 0; realloc(m_size, m_alloc, true); } explicit QRawVector(int size); @@ -270,17 +264,18 @@ private: T *allocate(int alloc); void realloc(int size, int alloc, bool ref); void free(T *begin, int size); - int sizeOfTypedData() { - // this is more or less the same as sizeof(Data), except that it doesn't - // count the padding at the end - return reinterpret_cast(&(reinterpret_cast(this))->array[1]) - reinterpret_cast(this); + + static Q_DECL_CONSTEXPR int offsetOfTypedData() + { + // (non-POD)-safe offsetof(Data, array) + return (sizeof(QVectorData) + (alignOfTypedData() - 1)) & ~(alignOfTypedData() - 1); } - static inline int alignOfTypedData() + static Q_DECL_CONSTEXPR int alignOfTypedData() { #ifdef Q_ALIGNOF - return qMax(sizeof(void*), Q_ALIGNOF(Data)); + return Q_ALIGNOF(Data); #else - return 0; + return sizeof(void *); #endif } @@ -308,7 +303,7 @@ void QRawVector::reserve(int asize) template void QRawVector::resize(int asize) { realloc(asize, (asize > m_alloc || (asize < m_size && asize < (m_alloc >> 1))) - ? QVectorData::grow(sizeOfTypedData(), asize, sizeof(T)) + ? QVectorData::grow(offsetOfTypedData(), asize, sizeof(T)) : m_alloc, false); } template inline void QRawVector::clear() @@ -369,7 +364,7 @@ QRawVector &QRawVector::operator=(const QRawVector &v) template inline T *QRawVector::allocate(int aalloc) { - QVectorData *d = QVectorData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData()); + QVectorData *d = QVectorData::allocate(offsetOfTypedData() + aalloc * sizeof(T), alignOfTypedData()); Q_CHECK_PTR(d); return fromBase(d); } @@ -445,10 +440,9 @@ void QRawVector::realloc(int asize, int aalloc, bool ref) changed = true; } else { QT_TRY { - QVectorData *mem = QVectorData::reallocate( - toBase(m_begin), sizeOfTypedData() + (aalloc - 1) * sizeof(T), - sizeOfTypedData() -+ (xalloc - 1) * sizeof(T), alignOfTypedData()); + QVectorData *mem = QVectorData::reallocate(toBase(m_begin), + offsetOfTypedData() + aalloc * sizeof(T), + offsetOfTypedData() + xalloc * sizeof(T), alignOfTypedData()); Q_CHECK_PTR(mem); xbegin = fromBase(mem); xsize = m_size; @@ -510,7 +504,7 @@ void QRawVector::append(const T &t) { if (m_size + 1 > m_alloc) { const T copy(t); - realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + 1, sizeof(T)), false); + realloc(m_size, QVectorData::grow(offsetOfTypedData(), m_size + 1, sizeof(T)), false); if (QTypeInfo::isComplex) new (m_begin + m_size) T(copy); else @@ -531,7 +525,7 @@ typename QRawVector::iterator QRawVector::insert(iterator before, size_typ if (n != 0) { const T copy(t); if (m_size + n > m_alloc) - realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + n, sizeof(T)), false); + realloc(m_size, QVectorData::grow(offsetOfTypedData(), m_size + n, sizeof(T)), false); if (QTypeInfo::isStatic) { T *b = m_begin + m_size; T *i = m_begin + m_size + n; -- cgit v1.2.3 From 4c8a4058c359c8d163c643120426079fc80c8214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Feb 2012 14:11:28 +0100 Subject: Change meaning of offset in QByteArrayData It used to be an index into the first element in 'd' that came after 'offset'. It is now the byte offset from the beginning of the QByteArrayData structure. By no longer using an actual array to access characters, we also steer clear of GCC bug #43247: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43247 This aligns this data structure with QArrayData. The intention is to have QVector, QString and QByteArray share the same memory layout and possibly code. Change-Id: I8546e5f51cd2161ba09bd4ada174b7f5e6f09db7 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 4fb74a2af5..e442aa7e1a 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -1592,7 +1592,7 @@ void tst_QByteArray::literals() QVERIFY(str.length() == 4); QVERIFY(str == "abcd"); QVERIFY(str.data_ptr()->ref.isStatic()); - QVERIFY(str.data_ptr()->offset == 0); + QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData)); const char *s = str.constData(); QByteArray str2 = str; -- cgit v1.2.3 From 3fe1eed0537c3b08a51295b544e0620ade1eca22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 22 Feb 2012 01:25:28 +0100 Subject: Workaround compiler issue I can't figure this one out, but it seems to be a clang compiler bug that is triggered in association with -DQT_NO_DEBUG. Changing the test from QVERIFY to QCOMPARE keeps the intent and the check, but makes the failure go away. It can't hurt... Change-Id: Ib34e5e850e5b731d729e417430dec55e372805ac Reviewed-by: Chris Adams --- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 00873a84d1..561491da00 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -1216,7 +1216,7 @@ void tst_QArrayData::literals() #endif QVERIFY(v.isSharable()); - QVERIFY(v.constBegin() + v.size() == v.constEnd()); + QCOMPARE(v.constBegin() + v.size(), v.constEnd()); for (int i = 0; i < 10; ++i) QCOMPARE(const_(v)[i], char('A' + i)); -- cgit v1.2.3 From a5233b6b22e20bf249d8ae993a4224c6874abccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Feb 2012 14:18:45 +0100 Subject: Change meaning of offset in QStringData It used to be an index into the first element in 'd' that came after 'offset'. It is now the byte offset from the beginning of the QStringData structure. By no longer using an actual array to access characters, we also steer clear of GCC bug #43247: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43247 This aligns this data structure with QArrayData. The intention is to have QVector, QString and QByteArray share the same memory layout and possibly code. Change-Id: I4850813e1bd47c3cb670c50c9a8ccc1bff2e8597 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index e3808244d3..ba583f3cb8 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -5150,7 +5150,7 @@ void tst_QString::literals() QVERIFY(str.length() == 4); QVERIFY(str == QLatin1String("abcd")); QVERIFY(str.data_ptr()->ref.isStatic()); - QVERIFY(str.data_ptr()->offset == 0); + QVERIFY(str.data_ptr()->offset == sizeof(QStringData)); const QChar *s = str.constData(); QString str2 = str; -- cgit v1.2.3 From a1621d235dad75b8042f4e13712e1ea3440bf717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Feb 2012 12:10:03 +0100 Subject: Change QVector's in-memory data layout The new layout matches that of QByteArrayData and QStringData, except for offset which is measured from the beginning of QVectorData, whereas in those classes it (still?) references the end of the header data. The new layout uses an extra member for storing an offset into the data, which will allow introducing QVector::fromRawData, similar to the same functionality already existing in QString and QByteArray. By not using an actual array to index array members, we also steer clear of GCC bug #43247: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43247 Change-Id: I408915aacadf616b4633bbbf5cae1fc19e415087 Reviewed-by: Thiago Macieira --- tests/benchmarks/corelib/tools/qvector/qrawvector.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index 1342513a7f..0fdfa86f1d 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE template class QRawVector { - struct Data : QVectorData { T array[1]; }; + typedef QVectorTypedData Data; T *m_begin; int m_size; @@ -265,15 +265,17 @@ private: void realloc(int size, int alloc, bool ref); void free(T *begin, int size); + class AlignmentDummy { QVectorData header; T array[1]; }; + static Q_DECL_CONSTEXPR int offsetOfTypedData() { - // (non-POD)-safe offsetof(Data, array) + // (non-POD)-safe offsetof(AlignmentDummy, array) return (sizeof(QVectorData) + (alignOfTypedData() - 1)) & ~(alignOfTypedData() - 1); } static Q_DECL_CONSTEXPR int alignOfTypedData() { #ifdef Q_ALIGNOF - return Q_ALIGNOF(Data); + return Q_ALIGNOF(AlignmentDummy); #else return sizeof(void *); #endif @@ -286,7 +288,8 @@ public: d->ref.initializeOwned(); d->alloc = m_alloc; d->size = m_size; - d->capacity = 0; + d->capacityReserved = 0; + d->offset = offsetOfTypedData(); QVector v; *reinterpret_cast(&v) = d; -- cgit v1.2.3 From 91e20fff873d8d352dd94fc94b0f54ab0feb3aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Feb 2012 00:29:12 +0100 Subject: SimpleVector: don't assert when reserving on empty Change-Id: I09ac235085e645c8149c153653377252fef6fa3d Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 5 +- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 62 ++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index b16025b34a..a0a9b5f764 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -156,9 +156,10 @@ public: } } - SimpleVector detached(Data::allocate(n, + SimpleVector detached(Data::allocate(qMax(n, size()), d->detachFlags() | Data::CapacityReserved)); - detached.d->copyAppend(constBegin(), constEnd()); + if (size()) + detached.d->copyAppend(constBegin(), constEnd()); detached.swap(*this); } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 561491da00..0112d714f6 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -72,6 +72,8 @@ private slots: void sharedNullEmpty(); void staticData(); void simpleVector(); + void simpleVectorReserve_data(); + void simpleVectorReserve(); void allocate_data(); void allocate(); void alignment_data(); @@ -529,6 +531,66 @@ void tst_QArrayData::simpleVector() } } +Q_DECLARE_METATYPE(SimpleVector) + +void tst_QArrayData::simpleVectorReserve_data() +{ + QTest::addColumn >("vector"); + QTest::addColumn("capacity"); + QTest::addColumn("size"); + + QTest::newRow("null") << SimpleVector() << size_t(0) << size_t(0); + QTest::newRow("empty") << SimpleVector(0, 42) << size_t(0) << size_t(0); + QTest::newRow("non-empty") << SimpleVector(5, 42) << size_t(5) << size_t(5); + + static const QStaticArrayData array = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 15), + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } }; + QArrayDataPointerRef p = { + static_cast *>( + const_cast(&array.header)) }; + + QTest::newRow("static") << SimpleVector(p) << size_t(0) << size_t(15); + QTest::newRow("raw-data") << SimpleVector::fromRawData(array.data, 15) << size_t(0) << size_t(15); +} + +void tst_QArrayData::simpleVectorReserve() +{ + QFETCH(SimpleVector, vector); + QFETCH(size_t, capacity); + QFETCH(size_t, size); + + QVERIFY(!capacity || capacity >= size); + + QCOMPARE(vector.capacity(), capacity); + QCOMPARE(vector.size(), size); + + const SimpleVector copy(vector); + + vector.reserve(0); + QCOMPARE(vector.capacity(), capacity); + QCOMPARE(vector.size(), size); + + vector.reserve(10); + + // zero-capacity (immutable) resets with detach + if (!capacity) + capacity = size; + + QCOMPARE(vector.capacity(), qMax(size_t(10), capacity)); + QCOMPARE(vector.size(), size); + + vector.reserve(20); + QCOMPARE(vector.capacity(), size_t(20)); + QCOMPARE(vector.size(), size); + + vector.reserve(30); + QCOMPARE(vector.capacity(), size_t(30)); + QCOMPARE(vector.size(), size); + + QVERIFY(vector == copy); +} + struct Deallocator { Deallocator(size_t objectSize, size_t alignment) -- cgit v1.2.3 From 57aba47cdeaf2a107822a683c280b3929c5ee0e6 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 17 Feb 2012 22:45:08 +0100 Subject: Port badxml autotest to QMetaObjectBuilder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The meta-object format is going to change for Qt5. Use QMOB to insulate the badxml test from such changes. (It just so happens that the QFAIL("a failure") statement is still on line 109 after the refactoring, so the expected_badxml.* files' location tags did not have to be changed.) Change-Id: I04421d13c4df71c8004fa71cafc4823a59079a41 Reviewed-by: Thiago Macieira Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald (cherry picked from commit 12520e83009fb8bd694d9768801875558bcc6321) Reviewed-by: João Abecasis --- tests/auto/testlib/selftests/badxml/badxml.pro | 2 +- tests/auto/testlib/selftests/badxml/tst_badxml.cpp | 30 +++++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'tests') diff --git a/tests/auto/testlib/selftests/badxml/badxml.pro b/tests/auto/testlib/selftests/badxml/badxml.pro index 5eaa1c3216..7b3b0f701c 100644 --- a/tests/auto/testlib/selftests/badxml/badxml.pro +++ b/tests/auto/testlib/selftests/badxml/badxml.pro @@ -1,5 +1,5 @@ SOURCES += tst_badxml.cpp -QT = core testlib +QT = core-private testlib mac:CONFIG -= app_bundle CONFIG -= debug_and_release_target diff --git a/tests/auto/testlib/selftests/badxml/tst_badxml.cpp b/tests/auto/testlib/selftests/badxml/tst_badxml.cpp index 1a143e5243..2fb9e5ea90 100644 --- a/tests/auto/testlib/selftests/badxml/tst_badxml.cpp +++ b/tests/auto/testlib/selftests/badxml/tst_badxml.cpp @@ -42,6 +42,7 @@ #include #include +#include /* This test makes a testlog containing lots of characters which have a special meaning in @@ -73,27 +74,26 @@ class EmptyClass : public tst_BadXml class tst_BadXmlSub : public tst_BadXml { public: + tst_BadXmlSub() + : className("tst_BadXml"), mo(0) {} + ~tst_BadXmlSub() { qFree(mo); } + const QMetaObject* metaObject() const; - static char const* className; + QByteArray className; +private: + QMetaObject *mo; }; -char const* tst_BadXmlSub::className = "tst_BadXml"; const QMetaObject* tst_BadXmlSub::metaObject() const { - const QMetaObject& empty = EmptyClass::staticMetaObject; - static QMetaObject mo = { - { empty.d.superdata, empty.d.stringdata, empty.d.data, empty.d.extradata } - }; - static char currentClassName[1024]; - qstrcpy(currentClassName, className); - int len = qstrlen(className); - currentClassName[len] = 0; - currentClassName[len+1] = 0; - - mo.d.stringdata = currentClassName; - - return &mo; + if (!mo || (mo->className() != className)) { + qFree(mo); + QMetaObjectBuilder builder(&EmptyClass::staticMetaObject); + builder.setClassName(className); + const_cast(this)->mo = builder.toMetaObject(); + } + return mo; } /* -- cgit v1.2.3 From 3f7a222414fc9d3e9f2e2cfdd05f33740c5afb7e Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sat, 18 Feb 2012 20:36:06 +0100 Subject: Change the representation of meta-object string data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Up to and including meta-object revision 6, string data have been stored as 0-terminated C-style strings, that were made directly accessible as const char pointers through the public API (QMetaMethod and friends). This commit changes moc to generate an array of QByteArrayData instead, and adapts the QObject kernel accordingly. Generating an array of QByteArrayData (byte array literals) means that the strings can now be returned from public (or private) API as QByteArrays, rather than const char *, with zero allocation or copying. Also, the string length is now computed at compile time (it's part of the QByteArrayData). This commit only changes the internal representation, and does not affect existing public API. The actual (C) string data that the byte array literals reference still consists of zero-terminated strings. The benefit of having the QByteArrayData array will only become apparent in the upcoming meta-object data format change, which changes the format of property and method descriptors. Support for the old meta-object string data format was kept; the codepaths for old revisions (6 and below) will be removed in a separate commit, once all the other meta-object changes are done and affected code has been adapted accordingly. Task-number: QTBUG-24154 Change-Id: I4ec3b363bbc31b8192e5d8915ef091c442c2efad Reviewed-by: Lars Knoll Reviewed-by: Olivier Goffart Reviewed-by: João Abecasis Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp b/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp index 2d180b88ea..021079a8e7 100644 --- a/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp +++ b/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp @@ -90,7 +90,7 @@ static const char qt_meta_stringdata_OldNormalizeObject[] = { }; const QMetaObject OldNormalizeObject::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_OldNormalizeObject, + { &QObject::staticMetaObject, reinterpret_cast(qt_meta_stringdata_OldNormalizeObject), qt_meta_data_OldNormalizeObject, 0 } }; -- cgit v1.2.3 From 96f2365cf4cebc074c3171878dcd25ce19ee7486 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sat, 18 Feb 2012 23:16:24 +0100 Subject: Rename QMetaMethod::signature() to methodSignature() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Qt5 the meta-data format will be changed to not store the method signature string explicitly; the signature will be reconstructed on demand from the method name and parameter type information. The QMetaMethod::signature() method returns a const char pointer. Changing the return type to QByteArray can lead to silent bugs due to the implicit conversion to char *. Even though it's a source- incompatible change, it's therefore better to introduce a new function, methodSignature(), and remove the old signature(). Task-number: QTBUG-24154 Change-Id: Ib3579dedd27a3c7c8914d5f1b231947be2cf4027 Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira Reviewed-by: João Abecasis --- .../corelib/kernel/qmetamethod/tst_qmetamethod.cpp | 2 +- .../corelib/kernel/qmetaobject/tst_qmetaobject.cpp | 10 ++++----- .../qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 6 ++--- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 16 ++++++------- .../dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp | 2 +- tests/auto/tools/moc/tst_moc.cpp | 26 +++++++++++----------- .../auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 2 +- .../benchmarks/corelib/kernel/qmetaobject/main.cpp | 6 ++--- 8 files changed, 35 insertions(+), 35 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 1651d00738..f653e66bfd 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -603,7 +603,7 @@ void tst_QMetaMethod::method() QCOMPARE(method.methodType(), methodType); QCOMPARE(method.access(), access); - QCOMPARE(method.signature(), signature.constData()); + QCOMPARE(method.methodSignature(), signature); QCOMPARE(method.tag(), ""); diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 09fd0a7adb..b6b68338cd 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -978,25 +978,25 @@ void tst_QMetaObject::propertyNotify() QVERIFY(prop.isValid()); QVERIFY(prop.hasNotifySignal()); QMetaMethod signal = prop.notifySignal(); - QCOMPARE(signal.signature(), "value6Changed()"); + QCOMPARE(signal.methodSignature(), QByteArray("value6Changed()")); prop = mo->property(mo->indexOfProperty("value7")); QVERIFY(prop.isValid()); QVERIFY(prop.hasNotifySignal()); signal = prop.notifySignal(); - QCOMPARE(signal.signature(), "value7Changed(QString)"); + QCOMPARE(signal.methodSignature(), QByteArray("value7Changed(QString)")); prop = mo->property(mo->indexOfProperty("value8")); QVERIFY(prop.isValid()); QVERIFY(!prop.hasNotifySignal()); signal = prop.notifySignal(); - QCOMPARE(signal.signature(), (const char *)0); + QCOMPARE(signal.methodSignature(), QByteArray()); prop = mo->property(mo->indexOfProperty("value")); QVERIFY(prop.isValid()); QVERIFY(!prop.hasNotifySignal()); signal = prop.notifySignal(); - QCOMPARE(signal.signature(), (const char *)0); + QCOMPARE(signal.methodSignature(), QByteArray()); } void tst_QMetaObject::propertyConstant() @@ -1114,7 +1114,7 @@ void tst_QMetaObject::indexOfMethod() QFETCH(bool, isSignal); int idx = object->metaObject()->indexOfMethod(name); QVERIFY(idx >= 0); - QCOMPARE(object->metaObject()->method(idx).signature(), name.constData()); + QCOMPARE(object->metaObject()->method(idx).methodSignature(), name); QCOMPARE(object->metaObject()->indexOfSlot(name), isSignal ? -1 : idx); QCOMPARE(object->metaObject()->indexOfSignal(name), !isSignal ? -1 : idx); } diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 97b14a374e..28794050c9 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -1161,7 +1161,7 @@ bool tst_QMetaObjectBuilder::checkForSideEffects static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2) { - if (QByteArray(method1.signature()) != QByteArray(method2.signature())) + if (method1.methodSignature() != method2.methodSignature()) return false; if (QByteArray(method1.typeName()) != QByteArray(method2.typeName())) @@ -1466,7 +1466,7 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, if (_a[0]) *reinterpret_cast(_a[0]) = _r; } break; default: { QMetaMethod ctor = _o->metaObject()->constructor(_id); - qFatal("You forgot to add a case for CreateInstance %s", ctor.signature()); + qFatal("You forgot to add a case for CreateInstance %s", ctor.methodSignature().constData()); } } } else if (_c == QMetaObject::InvokeMetaMethod) { @@ -1478,7 +1478,7 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, case 2: *reinterpret_cast(_a[0]) = _t->listInvokableQRealQString(*reinterpret_cast(_a[1]), *reinterpret_cast(_a[2])); break; default: { QMetaMethod method = _o->metaObject()->method(_o->metaObject()->methodOffset() + _id); - qFatal("You forgot to add a case for InvokeMetaMethod %s", method.signature()); + qFatal("You forgot to add a case for InvokeMetaMethod %s", method.methodSignature().constData()); } } } else if (_c == QMetaObject::IndexOfMethod) { diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index a6ad1d53bc..c6667ff2a8 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -1793,56 +1793,56 @@ void tst_QObject::metamethod() QMetaMethod m; m = mobj->method(mobj->indexOfMethod("invoke1()")); - QVERIFY(QByteArray(m.signature()) == "invoke1()"); + QVERIFY(m.methodSignature() == "invoke1()"); QVERIFY(m.methodType() == QMetaMethod::Method); QVERIFY(m.access() == QMetaMethod::Public); QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); QVERIFY(!(m.attributes() & QMetaMethod::Compatibility)); m = mobj->method(mobj->indexOfMethod("sinvoke1()")); - QVERIFY(QByteArray(m.signature()) == "sinvoke1()"); + QVERIFY(m.methodSignature() == "sinvoke1()"); QVERIFY(m.methodType() == QMetaMethod::Method); QVERIFY(m.access() == QMetaMethod::Public); QVERIFY((m.attributes() & QMetaMethod::Scriptable)); QVERIFY(!(m.attributes() & QMetaMethod::Compatibility)); m = mobj->method(mobj->indexOfMethod("invoke2()")); - QVERIFY(QByteArray(m.signature()) == "invoke2()"); + QVERIFY(m.methodSignature() == "invoke2()"); QVERIFY(m.methodType() == QMetaMethod::Method); QVERIFY(m.access() == QMetaMethod::Protected); QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); QVERIFY((m.attributes() & QMetaMethod::Compatibility)); m = mobj->method(mobj->indexOfMethod("sinvoke2()")); - QVERIFY(QByteArray(m.signature()) == "sinvoke2()"); + QVERIFY(m.methodSignature() == "sinvoke2()"); QVERIFY(m.methodType() == QMetaMethod::Method); QVERIFY(m.access() == QMetaMethod::Protected); QVERIFY((m.attributes() & QMetaMethod::Scriptable)); QVERIFY((m.attributes() & QMetaMethod::Compatibility)); m = mobj->method(mobj->indexOfMethod("invoke3()")); - QVERIFY(QByteArray(m.signature()) == "invoke3()"); + QVERIFY(m.methodSignature() == "invoke3()"); QVERIFY(m.methodType() == QMetaMethod::Method); QVERIFY(m.access() == QMetaMethod::Private); QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); QVERIFY(!(m.attributes() & QMetaMethod::Compatibility)); m = mobj->method(mobj->indexOfMethod("sinvoke3()")); - QVERIFY(QByteArray(m.signature()) == "sinvoke3()"); + QVERIFY(m.methodSignature() == "sinvoke3()"); QVERIFY(m.methodType() == QMetaMethod::Method); QVERIFY(m.access() == QMetaMethod::Private); QVERIFY((m.attributes() & QMetaMethod::Scriptable)); QVERIFY(!(m.attributes() & QMetaMethod::Compatibility)); m = mobj->method(mobj->indexOfMethod("signal5()")); - QVERIFY(QByteArray(m.signature()) == "signal5()"); + QVERIFY(m.methodSignature() == "signal5()"); QVERIFY(m.methodType() == QMetaMethod::Signal); QVERIFY(m.access() == QMetaMethod::Protected); QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); QVERIFY((m.attributes() & QMetaMethod::Compatibility)); m = mobj->method(mobj->indexOfMethod("aPublicSlot()")); - QVERIFY(QByteArray(m.signature()) == "aPublicSlot()"); + QVERIFY(m.methodSignature() == "aPublicSlot()"); QVERIFY(m.methodType() == QMetaMethod::Slot); QVERIFY(m.access() == QMetaMethod::Public); QVERIFY(!(m.attributes() & QMetaMethod::Scriptable)); diff --git a/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp b/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp index ed4ed4c6a2..f705fe474c 100644 --- a/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp +++ b/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp @@ -397,7 +397,7 @@ void tst_QDBusMetaObject::types() for (int i = metaobject->methodOffset(); i < metaobject->methodCount(); ++i) { QMetaMethod expected = metaobject->method(i); - int methodIdx = result->indexOfMethod(expected.signature()); + int methodIdx = result->indexOfMethod(expected.methodSignature().constData()); QVERIFY(methodIdx != -1); QMetaMethod constructed = result->method(methodIdx); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 27db6cc59c..ae3780207b 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -747,7 +747,7 @@ void tst_Moc::classinfoWithEscapes() QCOMPARE(mobj->methodCount() - mobj->methodOffset(), 1); QMetaMethod mm = mobj->method(mobj->methodOffset()); - QCOMPARE(mm.signature(), "slotWithAReallyLongName(int)"); + QCOMPARE(mm.methodSignature(), QByteArray("slotWithAReallyLongName(int)")); } void tst_Moc::trNoopInClassInfo() @@ -1092,14 +1092,14 @@ void tst_Moc::invokable() { const QMetaObject &mobj = InvokableBeforeReturnType::staticMetaObject; QCOMPARE(mobj.methodCount(), 6); - QVERIFY(mobj.method(5).signature() == QByteArray("foo()")); + QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()")); } { const QMetaObject &mobj = InvokableBeforeInline::staticMetaObject; QCOMPARE(mobj.methodCount(), 7); - QVERIFY(mobj.method(5).signature() == QByteArray("foo()")); - QVERIFY(mobj.method(6).signature() == QByteArray("bar()")); + QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()")); + QVERIFY(mobj.method(6).methodSignature() == QByteArray("bar()")); } } @@ -1108,22 +1108,22 @@ void tst_Moc::singleFunctionKeywordSignalAndSlot() { const QMetaObject &mobj = SingleFunctionKeywordBeforeReturnType::staticMetaObject; QCOMPARE(mobj.methodCount(), 7); - QVERIFY(mobj.method(5).signature() == QByteArray("mySignal()")); - QVERIFY(mobj.method(6).signature() == QByteArray("mySlot()")); + QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()")); + QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()")); } { const QMetaObject &mobj = SingleFunctionKeywordBeforeInline::staticMetaObject; QCOMPARE(mobj.methodCount(), 7); - QVERIFY(mobj.method(5).signature() == QByteArray("mySignal()")); - QVERIFY(mobj.method(6).signature() == QByteArray("mySlot()")); + QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()")); + QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()")); } { const QMetaObject &mobj = SingleFunctionKeywordAfterInline::staticMetaObject; QCOMPARE(mobj.methodCount(), 7); - QVERIFY(mobj.method(5).signature() == QByteArray("mySignal()")); - QVERIFY(mobj.method(6).signature() == QByteArray("mySlot()")); + QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()")); + QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()")); } } @@ -1230,7 +1230,7 @@ void tst_Moc::constructors() QMetaMethod mm = mo->constructor(0); QCOMPARE(mm.access(), QMetaMethod::Public); QCOMPARE(mm.methodType(), QMetaMethod::Constructor); - QCOMPARE(mm.signature(), "CtorTestClass(QObject*)"); + QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QObject*)")); QCOMPARE(mm.typeName(), ""); QList paramNames = mm.parameterNames(); QCOMPARE(paramNames.size(), 1); @@ -1243,7 +1243,7 @@ void tst_Moc::constructors() QMetaMethod mm = mo->constructor(1); QCOMPARE(mm.access(), QMetaMethod::Public); QCOMPARE(mm.methodType(), QMetaMethod::Constructor); - QCOMPARE(mm.signature(), "CtorTestClass()"); + QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass()")); QCOMPARE(mm.typeName(), ""); QCOMPARE(mm.parameterNames().size(), 0); QCOMPARE(mm.parameterTypes().size(), 0); @@ -1252,7 +1252,7 @@ void tst_Moc::constructors() QMetaMethod mm = mo->constructor(2); QCOMPARE(mm.access(), QMetaMethod::Public); QCOMPARE(mm.methodType(), QMetaMethod::Constructor); - QCOMPARE(mm.signature(), "CtorTestClass(QString)"); + QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QString)")); QCOMPARE(mm.typeName(), ""); QList paramNames = mm.parameterNames(); QCOMPARE(paramNames.size(), 1); diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index 82632a018c..e97b044dbc 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -1275,7 +1275,7 @@ static int numberOfConnectedSignals(MySubWindow *subWindow) QMetaMethod method = subWindow->metaObject()->method(i); if (method.methodType() == QMetaMethod::Signal) { QString signature(QLatin1String("2")); - signature += QLatin1String(method.signature()); + signature += QLatin1String(method.methodSignature().constData()); numConnectedSignals += subWindow->receivers(signature.toLatin1()); } } diff --git a/tests/benchmarks/corelib/kernel/qmetaobject/main.cpp b/tests/benchmarks/corelib/kernel/qmetaobject/main.cpp index ab26158f9a..6d7c5c3853 100644 --- a/tests/benchmarks/corelib/kernel/qmetaobject/main.cpp +++ b/tests/benchmarks/corelib/kernel/qmetaobject/main.cpp @@ -174,7 +174,7 @@ void tst_qmetaobject::indexOfMethod_data() const QMetaObject *mo = &QTreeView::staticMetaObject; for (int i = 0; i < mo->methodCount(); ++i) { QMetaMethod method = mo->method(i); - QByteArray sig = method.signature(); + QByteArray sig = method.methodSignature(); QTest::newRow(sig) << sig; } } @@ -197,7 +197,7 @@ void tst_qmetaobject::indexOfSignal_data() QMetaMethod method = mo->method(i); if (method.methodType() != QMetaMethod::Signal) continue; - QByteArray sig = method.signature(); + QByteArray sig = method.methodSignature(); QTest::newRow(sig) << sig; } } @@ -220,7 +220,7 @@ void tst_qmetaobject::indexOfSlot_data() QMetaMethod method = mo->method(i); if (method.methodType() != QMetaMethod::Slot) continue; - QByteArray sig = method.signature(); + QByteArray sig = method.methodSignature(); QTest::newRow(sig) << sig; } } -- cgit v1.2.3 From f95181c7bb340744a0ce172e8c5a8fcdc2543297 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sun, 19 Feb 2012 00:15:00 +0100 Subject: Long live Qt5 meta-object method/property descriptors This commit introduces two significant changes to the meta-object data format: 1) Meta-type information (QMetaType type/name) information is stored directly in the meta-data for both properties and methods; 2) The original signature (string) of a method is no longer stored in the meta-data, since it can be reconstructed from the method name and parameter type info. The motivation for this change is to enable direct access to method names and type information (avoiding string-based lookup for types if possible), since that's typically the information language bindings (e.g. QML) need. (moc already had all the desired information about methods, but it threw it away!) This change keeps support for the older (6 and below) meta-object revisions, but the support will be removed after a short grace period. The following public QMetaMethod functions have been added: name() : QByteArray returnType() : int parameterCount() : int parameterType(int index) : int The following internal QMetaMethod function has been added: getParameterTypes(int *types) : void This commit extends the meta-method data to include explicit type/name data for methods. The new data follows the existing (5-word) method descriptors in the meta-data. The method descriptor format was modified to enable this. First, the descriptor now contains the meta-data index where the method's type/name information can be found. Second, the descriptor contains the number of parameters. Third, the descriptor has a reference to the name of the method, not the full signature. Each entry of a method's type/name array contains either the type id (if it could be determined at meta-object definition time), or a reference to the name of the type (so that the type id can be resolved at runtime). Lastly, instead of storing the method parameter names as a comma-separated list that needs to be parsed at runtime (which was how it was done prior to this commit), the names are now stored as separate entries in the meta-object string table, and their indexes are stored immediately after the method type info array. Hence, parameter names can be queried through the public API without parsing/allocating/copying, too. Task-number: QTBUG-24154 Change-Id: Idb7ab81f12d4bfd658b74e18a0fce594f580cba3 Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- .../corelib/kernel/qmetamethod/tst_qmetamethod.cpp | 44 ++++++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index f653e66bfd..60c8fdb2f2 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -603,15 +603,51 @@ void tst_QMetaMethod::method() QCOMPARE(method.methodType(), methodType); QCOMPARE(method.access(), access); - QCOMPARE(method.methodSignature(), signature); + QVERIFY(!method.methodSignature().isEmpty()); + if (method.methodSignature() != signature) { + // QMetaMethod should always produce a semantically equivalent signature + int signatureIndex = (methodType == QMetaMethod::Constructor) + ? mo->indexOfConstructor(method.methodSignature()) + : mo->indexOfMethod(method.methodSignature()); + QCOMPARE(signatureIndex, index); + } + + QByteArray computedName = signature.left(signature.indexOf('(')); + QCOMPARE(method.name(), computedName); QCOMPARE(method.tag(), ""); - QCOMPARE(method.typeName(), returnTypeName.constData()); - QCOMPARE(QMetaType::type(method.typeName()), returnType); + QCOMPARE(method.returnType(), returnType); + if (QByteArray(method.typeName()) != returnTypeName) { + // QMetaMethod should always produce a semantically equivalent typename + QCOMPARE(QMetaType::type(method.typeName()), QMetaType::type(returnTypeName)); + } - QCOMPARE(method.parameterTypes(), parameterTypeNames); + if (method.parameterTypes() != parameterTypeNames) { + // QMetaMethod should always produce semantically equivalent typenames + QList actualTypeNames = method.parameterTypes(); + QCOMPARE(actualTypeNames.size(), parameterTypeNames.size()); + for (int i = 0; i < parameterTypeNames.size(); ++i) { + QCOMPARE(QMetaType::type(actualTypeNames.at(i)), + QMetaType::type(parameterTypeNames.at(i))); + } + } QCOMPARE(method.parameterNames(), parameterNames); + + QCOMPARE(method.parameterCount(), parameterTypes.size()); + for (int i = 0; i < parameterTypes.size(); ++i) + QCOMPARE(method.parameterType(i), parameterTypes.at(i)); + + { + QVector actualParameterTypes(parameterTypes.size()); + method.getParameterTypes(actualParameterTypes.data()); + for (int i = 0; i < parameterTypes.size(); ++i) + QCOMPARE(actualParameterTypes.at(i), parameterTypes.at(i)); + } + + // Bogus indexes + QCOMPARE(method.parameterType(-1), 0); + QCOMPARE(method.parameterType(parameterTypes.size()), 0); } void tst_QMetaMethod::invalidMethod() -- cgit v1.2.3 From 69e3e544864e55ebe42df035daf3bf66e25c820f Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 6 Feb 2012 20:42:33 +0100 Subject: Add QMetaMethodBuilder::parameterTypes() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function matches QMetaMethod::parameterTypes(). The implementation of QMetaMethod::parameterTypes() was moved to a helper function in QMetaObjectPrivate, so that it can be shared with QMetaMethodBuilder. Change-Id: I4361713996dc4ea31a79c2fc74c813ee5e9c3069 Reviewed-by: Thiago Macieira Reviewed-by: João Abecasis --- .../qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 28794050c9..f187425c84 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -217,6 +217,7 @@ void tst_QMetaObjectBuilder::method() QCOMPARE(nullMethod.signature(), QByteArray()); QVERIFY(nullMethod.methodType() == QMetaMethod::Method); QVERIFY(nullMethod.returnType().isEmpty()); + QVERIFY(nullMethod.parameterTypes().isEmpty()); QVERIFY(nullMethod.parameterNames().isEmpty()); QVERIFY(nullMethod.tag().isEmpty()); QVERIFY(nullMethod.access() == QMetaMethod::Public); @@ -229,6 +230,7 @@ void tst_QMetaObjectBuilder::method() QCOMPARE(method1.signature(), QByteArray("foo(QString,int)")); QVERIFY(method1.methodType() == QMetaMethod::Method); QVERIFY(method1.returnType().isEmpty()); + QCOMPARE(method1.parameterTypes(), QList() << "QString" << "int"); QVERIFY(method1.parameterNames().isEmpty()); QVERIFY(method1.tag().isEmpty()); QVERIFY(method1.access() == QMetaMethod::Public); @@ -242,6 +244,7 @@ void tst_QMetaObjectBuilder::method() QCOMPARE(method2.signature(), QByteArray("bar(QString)")); QVERIFY(method2.methodType() == QMetaMethod::Method); QCOMPARE(method2.returnType(), QByteArray("int")); + QCOMPARE(method2.parameterTypes(), QList() << "QString"); QVERIFY(method2.parameterNames().isEmpty()); QVERIFY(method2.tag().isEmpty()); QVERIFY(method2.access() == QMetaMethod::Public); @@ -267,6 +270,7 @@ void tst_QMetaObjectBuilder::method() QCOMPARE(method1.signature(), QByteArray("foo(QString,int)")); QVERIFY(method1.methodType() == QMetaMethod::Method); QCOMPARE(method1.returnType(), QByteArray("int")); + QCOMPARE(method1.parameterTypes(), QList() << "QString" << "int"); QCOMPARE(method1.parameterNames(), QList() << "a" << "b"); QCOMPARE(method1.tag(), QByteArray("tag")); QVERIFY(method1.access() == QMetaMethod::Private); @@ -276,6 +280,7 @@ void tst_QMetaObjectBuilder::method() QCOMPARE(method2.signature(), QByteArray("bar(QString)")); QVERIFY(method2.methodType() == QMetaMethod::Method); QCOMPARE(method2.returnType(), QByteArray("int")); + QCOMPARE(method2.parameterTypes(), QList() << "QString"); QVERIFY(method2.parameterNames().isEmpty()); QVERIFY(method2.tag().isEmpty()); QVERIFY(method2.access() == QMetaMethod::Public); @@ -296,6 +301,7 @@ void tst_QMetaObjectBuilder::method() QCOMPARE(method1.signature(), QByteArray("foo(QString,int)")); QVERIFY(method1.methodType() == QMetaMethod::Method); QCOMPARE(method1.returnType(), QByteArray("int")); + QCOMPARE(method1.parameterTypes(), QList() << "QString" << "int"); QCOMPARE(method1.parameterNames(), QList() << "a" << "b"); QCOMPARE(method1.tag(), QByteArray("tag")); QVERIFY(method1.access() == QMetaMethod::Private); @@ -305,6 +311,7 @@ void tst_QMetaObjectBuilder::method() QCOMPARE(method2.signature(), QByteArray("bar(QString)")); QVERIFY(method2.methodType() == QMetaMethod::Method); QCOMPARE(method2.returnType(), QByteArray("QString")); + QCOMPARE(method2.parameterTypes(), QList() << "QString"); QCOMPARE(method2.parameterNames(), QList() << "c"); QCOMPARE(method2.tag(), QByteArray("Q_FOO")); QVERIFY(method2.access() == QMetaMethod::Protected); @@ -320,6 +327,7 @@ void tst_QMetaObjectBuilder::method() QCOMPARE(method2.signature(), QByteArray("bar(QString)")); QVERIFY(method2.methodType() == QMetaMethod::Method); QCOMPARE(method2.returnType(), QByteArray("QString")); + QCOMPARE(method2.parameterTypes(), QList() << "QString"); QCOMPARE(method2.parameterNames(), QList() << "c"); QCOMPARE(method2.tag(), QByteArray("Q_FOO")); QVERIFY(method2.access() == QMetaMethod::Protected); @@ -347,6 +355,7 @@ void tst_QMetaObjectBuilder::slot() QCOMPARE(method1.signature(), QByteArray("foo(QString,int)")); QVERIFY(method1.methodType() == QMetaMethod::Slot); QVERIFY(method1.returnType().isEmpty()); + QCOMPARE(method1.parameterTypes(), QList() << "QString" << "int"); QVERIFY(method1.parameterNames().isEmpty()); QVERIFY(method1.tag().isEmpty()); QVERIFY(method1.access() == QMetaMethod::Public); @@ -359,6 +368,7 @@ void tst_QMetaObjectBuilder::slot() QCOMPARE(method2.signature(), QByteArray("bar(QString)")); QVERIFY(method2.methodType() == QMetaMethod::Slot); QVERIFY(method2.returnType().isEmpty()); + QCOMPARE(method2.parameterTypes(), QList() << "QString"); QVERIFY(method2.parameterNames().isEmpty()); QVERIFY(method2.tag().isEmpty()); QVERIFY(method2.access() == QMetaMethod::Public); @@ -384,6 +394,7 @@ void tst_QMetaObjectBuilder::signal() QCOMPARE(method1.signature(), QByteArray("foo(QString,int)")); QVERIFY(method1.methodType() == QMetaMethod::Signal); QVERIFY(method1.returnType().isEmpty()); + QCOMPARE(method1.parameterTypes(), QList() << "QString" << "int"); QVERIFY(method1.parameterNames().isEmpty()); QVERIFY(method1.tag().isEmpty()); QVERIFY(method1.access() == QMetaMethod::Protected); @@ -396,6 +407,7 @@ void tst_QMetaObjectBuilder::signal() QCOMPARE(method2.signature(), QByteArray("bar(QString)")); QVERIFY(method2.methodType() == QMetaMethod::Signal); QVERIFY(method2.returnType().isEmpty()); + QCOMPARE(method2.parameterTypes(), QList() << "QString"); QVERIFY(method2.parameterNames().isEmpty()); QVERIFY(method2.tag().isEmpty()); QVERIFY(method2.access() == QMetaMethod::Protected); @@ -421,6 +433,7 @@ void tst_QMetaObjectBuilder::constructor() QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)")); QVERIFY(ctor1.methodType() == QMetaMethod::Constructor); QVERIFY(ctor1.returnType().isEmpty()); + QCOMPARE(ctor1.parameterTypes(), QList() << "QString" << "int"); QVERIFY(ctor1.parameterNames().isEmpty()); QVERIFY(ctor1.tag().isEmpty()); QVERIFY(ctor1.access() == QMetaMethod::Public); @@ -433,6 +446,7 @@ void tst_QMetaObjectBuilder::constructor() QCOMPARE(ctor2.signature(), QByteArray("bar(QString)")); QVERIFY(ctor2.methodType() == QMetaMethod::Constructor); QVERIFY(ctor2.returnType().isEmpty()); + QCOMPARE(ctor2.parameterTypes(), QList() << "QString"); QVERIFY(ctor2.parameterNames().isEmpty()); QVERIFY(ctor2.tag().isEmpty()); QVERIFY(ctor2.access() == QMetaMethod::Public); @@ -458,6 +472,7 @@ void tst_QMetaObjectBuilder::constructor() QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)")); QVERIFY(ctor1.methodType() == QMetaMethod::Constructor); QCOMPARE(ctor1.returnType(), QByteArray("int")); + QCOMPARE(ctor1.parameterTypes(), QList() << "QString" << "int"); QCOMPARE(ctor1.parameterNames(), QList() << "a" << "b"); QCOMPARE(ctor1.tag(), QByteArray("tag")); QVERIFY(ctor1.access() == QMetaMethod::Private); @@ -466,6 +481,7 @@ void tst_QMetaObjectBuilder::constructor() QCOMPARE(ctor2.signature(), QByteArray("bar(QString)")); QVERIFY(ctor2.methodType() == QMetaMethod::Constructor); QVERIFY(ctor2.returnType().isEmpty()); + QCOMPARE(ctor2.parameterTypes(), QList() << "QString"); QVERIFY(ctor2.parameterNames().isEmpty()); QVERIFY(ctor2.tag().isEmpty()); QVERIFY(ctor2.access() == QMetaMethod::Public); @@ -484,6 +500,7 @@ void tst_QMetaObjectBuilder::constructor() QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)")); QVERIFY(ctor1.methodType() == QMetaMethod::Constructor); QCOMPARE(ctor1.returnType(), QByteArray("int")); + QCOMPARE(ctor1.parameterTypes(), QList() << "QString" << "int"); QCOMPARE(ctor1.parameterNames(), QList() << "a" << "b"); QCOMPARE(ctor1.tag(), QByteArray("tag")); QVERIFY(ctor1.access() == QMetaMethod::Private); @@ -492,6 +509,7 @@ void tst_QMetaObjectBuilder::constructor() QCOMPARE(ctor2.signature(), QByteArray("bar(QString)")); QVERIFY(ctor2.methodType() == QMetaMethod::Constructor); QCOMPARE(ctor2.returnType(), QByteArray("QString")); + QCOMPARE(ctor2.parameterTypes(), QList() << "QString"); QCOMPARE(ctor2.parameterNames(), QList() << "c"); QCOMPARE(ctor2.tag(), QByteArray("Q_FOO")); QVERIFY(ctor2.access() == QMetaMethod::Protected); @@ -506,6 +524,7 @@ void tst_QMetaObjectBuilder::constructor() QCOMPARE(ctor2.signature(), QByteArray("bar(QString)")); QVERIFY(ctor2.methodType() == QMetaMethod::Constructor); QCOMPARE(ctor2.returnType(), QByteArray("QString")); + QCOMPARE(ctor2.parameterTypes(), QList() << "QString"); QCOMPARE(ctor2.parameterNames(), QList() << "c"); QCOMPARE(ctor2.tag(), QByteArray("Q_FOO")); QVERIFY(ctor2.access() == QMetaMethod::Protected); @@ -525,6 +544,7 @@ void tst_QMetaObjectBuilder::constructor() QCOMPARE(prototypeConstructor.signature(), QByteArray("SomethingOfEverything()")); QVERIFY(prototypeConstructor.methodType() == QMetaMethod::Constructor); QCOMPARE(prototypeConstructor.returnType(), QByteArray()); + QVERIFY(prototypeConstructor.parameterTypes().isEmpty()); QVERIFY(prototypeConstructor.access() == QMetaMethod::Public); QCOMPARE(prototypeConstructor.index(), 1); @@ -1167,6 +1187,9 @@ static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2) if (QByteArray(method1.typeName()) != QByteArray(method2.typeName())) return false; + if (method1.parameterTypes() != method2.parameterTypes()) + return false; + if (method1.parameterNames() != method2.parameterNames()) return false; -- cgit v1.2.3 From 3b844c16e0988b017c67b2329cbe34d4da112b33 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Sun, 19 Feb 2012 13:25:04 +0100 Subject: Port QDBusMetaObject to Qt5 meta-property/method descriptor format Adapts QDBusMetaObject to be in sync with the moc/meta-object changes for property and method descriptors (storing the name and argument count of methods, and more elaborate type information). Now that the method name is stored in the standard method descriptor, QtDBus doesn't need to store it separately anymore, and the QMetaObjectPrivate::rawStringData() function can be removed. Change-Id: I04efdbe05b52bbd85405e1713509e55308ac42da Reviewed-by: Thiago Macieira --- .../dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp | 224 +++++++++++++++++++++ 1 file changed, 224 insertions(+) (limited to 'tests') diff --git a/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp b/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp index f705fe474c..a523a66bdd 100644 --- a/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp +++ b/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp @@ -403,10 +403,15 @@ void tst_QDBusMetaObject::types() QCOMPARE(int(constructed.access()), int(expected.access())); QCOMPARE(int(constructed.methodType()), int(expected.methodType())); + QCOMPARE(constructed.name(), expected.name()); + QCOMPARE(constructed.parameterCount(), expected.parameterCount()); QCOMPARE(constructed.parameterNames(), expected.parameterNames()); QCOMPARE(constructed.parameterTypes(), expected.parameterTypes()); + for (int j = 0; j < constructed.parameterCount(); ++j) + QCOMPARE(constructed.parameterType(j), expected.parameterType(j)); QCOMPARE(constructed.tag(), expected.tag()); QCOMPARE(constructed.typeName(), expected.typeName()); + QCOMPARE(constructed.returnType(), expected.returnType()); } for (int i = metaobject->propertyOffset(); i < metaobject->propertyCount(); ++i) { @@ -427,6 +432,8 @@ void tst_QDBusMetaObject::types() QCOMPARE(constructed.isUser(), expected.isUser()); QCOMPARE(constructed.isWritable(), expected.isWritable()); QCOMPARE(constructed.typeName(), expected.typeName()); + QCOMPARE(constructed.type(), expected.type()); + QCOMPARE(constructed.userType(), expected.userType()); } } @@ -667,6 +674,204 @@ const char PropertyTest4_xml[] = "" ""; +class PropertyTest_b: public QObject +{ + Q_OBJECT + Q_PROPERTY(bool property READ property WRITE setProperty) +public: + bool property() { return false; } + void setProperty(bool) { } +}; +const char PropertyTest_b_xml[] = + ""; + +class PropertyTest_y: public QObject +{ + Q_OBJECT + Q_PROPERTY(uchar property READ property WRITE setProperty) +public: + uchar property() { return 0; } + void setProperty(uchar) { } +}; +const char PropertyTest_y_xml[] = + ""; + +class PropertyTest_n: public QObject +{ + Q_OBJECT + Q_PROPERTY(short property READ property WRITE setProperty) +public: + short property() { return 0; } + void setProperty(short) { } +}; +const char PropertyTest_n_xml[] = + ""; + +class PropertyTest_q: public QObject +{ + Q_OBJECT + Q_PROPERTY(ushort property READ property WRITE setProperty) +public: + ushort property() { return 0; } + void setProperty(ushort) { } +}; +const char PropertyTest_q_xml[] = + ""; + +class PropertyTest_u: public QObject +{ + Q_OBJECT + Q_PROPERTY(uint property READ property WRITE setProperty) +public: + uint property() { return 0; } + void setProperty(uint) { } +}; +const char PropertyTest_u_xml[] = + ""; + +class PropertyTest_x: public QObject +{ + Q_OBJECT + Q_PROPERTY(qlonglong property READ property WRITE setProperty) +public: + qlonglong property() { return 0; } + void setProperty(qlonglong) { } +}; +const char PropertyTest_x_xml[] = + ""; + +class PropertyTest_t: public QObject +{ + Q_OBJECT + Q_PROPERTY(qulonglong property READ property WRITE setProperty) +public: + qulonglong property() { return 0; } + void setProperty(qulonglong) { } +}; +const char PropertyTest_t_xml[] = + ""; + +class PropertyTest_d: public QObject +{ + Q_OBJECT + Q_PROPERTY(double property READ property WRITE setProperty) +public: + double property() { return 0; } + void setProperty(double) { } +}; +const char PropertyTest_d_xml[] = + ""; + +class PropertyTest_s: public QObject +{ + Q_OBJECT + Q_PROPERTY(QString property READ property WRITE setProperty) +public: + QString property() { return QString(); } + void setProperty(QString) { } +}; +const char PropertyTest_s_xml[] = + ""; + +class PropertyTest_v: public QObject +{ + Q_OBJECT + Q_PROPERTY(QDBusVariant property READ property WRITE setProperty) +public: + QDBusVariant property() { return QDBusVariant(); } + void setProperty(QDBusVariant) { } +}; +const char PropertyTest_v_xml[] = + ""; + +class PropertyTest_o: public QObject +{ + Q_OBJECT + Q_PROPERTY(QDBusObjectPath property READ property WRITE setProperty) +public: + QDBusObjectPath property() { return QDBusObjectPath(); } + void setProperty(QDBusObjectPath) { } +}; +const char PropertyTest_o_xml[] = + ""; + +class PropertyTest_g: public QObject +{ + Q_OBJECT + Q_PROPERTY(QDBusSignature property READ property WRITE setProperty) +public: + QDBusSignature property() { return QDBusSignature(); } + void setProperty(QDBusSignature) { } +}; +const char PropertyTest_g_xml[] = + ""; + +class PropertyTest_h: public QObject +{ + Q_OBJECT + Q_PROPERTY(QDBusUnixFileDescriptor property READ property WRITE setProperty) +public: + QDBusUnixFileDescriptor property() { return QDBusUnixFileDescriptor(); } + void setProperty(QDBusUnixFileDescriptor) { } +}; +const char PropertyTest_h_xml[] = + ""; + +class PropertyTest_ay: public QObject +{ + Q_OBJECT + Q_PROPERTY(QByteArray property READ property WRITE setProperty) +public: + QByteArray property() { return QByteArray(); } + void setProperty(QByteArray) { } +}; +const char PropertyTest_ay_xml[] = + ""; + +class PropertyTest_as: public QObject +{ + Q_OBJECT + Q_PROPERTY(QStringList property READ property WRITE setProperty) +public: + QStringList property() { return QStringList(); } + void setProperty(QStringList) { } +}; +const char PropertyTest_as_xml[] = + ""; + +class PropertyTest_av: public QObject +{ + Q_OBJECT + Q_PROPERTY(QVariantList property READ property WRITE setProperty) +public: + QVariantList property() { return QVariantList(); } + void setProperty(QVariantList) { } +}; +const char PropertyTest_av_xml[] = + ""; + +class PropertyTest_ao: public QObject +{ + Q_OBJECT + Q_PROPERTY(QList property READ property WRITE setProperty) +public: + QList property() { return QList(); } + void setProperty(QList) { } +}; +const char PropertyTest_ao_xml[] = + ""; + +class PropertyTest_ag: public QObject +{ + Q_OBJECT + Q_PROPERTY(QList property READ property WRITE setProperty) +public: + QList property() { return QList(); } + void setProperty(QList) { } +}; +const char PropertyTest_ag_xml[] = + ""; + void tst_QDBusMetaObject::properties_data() { QTest::addColumn("metaobject"); @@ -676,6 +881,25 @@ void tst_QDBusMetaObject::properties_data() QTest::newRow("readwrite") << &PropertyTest2::staticMetaObject << QString(PropertyTest2_xml); QTest::newRow("write") << &PropertyTest3::staticMetaObject << QString(PropertyTest3_xml); QTest::newRow("customtype") << &PropertyTest4::staticMetaObject << QString(PropertyTest4_xml); + + QTest::newRow("bool") << &PropertyTest_b::staticMetaObject << QString(PropertyTest_b_xml); + QTest::newRow("byte") << &PropertyTest_y::staticMetaObject << QString(PropertyTest_y_xml); + QTest::newRow("short") << &PropertyTest_n::staticMetaObject << QString(PropertyTest_n_xml); + QTest::newRow("ushort") << &PropertyTest_q::staticMetaObject << QString(PropertyTest_q_xml); + QTest::newRow("uint") << &PropertyTest_u::staticMetaObject << QString(PropertyTest_u_xml); + QTest::newRow("qlonglong") << &PropertyTest_x::staticMetaObject << QString(PropertyTest_x_xml); + QTest::newRow("qulonglong") << &PropertyTest_t::staticMetaObject << QString(PropertyTest_t_xml); + QTest::newRow("double") << &PropertyTest_d::staticMetaObject << QString(PropertyTest_d_xml); + QTest::newRow("QString") << &PropertyTest_s::staticMetaObject << QString(PropertyTest_s_xml); + QTest::newRow("QDBusVariant") << &PropertyTest_v::staticMetaObject << QString(PropertyTest_v_xml); + QTest::newRow("QDBusObjectPath") << &PropertyTest_o::staticMetaObject << QString(PropertyTest_o_xml); + QTest::newRow("QDBusSignature") << &PropertyTest_g::staticMetaObject << QString(PropertyTest_g_xml); + QTest::newRow("QDBusUnixFileDescriptor") << &PropertyTest_h::staticMetaObject << QString(PropertyTest_h_xml); + QTest::newRow("QByteArray") << &PropertyTest_ay::staticMetaObject << QString(PropertyTest_ay_xml); + QTest::newRow("QStringList") << &PropertyTest_as::staticMetaObject << QString(PropertyTest_as_xml); + QTest::newRow("QVariantList") << &PropertyTest_av::staticMetaObject << QString(PropertyTest_av_xml); + QTest::newRow("QList") << &PropertyTest_ao::staticMetaObject << QString(PropertyTest_ao_xml); + QTest::newRow("QList") << &PropertyTest_ag::staticMetaObject << QString(PropertyTest_ag_xml); } void tst_QDBusMetaObject::properties() -- cgit v1.2.3 From f94709366229b479a17457021cff0d664cfe8de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Feb 2012 01:14:08 +0100 Subject: Test setSharable with "raw data" Change-Id: I91774685e84416407aa1fa136f27fedb82545a12 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 0112d714f6..36bf7516a9 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -1104,6 +1104,8 @@ void tst_QArrayData::setSharable_data() QArrayData::CapacityReserved)); QArrayDataPointer staticArray( static_cast *>(&staticArrayData.header)); + QArrayDataPointer rawData( + QTypedArrayData::fromRawData(staticArrayData.data, 10)); nonEmpty->copyAppend(5, 1); nonEmptyReserved->copyAppend(7, 2); @@ -1115,6 +1117,7 @@ void tst_QArrayData::setSharable_data() QTest::newRow("non-empty") << nonEmpty << size_t(5) << size_t(10) << false << 1; QTest::newRow("non-empty-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2; QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3; + QTest::newRow("raw-data") << rawData << size_t(10) << size_t(0) << false << 3; } void tst_QArrayData::setSharable() -- cgit v1.2.3 From 7919c0529ed5bdafd9a7dab82780ad1b1bf33178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Feb 2012 23:25:33 +0100 Subject: Add AllocationOption::Grow This is meant to reduce the number of allocations on growing containers. It serves the same purpose as the existing qAllocMore which is currently used by container classes. While only a container knows when it is growing, it doesn't need to care how that information is used. qAllocMore is currently treated as a black-box and its result is (basically) forwarded blindly to an allocate function. In that respect, container code using qAllocMore acts as an intermediary. By merging that functionality in the allocate function itself we offer the same benefits without the intermediaries, allowing for simpler code and centralized decisions on memory allocation. Once all users of qAllocMore get ported to QArrayData and QArrayData::allocate, qAllocMore can be moved or more closely integrated into qarraydata.cpp and qtools_p.h can be dropped. Change-Id: I4c09bf7df274b45c399082fc7113a18e4641c5f0 Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qarraydata/simplevector.h | 6 ++-- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 34 +++++++++++++++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index a0a9b5f764..fe8108bff2 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -178,7 +178,7 @@ public: || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( qMax(capacity(), size() + (last - first)), - d->detachFlags())); + d->detachFlags() | Data::Grow)); detached.d->copyAppend(first, last); detached.d->copyAppend(begin, begin + d->size); @@ -199,7 +199,7 @@ public: || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( qMax(capacity(), size() + (last - first)), - d->detachFlags())); + d->detachFlags() | Data::Grow)); if (d->size) { const T *const begin = constBegin(); @@ -239,7 +239,7 @@ public: || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( qMax(capacity(), size() + (last - first)), - d->detachFlags())); + d->detachFlags() | Data::Grow)); if (position) detached.d->copyAppend(begin, where); diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 36bf7516a9..f3f1daba0f 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -87,6 +87,7 @@ private slots: void literals(); void variadicLiterals(); void rValueReferences(); + void grow(); }; template const T &const_(const T &t) { return t; } @@ -651,6 +652,7 @@ void tst_QArrayData::allocate_data() QArrayData::CapacityReserved | QArrayData::Unsharable, true, false, unsharable_empty }, { "Unsharable", QArrayData::Unsharable, false, false, unsharable_empty }, + { "Grow", QArrayData::Grow, false, true, shared_empty } }; for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i) @@ -690,7 +692,10 @@ void tst_QArrayData::allocate() keeper.headers.append(data); QCOMPARE(data->size, 0); - QVERIFY(data->alloc >= uint(capacity)); + if (allocateOptions & QArrayData::Grow) + QVERIFY(data->alloc > uint(capacity)); + else + QCOMPARE(data->alloc, uint(capacity)); QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); QCOMPARE(data->ref.isSharable(), isSharable); @@ -1385,5 +1390,32 @@ void tst_QArrayData::rValueReferences() #endif } +void tst_QArrayData::grow() +{ + SimpleVector vector; + + QCOMPARE(vector.size(), size_t(0)); + + size_t previousCapacity = vector.capacity(); + size_t allocations = 0; + for (size_t i = 1; i <= (1 << 20); ++i) { + int source[1] = { i }; + vector.append(source, source + 1); + QCOMPARE(vector.size(), i); + if (vector.capacity() != previousCapacity) { + previousCapacity = vector.capacity(); + ++allocations; + } + } + QCOMPARE(vector.size(), size_t(1 << 20)); + + // QArrayData::Grow prevents excessive allocations on a growing container + QVERIFY(allocations > 20 / 2); + QVERIFY(allocations < 20 * 2); + + for (size_t i = 0; i < (1 << 20); ++i) + QCOMPARE(const_(vector).at(i), int(i + 1)); +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3 From 362bde8e8eef41fc6a338ed8fbe6cbf7e9996019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 13 Feb 2012 16:26:35 +0100 Subject: Introduce QMetaType::UnknownType. QMetaType::Void was ambiguous, it was pointing to a valid type (void) and in the same time it was signaling errors in QMetaType. There was no clean way to check if returned type was valid void or some unregistered type. This feature will be used by new QMetaObject revision which will store type ids instead of type names. So it will be easy to distinguish between: void mySlot(); MyUnregisteredType mySlot(); Change-Id: I73ff097f75585a95e12df74d50c6f3141153e771 Reviewed-by: Kent Hansen Reviewed-by: Olivier Goffart --- .../auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp | 17 ++++++++--------- tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 4 ++++ tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 12 +++++++++++- 3 files changed, 23 insertions(+), 10 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 60c8fdb2f2..f44a671180 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -223,7 +223,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject()") << QByteArray("MethodTestObject()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList()) << (QList()) << (QList()) @@ -259,7 +259,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(int)") << QByteArray("MethodTestObject(int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << int(QMetaType::Int)) << (QList() << QByteArray("int")) << (QList() << QByteArray("constructorIntArg")) @@ -295,7 +295,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(qreal)") << QByteArray("MethodTestObject(qreal)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << qMetaTypeId()) << (QList() << QByteArray("qreal")) << (QList() << QByteArray("constructorQRealArg")) @@ -331,7 +331,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(QString)") << QByteArray("MethodTestObject(QString)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << int(QMetaType::QString)) << (QList() << QByteArray("QString")) << (QList() << QByteArray("constructorQStringArg")) @@ -367,7 +367,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(CustomType)") << QByteArray("MethodTestObject(CustomType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << qMetaTypeId()) << (QList() << QByteArray("CustomType")) << (QList() << QByteArray("constructorCustomTypeArg")) @@ -403,7 +403,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(CustomUnregisteredType)") << QByteArray("MethodTestObject(CustomUnregisteredType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << 0) << (QList() << QByteArray("CustomUnregisteredType")) << (QList() << QByteArray("constructorCustomUnregisteredTypeArg")) @@ -536,7 +536,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)") << QByteArray("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << parameterTypes << parameterTypeNames << parameterNames << QMetaMethod::Public << QMetaMethod::Constructor; @@ -571,7 +571,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(bool,int)") << QByteArray("MethodTestObject(bool,int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList() << int(QMetaType::Bool) << int(QMetaType::Int)) << (QList() << QByteArray("bool") << QByteArray("int")) << (QList() << QByteArray("") << QByteArray("")) @@ -616,7 +616,6 @@ void tst_QMetaMethod::method() QCOMPARE(method.name(), computedName); QCOMPARE(method.tag(), ""); - QCOMPARE(method.returnType(), returnType); if (QByteArray(method.typeName()) != returnTypeName) { // QMetaMethod should always produce a semantically equivalent typename diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 72913d10f2..4f283cef90 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -315,6 +315,7 @@ void tst_QMetaType::typeName_data() QT_FOR_EACH_STATIC_TYPE(TYPENAME_DATA) QT_FOR_EACH_STATIC_ALIAS_TYPE(TYPENAME_DATA_ALIAS) + QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << static_cast(0); } void tst_QMetaType::typeName() @@ -625,6 +626,8 @@ void tst_QMetaType::sizeOf_data() { QTest::addColumn("type"); QTest::addColumn("size"); + + QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << 0; #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ QTest::newRow(#RealType) << QMetaType::MetaTypeName << int(QTypeInfo::sizeOf); FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW) @@ -984,6 +987,7 @@ void tst_QMetaType::isRegistered_data() QTest::newRow("-1") << -1 << false; QTest::newRow("-42") << -42 << false; QTest::newRow("IsRegisteredDummyType + 1") << (dummyTypeId + 1) << false; + QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << false; } void tst_QMetaType::isRegistered() diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index ccdab17668..ffe1d2bec4 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -3542,6 +3542,10 @@ void tst_QVariant::loadQVariantFromDataStream(QDataStream::Version version) stream >> typeName >> loadedVariant; const int id = QMetaType::type(typeName.toLatin1()); + if (id == QMetaType::Void) { + // Void type is not supported by QVariant + return; + } QVariant constructedVariant(static_cast(id)); QCOMPARE(constructedVariant.userType(), id); @@ -3561,6 +3565,10 @@ void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version) dataFileStream >> typeName; QByteArray data = file.readAll(); const int id = QMetaType::type(typeName.toLatin1()); + if (id == QMetaType::Void) { + // Void type is not supported by QVariant + return; + } QBuffer buffer; buffer.open(QIODevice::ReadWrite); @@ -3621,7 +3629,9 @@ void tst_QVariant::debugStream_data() const char *tagName = QMetaType::typeName(id); if (!tagName) continue; - QTest::newRow(tagName) << QVariant(static_cast(id)) << id; + if (id != QMetaType::Void) { + QTest::newRow(tagName) << QVariant(static_cast(id)) << id; + } } QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId(); QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId(), 0) << qMetaTypeId(); -- cgit v1.2.3 From 7e4f32993498db0e06346e32458a1ec7d0c7b3ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 21 Feb 2012 14:51:22 +0100 Subject: Base QList::setSharable on RefCount::setSharable Change-Id: I2acccdf9ee595a0eee33c9f7ddded9cc121412c1 Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qlist/tst_qlist.cpp | 172 +++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index fbb821c730..3baa47f013 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -54,6 +54,9 @@ class tst_QList : public QObject Q_OBJECT private slots: + void init(); + void cleanup(); + void length() const; void lengthSignature() const; void append() const; @@ -90,8 +93,100 @@ private slots: void initializeList() const; void const_shared_null() const; + void setSharable1_data() const; + void setSharable1() const; + void setSharable2_data() const; + void setSharable2() const; + +private: + int dummyForGuard; +}; + +struct Complex +{ + Complex(int val) + : value(val) + , checkSum(this) + { + ++liveCount; + } + + Complex(Complex const &other) + : value(other.value) + , checkSum(this) + { + ++liveCount; + } + + Complex &operator=(Complex const &other) + { + check(); other.check(); + + value = other.value; + return *this; + } + + ~Complex() + { + --liveCount; + check(); + } + + operator int() const { return value; } + + bool operator==(Complex const &other) const + { + check(); other.check(); + return value == other.value; + } + + bool check() const + { + if (this != checkSum) { + ++errorCount; + return false; + } + return true; + } + + struct Guard + { + Guard() : initialLiveCount(liveCount) {} + ~Guard() { if (liveCount != initialLiveCount) ++errorCount; } + + private: + Q_DISABLE_COPY(Guard); + int initialLiveCount; + }; + + static void resetErrors() { errorCount = 0; } + static int errors() { return errorCount; } + +private: + static int errorCount; + static int liveCount; + + int value; + void *checkSum; }; +int Complex::errorCount = 0; +int Complex::liveCount = 0; + +void tst_QList::init() +{ + Complex::resetErrors(); + new (&dummyForGuard) Complex::Guard(); +} + +void tst_QList::cleanup() +{ + QCOMPARE(Complex::errors(), 0); + + reinterpret_cast(&dummyForGuard)->~Guard(); + QCOMPARE(Complex::errors(), 0); +} + void tst_QList::length() const { /* Empty list. */ @@ -696,5 +791,82 @@ void tst_QList::const_shared_null() const QVERIFY(!list2.isDetached()); } +Q_DECLARE_METATYPE(QList); +Q_DECLARE_METATYPE(QList); + +template +void generateSetSharableData() +{ + QTest::addColumn >("list"); + QTest::addColumn("size"); + + QTest::newRow("null") << QList() << 0; + QTest::newRow("non-empty") << (QList() << T(0) << T(1) << T(2) << T(3) << T(4)) << 5; +} + +template +void runSetSharableTest() +{ + QFETCH(QList, list); + QFETCH(int, size); + + QVERIFY(!list.isDetached()); // Shared with QTest + + list.setSharable(true); + + QCOMPARE(list.size(), size); + + { + QList copy(list); + QVERIFY(!copy.isDetached()); + QVERIFY(copy.isSharedWith(list)); + } + + list.setSharable(false); + QVERIFY(list.isDetached() || list.isSharedWith(QList())); + + { + QList copy(list); + + QVERIFY(copy.isDetached() || copy.isSharedWith(QList())); + QCOMPARE(copy.size(), size); + QCOMPARE(copy, list); + } + + list.setSharable(true); + + { + QList copy(list); + + QVERIFY(!copy.isDetached()); + QVERIFY(copy.isSharedWith(list)); + } + + for (int i = 0; i < list.size(); ++i) + QCOMPARE(int(list[i]), i); + + QCOMPARE(list.size(), size); +} + +void tst_QList::setSharable1_data() const +{ + generateSetSharableData(); +} + +void tst_QList::setSharable2_data() const +{ + generateSetSharableData(); +} + +void tst_QList::setSharable1() const +{ + runSetSharableTest(); +} + +void tst_QList::setSharable2() const +{ + runSetSharableTest(); +} + QTEST_APPLESS_MAIN(tst_QList) #include "tst_qlist.moc" -- cgit v1.2.3 From eb24dfcccb304c84a147f0eafd3b3fc3df3ef4f3 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 2 Mar 2012 14:48:09 +0100 Subject: Add template specialization of QMetaType for QObject derived pointers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it possible to do things like QVariant::fromValue(new SomeObject); without first using Q_DECLARE_METATYPE(Something*) This functionality was originally part of http://codereview.qt-project.org/#change,11710 but was rejected because the functionality was based on specialization of QVariant::fromValue which could be dangerous. This new implementation doesn't have such danger. Change-Id: I83fe941b6984be54469bc6b9191f6eacaceaa036 Reviewed-by: Jędrzej Nowacki Reviewed-by: Olivier Goffart --- tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 17 +++++++++++++++++ tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 15 +++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index f8403f11a1..572ecc9ba8 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -100,12 +100,29 @@ private slots: struct Foo { int i; }; + +class CustomQObject : public QObject +{ + Q_OBJECT +public: + CustomQObject(QObject *parent = 0) + : QObject(parent) + { + } +}; + +class CustomNonQObject {}; + void tst_QMetaType::defined() { QCOMPARE(int(QMetaTypeId2::Defined), 1); QCOMPARE(int(QMetaTypeId2::Defined), 0); QCOMPARE(int(QMetaTypeId2::Defined), 1); QCOMPARE(int(QMetaTypeId2::Defined), 0); + QVERIFY(QMetaTypeId2::Defined); + QVERIFY(!QMetaTypeId2::Defined); + QVERIFY(!QMetaTypeId2::Defined); + QVERIFY(!QMetaTypeId2::Defined); } struct Bar diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index ccdab17668..5aa1389b65 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -2541,8 +2541,23 @@ public: }; Q_DECLARE_METATYPE(CustomQObjectDerived*) +class CustomQObjectDerivedNoMetaType : public CustomQObject { + Q_OBJECT +public: + CustomQObjectDerivedNoMetaType(QObject *parent = 0) : CustomQObject(parent) {} +}; + void tst_QVariant::qvariant_cast_QObject_derived() { + { + CustomQObjectDerivedNoMetaType *object = new CustomQObjectDerivedNoMetaType(this); + QVariant data = QVariant::fromValue(object); + QVERIFY(data.userType() == qMetaTypeId()); + QCOMPARE(data.value(), object); + QCOMPARE(data.value(), object); + QCOMPARE(data.value(), object); + QVERIFY(data.value() == 0); + } { CustomQObjectDerived *object = new CustomQObjectDerived(this); QVariant data = QVariant::fromValue(object); -- cgit v1.2.3 From 676304e706266f09357ad8bfbe6c4c281f3f3873 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 2 Mar 2012 15:46:39 +0100 Subject: Add test for QUrl::isLocalFile (there weren't any). Change-Id: I839d2eee7b0651700516d6140635151a52a9fa40 Reviewed-by: Thiago Macieira --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index a74d817b8a..f782b26b46 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -1001,6 +1001,7 @@ void tst_QUrl::toLocalFile() QUrl url(theUrl); QCOMPARE(url.toLocalFile(), theFile); + QCOMPARE(url.isLocalFile(), !theFile.isEmpty()); } void tst_QUrl::fromLocalFile_data() -- cgit v1.2.3 From a6a7cabcd3b38dbd65570a23a800d7e3800a78d0 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 2 Mar 2012 15:41:51 +0100 Subject: Add QUrl formatting option "PreferLocalFile". For the readonly case (e.g. progress dialogs), where local file paths look much nicer to end users than file:/// URLs. Change-Id: I899fed27cfb73ebf565389cfd489d2d2fcbeac7c Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index f782b26b46..3bff330db2 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -262,9 +262,16 @@ void tst_QUrl::hashInPath() QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi#mum.txt")); QCOMPARE(withHashInPath.toEncoded(), QByteArray("hi%23mum.txt")); QCOMPARE(withHashInPath.toString(), QString("hi%23mum.txt")); + QCOMPARE(withHashInPath.toDisplayString(QUrl::PreferLocalFile), QString("hi%23mum.txt")); QUrl fromHashInPath = QUrl::fromEncoded(withHashInPath.toEncoded()); QVERIFY(withHashInPath == fromHashInPath); + + const QUrl localWithHash = QUrl::fromLocalFile("/hi#mum.txt"); + QCOMPARE(localWithHash.path(), QString::fromLatin1("/hi#mum.txt")); + QCOMPARE(localWithHash.toEncoded(), QByteArray("file:///hi%23mum.txt")); + QCOMPARE(localWithHash.toString(), QString("file:///hi%23mum.txt")); + QCOMPARE(localWithHash.toDisplayString(QUrl::PreferLocalFile), QString("/hi#mum.txt")); } void tst_QUrl::unc() @@ -352,6 +359,7 @@ void tst_QUrl::setUrl() QCOMPARE(url.port(), -1); QCOMPARE(url.toString(), QString::fromLatin1("file:///")); QCOMPARE(url.toDisplayString(), QString::fromLatin1("file:///")); + QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("/")); } { @@ -367,6 +375,7 @@ void tst_QUrl::setUrl() QCOMPARE(url.port(), 80); QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar:80")); QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://www.foo.bar:80")); + QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("http://www.foo.bar:80")); QUrl url2("//www1.foo.bar"); QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www1.foo.bar")); @@ -451,15 +460,7 @@ void tst_QUrl::setUrl() QUrl url = u1; QVERIFY(url.isValid()); QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my#myref")); - QCOMPARE(url.fragment(), QString::fromLatin1("myref")); - } - - { - QString u1 = "file:/home/dfaure/my#myref"; - QUrl url = u1; - QVERIFY(url.isValid()); - - QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my#myref")); + QCOMPARE(url.toString(QUrl::PreferLocalFile), QString::fromLatin1("file:///home/dfaure/my#myref")); QCOMPARE(url.fragment(), QString::fromLatin1("myref")); } -- cgit v1.2.3 From 8141e34280a92088a527e0935765ad8ba8e92be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 8 Mar 2012 11:48:26 +0100 Subject: Skip test when implicit move operators not available Besides rvalue-references, this test depends on the compiler to generate implicit move operators on a derived class, based on the ones available on its base class. At least Visual Studio 2010 and some variations of clang 3.0 are known not to generate implicit move constructors and assignment operators. Gcc 4.6 and up seem to support the feature. Change-Id: Ied464ef678f517321b19f8a7bacddb6cd6665585 Reviewed-by: Kent Hansen --- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index f3f1daba0f..884f4f7d1d 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -1356,11 +1356,54 @@ typename RemoveReference::Type &&cxx11Move(T &&t) { return static_cast::Type &&>(t); } + +struct CompilerHasCxx11ImplicitMoves +{ + static bool value() + { + DetectImplicitMove d(cxx11Move(DetectImplicitMove())); + return d.constructor == DetectConstructor::MoveConstructor; + } + + struct DetectConstructor + { + Q_DECL_CONSTEXPR DetectConstructor() + : constructor(DefaultConstructor) + { + } + + Q_DECL_CONSTEXPR DetectConstructor(const DetectConstructor &) + : constructor(CopyConstructor) + { + } + + Q_DECL_CONSTEXPR DetectConstructor(DetectConstructor &&) + : constructor(MoveConstructor) + { + } + + enum Constructor { + DefaultConstructor, + CopyConstructor, + MoveConstructor + }; + + Constructor constructor; + }; + + struct DetectImplicitMove + : DetectConstructor + { + }; +}; #endif void tst_QArrayData::rValueReferences() { #ifdef Q_COMPILER_RVALUE_REFS + if (!CompilerHasCxx11ImplicitMoves::value()) + QSKIP("Implicit move ctor not supported in current configuration"); + SimpleVector v1(1, 42); SimpleVector v2; -- cgit v1.2.3 From 86abc878832db67da87b9fe34faa4bc8d71446b0 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 1 Mar 2012 09:01:12 +0100 Subject: {QTouchEvent,QWindowSystemInterface}::TouchPoint: replace QList with QVector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QPointF is in the category of types for which QList is needlessly inefficient (elements are copy-constructed onto the heap and held through pointers). Use a vector instead. This is consistent with the QPainter API. Change-Id: Ie3d6647e05b40a33a7bb0598cbbcde4676e00836 Reviewed-by: Laszlo Agocs Reviewed-by: Samuel Rødal --- tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index 391600dd57..997e15ed55 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -595,7 +595,7 @@ void tst_QTouchEvent::basicRawEventTranslation() rawTouchPoint.setState(Qt::TouchPointPressed); rawTouchPoint.setScreenPos(screenPos); rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry)); - QList rawPosList; + QVector rawPosList; rawPosList << QPointF(12, 34) << QPointF(56, 78); rawTouchPoint.setRawScreenPositions(rawPosList); const ulong timestamp = 1234; -- cgit v1.2.3 From 865fbbddc95e38290f1cf0836acce3faa7ca9e60 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Fri, 9 Mar 2012 09:18:31 +0100 Subject: Mark tst_qtimeline as insignificant on Windows Change-Id: If8f699f867d3950cced17b150cb5f02fddd1f9a8 Reviewed-by: Friedemann Kleint Reviewed-by: Kent Hansen --- tests/auto/corelib/tools/qtimeline/qtimeline.pro | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qtimeline/qtimeline.pro b/tests/auto/corelib/tools/qtimeline/qtimeline.pro index 3a6c120b5a..430b61b103 100644 --- a/tests/auto/corelib/tools/qtimeline/qtimeline.pro +++ b/tests/auto/corelib/tools/qtimeline/qtimeline.pro @@ -2,3 +2,5 @@ CONFIG += testcase parallel_test TARGET = tst_qtimeline QT = core testlib SOURCES = tst_qtimeline.cpp + +win32:CONFIG+=insignificant_test # This has been blacklisted in the past -- cgit v1.2.3 From 6c2695d677215868447790297c1401628eabc47e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 6 Mar 2012 22:23:18 +0100 Subject: QtDBus: make some constructors explicit This is a semi-automatic search, so I'm reasonably sure that all the exported ones have been caught. Change-Id: I314d341ad0db4e9d4bbf353a9537c9422ad8a54b Reviewed-by: Thiago Macieira --- .../qdbuspendingreply/tst_qdbuspendingreply.cpp | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'tests') diff --git a/tests/auto/dbus/qdbuspendingreply/tst_qdbuspendingreply.cpp b/tests/auto/dbus/qdbuspendingreply/tst_qdbuspendingreply.cpp index 5836945484..865c9a86ff 100644 --- a/tests/auto/dbus/qdbuspendingreply/tst_qdbuspendingreply.cpp +++ b/tests/auto/dbus/qdbuspendingreply/tst_qdbuspendingreply.cpp @@ -474,77 +474,77 @@ void tst_QDBusPendingReply::multipleTypes() void tst_QDBusPendingReply::synchronousSimpleTypes() { - QDBusPendingReply rbool = iface->call("retrieveBool"); + QDBusPendingReply rbool(iface->call("retrieveBool")); rbool.waitForFinished(); QVERIFY(rbool.isFinished()); QCOMPARE(rbool.argumentAt<0>(), adaptor->retrieveBool()); - QDBusPendingReply ruchar = iface->call("retrieveUChar"); + QDBusPendingReply ruchar(iface->call("retrieveUChar")); ruchar.waitForFinished(); QVERIFY(ruchar.isFinished()); QCOMPARE(ruchar.argumentAt<0>(), adaptor->retrieveUChar()); - QDBusPendingReply rshort = iface->call("retrieveShort"); + QDBusPendingReply rshort(iface->call("retrieveShort")); rshort.waitForFinished(); QVERIFY(rshort.isFinished()); QCOMPARE(rshort.argumentAt<0>(), adaptor->retrieveShort()); - QDBusPendingReply rushort = iface->call("retrieveUShort"); + QDBusPendingReply rushort(iface->call("retrieveUShort")); rushort.waitForFinished(); QVERIFY(rushort.isFinished()); QCOMPARE(rushort.argumentAt<0>(), adaptor->retrieveUShort()); - QDBusPendingReply rint = iface->call("retrieveInt"); + QDBusPendingReply rint(iface->call("retrieveInt")); rint.waitForFinished(); QVERIFY(rint.isFinished()); QCOMPARE(rint.argumentAt<0>(), adaptor->retrieveInt()); - QDBusPendingReply ruint = iface->call("retrieveUInt"); + QDBusPendingReply ruint(iface->call("retrieveUInt")); ruint.waitForFinished(); QVERIFY(ruint.isFinished()); QCOMPARE(ruint.argumentAt<0>(), adaptor->retrieveUInt()); - QDBusPendingReply rqlonglong = iface->call("retrieveLongLong"); + QDBusPendingReply rqlonglong(iface->call("retrieveLongLong")); rqlonglong.waitForFinished(); QVERIFY(rqlonglong.isFinished()); QCOMPARE(rqlonglong.argumentAt<0>(), adaptor->retrieveLongLong()); - QDBusPendingReply rqulonglong = iface->call("retrieveULongLong"); + QDBusPendingReply rqulonglong(iface->call("retrieveULongLong")); rqulonglong.waitForFinished(); QVERIFY(rqulonglong.isFinished()); QCOMPARE(rqulonglong.argumentAt<0>(), adaptor->retrieveULongLong()); - QDBusPendingReply rdouble = iface->call("retrieveDouble"); + QDBusPendingReply rdouble(iface->call("retrieveDouble")); rdouble.waitForFinished(); QVERIFY(rdouble.isFinished()); QCOMPARE(rdouble.argumentAt<0>(), adaptor->retrieveDouble()); - QDBusPendingReply rstring = iface->call("retrieveString"); + QDBusPendingReply rstring(iface->call("retrieveString")); rstring.waitForFinished(); QVERIFY(rstring.isFinished()); QCOMPARE(rstring.argumentAt<0>(), adaptor->retrieveString()); - QDBusPendingReply robjectpath = iface->call("retrieveObjectPath"); + QDBusPendingReply robjectpath(iface->call("retrieveObjectPath")); robjectpath.waitForFinished(); QVERIFY(robjectpath.isFinished()); QCOMPARE(robjectpath.argumentAt<0>().path(), adaptor->retrieveObjectPath().path()); - QDBusPendingReply rsignature = iface->call("retrieveSignature"); + QDBusPendingReply rsignature(iface->call("retrieveSignature")); rsignature.waitForFinished(); QVERIFY(rsignature.isFinished()); QCOMPARE(rsignature.argumentAt<0>().signature(), adaptor->retrieveSignature().signature()); - QDBusPendingReply rdbusvariant = iface->call("retrieveVariant"); + QDBusPendingReply rdbusvariant(iface->call("retrieveVariant")); rdbusvariant.waitForFinished(); QVERIFY(rdbusvariant.isFinished()); QCOMPARE(rdbusvariant.argumentAt<0>().variant(), adaptor->retrieveVariant().variant()); - QDBusPendingReply rbytearray = iface->call("retrieveByteArray"); + QDBusPendingReply rbytearray(iface->call("retrieveByteArray")); rbytearray.waitForFinished(); QVERIFY(rbytearray.isFinished()); QCOMPARE(rbytearray.argumentAt<0>(), adaptor->retrieveByteArray()); - QDBusPendingReply rstringlist = iface->call("retrieveStringList"); + QDBusPendingReply rstringlist(iface->call("retrieveStringList")); rstringlist.waitForFinished(); QVERIFY(rstringlist.isFinished()); QCOMPARE(rstringlist.argumentAt<0>(), adaptor->retrieveStringList()); @@ -559,28 +559,28 @@ void tst_QDBusPendingReply::errors() { QDBusError error; - QDBusPendingReply<> rvoid = iface->asyncCall("sendError"); + QDBusPendingReply<> rvoid(iface->asyncCall("sendError")); rvoid.waitForFinished(); QVERIFY(rvoid.isFinished()); QVERIFY(rvoid.isError()); error = rvoid.error(); VERIFY_ERROR(error); - QDBusPendingReply rint = iface->asyncCall("sendError"); + QDBusPendingReply rint(iface->asyncCall("sendError")); rint.waitForFinished(); QVERIFY(rint.isFinished()); QVERIFY(rint.isError()); error = rint.error(); VERIFY_ERROR(error); - QDBusPendingReply rintint = iface->asyncCall("sendError"); + QDBusPendingReply rintint(iface->asyncCall("sendError")); rintint.waitForFinished(); QVERIFY(rintint.isFinished()); QVERIFY(rintint.isError()); error = rintint.error(); VERIFY_ERROR(error); - QDBusPendingReply rstring = iface->asyncCall("sendError"); + QDBusPendingReply rstring(iface->asyncCall("sendError")); rstring.waitForFinished(); QVERIFY(rstring.isFinished()); QVERIFY(rstring.isError()); -- cgit v1.2.3 From e57e2f3e32cca2bf592a49cd62eaf567f3795c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 12 Mar 2012 12:58:19 +0100 Subject: Fix QString:mid and midRef, again In commit 75286739 it was assumed that negative positions shouldn't influence the size of the returned substring. That however changes behaviour that was depended on even inside Qt. With this change, the old behaviour is reestablished. A negative value of n is still taken to mean "all the way to the end", regardless of position, and overflows are still avoided. Change-Id: I7d6ed17cc5e274c7c7ddf0eb0c3238e1159ec4f6 Reviewed-by: Kent Hansen Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 52 ++++++++++++++++++++---- 1 file changed, 44 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index a8f706ff80..355e4d7d00 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -1421,8 +1421,14 @@ void tst_QString::mid() QVERIFY(a.mid(9999).isNull()); QVERIFY(a.mid(9999,1).isNull()); - QCOMPARE(a.mid(-1, 6), QString("ABCDEF")); - QCOMPARE(a.mid(-100, 6), QString("ABCDEF")); + QCOMPARE(a.mid(-1, 6), a.mid(0, 5)); + QVERIFY(a.mid(-100, 6).isEmpty()); + QVERIFY(a.mid(INT_MIN, 0).isEmpty()); + QCOMPARE(a.mid(INT_MIN, -1), a); + QVERIFY(a.mid(INT_MIN, INT_MAX).isNull()); + QVERIFY(a.mid(INT_MIN + 1, INT_MAX).isEmpty()); + QCOMPARE(a.mid(INT_MIN + 2, INT_MAX), a.left(1)); + QCOMPARE(a.mid(INT_MIN + a.size() + 1, INT_MAX), a); QVERIFY(a.mid(INT_MAX).isNull()); QVERIFY(a.mid(INT_MAX, INT_MAX).isNull()); QCOMPARE(a.mid(-5, INT_MAX), a); @@ -1441,6 +1447,12 @@ void tst_QString::mid() QVERIFY(n.mid(-1, 6).isNull()); QVERIFY(n.mid(-100, 6).isNull()); + QVERIFY(n.mid(INT_MIN, 0).isNull()); + QVERIFY(n.mid(INT_MIN, -1).isNull()); + QVERIFY(n.mid(INT_MIN, INT_MAX).isNull()); + QVERIFY(n.mid(INT_MIN + 1, INT_MAX).isNull()); + QVERIFY(n.mid(INT_MIN + 2, INT_MAX).isNull()); + QVERIFY(n.mid(INT_MIN + n.size() + 1, INT_MAX).isNull()); QVERIFY(n.mid(INT_MAX).isNull()); QVERIFY(n.mid(INT_MAX, INT_MAX).isNull()); QVERIFY(n.mid(-5, INT_MAX).isNull()); @@ -1455,8 +1467,14 @@ void tst_QString::mid() QCOMPARE(x.mid(5, 4), QString("pine")); QCOMPARE(x.mid(5), QString("pineapples")); - QCOMPARE(x.mid(-1, 6), QString("Nine p")); - QCOMPARE(x.mid(-100, 6), QString("Nine p")); + QCOMPARE(x.mid(-1, 6), x.mid(0, 5)); + QVERIFY(x.mid(-100, 6).isEmpty()); + QVERIFY(x.mid(INT_MIN, 0).isEmpty()); + QCOMPARE(x.mid(INT_MIN, -1), x); + QVERIFY(x.mid(INT_MIN, INT_MAX).isNull()); + QVERIFY(x.mid(INT_MIN + 1, INT_MAX).isEmpty()); + QCOMPARE(x.mid(INT_MIN + 2, INT_MAX), x.left(1)); + QCOMPARE(x.mid(INT_MIN + x.size() + 1, INT_MAX), x); QVERIFY(x.mid(INT_MAX).isNull()); QVERIFY(x.mid(INT_MAX, INT_MAX).isNull()); QCOMPARE(x.mid(-5, INT_MAX), x); @@ -1482,8 +1500,14 @@ void tst_QString::midRef() QVERIFY(a.midRef(9999).toString().isEmpty()); QVERIFY(a.midRef(9999,1).toString().isEmpty()); - QCOMPARE(a.midRef(-1, 6).toString(), QString("ABCDEF")); - QCOMPARE(a.midRef(-100, 6).toString(), QString("ABCDEF")); + QCOMPARE(a.midRef(-1, 6), a.midRef(0, 5)); + QVERIFY(a.midRef(-100, 6).isEmpty()); + QVERIFY(a.midRef(INT_MIN, 0).isEmpty()); + QCOMPARE(a.midRef(INT_MIN, -1).toString(), a); + QVERIFY(a.midRef(INT_MIN, INT_MAX).isNull()); + QVERIFY(a.midRef(INT_MIN + 1, INT_MAX).isEmpty()); + QCOMPARE(a.midRef(INT_MIN + 2, INT_MAX), a.leftRef(1)); + QCOMPARE(a.midRef(INT_MIN + a.size() + 1, INT_MAX).toString(), a); QVERIFY(a.midRef(INT_MAX).isNull()); QVERIFY(a.midRef(INT_MAX, INT_MAX).isNull()); QCOMPARE(a.midRef(-5, INT_MAX).toString(), a); @@ -1502,6 +1526,12 @@ void tst_QString::midRef() QVERIFY(n.midRef(-1, 6).isNull()); QVERIFY(n.midRef(-100, 6).isNull()); + QVERIFY(n.midRef(INT_MIN, 0).isNull()); + QVERIFY(n.midRef(INT_MIN, -1).isNull()); + QVERIFY(n.midRef(INT_MIN, INT_MAX).isNull()); + QVERIFY(n.midRef(INT_MIN + 1, INT_MAX).isNull()); + QVERIFY(n.midRef(INT_MIN + 2, INT_MAX).isNull()); + QVERIFY(n.midRef(INT_MIN + n.size() + 1, INT_MAX).isNull()); QVERIFY(n.midRef(INT_MAX).isNull()); QVERIFY(n.midRef(INT_MAX, INT_MAX).isNull()); QVERIFY(n.midRef(-5, INT_MAX).isNull()); @@ -1516,8 +1546,14 @@ void tst_QString::midRef() QCOMPARE(x.midRef(5, 4).toString(), QString("pine")); QCOMPARE(x.midRef(5).toString(), QString("pineapples")); - QCOMPARE(x.midRef(-1, 6).toString(), QString("Nine p")); - QCOMPARE(x.midRef(-100, 6).toString(), QString("Nine p")); + QCOMPARE(x.midRef(-1, 6), x.midRef(0, 5)); + QVERIFY(x.midRef(-100, 6).isEmpty()); + QVERIFY(x.midRef(INT_MIN, 0).isEmpty()); + QCOMPARE(x.midRef(INT_MIN, -1).toString(), x); + QVERIFY(x.midRef(INT_MIN, INT_MAX).isNull()); + QVERIFY(x.midRef(INT_MIN + 1, INT_MAX).isEmpty()); + QCOMPARE(x.midRef(INT_MIN + 2, INT_MAX), x.leftRef(1)); + QCOMPARE(x.midRef(INT_MIN + x.size() + 1, INT_MAX).toString(), x); QVERIFY(x.midRef(INT_MAX).isNull()); QVERIFY(x.midRef(INT_MAX, INT_MAX).isNull()); QCOMPARE(x.midRef(-5, INT_MAX).toString(), x); -- cgit v1.2.3 From 91248b0f3b40aaebb0e02a127ee936b581b10eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 8 Mar 2012 11:46:08 +0100 Subject: Silence 'narrowing conversion' warning in test Seen with gcc 4.6: tst_qarraydata.cpp: In member function 'void tst_QArrayData::grow()': tst_qarraydata.cpp:1445:29: error: narrowing conversion of 'i' from 'size_t {aka long unsigned int}' to 'int' inside { } [-fpermissive] Change-Id: Iad55659554b64ee34655640d606153f058a8cd05 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 884f4f7d1d..7ea91bc538 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -1442,7 +1442,7 @@ void tst_QArrayData::grow() size_t previousCapacity = vector.capacity(); size_t allocations = 0; for (size_t i = 1; i <= (1 << 20); ++i) { - int source[1] = { i }; + int source[1] = { int(i) }; vector.append(source, source + 1); QCOMPARE(vector.size(), i); if (vector.capacity() != previousCapacity) { -- cgit v1.2.3 From 08790636f2b19a6bab97e3462211bec5b2d23c45 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 11 Mar 2012 00:26:17 +0000 Subject: QRegularExpression: QMetaType and QVariant support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed the Q_DECLARE_METATYPE in favour of first-class support inside QMetaType and QVariant. Change-Id: I904236822bfab967dc0fbd4d4cc2bcb68c741adc Reviewed-by: Jędrzej Nowacki Reviewed-by: Stephen Kelly --- .../auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 10 ++++++++++ .../qvariant/stream/qt5.0/qregularexpression.bin | Bin 0 -> 53 bytes tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 589b8385a1..7fcf2ff4eb 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -528,6 +528,16 @@ template<> struct TestValueFactory { #endif } }; +template<> struct TestValueFactory { + static QRegularExpression *create() + { +#ifndef QT_NO_REGEXP + return new QRegularExpression("abc.*def"); +#else + return 0; +#endif + } +}; template<> struct TestValueFactory { static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); } }; diff --git a/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin b/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin new file mode 100644 index 0000000000..eaa50f7310 Binary files /dev/null and b/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin differ diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 9c9c9be99b..05655b4df6 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -192,6 +192,7 @@ private slots: void toLocale(); void toRegExp(); + void toRegularExpression(); void matrix(); @@ -1319,6 +1320,21 @@ void tst_QVariant::toRegExp() rx = variant.toRegExp(); } +void tst_QVariant::toRegularExpression() +{ + QVariant variant; + QRegularExpression re = variant.toRegularExpression(); + QCOMPARE(re, QRegularExpression()); + + variant = QRegularExpression("abc.*def"); + re = variant.toRegularExpression(); + QCOMPARE(re, QRegularExpression("abc.*def")); + + variant = QVariant::fromValue(QRegularExpression("[ab]\\w+")); + re = variant.value(); + QCOMPARE(re, QRegularExpression("[ab]\\w+")); +} + void tst_QVariant::matrix() { QVariant variant; @@ -1519,6 +1535,8 @@ void tst_QVariant::writeToReadFromDataStream_data() QTest::newRow( "qchar_null" ) << QVariant(QChar(0)) << true; QTest::newRow( "regexp" ) << QVariant(QRegExp("foo", Qt::CaseInsensitive)) << false; QTest::newRow( "regexp_empty" ) << QVariant(QRegExp()) << false; + QTest::newRow( "regularexpression" ) << QVariant(QRegularExpression("abc.*def")) << false; + QTest::newRow( "regularexpression_empty" ) << QVariant(QRegularExpression()) << false; // types known to QMetaType, but not part of QVariant::Type QTest::newRow("QMetaType::Long invalid") << QVariant(QMetaType::Long, (void *) 0) << false; @@ -1944,6 +1962,7 @@ void tst_QVariant::typeName_data() QTest::newRow("48") << int(QVariant::Vector3D) << QByteArray("QVector3D"); QTest::newRow("49") << int(QVariant::Vector4D) << QByteArray("QVector4D"); QTest::newRow("50") << int(QVariant::Quaternion) << QByteArray("QQuaternion"); + QTest::newRow("51") << int(QVariant::RegularExpression) << QByteArray("QRegularExpression"); } void tst_QVariant::typeName() -- cgit v1.2.3 From c005c75080d6e40ac9fd8d458183aae32def9984 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 12 Feb 2012 01:04:16 +0000 Subject: QRegularExpression: support for QString overloads Added support for QString overloads taking a QRegularExpression. Change-Id: I8608ab0b66e5fdd2e966992e1072cf1ef7883c8e Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 110 +++++++++++++++++------ 1 file changed, 83 insertions(+), 27 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 355e4d7d00..7d4a9b5aba 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -194,6 +195,7 @@ private slots: void localeAwareCompare(); void split_data(); void split(); + void split_regexp_data(); void split_regexp(); void fromUtf16_data(); void fromUtf16(); @@ -1080,6 +1082,17 @@ void tst_QString::indexOf() QCOMPARE( rx2.matchedLength(), -1 ); } + { + QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption; + if (!bcs) + options |= QRegularExpression::CaseInsensitiveOption; + + QRegularExpression re(QRegularExpression::escape(needle), options); + QEXPECT_FAIL("data58", "QRegularExpression does not support case folding", Continue); + QEXPECT_FAIL("data59", "QRegularExpression does not support case folding", Continue); + QCOMPARE( haystack.indexOf(re, startpos), resultpos ); + } + if (cs == Qt::CaseSensitive) { QCOMPARE( haystack.indexOf(needle, startpos), resultpos ); QCOMPARE( haystack.indexOf(ref, startpos), resultpos ); @@ -1267,6 +1280,15 @@ void tst_QString::lastIndexOf() QCOMPARE(rx1.matchedLength(), -1); QCOMPARE(rx2.matchedLength(), -1); } + + { + QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption; + if (!caseSensitive) + options |= QRegularExpression::CaseInsensitiveOption; + + QRegularExpression re(QRegularExpression::escape(needle), options); + QCOMPARE(haystack.lastIndexOf(re, from), expected); + } } if (cs == Qt::CaseSensitive) { @@ -1302,6 +1324,9 @@ void tst_QString::count() QCOMPARE(a.count( "", Qt::CaseInsensitive), 16); QCOMPARE(a.count(QRegExp("[FG][HI]")),1); QCOMPARE(a.count(QRegExp("[G][HE]")),2); + QCOMPARE(a.count(QRegularExpression("[FG][HI]")), 1); + QCOMPARE(a.count(QRegularExpression("[G][HE]")), 2); + CREATE_REF(QLatin1String("FG")); QCOMPARE(a.count(ref),2); @@ -1327,6 +1352,8 @@ void tst_QString::contains() QVERIFY(a.contains( "", Qt::CaseInsensitive)); QVERIFY(a.contains(QRegExp("[FG][HI]"))); QVERIFY(a.contains(QRegExp("[G][HE]"))); + QVERIFY(a.contains(QRegularExpression("[FG][HI]"))); + QVERIFY(a.contains(QRegularExpression("[G][HE]"))); CREATE_REF(QLatin1String("FG")); QVERIFY(a.contains(ref)); @@ -2172,6 +2199,9 @@ void tst_QString::replace_regexp() QString s2 = string; s2.replace( QRegExp(regexp), after ); QTEST( s2, "result" ); + s2 = string; + s2.replace( QRegularExpression(regexp), after ); + QTEST( s2, "result" ); } void tst_QString::remove_uint_uint() @@ -2236,8 +2266,13 @@ void tst_QString::remove_regexp() QFETCH( QString, after ); if ( after.length() == 0 ) { - string.remove( QRegExp(regexp) ); - QTEST( string, "result" ); + QString s2 = string; + s2.remove( QRegExp(regexp) ); + QTEST( s2, "result" ); + + s2 = string; + s2.remove( QRegularExpression(regexp) ); + QTEST( s2, "result" ); } else { QCOMPARE( 0, 0 ); // shut QtTest } @@ -3978,8 +4013,12 @@ void tst_QString::section() QFETCH( bool, regexp ); if (regexp) { QCOMPARE( wholeString.section( QRegExp(sep), start, end, QString::SectionFlag(flags) ), sectionString ); + QCOMPARE( wholeString.section( QRegularExpression(sep), start, end, QString::SectionFlag(flags) ), sectionString ); } else { QCOMPARE( wholeString.section( sep, start, end, QString::SectionFlag(flags) ), sectionString ); + QCOMPARE( wholeString.section( QRegExp(QRegExp::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString ); + QCOMPARE( wholeString.section( QRegularExpression(QRegularExpression::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString ); + } } @@ -4500,6 +4539,7 @@ void tst_QString::split() QFETCH(QStringList, result); QRegExp rx = QRegExp(QRegExp::escape(sep)); + QRegularExpression re(QRegularExpression::escape(sep)); QStringList list; @@ -4507,6 +4547,8 @@ void tst_QString::split() QVERIFY(list == result); list = str.split(rx); QVERIFY(list == result); + list = str.split(re); + QVERIFY(list == result); if (sep.size() == 1) { list = str.split(sep.at(0)); QVERIFY(list == result); @@ -4516,6 +4558,8 @@ void tst_QString::split() QVERIFY(list == result); list = str.split(rx, QString::KeepEmptyParts); QVERIFY(list == result); + list = str.split(re, QString::KeepEmptyParts); + QVERIFY(list == result); if (sep.size() == 1) { list = str.split(sep.at(0), QString::KeepEmptyParts); QVERIFY(list == result); @@ -4526,39 +4570,51 @@ void tst_QString::split() QVERIFY(list == result); list = str.split(rx, QString::SkipEmptyParts); QVERIFY(list == result); + list = str.split(re, QString::SkipEmptyParts); + QVERIFY(list == result); if (sep.size() == 1) { list = str.split(sep.at(0), QString::SkipEmptyParts); QVERIFY(list == result); } } +void tst_QString::split_regexp_data() +{ + QTest::addColumn("string"); + QTest::addColumn("pattern"); + QTest::addColumn("result"); + + QTest::newRow("data01") << "Some text\n\twith strange whitespace." + << "\\s+" + << (QStringList() << "Some" << "text" << "with" << "strange" << "whitespace." ); + + QTest::newRow("data02") << "This time, a normal English sentence." + << "\\W+" + << (QStringList() << "This" << "time" << "a" << "normal" << "English" << "sentence" << ""); + + QTest::newRow("data03") << "Now: this sentence fragment." + << "\\b" + << (QStringList() << "" << "Now" << ": " << "this" << " " << "sentence" << " " << "fragment" << "."); +} + void tst_QString::split_regexp() { - QString str1 = "Some text\n\twith strange whitespace."; - QStringList list1 = str1.split(QRegExp("\\s+")); - QStringList result1; - result1 << "Some" << "text" << "with" << "strange" << "whitespace."; - QVERIFY(list1 == result1); - list1 = str1.split(QRegExp("\\s"), QString::SkipEmptyParts); - QVERIFY(list1 == result1); - - QString str2 = "This time, a normal English sentence."; - QStringList list2 = str2.split(QRegExp("\\W+")); - QStringList result2; - result2 << "This" << "time" << "a" << "normal" << "English" << "sentence" << ""; - QVERIFY(list2 == result2); - list2 = str2.split(QRegExp("\\W"), QString::SkipEmptyParts); - result2.removeAll(QString()); - QVERIFY(list2 == result2); - - QString str3 = "Now: this sentence fragment."; - QStringList list3 = str3.split(QRegExp("\\b")); - QStringList result3; - result3 << "" << "Now" << ": " << "this" << " " << "sentence" << " " << "fragment" << "."; - QVERIFY(list3 == result3); - list3 = str3.split(QRegExp("\\b"), QString::SkipEmptyParts); - result3.removeAll(QString()); - QVERIFY(list3 == result3); + QFETCH(QString, string); + QFETCH(QString, pattern); + QFETCH(QStringList, result); + + QStringList list; + list = string.split(QRegExp(pattern)); + QCOMPARE(list, result); + list = string.split(QRegularExpression(pattern)); + QCOMPARE(list, result); + + result.removeAll(QString()); + + list = string.split(QRegExp(pattern), QString::SkipEmptyParts); + QCOMPARE(list, result); + list = string.split(QRegularExpression(pattern), QString::SkipEmptyParts); + QCOMPARE(list, result); } void tst_QString::fromUtf16_data() -- cgit v1.2.3 From c67efb6506b16608921208c9f45a65abb97de029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 7 Mar 2012 14:09:45 +0100 Subject: Fix invalid read, detected by valgrind Commit 3fe1eed0 changed the QVERIFY in line 1354 to QCOMPARE. This was done to work around a (not yet understood) compiler issue. That however was wrong, as char pointers in QCOMPARE are assumed to point to '\0'-terminated strings and will get dereferenced. In this case the intent was to compare the actual pointer values, as the pointers point past the end of the array and should not be dereferenced. Explicitly casting to (void *) and using QCOMPARE will not only keep the intent, it will hopefully also provide meaningful output on failures. As such the fix was applied throughout the test. Change-Id: Ib0968df492ccc11d7c391bb69037cd7241e55493 Reviewed-by: Robin Burchell --- .../auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 7ea91bc538..9bfbac0017 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -314,11 +314,11 @@ void tst_QArrayData::simpleVector() QVERIFY(!v1.isSharedWith(v5)); QVERIFY(!v1.isSharedWith(v6)); - QVERIFY(v1.constBegin() == v1.constEnd()); - QVERIFY(v4.constBegin() == v4.constEnd()); - QVERIFY(v6.constBegin() + v6.size() == v6.constEnd()); - QVERIFY(v7.constBegin() + v7.size() == v7.constEnd()); - QVERIFY(v8.constBegin() + v8.size() == v8.constEnd()); + QCOMPARE((void *)v1.constBegin(), (void *)v1.constEnd()); + QCOMPARE((void *)v4.constBegin(), (void *)v4.constEnd()); + QCOMPARE((void *)(v6.constBegin() + v6.size()), (void *)v6.constEnd()); + QCOMPARE((void *)(v7.constBegin() + v7.size()), (void *)v7.constEnd()); + QCOMPARE((void *)(v8.constBegin() + v8.size()), (void *)v8.constEnd()); QVERIFY(v1 == v2); QVERIFY(v1 == v3); @@ -1216,7 +1216,7 @@ void tst_QArrayData::fromRawData() QCOMPARE(raw.size(), size_t(11)); QCOMPARE(raw.constBegin(), array); - QCOMPARE(raw.constEnd(), array + sizeof(array)/sizeof(array[0])); + QCOMPARE((void *)raw.constEnd(), (void *)(array + sizeof(array)/sizeof(array[0]))); QVERIFY(!raw.isShared()); QVERIFY(SimpleVector(raw).isSharedWith(raw)); @@ -1234,7 +1234,7 @@ void tst_QArrayData::fromRawData() QCOMPARE(raw.size(), size_t(11)); QCOMPARE(raw.constBegin(), array); - QCOMPARE(raw.constEnd(), array + sizeof(array)/sizeof(array[0])); + QCOMPARE((void *)raw.constEnd(), (void *)(array + sizeof(array)/sizeof(array[0]))); SimpleVector copy(raw); QVERIFY(!copy.isSharedWith(raw)); @@ -1247,7 +1247,7 @@ void tst_QArrayData::fromRawData() QCOMPARE(raw.size(), size_t(11)); QCOMPARE(raw.constBegin(), array); - QCOMPARE(raw.constEnd(), array + sizeof(array)/sizeof(array[0])); + QCOMPARE((void *)raw.constEnd(), (void *)(array + sizeof(array)/sizeof(array[0]))); // Detach QCOMPARE(raw.back(), 11); @@ -1286,7 +1286,7 @@ void tst_QArrayData::literals() #endif QVERIFY(v.isSharable()); - QCOMPARE(v.constBegin() + v.size(), v.constEnd()); + QCOMPARE((void *)(v.constBegin() + v.size()), (void *)v.constEnd()); for (int i = 0; i < 10; ++i) QCOMPARE(const_(v)[i], char('A' + i)); @@ -1335,7 +1335,7 @@ void tst_QArrayData::variadicLiterals() QVERIFY(v.isStatic()); QVERIFY(v.isSharable()); - QVERIFY(v.constBegin() + v.size() == v.constEnd()); + QCOMPARE((void *)(v.constBegin() + v.size()), (void *)v.constEnd()); for (int i = 0; i < 7; ++i) QCOMPARE(const_(v)[i], i); -- cgit v1.2.3 From 0731c90eec594224954ea1c6677e6bf2cff50e51 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 2 Mar 2012 12:41:43 +0100 Subject: moc: test signature with (void) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id63ed21e9f5e7447ced877ec19a2786d20f439f0 Reviewed-by: Kent Hansen Reviewed-by: Jędrzej Nowacki --- tests/auto/tools/moc/slots-with-void-template.h | 2 ++ tests/auto/tools/moc/tst_moc.cpp | 2 ++ 2 files changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/auto/tools/moc/slots-with-void-template.h b/tests/auto/tools/moc/slots-with-void-template.h index 081b03eb4a..73f07d1dc7 100644 --- a/tests/auto/tools/moc/slots-with-void-template.h +++ b/tests/auto/tools/moc/slots-with-void-template.h @@ -51,9 +51,11 @@ class SlotsWithVoidTemplateTest : public QObject Q_OBJECT public slots: inline void dummySlot() {} + inline void dummySlot2(void) {} inline void anotherSlot(const TestTemplate &) {} inline TestTemplate mySlot() { return TestTemplate(); } signals: void mySignal(const TestTemplate &); void myVoidSignal(); + void myVoidSignal2(void); }; diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index e8639eec47..f7ce54959e 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -874,6 +874,8 @@ void tst_Moc::slotsWithVoidTemplate() &test, SLOT(dummySlot(void)))); QVERIFY(QObject::connect(&test, SIGNAL(mySignal(const TestTemplate &)), &test, SLOT(anotherSlot(const TestTemplate &)))); + QVERIFY(QObject::connect(&test, SIGNAL(myVoidSignal2()), + &test, SLOT(dummySlot2()))); } void tst_Moc::structQObject() -- cgit v1.2.3 From 72367b1679f8176c8f8a2a424a1c9325433dd8cd Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 8 Mar 2012 23:43:28 +0100 Subject: Bootstrap qdbuscpp2xml. This involves invoking the Moc classes directly and using the data structures it provides instead of invoking the moc exectutable and parsing the generated code. Change-Id: Ia5c654e8ef58d52d0d3376252c13e13885f80da3 Reviewed-by: Thiago Macieira --- tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.pro | 11 ++ tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.qrc | 5 + tests/auto/tools/qdbuscpp2xml/test1.h | 128 +++++++++++++++ tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp | 181 +++++++++++++++++++++ tests/auto/tools/tools.pro | 1 + 5 files changed, 326 insertions(+) create mode 100644 tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.pro create mode 100644 tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.qrc create mode 100644 tests/auto/tools/qdbuscpp2xml/test1.h create mode 100644 tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp (limited to 'tests') diff --git a/tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.pro b/tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.pro new file mode 100644 index 0000000000..4217d5e73c --- /dev/null +++ b/tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.pro @@ -0,0 +1,11 @@ +CONFIG += testcase +QT = core testlib dbus +TARGET = tst_qdbuscpp2xml + +QMAKE_CXXFLAGS += $$QT_CFLAGS_DBUS + +SOURCES += tst_qdbuscpp2xml.cpp \ + +RESOURCES += qdbuscpp2xml.qrc + +HEADERS += test1.h \ No newline at end of file diff --git a/tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.qrc b/tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.qrc new file mode 100644 index 0000000000..b4cffb842e --- /dev/null +++ b/tests/auto/tools/qdbuscpp2xml/qdbuscpp2xml.qrc @@ -0,0 +1,5 @@ + + + test1.h + + diff --git a/tests/auto/tools/qdbuscpp2xml/test1.h b/tests/auto/tools/qdbuscpp2xml/test1.h new file mode 100644 index 0000000000..35dee2cc38 --- /dev/null +++ b/tests/auto/tools/qdbuscpp2xml/test1.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDBUSCPP2XML_TEST1_H +#define QDBUSCPP2XML_TEST1_H + +#include + +class QDBusObjectPath; +class QDBusUnixFileDescriptor; +class QDBusSignature; + +class Test1 : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.qtProject.qdbuscpp2xmlTests.Test1") + Q_PROPERTY(int numProperty1 READ numProperty1 CONSTANT) + Q_PROPERTY(int numProperty2 READ numProperty2 WRITE setNumProperty2) +public: + Test1(QObject *parent = 0) : QObject(parent) {} + + int numProperty1() { return 42; } + + int numProperty2() { return 42; } + void setNumProperty2(int) {} + +signals: + void signalVoidType(); + int signalIntType(); + void signal_primitive_args(int a1, bool a2, short a3, ushort a4, uint a5, qlonglong a6, double a7, qlonglong a8 = 0); + void signal_string_args(const QByteArray &ba, const QString &a2); + void signal_Qt_args1(const QDate &a1, const QTime &a2, const QDateTime &a3, + const QRect &a4, const QRectF &a5, const QSize &a6, const QSizeF &a7); + void signal_Qt_args2(const QPoint &a1, const QPointF &a2, const QLine &a3, const QLineF &a4, + const QVariantList &a5, const QVariantMap &a6, const QVariantHash &a7); + + void signal_QDBus_args(const QDBusObjectPath &a1, const QDBusSignature &a2, const QDBusUnixFileDescriptor &a3); + + void signal_container_args1(const QList &a1, const QList &a2, const QList &a3, const QList &a4, const QList &a5); + void signal_container_args2(const QList &a1, const QList &a2, const QList &a3, const QList &a4, const QList &a5, const QList &a6); + + Q_SCRIPTABLE void signalVoidType_scriptable(); + Q_SCRIPTABLE int signalIntType_scriptable(); + Q_SCRIPTABLE void signal_primitive_args_scriptable(int a1, bool a2, short a3, ushort a4, uint a5, qlonglong a6, double a7, qlonglong a8 = 0); + Q_SCRIPTABLE void signal_string_args_scriptable(const QByteArray &ba, const QString &a2); + Q_SCRIPTABLE void signal_Qt_args1_scriptable(const QDate &a1, const QTime &a2, const QDateTime &a3, + const QRect &a4, const QRectF &a5, const QSize &a6, const QSizeF &a7); + Q_SCRIPTABLE void signal_Qt_args2_scriptable(const QPoint &a1, const QPointF &a2, const QLine &a3, const QLineF &a4, + const QVariantList &a5, const QVariantMap &a6, const QVariantHash &a7); + + Q_SCRIPTABLE void signal_QDBus_args_scriptable(const QDBusObjectPath &a1, const QDBusSignature &a2, const QDBusUnixFileDescriptor &a3); + + Q_SCRIPTABLE void signal_container_args1_scriptable(const QList &a1, const QList &a2, const QList &a3, const QList &a4, const QList &a5); + Q_SCRIPTABLE void signal_container_args2_scriptable(const QList &a1, const QList &a2, const QList &a3, const QList &a4, const QList &a5, const QList &a6); + +public slots: + void slotVoidType() {} + int slotIntType() { return 42; } + + Q_SCRIPTABLE void slotVoidType_scriptable() {} + Q_SCRIPTABLE int slotIntType_scriptable() { return 42; } + +protected slots: + void neverExported1() {} + int neverExported2() { return 42; } + + Q_SCRIPTABLE void neverExported3() {} + Q_SCRIPTABLE int neverExported4() { return 42; } + +private slots: + void neverExported5() {} + int neverExported6() { return 42; } + + Q_SCRIPTABLE void neverExported7() {} + Q_SCRIPTABLE int neverExported8() { return 42; } + +public: + Q_SCRIPTABLE void methodVoidType() {} + Q_SCRIPTABLE int methodIntType() { return 42; } + +protected: + Q_SCRIPTABLE void neverExported9() {} + Q_SCRIPTABLE int neverExported10() { return 42; } + +private: + Q_SCRIPTABLE void neverExported11() {} + Q_SCRIPTABLE int neverExported12() { return 42; } +}; + +#endif diff --git a/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp b/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp new file mode 100644 index 0000000000..5510c656e1 --- /dev/null +++ b/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "test1.h" + +#include + +// in qdbusxmlgenerator.cpp +QT_BEGIN_NAMESPACE +extern Q_DBUS_EXPORT QString qDBusGenerateMetaObjectXml(QString interface, + const QMetaObject *mo, + const QMetaObject *base, + int flags); +QT_END_NAMESPACE + +static QString addXmlHeader(const QString &input) +{ + return + "\n" + + (input.isEmpty() ? QString() : QString("\n " + input.trimmed())) + + "\n\n"; +} + +class tst_qdbuscpp2xml : public QObject +{ + Q_OBJECT + +private slots: + void qdbuscpp2xml_data(); + void qdbuscpp2xml(); + + void initTestCase(); + void cleanupTestCase(); + +private: + QHash m_tests; +}; + +void tst_qdbuscpp2xml::initTestCase() +{ + m_tests.insert("test1", new Test1); +} + +void tst_qdbuscpp2xml::cleanupTestCase() +{ + qDeleteAll(m_tests); +} + +void tst_qdbuscpp2xml::qdbuscpp2xml_data() +{ + QTest::addColumn("inputfile"); + QTest::addColumn("flags"); + + QBitArray doneFlags(QDBusConnection::ExportAllContents + 1); + for (int flag = 0x10; flag < QDBusConnection::ExportScriptableContents; flag += 0x10) { + QTest::newRow("xmlgenerator-" + QByteArray::number(flag)) << "test1" << flag; + doneFlags.setBit(flag); + for (int mask = QDBusConnection::ExportAllSlots; mask <= QDBusConnection::ExportAllContents; mask += 0x110) { + int flags = flag | mask; + if (doneFlags.testBit(flags)) + continue; + QTest::newRow("xmlgenerator-" + QByteArray::number(flags)) << "test1" << flags; + doneFlags.setBit(flags); + } + } +} + +void tst_qdbuscpp2xml::qdbuscpp2xml() +{ + QFETCH(QString, inputfile); + QFETCH(int, flags); + + // qdbuscpp2xml considers these equivalent + if (flags & QDBusConnection::ExportScriptableSlots) + flags |= QDBusConnection::ExportScriptableInvokables; + if (flags & QDBusConnection::ExportNonScriptableSlots) + flags |= QDBusConnection::ExportNonScriptableInvokables; + + if (flags & QDBusConnection::ExportScriptableInvokables) + flags |= QDBusConnection::ExportScriptableSlots; + if (flags & QDBusConnection::ExportNonScriptableInvokables) + flags |= QDBusConnection::ExportNonScriptableSlots; + + QStringList options; + if (flags & QDBusConnection::ExportScriptableProperties) { + if (flags & QDBusConnection::ExportNonScriptableProperties) + options << "-P"; + else + options << "-p"; + } + if (flags & QDBusConnection::ExportScriptableSignals) { + if (flags & QDBusConnection::ExportNonScriptableSignals) + options << "-S"; + else + options << "-s"; + } + if (flags & QDBusConnection::ExportScriptableSlots) { + if (flags & QDBusConnection::ExportNonScriptableSlots) + options << "-M"; + else + options << "-m"; + } + + // Launch + const QString command = QLatin1String("qdbuscpp2xml"); + QProcess process; + process.start(command, QStringList() << options << (QFINDTESTDATA(inputfile + QStringLiteral(".h")))); + if (!process.waitForFinished()) { + const QString path = QString::fromLocal8Bit(qgetenv("PATH")); + QString message = QString::fromLatin1("'%1' could not be found when run from '%2'. Path: '%3' "). + arg(command, QDir::currentPath(), path); + QFAIL(qPrintable(message)); + } + const QChar cr = QLatin1Char('\r'); + const QString err = QString::fromLocal8Bit(process.readAllStandardError()).remove(cr); + const QString out = QString::fromAscii(process.readAllStandardOutput()).remove(cr); + + if (!err.isEmpty()) { + qDebug() << "UNEXPECTED STDERR CONTENTS: " << err; + QFAIL("UNEXPECTED STDERR CONTENTS"); + } + + const QChar nl = QLatin1Char('\n'); + const QStringList actualLines = out.split(nl); + + QObject *testObject = m_tests.value(inputfile); + + if (flags == 0) + flags = QDBusConnection::ExportScriptableContents + | QDBusConnection::ExportNonScriptableContents; + + QString expected = qDBusGenerateMetaObjectXml(QString(), testObject->metaObject(), &QObject::staticMetaObject, flags); + + expected = addXmlHeader(expected); + + QCOMPARE(out, expected); +} + +QTEST_APPLESS_MAIN(tst_qdbuscpp2xml) + +#include "tst_qdbuscpp2xml.moc" diff --git a/tests/auto/tools/tools.pro b/tests/auto/tools/tools.pro index 6bf6ddf64f..0a2821773f 100644 --- a/tests/auto/tools/tools.pro +++ b/tests/auto/tools/tools.pro @@ -5,3 +5,4 @@ SUBDIRS=\ moc \ rcc \ +contains(QT_CONFIG, dbus):SUBDIRS += qdbuscpp2xml -- cgit v1.2.3 From b20cbf7102c62c8c769ed1d1b0c4949e603a7a4c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 14 Mar 2012 14:09:27 +0100 Subject: Move CMake macros and tests for dbus tools from qttools. Change-Id: I9d589a2d33eb8fcac63443565bb3e2319be3e04f Reviewed-by: Thiago Macieira --- tests/manual/cmake/CMakeLists.txt | 1 + tests/manual/cmake/pass9/CMakeLists.txt | 32 +++++++++++++++++ tests/manual/cmake/pass9/mydbusobject.cpp | 56 +++++++++++++++++++++++++++++ tests/manual/cmake/pass9/mydbusobject.h | 58 +++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 tests/manual/cmake/pass9/CMakeLists.txt create mode 100644 tests/manual/cmake/pass9/mydbusobject.cpp create mode 100644 tests/manual/cmake/pass9/mydbusobject.h (limited to 'tests') diff --git a/tests/manual/cmake/CMakeLists.txt b/tests/manual/cmake/CMakeLists.txt index 2d0164a47b..241454e763 100644 --- a/tests/manual/cmake/CMakeLists.txt +++ b/tests/manual/cmake/CMakeLists.txt @@ -89,3 +89,4 @@ expect_fail(fail5) expect_pass("pass(needsquoting)6") expect_pass(pass7) expect_pass(pass8) +expect_pass(pass9) diff --git a/tests/manual/cmake/pass9/CMakeLists.txt b/tests/manual/cmake/pass9/CMakeLists.txt new file mode 100644 index 0000000000..6aefd37696 --- /dev/null +++ b/tests/manual/cmake/pass9/CMakeLists.txt @@ -0,0 +1,32 @@ + +cmake_minimum_required(VERSION 2.8) + +project(pass9) + +find_package(Qt5DBus REQUIRED) + +include_directories( + ${Qt5DBus_INCLUDE_DIRS} +) + +add_definitions(${Qt5DBus_DEFINITIONS}) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(my_srcs mydbusobject.cpp) + +qt5_wrap_cpp(moc_files mydbusobject.h) + +qt5_generate_dbus_interface( + mydbusobject.h + ${CMAKE_BINARY_DIR}/org.qtProject.Tests.MyDBusObject.xml +) + +qt5_add_dbus_adaptor(my_srcs + ${CMAKE_BINARY_DIR}/org.qtProject.Tests.MyDBusObject.xml + mydbusobject.h + MyDBusObject +) + +add_executable(myobject ${my_srcs} ${moc_files}) +target_link_libraries(myobject ${Qt5DBus_LIBRARIES}) diff --git a/tests/manual/cmake/pass9/mydbusobject.cpp b/tests/manual/cmake/pass9/mydbusobject.cpp new file mode 100644 index 0000000000..ee211bbe9b --- /dev/null +++ b/tests/manual/cmake/pass9/mydbusobject.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mydbusobject.h" +#include "mydbusobjectadaptor.h" + +MyDBusObject::MyDBusObject(QObject *parent) + : QObject(parent) +{ + new MyDBusObjectAdaptor(this); + emit someSignal(); +} + +int main(int argc, char **argv) +{ + MyDBusObject myDBusObject; + return 0; +} diff --git a/tests/manual/cmake/pass9/mydbusobject.h b/tests/manual/cmake/pass9/mydbusobject.h new file mode 100644 index 0000000000..dd9a023ffe --- /dev/null +++ b/tests/manual/cmake/pass9/mydbusobject.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYDBUSOBJECT_H +#define MYDBUSOBJECT_H + +#include + +class MyDBusObject : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.qtProject.Tests.MyDBusObject") +public: + MyDBusObject(QObject *parent = 0); + +signals: + void someSignal(); +}; + +#endif -- cgit v1.2.3 From 3f64a7b67bfbcaab65ebb03f84962cce5834790b Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 15 Mar 2012 21:05:01 +0100 Subject: Add autotests for QMetaType::load() and save() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These were not covered at all by tst_qmetatype. Change-Id: Ic957470ac78b2c15fe449efe17e1f178a41c3690 Reviewed-by: João Abecasis --- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 126 +++++++++++++++++++++ 1 file changed, 126 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 96c391d582..942d41d669 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -97,6 +97,9 @@ private slots: void isEnum(); void registerStreamBuiltin(); void automaticTemplateRegistration(); + void saveAndLoadBuiltin_data(); + void saveAndLoadBuiltin(); + void saveAndLoadCustom(); }; struct Foo { int i; }; @@ -1314,6 +1317,129 @@ void tst_QMetaType::automaticTemplateRegistration() } } +template +struct StreamingTraits +{ + enum { isStreamable = 1 }; // Streamable by default +}; + +// Non-streamable types + +#define DECLARE_NONSTREAMABLE(Type) \ + template<> struct StreamingTraits { enum { isStreamable = 0 }; }; + +DECLARE_NONSTREAMABLE(void) +DECLARE_NONSTREAMABLE(void*) +DECLARE_NONSTREAMABLE(QModelIndex) +DECLARE_NONSTREAMABLE(QObject*) +DECLARE_NONSTREAMABLE(QWidget*) + +#define DECLARE_GUI_CLASS_NONSTREAMABLE(MetaTypeName, MetaTypeId, RealType) \ + DECLARE_NONSTREAMABLE(RealType) +QT_FOR_EACH_STATIC_GUI_CLASS(DECLARE_GUI_CLASS_NONSTREAMABLE) +#undef DECLARE_GUI_CLASS_NONSTREAMABLE + +#define DECLARE_WIDGETS_CLASS_NONSTREAMABLE(MetaTypeName, MetaTypeId, RealType) \ + DECLARE_NONSTREAMABLE(RealType) +QT_FOR_EACH_STATIC_WIDGETS_CLASS(DECLARE_WIDGETS_CLASS_NONSTREAMABLE) +#undef DECLARE_WIDGETS_CLASS_NONSTREAMABLE + +#undef DECLARE_NONSTREAMABLE + +void tst_QMetaType::saveAndLoadBuiltin_data() +{ + QTest::addColumn("type"); + QTest::addColumn("isStreamable"); + +#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ + QTest::newRow(#RealType) << MetaTypeId << bool(StreamingTraits::isStreamable); + QT_FOR_EACH_STATIC_TYPE(ADD_METATYPE_TEST_ROW) +#undef ADD_METATYPE_TEST_ROW +} + +void tst_QMetaType::saveAndLoadBuiltin() +{ + QFETCH(int, type); + QFETCH(bool, isStreamable); + + void *value = QMetaType::create(type); + + QByteArray ba; + QDataStream stream(&ba, QIODevice::ReadWrite); + QCOMPARE(QMetaType::save(stream, type, value), isStreamable); + QCOMPARE(stream.status(), QDataStream::Ok); + + if (isStreamable) { + QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false? + QCOMPARE(stream.status(), QDataStream::ReadPastEnd); + } + + stream.device()->seek(0); + stream.resetStatus(); + QCOMPARE(QMetaType::load(stream, type, value), isStreamable); + QCOMPARE(stream.status(), QDataStream::Ok); + + if (isStreamable) { + QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false? + QCOMPARE(stream.status(), QDataStream::ReadPastEnd); + } + + QMetaType::destroy(type, value); +} + +struct CustomStreamableType +{ + int a; +}; +Q_DECLARE_METATYPE(CustomStreamableType) + +QDataStream &operator<<(QDataStream &out, const CustomStreamableType &t) +{ + out << t.a; return out; +} + +QDataStream &operator>>(QDataStream &in, CustomStreamableType &t) +{ + int a; + in >> a; + if (in.status() == QDataStream::Ok) + t.a = a; + return in; +} + +void tst_QMetaType::saveAndLoadCustom() +{ + CustomStreamableType t; + t.a = 123; + + int id = ::qMetaTypeId(); + QByteArray ba; + QDataStream stream(&ba, QIODevice::ReadWrite); + QVERIFY(!QMetaType::save(stream, id, &t)); + QCOMPARE(stream.status(), QDataStream::Ok); + QVERIFY(!QMetaType::load(stream, id, &t)); + QCOMPARE(stream.status(), QDataStream::Ok); + + qRegisterMetaTypeStreamOperators("CustomStreamableType"); + QVERIFY(QMetaType::save(stream, id, &t)); + QCOMPARE(stream.status(), QDataStream::Ok); + + CustomStreamableType t2; + t2.a = -1; + QVERIFY(QMetaType::load(stream, id, &t2)); // Hmmm, shouldn't it return false? + QCOMPARE(stream.status(), QDataStream::ReadPastEnd); + QCOMPARE(t2.a, -1); + + stream.device()->seek(0); + stream.resetStatus(); + QVERIFY(QMetaType::load(stream, id, &t2)); + QCOMPARE(stream.status(), QDataStream::Ok); + QCOMPARE(t2.a, t.a); + + QVERIFY(QMetaType::load(stream, id, &t2)); // Hmmm, shouldn't it return false? + QCOMPARE(stream.status(), QDataStream::ReadPastEnd); +} + // Compile-time test, it should be possible to register function pointer types class Undefined; -- cgit v1.2.3 From 83e055424af8331eafd744ea33dfe8a4ecdaf1e6 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 15 Mar 2012 21:30:55 +0100 Subject: Add QtJson types to meta-type system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make QJsonValue, QJsonObject, QJsonArray and QJsonDocument first-class meta-types. This is an enabler for a lightweight integration with QML. Change-Id: I4725efdd2746cf97fd26d3632a99e8eee849f834 Reviewed-by: Jędrzej Nowacki Reviewed-by: Lars Knoll --- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 34 ++++++++++++++++++++++ .../auto/corelib/kernel/qvariant/tst_qvariant.cpp | 4 +-- 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index b22a3d526a..72ad3080d6 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -541,6 +541,36 @@ template<> struct TestValueFactory { #endif } }; +template<> struct TestValueFactory { + static QJsonValue *create() { return new QJsonValue(123.); } +}; +template<> struct TestValueFactory { + static QJsonObject *create() { + QJsonObject *o = new QJsonObject(); + o->insert("a", 123.); + o->insert("b", true); + o->insert("c", QJsonValue::Null); + o->insert("d", QLatin1String("ciao")); + return o; + } +}; +template<> struct TestValueFactory { + static QJsonArray *create() { + QJsonArray *a = new QJsonArray(); + a->append(123.); + a->append(true); + a->append(QJsonValue::Null); + a->append(QLatin1String("ciao")); + return a; + } +}; +template<> struct TestValueFactory { + static QJsonDocument *create() { + return new QJsonDocument( + QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }") + ); + } +}; template<> struct TestValueFactory { static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); } }; @@ -1339,6 +1369,10 @@ struct StreamingTraits DECLARE_NONSTREAMABLE(void) DECLARE_NONSTREAMABLE(void*) DECLARE_NONSTREAMABLE(QModelIndex) +DECLARE_NONSTREAMABLE(QJsonValue) +DECLARE_NONSTREAMABLE(QJsonObject) +DECLARE_NONSTREAMABLE(QJsonArray) +DECLARE_NONSTREAMABLE(QJsonDocument) DECLARE_NONSTREAMABLE(QObject*) DECLARE_NONSTREAMABLE(QWidget*) diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 05655b4df6..3d4692db39 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -1643,8 +1643,8 @@ void tst_QVariant::writeToReadFromOldDataStream() void tst_QVariant::checkDataStream() { - QTest::ignoreMessage(QtWarningMsg, "Trying to construct an instance of an invalid type, type id: 46"); - const QByteArray settingsHex("0000002effffffffff"); + QTest::ignoreMessage(QtWarningMsg, "Trying to construct an instance of an invalid type, type id: 49"); + const QByteArray settingsHex("00000031ffffffffff"); const QByteArray settings = QByteArray::fromHex(settingsHex); QDataStream in(settings); QVariant v; -- cgit v1.2.3 From 37b0a8e7e645b97df57aae44059b2aa35bc909c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Fri, 16 Mar 2012 16:32:38 +0100 Subject: Fix qDebug stream for an invalid QVariant. This patch changes invalid QVariant qDebug stream value from "QVariant(, QVariant::Invalid)" to "QVariant(Invalid)" New tests were added. Change-Id: Ia57d4fc2d775cc9fce28e03eba402c2173845b35 Reviewed-by: Kent Hansen --- .../auto/corelib/kernel/qvariant/tst_qvariant.cpp | 57 ++++++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 3d4692db39..89c8f77e4a 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -275,6 +275,8 @@ private slots: void forwardDeclare(); void debugStream_data(); void debugStream(); + void debugStreamType_data(); + void debugStreamType(); void loadQt4Stream_data(); void loadQt4Stream(); @@ -3630,8 +3632,8 @@ void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version) class MessageHandler { public: - MessageHandler(const int typeId) - : oldMsgHandler(qInstallMsgHandler(handler)) + MessageHandler(const int typeId, QtMsgHandler msgHandler = handler) + : oldMsgHandler(qInstallMsgHandler(msgHandler)) { currentId = typeId; } @@ -3645,13 +3647,24 @@ public: { return ok; } -private: +protected: static void handler(QtMsgType, const char *txt) { QString msg = QString::fromLatin1(txt); // Format itself is not important, but basic data as a type name should be included in the output - ok = msg.startsWith("QVariant(") + QMetaType::typeName(currentId); - QVERIFY2(ok, (QString::fromLatin1("Message is not valid: '") + msg + '\'').toLatin1().constData()); + ok = msg.startsWith("QVariant("); + QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '") + msg + '\'').toLatin1().constData()); + ok &= (currentId == QMetaType::UnknownType + ? msg.contains("Invalid") + : msg.contains(QMetaType::typeName(currentId))); + QVERIFY2(ok, (QString::fromLatin1("Message doesn't contain type name: '") + msg + '\'').toLatin1().constData()); + if (currentId == QMetaType::Char || currentId == QMetaType::QChar) { + // Chars insert '\0' into the qdebug stream, it is not possible to find a real string length + return; + } + ok &= msg.endsWith(") "); + QVERIFY2(ok, (QString::fromLatin1("Message is not correctly finished: '") + msg + '\'').toLatin1().constData()); + } QtMsgHandler oldMsgHandler; @@ -3676,6 +3689,7 @@ void tst_QVariant::debugStream_data() QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId(); QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId(), 0) << qMetaTypeId(); QTest::newRow("MyClass") << QVariant(qMetaTypeId(), 0) << qMetaTypeId(); + QTest::newRow("InvalidVariant") << QVariant() << int(QMetaType::UnknownType); } void tst_QVariant::debugStream() @@ -3688,5 +3702,38 @@ void tst_QVariant::debugStream() QVERIFY(msgHandler.testPassed()); } +struct MessageHandlerType : public MessageHandler +{ + MessageHandlerType(const int typeId) + : MessageHandler(typeId, handler) + {} + static void handler(QtMsgType, const char *txt) + { + QString msg = QString::fromLatin1(txt); + // Format itself is not important, but basic data as a type name should be included in the output + ok = msg.startsWith("QVariant::"); + QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '") + msg + '\'').toLatin1().constData()); + ok &= (currentId == QMetaType::UnknownType + ? msg.contains("Invalid") + : msg.contains(QMetaType::typeName(currentId))); + QVERIFY2(ok, (QString::fromLatin1("Message doesn't contain type name: '") + msg + '\'').toLatin1().constData()); + } +}; + +void tst_QVariant::debugStreamType_data() +{ + debugStream_data(); +} + +void tst_QVariant::debugStreamType() +{ + QFETCH(QVariant, variant); + QFETCH(int, typeId); + + MessageHandlerType msgHandler(typeId); + qDebug() << QVariant::Type(typeId); + QVERIFY(msgHandler.testPassed()); +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" -- cgit v1.2.3 From bfd2b30faf3da224e5bc5f86d13a57524cd6b2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Fri, 16 Mar 2012 17:28:47 +0100 Subject: Crash fix in ~QVariant QVariant handlers can not be unregistered. We are not able to guarantee that such operation is safe and we do not want to. Change-Id: Id9a12e6a8c750110e4a08eab1de3e07e5c408675 Reviewed-by: Thiago Macieira --- .../auto/corelib/kernel/qvariant/tst_qvariant.cpp | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 89c8f77e4a..b6cb6b3632 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -286,6 +287,9 @@ private slots: void loadQt5Stream(); void saveQt5Stream_data(); void saveQt5Stream(); + + void guiVariantAtExit(); + void widgetsVariantAtExit(); private: void dataStream_data(QDataStream::Version version); void loadQVariantFromDataStream(QDataStream::Version version); @@ -3735,5 +3739,29 @@ void tst_QVariant::debugStreamType() QVERIFY(msgHandler.testPassed()); } +void tst_QVariant::guiVariantAtExit() +{ + // crash test, it should not crash at QGuiApplication exit + static QVariant cursor = QCursor(); + static QVariant point = QPoint(); + static QVariant image = QImage(); + static QVariant pallete = QPalette(); + Q_UNUSED(cursor); + Q_UNUSED(point); + Q_UNUSED(image); + Q_UNUSED(pallete); + QVERIFY(true); +} + +void tst_QVariant::widgetsVariantAtExit() +{ + // crash test, it should not crash at QGuiApplication exit + static QVariant icon= QIcon(); + static QVariant sizePolicy = QSizePolicy(); + Q_UNUSED(icon); + Q_UNUSED(sizePolicy); + QVERIFY(true); +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" -- cgit v1.2.3 From 865949520252d7c0e5a78f4bb2c195f090f1f601 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 13 Mar 2012 07:24:27 +0000 Subject: QRegularExpression: support for QStringList overloads Change-Id: Ia9017348742e41187684185d04b56d27edd383b5 Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- .../corelib/tools/qstringlist/tst_qstringlist.cpp | 96 ++++++++++++++++++---- 1 file changed, 78 insertions(+), 18 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp index 6066f7c8e0..d02e649bdf 100644 --- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp +++ b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp @@ -41,6 +41,7 @@ #include #include +#include #include class tst_QStringList : public QObject @@ -72,18 +73,37 @@ void tst_QStringList::indexOf_regExp() { QStringList list; list << "harald" << "trond" << "vohi" << "harald"; + { + QRegExp re(".*o.*"); - QRegExp re(".*o.*"); + QCOMPARE(list.indexOf(re), 1); + QCOMPARE(list.indexOf(re, 2), 2); + QCOMPARE(list.indexOf(re, 3), -1); - QCOMPARE(list.indexOf(re), 1); - QCOMPARE(list.indexOf(re, 2), 2); - QCOMPARE(list.indexOf(re, 3), -1); + QCOMPARE(list.indexOf(QRegExp(".*x.*")), -1); + QCOMPARE(list.indexOf(re, -1), -1); + QCOMPARE(list.indexOf(re, -3), 1); + QCOMPARE(list.indexOf(re, -9999), 1); + QCOMPARE(list.indexOf(re, 9999), -1); - QCOMPARE(list.indexOf(QRegExp(".*x.*")), -1); - QCOMPARE(list.indexOf(re, -1), -1); - QCOMPARE(list.indexOf(re, -3), 1); - QCOMPARE(list.indexOf(re, -9999), 1); - QCOMPARE(list.indexOf(re, 9999), -1); + QCOMPARE(list.indexOf(QRegExp("[aeiou]")), -1); + } + + { + QRegularExpression re(".*o.*"); + + QCOMPARE(list.indexOf(re), 1); + QCOMPARE(list.indexOf(re, 2), 2); + QCOMPARE(list.indexOf(re, 3), -1); + + QCOMPARE(list.indexOf(QRegularExpression(".*x.*")), -1); + QCOMPARE(list.indexOf(re, -1), -1); + QCOMPARE(list.indexOf(re, -3), 1); + QCOMPARE(list.indexOf(re, -9999), 1); + QCOMPARE(list.indexOf(re, 9999), -1); + + QCOMPARE(list.indexOf(QRegularExpression("[aeiou]")), -1); + } } void tst_QStringList::lastIndexOf_regExp() @@ -91,17 +111,39 @@ void tst_QStringList::lastIndexOf_regExp() QStringList list; list << "harald" << "trond" << "vohi" << "harald"; - QRegExp re(".*o.*"); + { + QRegExp re(".*o.*"); + + QCOMPARE(list.lastIndexOf(re), 2); + QCOMPARE(list.lastIndexOf(re, 2), 2); + QCOMPARE(list.lastIndexOf(re, 1), 1); + + QCOMPARE(list.lastIndexOf(QRegExp(".*x.*")), -1); + QCOMPARE(list.lastIndexOf(re, -1), 2); + QCOMPARE(list.lastIndexOf(re, -3), 1); + QCOMPARE(list.lastIndexOf(re, -9999), -1); + QCOMPARE(list.lastIndexOf(re, 9999), 2); + + QCOMPARE(list.lastIndexOf(QRegExp("[aeiou]")), -1); + } + + { + QRegularExpression re(".*o.*"); + + QCOMPARE(list.lastIndexOf(re), 2); + QCOMPARE(list.lastIndexOf(re, 2), 2); + QCOMPARE(list.lastIndexOf(re, 1), 1); + + QCOMPARE(list.lastIndexOf(QRegularExpression(".*x.*")), -1); + QCOMPARE(list.lastIndexOf(re, -1), 2); + QCOMPARE(list.lastIndexOf(re, -3), 1); + QCOMPARE(list.lastIndexOf(re, -9999), -1); + QCOMPARE(list.lastIndexOf(re, 9999), 2); + + QCOMPARE(list.lastIndexOf(QRegularExpression("[aeiou]")), -1); + } - QCOMPARE(list.lastIndexOf(re), 2); - QCOMPARE(list.lastIndexOf(re, 2), 2); - QCOMPARE(list.lastIndexOf(re, 1), 1); - QCOMPARE(list.lastIndexOf(QRegExp(".*x.*")), -1); - QCOMPARE(list.lastIndexOf(re, -1), 2); - QCOMPARE(list.lastIndexOf(re, -3), 1); - QCOMPARE(list.lastIndexOf(re, -9999), -1); - QCOMPARE(list.lastIndexOf(re, 9999), 2); } void tst_QStringList::indexOf() @@ -149,6 +191,12 @@ void tst_QStringList::filter() list3 = list3.filter( QRegExp("[i]ll") ); list4 << "Bill Gates" << "Bill Clinton"; QCOMPARE( list3, list4 ); + + QStringList list5, list6; + list5 << "Bill Gates" << "Joe Blow" << "Bill Clinton"; + list5 = list5.filter( QRegularExpression("[i]ll") ); + list6 << "Bill Gates" << "Bill Clinton"; + QCOMPARE( list5, list6 ); } void tst_QStringList::replaceInStrings() @@ -170,6 +218,18 @@ void tst_QStringList::replaceInStrings() list6 << "Bill Clinton" << "Bill Gates"; list5.replaceInStrings( QRegExp("^(.*), (.*)$"), "\\2 \\1" ); QCOMPARE( list5, list6 ); + + QStringList list7, list8; + list7 << "alpha" << "beta" << "gamma" << "epsilon"; + list7.replaceInStrings( QRegularExpression("^a"), "o" ); + list8 << "olpha" << "beta" << "gamma" << "epsilon"; + QCOMPARE( list7, list8 ); + + QStringList list9, list10; + list9 << "Bill Clinton" << "Gates, Bill"; + list10 << "Bill Clinton" << "Bill Gates"; + list9.replaceInStrings( QRegularExpression("^(.*), (.*)$"), "\\2 \\1" ); + QCOMPARE( list9, list10 ); } void tst_QStringList::contains() -- cgit v1.2.3 From cb32450c47e6bd6169c9f514a2e950729f82756f Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 13 Mar 2012 05:30:17 +0000 Subject: QRegularExpression: add QObject::findChildren overload This actually involved tiding up QObject sources a little bit to clearly separate QString / QRegExp overloads of findChildren. The corresponding qFindChildren overload for MSVC 6 compatibiltiy was *not* added. Change-Id: I84826b3df9275a9bda03608a5b66756890eda6f8 Reviewed-by: Lars Knoll --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index c6667ff2a8..c2ded70d80 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -656,6 +657,26 @@ void tst_QObject::findChildren() l = qFindChildren(&o, QRegExp("harry")); QCOMPARE(l.size(), 0); + l = o.findChildren(QRegularExpression("o.*")); + QCOMPARE(l.size(), 5); + QVERIFY(l.contains(&o1)); + QVERIFY(l.contains(&o2)); + QVERIFY(l.contains(&o11)); + QVERIFY(l.contains(&o12)); + QVERIFY(l.contains(&o111)); + l = o.findChildren(QRegularExpression("t.*")); + QCOMPARE(l.size(), 2); + QVERIFY(l.contains(&t1)); + QVERIFY(l.contains(&t121)); + tl = o.findChildren(QRegularExpression(".*")); + QCOMPARE(tl.size(), 3); + QVERIFY(tl.contains(&t1)); + QVERIFY(tl.contains(&t121)); + tl = o.findChildren(QRegularExpression("o.*")); + QCOMPARE(tl.size(), 0); + l = o.findChildren(QRegularExpression("harry")); + QCOMPARE(l.size(), 0); + // empty and null string check op = qFindChild(&o); QCOMPARE(op, &o1); -- cgit v1.2.3 From b8d71ed60ba57142237555edb97d4cc7d3675b5c Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 21 Mar 2012 14:06:43 +0100 Subject: Fix QMetaObject::normalizedType() for "void" argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the introduction of QMetaType::UnknownType, void is a proper meta-type, and the normalized form of "void" should be "void", not an empty string. Add more tests to ensure that we do remove "void" in the one case where it actually should be removed (e.g. "foo(void)"). Change-Id: I72dc2d24da67cf52da00c678f50213cff1b92e25 Reviewed-by: Jędrzej Nowacki Reviewed-by: Olivier Goffart Reviewed-by: João Abecasis --- tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp | 10 ++++++++++ tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp | 14 ++++++++++++++ tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 3 +++ 3 files changed, 27 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index f44a671180..0285dd0216 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -114,6 +114,7 @@ public slots: void voidSlotNoParameterNames(bool, int); signals: void voidSignal(); + void voidSignalVoid(void); void voidSignalInt(int voidSignalIntArg); void voidSignalQReal(qreal voidSignalQRealArg); void voidSignalQString(const QString &voidSignalQStringArg); @@ -230,6 +231,15 @@ void tst_QMetaMethod::method_data() << QMetaMethod::Public << QMetaMethod::Constructor; + QTest::newRow("voidSignalVoid") + << QByteArray("voidSignalVoid()") + << int(QMetaType::Void) << QByteArray("") + << QList() + << QList() + << QList() + << QMetaMethod::Protected + << QMetaMethod::Signal; + QTest::newRow("voidSignalInt") << QByteArray("voidSignalInt(int)") << int(QMetaType::Void) << QByteArray("") diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index b6b68338cd..5cf28b5141 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -816,9 +816,22 @@ void tst_QMetaObject::normalizedSignature_data() QTest::newRow("function") << "void foo()" << "void foo()"; QTest::newRow("spaces") << " void foo( ) " << "void foo()"; + QTest::newRow("void") << "void foo(void)" << "void foo()"; + QTest::newRow("void spaces") << "void foo( void )" << "void foo()"; + QTest::newRow("void*") << "void foo(void*)" << "void foo(void*)"; + QTest::newRow("void* spaces") << "void foo( void * )" << "void foo(void*)"; + QTest::newRow("function ptr") << "void foo(void(*)(void))" << "void foo(void(*)())"; + QTest::newRow("function ptr spaces") << "void foo( void ( * ) ( void ))" << "void foo(void(*)())"; + QTest::newRow("function ptr void*") << "void foo(void(*)(void*))" << "void foo(void(*)(void*))"; + QTest::newRow("function ptr void* spaces") << "void foo( void ( * ) ( void * ))" << "void foo(void(*)(void*))"; QTest::newRow("template args") << " void foo( QMap, QList) " << "void foo(QMap,QList)"; + QTest::newRow("void template args") << " void foo( Foo, Bar ) " + << "void foo(Foo,Bar)"; + QTest::newRow("void* template args") << " void foo( Foo, Bar ) " + << "void foo(Foo,Bar)"; QTest::newRow("rettype") << "QList foo()" << "QListfoo()"; + QTest::newRow("rettype void template") << "Foo foo()" << "Foofoo()"; QTest::newRow("const rettype") << "const QString *foo()" << "const QString*foo()"; QTest::newRow("const ref") << "const QString &foo()" << "const QString&foo()"; QTest::newRow("reference") << "QString &foo()" << "QString&foo()"; @@ -877,6 +890,7 @@ void tst_QMetaObject::normalizedType_data() QTest::newRow("struct") << "const struct foo*" << "const foo*"; QTest::newRow("struct2") << "struct foo const*" << "const foo*"; QTest::newRow("enum") << "enum foo" << "foo"; + QTest::newRow("void") << "void" << "void"; } void tst_QMetaObject::normalizedType() diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index c2ded70d80..fa6cf92460 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -165,6 +165,7 @@ signals: void signal3(); void signal4(); QT_MOC_COMPAT void signal5(); + void signal6(void); public slots: void aPublicSlot() { aPublicSlotCalled++; } @@ -824,6 +825,8 @@ void tst_QObject::connectDisconnectNotify_data() QTest::newRow("combo2") << SIGNAL( signal2(void) ) << SLOT( slot2( ) ); QTest::newRow("combo3") << SIGNAL( signal3( ) ) << SLOT( slot3(void) ); QTest::newRow("combo4") << SIGNAL( signal4( void ) )<< SLOT( slot4( void ) ); + QTest::newRow("combo5") << SIGNAL( signal6( void ) ) << SLOT( slot4() ); + QTest::newRow("combo6") << SIGNAL( signal6() ) << SLOT( slot4() ); } void tst_QObject::connectDisconnectNotify() -- cgit v1.2.3 From 22d621dd99417be289b311e3fea5a24f385596fb Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 20 Mar 2012 19:27:02 +0100 Subject: QMetaMethod::typeName() should return "void" if the return type is void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QMetaMethod::typeName() is documented to return an empty string if the return type is void. But after the introduction of QMetaType::UnknownType (where void was made a distinct type), returning an empty string causes the idiom QMetaType::type(method.typeName()) to break; the result will be QMetaType::UnknownType rather than the expected QMetaType::Void for methods that return void. New code should use the new function QMetaMethod::returnType() instead, but it would be good if existing code still did the right thing. The consequence of returning "void" instead of an empty string is that it breaks existing logic that uses the typeName() length to determine whether a method returns void. But we judge this as the lesser of the two evils; it's better to have a typeName() function that is consistent and keeps the QMetaType::type(method.typeName()) idiom working, than to force the typeName() inconsistency for void only to keep code that does "strlen(method.typeName()) == 0" working. The places in Qt that were relying on a zero-length typeName() (testlib, dbus, declarative) have already been changed to use returnType(). Also adapt QMetaObjectBuilder, which is internal API. Change-Id: I70249174029811c5b5d2a08c24b6db33b3723d19 Reviewed-by: Jędrzej Nowacki Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll --- .../corelib/kernel/qmetamethod/tst_qmetamethod.cpp | 45 +++++++++++----------- .../qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 10 ++--- 2 files changed, 28 insertions(+), 27 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 0285dd0216..55997a3ca0 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -197,7 +197,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignal") << QByteArray("voidSignal()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList()) << (QList()) << (QList()) @@ -206,7 +206,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokable") << QByteArray("voidInvokable()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList()) << (QList()) << (QList()) @@ -215,7 +215,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlot") << QByteArray("voidSlot()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList()) << (QList()) << (QList()) @@ -233,7 +233,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalVoid") << QByteArray("voidSignalVoid()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << QList() << QList() << QList() @@ -242,7 +242,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalInt") << QByteArray("voidSignalInt(int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << int(QMetaType::Int)) << (QList() << QByteArray("int")) << (QList() << QByteArray("voidSignalIntArg")) @@ -251,7 +251,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokableInt") << QByteArray("voidInvokableInt(int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << int(QMetaType::Int)) << (QList() << QByteArray("int")) << (QList() << QByteArray("voidInvokableIntArg")) @@ -260,7 +260,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlotInt") << QByteArray("voidSlotInt(int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << int(QMetaType::Int)) << (QList() << QByteArray("int")) << (QList() << QByteArray("voidSlotIntArg")) @@ -278,7 +278,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalQReal") << QByteArray("voidSignalQReal(qreal)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << qMetaTypeId()) << (QList() << QByteArray("qreal")) << (QList() << QByteArray("voidSignalQRealArg")) @@ -287,7 +287,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokableQReal") << QByteArray("voidInvokableQReal(qreal)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << qMetaTypeId()) << (QList() << QByteArray("qreal")) << (QList() << QByteArray("voidInvokableQRealArg")) @@ -296,7 +296,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlotQReal") << QByteArray("voidSlotQReal(qreal)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << qMetaTypeId()) << (QList() << QByteArray("qreal")) << (QList() << QByteArray("voidSlotQRealArg")) @@ -314,7 +314,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalQString") << QByteArray("voidSignalQString(QString)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << int(QMetaType::QString)) << (QList() << QByteArray("QString")) << (QList() << QByteArray("voidSignalQStringArg")) @@ -323,7 +323,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokableQString") << QByteArray("voidInvokableQString(QString)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << int(QMetaType::QString)) << (QList() << QByteArray("QString")) << (QList() << QByteArray("voidInvokableQStringArg")) @@ -332,7 +332,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlotQString") << QByteArray("voidSlotQString(QString)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << int(QMetaType::QString)) << (QList() << QByteArray("QString")) << (QList() << QByteArray("voidSlotQStringArg")) @@ -350,7 +350,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalCustomType") << QByteArray("voidSignalCustomType(CustomType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << qMetaTypeId()) << (QList() << QByteArray("CustomType")) << (QList() << QByteArray("voidSignalCustomTypeArg")) @@ -359,7 +359,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokableCustomType") << QByteArray("voidInvokableCustomType(CustomType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << qMetaTypeId()) << (QList() << QByteArray("CustomType")) << (QList() << QByteArray("voidInvokableCustomTypeArg")) @@ -368,7 +368,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlotCustomType") << QByteArray("voidSlotCustomType(CustomType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << qMetaTypeId()) << (QList() << QByteArray("CustomType")) << (QList() << QByteArray("voidSlotCustomTypeArg")) @@ -386,7 +386,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalCustomUnregisteredType") << QByteArray("voidSignalCustomUnregisteredType(CustomUnregisteredType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << 0) << (QList() << QByteArray("CustomUnregisteredType")) << (QList() << QByteArray("voidSignalCustomUnregisteredTypeArg")) @@ -395,7 +395,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokableCustomUnregisteredType") << QByteArray("voidInvokableCustomUnregisteredType(CustomUnregisteredType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << 0) << (QList() << QByteArray("CustomUnregisteredType")) << (QList() << QByteArray("voidInvokableCustomUnregisteredTypeArg")) @@ -404,7 +404,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlotCustomUnregisteredType") << QByteArray("voidSlotCustomUnregisteredType(CustomUnregisteredType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << 0) << (QList() << QByteArray("CustomUnregisteredType")) << (QList() << QByteArray("voidSlotCustomUnregisteredTypeArg")) @@ -554,7 +554,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalNoParameterNames") << QByteArray("voidSignalNoParameterNames(bool,int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << int(QMetaType::Bool) << int(QMetaType::Int)) << (QList() << QByteArray("bool") << QByteArray("int")) << (QList() << QByteArray("") << QByteArray("")) @@ -563,7 +563,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokableNoParameterNames") << QByteArray("voidInvokableNoParameterNames(bool,int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << int(QMetaType::Bool) << int(QMetaType::Int)) << (QList() << QByteArray("bool") << QByteArray("int")) << (QList() << QByteArray("") << QByteArray("")) @@ -572,7 +572,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlotNoParameterNames") << QByteArray("voidSlotNoParameterNames(bool,int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList() << int(QMetaType::Bool) << int(QMetaType::Int)) << (QList() << QByteArray("bool") << QByteArray("int")) << (QList() << QByteArray("") << QByteArray("")) @@ -627,6 +627,7 @@ void tst_QMetaMethod::method() QCOMPARE(method.tag(), ""); QCOMPARE(method.returnType(), returnType); + QVERIFY(method.typeName() != 0); if (QByteArray(method.typeName()) != returnTypeName) { // QMetaMethod should always produce a semantically equivalent typename QCOMPARE(QMetaType::type(method.typeName()), QMetaType::type(returnTypeName)); diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index f187425c84..0649d1e1d8 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -229,7 +229,7 @@ void tst_QMetaObjectBuilder::method() QMetaMethodBuilder method1 = builder.addMethod("foo(const QString&, int)"); QCOMPARE(method1.signature(), QByteArray("foo(QString,int)")); QVERIFY(method1.methodType() == QMetaMethod::Method); - QVERIFY(method1.returnType().isEmpty()); + QCOMPARE(method1.returnType(), QByteArray("void")); QCOMPARE(method1.parameterTypes(), QList() << "QString" << "int"); QVERIFY(method1.parameterNames().isEmpty()); QVERIFY(method1.tag().isEmpty()); @@ -354,7 +354,7 @@ void tst_QMetaObjectBuilder::slot() QMetaMethodBuilder method1 = builder.addSlot("foo(const QString&, int)"); QCOMPARE(method1.signature(), QByteArray("foo(QString,int)")); QVERIFY(method1.methodType() == QMetaMethod::Slot); - QVERIFY(method1.returnType().isEmpty()); + QCOMPARE(method1.returnType(), QByteArray("void")); QCOMPARE(method1.parameterTypes(), QList() << "QString" << "int"); QVERIFY(method1.parameterNames().isEmpty()); QVERIFY(method1.tag().isEmpty()); @@ -367,7 +367,7 @@ void tst_QMetaObjectBuilder::slot() QMetaMethodBuilder method2 = builder.addSlot("bar(QString)"); QCOMPARE(method2.signature(), QByteArray("bar(QString)")); QVERIFY(method2.methodType() == QMetaMethod::Slot); - QVERIFY(method2.returnType().isEmpty()); + QCOMPARE(method2.returnType(), QByteArray("void")); QCOMPARE(method2.parameterTypes(), QList() << "QString"); QVERIFY(method2.parameterNames().isEmpty()); QVERIFY(method2.tag().isEmpty()); @@ -393,7 +393,7 @@ void tst_QMetaObjectBuilder::signal() QMetaMethodBuilder method1 = builder.addSignal("foo(const QString&, int)"); QCOMPARE(method1.signature(), QByteArray("foo(QString,int)")); QVERIFY(method1.methodType() == QMetaMethod::Signal); - QVERIFY(method1.returnType().isEmpty()); + QCOMPARE(method1.returnType(), QByteArray("void")); QCOMPARE(method1.parameterTypes(), QList() << "QString" << "int"); QVERIFY(method1.parameterNames().isEmpty()); QVERIFY(method1.tag().isEmpty()); @@ -406,7 +406,7 @@ void tst_QMetaObjectBuilder::signal() QMetaMethodBuilder method2 = builder.addSignal("bar(QString)"); QCOMPARE(method2.signature(), QByteArray("bar(QString)")); QVERIFY(method2.methodType() == QMetaMethod::Signal); - QVERIFY(method2.returnType().isEmpty()); + QCOMPARE(method2.returnType(), QByteArray("void")); QCOMPARE(method2.parameterTypes(), QList() << "QString"); QVERIFY(method2.parameterNames().isEmpty()); QVERIFY(method2.tag().isEmpty()); -- cgit v1.2.3 From e1e0e83c5e5d0a2aa1d81e21ad031ab19fa52bb6 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 14 Mar 2012 07:52:30 +0100 Subject: Remove support for meta-object revisions < 7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For Qt5 we no longer want to support the older revisions due to the dual codepaths that must be maintained, and because the format of the meta-object data is quite different in revision 7. The dual codepaths have been replaced by asserts that indicate the revision in which the feature was introduced, and the older-revision fallbacks have been removed. It's not possible to build code generated by moc that has revision <= 6 with Qt5 because the type of the QMetaObject::stringdata member changed from const char * to const QByteArrayData *. For the same reason it's not possible to build a dynamic meta-object generator targeting revision <= 6 with Qt5. Hence, too old meta-objects will be caught at compile time, and the code will have to be ported to generate revision 7 (e.g., by running Qt5's moc on the original class declaration). Change-Id: I33f05878a2d3ee3de53fc7009f7a367f55c25e36 Reviewed-by: Jędrzej Nowacki Reviewed-by: Olivier Goffart Reviewed-by: João Abecasis Reviewed-by: Lars Knoll --- .../kernel/qobject/moc_oldnormalizeobject.cpp | 154 --------------------- .../corelib/kernel/qobject/oldnormalizeobject.h | 69 --------- tests/auto/corelib/kernel/qobject/test/test.pro | 4 - tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 78 ----------- 4 files changed, 305 deletions(-) delete mode 100644 tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp delete mode 100644 tests/auto/corelib/kernel/qobject/oldnormalizeobject.h (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp b/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp deleted file mode 100644 index 021079a8e7..0000000000 --- a/tests/auto/corelib/kernel/qobject/moc_oldnormalizeobject.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/**************************************************************************** -** Meta object code from reading C++ file 'oldnormalizeobject.h' -** -** Created: Wed Nov 18 11:43:05 2009 -** by: The Qt Meta Object Compiler version 62 (Qt 4.6.0) -** -*****************************************************************************/ - -// Yhis file was generated from moc version 4.6 to test binary compatibility -// It should *not* be generated by the current moc - -#include "oldnormalizeobject.h" - -QT_BEGIN_MOC_NAMESPACE -static const uint qt_meta_data_OldNormalizeObject[] = { - - // content: - 4, // revision - 0, // classname - 0, 0, // classinfo - 6, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 3, // signalCount - - // signals: signature, parameters, type, tag, flags - 24, 20, 19, 19, 0x05, - 57, 20, 19, 19, 0x05, - 100, 20, 19, 19, 0x05, - - // slots: signature, parameters, type, tag, flags - 149, 20, 19, 19, 0x0a, - 180, 20, 19, 19, 0x0a, - 221, 20, 19, 19, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_OldNormalizeObject[] = { - "OldNormalizeObject\0\0ref\0" - "typeRefSignal(Template&)\0" - "constTypeRefSignal(Template)\0" - "typeConstRefSignal(Templateconst&)\0" - "typeRefSlot(Template&)\0" - "constTypeRefSlot(Template)\0" - "typeConstRefSlot(Templateconst&)\0" -}; - -const QMetaObject OldNormalizeObject::staticMetaObject = { - { &QObject::staticMetaObject, reinterpret_cast(qt_meta_stringdata_OldNormalizeObject), - qt_meta_data_OldNormalizeObject, 0 } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &OldNormalizeObject::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *OldNormalizeObject::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *OldNormalizeObject::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_OldNormalizeObject)) - return static_cast(const_cast< OldNormalizeObject*>(this)); - return QObject::qt_metacast(_clname); -} - -int OldNormalizeObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - switch (_id) { - case 0: typeRefSignal((*reinterpret_cast< Template(*)>(_a[1]))); break; - case 1: constTypeRefSignal((*reinterpret_cast< const Template(*)>(_a[1]))); break; - case 2: typeConstRefSignal((*reinterpret_cast< Templateconst(*)>(_a[1]))); break; - case 3: typeRefSlot((*reinterpret_cast< Template(*)>(_a[1]))); break; - case 4: constTypeRefSlot((*reinterpret_cast< const Template(*)>(_a[1]))); break; - case 5: typeConstRefSlot((*reinterpret_cast< Templateconst(*)>(_a[1]))); break; - default: ; - } - _id -= 6; - } - return _id; -} - -// SIGNAL 0 -void OldNormalizeObject::typeRefSignal(Template & _t1) -{ - void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)) }; - QMetaObject::activate(this, &staticMetaObject, 0, _a); -} - -// SIGNAL 1 -void OldNormalizeObject::constTypeRefSignal(const Template & _t1) -{ - void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)) }; - QMetaObject::activate(this, &staticMetaObject, 1, _a); -} - -// SIGNAL 2 -void OldNormalizeObject::typeConstRefSignal(Template const & _t1) -{ - void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)) }; - QMetaObject::activate(this, &staticMetaObject, 2, _a); -} -QT_END_MOC_NAMESPACE diff --git a/tests/auto/corelib/kernel/qobject/oldnormalizeobject.h b/tests/auto/corelib/kernel/qobject/oldnormalizeobject.h deleted file mode 100644 index f73027707a..0000000000 --- a/tests/auto/corelib/kernel/qobject/oldnormalizeobject.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtTest module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef OLDNORMALIZEOBJECT_H -#define OLDNORMALIZEOBJECT_H - -#include - -struct Struct; -class Class; -template class Template; - -// An object with old moc output that incorrectly normalizes 'T const &' in the function -// signatures -class OldNormalizeObject : public QObject -{ - /* tmake ignore Q_OBJECT */ - Q_OBJECT - -signals: - void typeRefSignal(Template &ref); - void constTypeRefSignal(const Template &ref); - void typeConstRefSignal(Template const &ref); - -public slots: - void typeRefSlot(Template &) {} - void constTypeRefSlot(const Template &) {} - void typeConstRefSlot(Template const &) {} -}; - -#endif // OLDNORMALIZEOBJECT_H diff --git a/tests/auto/corelib/kernel/qobject/test/test.pro b/tests/auto/corelib/kernel/qobject/test/test.pro index 9443b2e2c7..9daf3d77a0 100644 --- a/tests/auto/corelib/kernel/qobject/test/test.pro +++ b/tests/auto/corelib/kernel/qobject/test/test.pro @@ -3,9 +3,5 @@ TARGET = ../tst_qobject QT = core-private network testlib SOURCES = ../tst_qobject.cpp -# this is here for a reason, moc_oldnormalizedobject.cpp is not auto-generated, it was generated by -# moc from Qt 4.6, and should *not* be generated by the current moc -SOURCES += ../moc_oldnormalizeobject.cpp - load(testcase) # for target.path and installTestHelperApp() installTestHelperApp("signalbug/signalbug",signalbug,signalbug) diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index fa6cf92460..90d20843e3 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -2315,8 +2315,6 @@ public slots: void constTemplateSlot3(const Template< const int >) {} }; -#include "oldnormalizeobject.h" - void tst_QObject::normalize() { NormalizeObject object; @@ -2627,82 +2625,6 @@ void tst_QObject::normalize() SIGNAL(typeConstRefSignal(Template const &)), SLOT(typeConstRefSlot(Template const &)))); - // same test again, this time with an object compiled with old moc output... we know that - // it is not possible to connect everything, whic is the purpose for this test - OldNormalizeObject oldobject; - - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template &)), - SLOT(constTypeRefSlot(const Template &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template &)), - SLOT(constTypeRefSlot(const Template &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template &)), - SLOT(constTypeRefSlot(Template const &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template const &)), - SLOT(constTypeRefSlot(Template const &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template const &)), - SLOT(constTypeRefSlot(Template const &)))); - - // these fail in older Qt versions, but pass now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template &)), - SLOT(typeConstRefSlot(const Template &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template &)), - SLOT(typeConstRefSlot(const Template &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template &)), - SLOT(typeConstRefSlot(Template const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template const &)), - SLOT(typeConstRefSlot(Template const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template const &)), - SLOT(typeConstRefSlot(Template const &)))); - - // these also fail in older Qt versions, but pass now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template &)), - SLOT(constTypeRefSlot(const Template &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template &)), - SLOT(constTypeRefSlot(const Template &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template &)), - SLOT(constTypeRefSlot(Template const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template const &)), - SLOT(constTypeRefSlot(Template const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template const &)), - SLOT(constTypeRefSlot(Template const &)))); - - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template &)), - SLOT(typeConstRefSlot(const Template &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template &)), - SLOT(typeConstRefSlot(const Template &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template &)), - SLOT(typeConstRefSlot(Template const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template const &)), - SLOT(typeConstRefSlot(Template const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template const &)), - SLOT(typeConstRefSlot(Template const &)))); - QVERIFY(object.connect(&object, SIGNAL(typePointerConstRefSignal(Class*const&)), SLOT(typePointerConstRefSlot(Class*const&)))); -- cgit v1.2.3 From 55fa3c189f88933d390177ad5606d3de9deacf93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 14 Mar 2012 17:55:43 +0100 Subject: Got rid of Map / Unmap events in favor of Expose event. Since change 2e4d8f67a871f2033 the need for Map and Unmap events has gone away, as now the Expose event is used to notify the application about when it can start rendering. The Map and Unmap events weren't really used except by QWidget to set the WA_Mapped flag, which we now set based on the expose / unexpose. Also guarantee that a Resize event is always sent before the first Expose, by re-introducing an asynchronous expose event handler. Since an expose is required before rendering to a QWindow, show a warning if QOpenGLContext::swapBuffers() or QBackingStore::flush() if called on a window that has not received its first expose. Change-Id: Ia6b609aa275d5b463b5011a96f2fd9bbe52e9bc4 Reviewed-by: Friedemann Kleint --- tests/auto/gui/kernel/kernel.pro | 1 + .../gui/kernel/qbackingstore/qbackingstore.pro | 9 ++ .../gui/kernel/qbackingstore/tst_qbackingstore.cpp | 103 +++++++++++++++++++++ tests/auto/gui/kernel/qwindow/qwindow.pro | 1 + tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 58 ++++++++++-- .../qgraphicsitem/tst_qgraphicsitem.cpp | 15 +-- .../qgraphicsscene/tst_qgraphicsscene.cpp | 32 ++----- 7 files changed, 182 insertions(+), 37 deletions(-) create mode 100644 tests/auto/gui/kernel/qbackingstore/qbackingstore.pro create mode 100644 tests/auto/gui/kernel/qbackingstore/tst_qbackingstore.cpp (limited to 'tests') diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index 48d94b9bf8..0bd988b68c 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -1,5 +1,6 @@ TEMPLATE=subdirs SUBDIRS=\ + qbackingstore \ qclipboard \ qdrag \ qevent \ diff --git a/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro b/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro new file mode 100644 index 0000000000..cc0a2c69f7 --- /dev/null +++ b/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro @@ -0,0 +1,9 @@ +CONFIG += testcase +TARGET = tst_qbackingstore + +QT += core-private gui-private testlib + +SOURCES += tst_qbackingstore.cpp + +mac: CONFIG += insignificant_test # QTBUG-23059 +win32: CONFIG += insignificant_test # QTBUG-24885 diff --git a/tests/auto/gui/kernel/qbackingstore/tst_qbackingstore.cpp b/tests/auto/gui/kernel/qbackingstore/tst_qbackingstore.cpp new file mode 100644 index 0000000000..678e616b19 --- /dev/null +++ b/tests/auto/gui/kernel/qbackingstore/tst_qbackingstore.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include + +#include + +// For QSignalSpy slot connections. +Q_DECLARE_METATYPE(Qt::ScreenOrientation) + +class tst_QBackingStore : public QObject +{ + Q_OBJECT + +private slots: + void flush(); +}; + +class Window : public QWindow +{ +public: + Window() + : backingStore(this) + { + } + + void resizeEvent(QResizeEvent *) + { + backingStore.resize(size()); + } + + void exposeEvent(QExposeEvent *event) + { + QRect rect(QPoint(), size()); + + backingStore.beginPaint(rect); + + QPainter p(backingStore.paintDevice()); + p.fillRect(rect, Qt::white); + p.end(); + + backingStore.endPaint(); + + backingStore.flush(event->region().boundingRect()); + } + +private: + QBackingStore backingStore; +}; + +void tst_QBackingStore::flush() +{ + Window window; + window.setGeometry(20, 20, 200, 200); + window.showMaximized(); + + QTRY_VERIFY(window.isExposed()); +} + +#include +QTEST_MAIN(tst_QBackingStore); diff --git a/tests/auto/gui/kernel/qwindow/qwindow.pro b/tests/auto/gui/kernel/qwindow/qwindow.pro index 363f7dd92e..fb8132afab 100644 --- a/tests/auto/gui/kernel/qwindow/qwindow.pro +++ b/tests/auto/gui/kernel/qwindow/qwindow.pro @@ -6,4 +6,5 @@ QT += core-private gui-private testlib SOURCES += tst_qwindow.cpp mac: CONFIG += insignificant_test # QTBUG-23059 +win32: CONFIG += insignificant_test # QTBUG-24904 diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index f4556f7e32..ebd8823149 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -53,8 +53,10 @@ class tst_QWindow: public QObject Q_OBJECT private slots: + void eventOrderOnShow(); void mapGlobal(); void positioning(); + void isExposed(); void isActive(); void testInputEvents(); void touchToMouseTranslation(); @@ -114,6 +116,7 @@ public: bool event(QEvent *event) { m_received[event->type()]++; + m_order << event->type(); return QWindow::event(event); } @@ -123,10 +126,32 @@ public: return m_received.value(type, 0); } + int eventIndex(QEvent::Type type) + { + return m_order.indexOf(type); + } + private: QHash m_received; + QVector m_order; }; +void tst_QWindow::eventOrderOnShow() +{ + QRect geometry(80, 80, 40, 40); + + Window window; + window.setGeometry(geometry); + window.show(); + + QTRY_COMPARE(window.received(QEvent::Show), 1); + QTRY_COMPARE(window.received(QEvent::Resize), 1); + QTRY_VERIFY(window.isExposed()); + + QVERIFY(window.eventIndex(QEvent::Show) < window.eventIndex(QEvent::Resize)); + QVERIFY(window.eventIndex(QEvent::Resize) < window.eventIndex(QEvent::Expose)); +} + void tst_QWindow::positioning() { QRect geometry(80, 80, 40, 40); @@ -137,7 +162,7 @@ void tst_QWindow::positioning() window.show(); QTRY_COMPARE(window.received(QEvent::Resize), 1); - QTRY_COMPARE(window.received(QEvent::Map), 1); + QTRY_VERIFY(window.received(QEvent::Expose) > 0); QMargins originalMargins = window.frameMargins(); @@ -148,6 +173,9 @@ void tst_QWindow::positioning() QPoint originalFramePos = window.framePos(); window.setWindowState(Qt::WindowFullScreen); +#ifdef Q_OS_WIN + QEXPECT_FAIL("", "QTBUG-24904 - Too many resize events on setting window state", Continue); +#endif QTRY_COMPARE(window.received(QEvent::Resize), 2); window.setWindowState(Qt::WindowNoState); @@ -179,13 +207,32 @@ void tst_QWindow::positioning() } } +void tst_QWindow::isExposed() +{ + QRect geometry(80, 80, 40, 40); + + Window window; + window.setGeometry(geometry); + QCOMPARE(window.geometry(), geometry); + window.show(); + + QTRY_VERIFY(window.received(QEvent::Expose) > 0); + QTRY_VERIFY(window.isExposed()); + + window.hide(); + + QTRY_VERIFY(window.received(QEvent::Expose) > 1); + QTRY_VERIFY(!window.isExposed()); +} + + void tst_QWindow::isActive() { Window window; window.setGeometry(80, 80, 40, 40); window.show(); - QTRY_COMPARE(window.received(QEvent::Map), 1); + QTRY_VERIFY(window.isExposed()); QTRY_COMPARE(window.received(QEvent::Resize), 1); QTRY_VERIFY(QGuiApplication::focusWindow() == &window); QVERIFY(window.isActive()); @@ -195,15 +242,14 @@ void tst_QWindow::isActive() child.setGeometry(10, 10, 20, 20); child.show(); - QTRY_COMPARE(child.received(QEvent::Map), 1); + QTRY_VERIFY(child.isExposed()); child.requestActivateWindow(); QTRY_VERIFY(QGuiApplication::focusWindow() == &child); QVERIFY(child.isActive()); - // parent shouldn't receive new map or resize events from child being shown - QTRY_COMPARE(window.received(QEvent::Map), 1); + // parent shouldn't receive new resize events from child being shown QTRY_COMPARE(window.received(QEvent::Resize), 1); QTRY_COMPARE(window.received(QEvent::FocusIn), 1); QTRY_COMPARE(window.received(QEvent::FocusOut), 1); @@ -219,7 +265,7 @@ void tst_QWindow::isActive() dialog.requestActivateWindow(); - QTRY_COMPARE(dialog.received(QEvent::Map), 1); + QTRY_VERIFY(dialog.isExposed()); QTRY_COMPARE(dialog.received(QEvent::Resize), 1); QTRY_VERIFY(QGuiApplication::focusWindow() == &dialog); QVERIFY(dialog.isActive()); diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 98c3866dd2..639a1f61a9 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -11116,20 +11116,23 @@ void tst_QGraphicsItem::doNotMarkFullUpdateIfNotInScene() view.showFullScreen(); else view.show(); - QTest::qWaitForWindowShown(&view); - QEXPECT_FAIL("", "QTBUG-22434", Abort); - QTRY_COMPARE(view.repaints, 1); - QTRY_COMPARE(item->painted, 1); + QTest::qWaitForWindowShown(view.windowHandle()); + view.activateWindow(); + QTRY_VERIFY(view.isActiveWindow()); + QTRY_VERIFY(view.repaints >= 1); + int count = view.repaints; + QTRY_COMPARE(item->painted, count); + // cached as graphics effects, not painted multiple times QTRY_COMPARE(item2->painted, 1); QTRY_COMPARE(item3->painted, 1); item2->update(); QApplication::processEvents(); - QTRY_COMPARE(item->painted, 2); + QTRY_COMPARE(item->painted, count + 1); QTRY_COMPARE(item2->painted, 2); QTRY_COMPARE(item3->painted, 2); item2->update(); QApplication::processEvents(); - QTRY_COMPARE(item->painted, 3); + QTRY_COMPARE(item->painted, count + 2); QTRY_COMPARE(item2->painted, 3); QTRY_COMPARE(item3->painted, 3); } diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index daa06d0762..d7b1ef9199 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -1078,19 +1078,14 @@ void tst_QGraphicsScene::addItem() CustomView view; view.setScene(&scene); view.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif + QTest::qWaitForWindowShown(view.windowHandle()); qApp->processEvents(); view.repaints = 0; scene.addItem(path); // Adding an item should always issue a repaint. - qApp->processEvents(); // <- delayed update is called - qApp->processEvents(); // <- scene schedules pending update - qApp->processEvents(); // <- pending update is sent to view - QVERIFY(view.repaints > 0); + QTRY_VERIFY(view.repaints > 0); view.repaints = 0; QCOMPARE(scene.itemAt(0, 0), path); @@ -1103,10 +1098,7 @@ void tst_QGraphicsScene::addItem() scene.addItem(path2); // Adding an item should always issue a repaint. - qApp->processEvents(); // <- delayed update is called - qApp->processEvents(); // <- scene schedules pending update - qApp->processEvents(); // <- pending update is sent to view - QVERIFY(view.repaints > 0); + QTRY_VERIFY(view.repaints > 0); QCOMPARE(scene.itemAt(100, 100), path2); } @@ -1285,9 +1277,7 @@ void tst_QGraphicsScene::removeItem() QGraphicsView view(&scene); view.setFixedSize(150, 150); view.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif + QTest::qWaitForWindowShown(view.windowHandle()); QTest::mouseMove(view.viewport(), QPoint(-1, -1)); { QMouseEvent moveEvent(QEvent::MouseMove, view.mapFromScene(hoverItem->scenePos() + QPointF(20, 20)), Qt::NoButton, 0, 0); @@ -1615,9 +1605,7 @@ void tst_QGraphicsScene::hoverEvents_siblings() view.rotate(10); view.scale(1.7, 1.7); view.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif + QTest::qWaitForWindowShown(view.windowHandle()); qApp->setActiveWindow(&view); view.activateWindow(); QTest::qWait(70); @@ -2748,11 +2736,8 @@ void tst_QGraphicsScene::contextMenuEvent() QGraphicsView view(&scene); view.show(); - QTest::qWaitForWindowShown(&view); + QTest::qWaitForWindowShown(view.windowHandle()); view.activateWindow(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif view.centerOn(item); { @@ -2785,10 +2770,7 @@ void tst_QGraphicsScene::contextMenuEvent_ItemIgnoresTransformations() QGraphicsView view(&scene, &topLevel); view.resize(200, 200); topLevel.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif - QTest::qWaitForWindowShown(&topLevel); + QTest::qWaitForWindowShown(topLevel.windowHandle()); { QPoint pos(50, 50); -- cgit v1.2.3 From 5ea56e93f74c0df88aa956199e6bb0db2f17bfba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Wed, 14 Mar 2012 15:15:17 +0100 Subject: Reserve more space for built-in types in id space. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are running out of type ids for built-in types, 255 is not enough. QMetaType already contains about ~70 types, situation is maybe not tragic now, but there is a great chance that we will want to add more built-in types from different modules like jsondb or declarative. Then it might be tight, because we are not allowed to reorganize type ids (it would be a binary incompatible change). This change was not possible up to now. Old moc generated code assumes that type id can be safely stored in 8 bits. This is source compatible change. Change-Id: Iec600adf6b6196a9f3f06ca6d865911084390cc2 Reviewed-by: Olivier Goffart Reviewed-by: João Abecasis Reviewed-by: Kent Hansen --- tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index b6cb6b3632..1e382dde3a 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -2827,7 +2827,7 @@ Q_DECLARE_METATYPE( MyClass ) void tst_QVariant::loadUnknownUserType() { qRegisterMetaType("MyClass"); - char data[] = {0, 0, 1, 0, 0, 0, 0, 0, 8, 77, 121, 67, 108, 97, 115, 115, 0}; + char data[] = {0, 0, QMetaType::User >> 8 , char(QMetaType::User), 0, 0, 0, 0, 8, 'M', 'y', 'C', 'l', 'a', 's', 's', 0}; QByteArray ba(data, sizeof(data)); QDataStream ds(&ba, QIODevice::ReadOnly); -- cgit v1.2.3 From 5cb0368516abd293daf67711a36bbacc99422e9a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 19 Mar 2012 20:53:20 +0100 Subject: Rewrite QMap to use a RB tree QMap used to use a skiplist in Qt 4.x, which has variable sized nodes and we can thus not optimise using custom allocators. The rewrite now uses a red-black tree, and all allocations and tree operations happen in the cpp file. This will allow us to introduce custom allocation schemes in later versions of Qt. Added some more tests and a benchmark. Memory consumption of the new QMap implementation is pretty much the same as before. Performance of insertion and lookup has increased by 10-30%. iteration is slower, but still extremely fast and should not matter compared to the work usually done when iterating. Change-Id: I8796c0e4b207d01111e2ead7ae55afb464dd88f5 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qmap/tst_qmap.cpp | 166 ++++++++++++++++++++++++++- tests/benchmarks/corelib/tools/qmap/main.cpp | 165 ++++++++++++++++++++++++++ tests/benchmarks/corelib/tools/qmap/qmap.pro | 5 + tests/benchmarks/corelib/tools/tools.pro | 1 + 4 files changed, 333 insertions(+), 4 deletions(-) create mode 100644 tests/benchmarks/corelib/tools/qmap/main.cpp create mode 100644 tests/benchmarks/corelib/tools/qmap/qmap.pro (limited to 'tests') diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index 7d0ef7d7e4..ac75c0e5bd 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -41,10 +41,10 @@ #define QT_STRICT_ITERATORS +#include #include #include -#include class tst_QMap : public QObject { @@ -74,6 +74,11 @@ private slots: void qmultimap_specific(); void const_shared_null(); + + void equal_range(); + void setSharable(); + + void insert(); }; typedef QMap StringMap; @@ -105,6 +110,11 @@ int MyClass::count = 0; typedef QMap MyMap; +QDebug operator << (QDebug d, const MyClass &c) { + d << c.str; + return d; +} + void tst_QMap::init() { MyClass::count = 0; @@ -152,6 +162,7 @@ void tst_QMap::count() map.insert( "Paul", MyClass("Tvete 6") ); QCOMPARE( map.count(), 9 ); + QCOMPARE( map.count("Paul"), 1 ); #ifndef Q_CC_SUN QCOMPARE( MyClass::count, 9 ); #endif @@ -519,6 +530,7 @@ void tst_QMap::find() for(i = 3; i < 10; ++i) { compareString = testString.arg(i); map1.insertMulti(4, compareString); + QCOMPARE(map1.count(4), i - 2); } QMap::const_iterator it=map1.constFind(4); @@ -588,6 +600,33 @@ void tst_QMap::lowerUpperBound() QCOMPARE(map1.lowerBound(2).key(), 5); // returns iterator to (5, "five") QCOMPARE(map1.lowerBound(10).key(), 10); // returns iterator to (10, "ten") QVERIFY(map1.lowerBound(999) == map1.end()); // returns end() + + map1.insert(3, "three"); + map1.insert(7, "seven"); + map1.insertMulti(7, "seven_2"); + + QCOMPARE(map1.upperBound(0).key(), 1); + QCOMPARE(map1.upperBound(1).key(), 3); + QCOMPARE(map1.upperBound(2).key(), 3); + QCOMPARE(map1.upperBound(3).key(), 5); + QCOMPARE(map1.upperBound(7).key(), 10); + QVERIFY(map1.upperBound(10) == map1.end()); + QVERIFY(map1.upperBound(999) == map1.end()); + + QCOMPARE(map1.lowerBound(0).key(), 1); + QCOMPARE(map1.lowerBound(1).key(), 1); + QCOMPARE(map1.lowerBound(2).key(), 3); + QCOMPARE(map1.lowerBound(3).key(), 3); + QCOMPARE(map1.lowerBound(4).key(), 5); + QCOMPARE(map1.lowerBound(5).key(), 5); + QCOMPARE(map1.lowerBound(6).key(), 7); + QCOMPARE(map1.lowerBound(7).key(), 7); + QCOMPARE(map1.lowerBound(6).value(), QString("seven_2")); + QCOMPARE(map1.lowerBound(7).value(), QString("seven_2")); + QCOMPARE((++map1.lowerBound(6)).value(), QString("seven")); + QCOMPARE((++map1.lowerBound(7)).value(), QString("seven")); + QCOMPARE(map1.lowerBound(10).key(), 10); + QVERIFY(map1.lowerBound(999) == map1.end()); } void tst_QMap::mergeCompare() @@ -846,10 +885,129 @@ void tst_QMap::const_shared_null() QMap map2; map2.setSharable(true); QVERIFY(!map2.isDetached()); +} + +void tst_QMap::equal_range() +{ + QMap map; + + QPair::iterator, QMap::iterator> result = map.equal_range(0); + QCOMPARE(result.first, map.end()); + QCOMPARE(result.second, map.end()); + + map.insert(1, "one"); + + result = map.equal_range(0); + QCOMPARE(result.first, map.find(1)); + QCOMPARE(result.second, map.find(1)); - QMap map3; - map3.setInsertInOrder(true); - map3.setInsertInOrder(false); + result = map.equal_range(1); + QCOMPARE(result.first, map.find(1)); + QCOMPARE(result.second, map.end()); + + result = map.equal_range(2); + QCOMPARE(result.first, map.end()); + QCOMPARE(result.second, map.end()); + + for (int i = -10; i < 10; i += 2) + map.insert(i, QString("%1").arg(i)); + + result = map.equal_range(0); + QCOMPARE(result.first, map.find(0)); + QCOMPARE(result.second, map.find(1)); + + result = map.equal_range(1); + QCOMPARE(result.first, map.find(1)); + QCOMPARE(result.second, map.find(2)); + + result = map.equal_range(2); + QCOMPARE(result.first, map.find(2)); + QCOMPARE(result.second, map.find(4)); + + map.insertMulti(1, "another one"); + result = map.equal_range(1); + QCOMPARE(result.first, map.find(1)); + QCOMPARE(result.second, map.find(2)); + + QCOMPARE(map.count(1), 2); +} + +template +const T &const_(const T &t) +{ + return t; +} + +void tst_QMap::setSharable() +{ + QMap map; + + map.insert(1, "um"); + map.insert(2, "dois"); + map.insert(4, "quatro"); + map.insert(5, "cinco"); + + map.setSharable(true); + QCOMPARE(map.size(), 4); + QCOMPARE(const_(map)[4], QString("quatro")); + + { + QMap copy(map); + + QVERIFY(!map.isDetached()); + QVERIFY(copy.isSharedWith(map)); + } + + map.setSharable(false); + QVERIFY(map.isDetached()); + QCOMPARE(map.size(), 4); + QCOMPARE(const_(map)[4], QString("quatro")); + + { + QMap copy(map); + + QVERIFY(map.isDetached()); + QVERIFY(copy.isDetached()); + + QCOMPARE(copy.size(), 4); + QCOMPARE(const_(copy)[4], QString("quatro")); + + QCOMPARE(map, copy); + } + + map.setSharable(true); + QCOMPARE(map.size(), 4); + QCOMPARE(const_(map)[4], QString("quatro")); + + { + QMap copy(map); + + QVERIFY(!map.isDetached()); + QVERIFY(copy.isSharedWith(map)); + } +} + +void tst_QMap::insert() +{ + QMap map; + map.insert("cs/key1", 1); + map.insert("cs/key2", 2); + map.insert("cs/key1", 3); + QCOMPARE(map.count(), 2); + + QMap intMap; + for (int i = 0; i < 1000; ++i) { + intMap.insert(i, i); + } + + QCOMPARE(intMap.size(), 1000); + + for (int i = 0; i < 1000; ++i) { + QCOMPARE(intMap.value(i), i); + intMap.insert(i, -1); + QCOMPARE(intMap.size(), 1000); + QCOMPARE(intMap.value(i), -1); + } } QTEST_APPLESS_MAIN(tst_QMap) diff --git a/tests/benchmarks/corelib/tools/qmap/main.cpp b/tests/benchmarks/corelib/tools/qmap/main.cpp new file mode 100644 index 0000000000..e68ea685a3 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qmap/main.cpp @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + + +class tst_QMap : public QObject +{ + Q_OBJECT + +private slots: + void insertion_int_int(); + void insertion_int_string(); + void insertion_string_int(); + + void lookup_int_int(); + void lookup_int_string(); + void lookup_string_int(); + + void iteration(); +}; + + +void tst_QMap::insertion_int_int() +{ + QMap map; + QBENCHMARK { + for (int i = 0; i < 100000; ++i) + map.insert(i, i); + } +} + +void tst_QMap::insertion_int_string() +{ + QMap map; + QString str("Hello World"); + QBENCHMARK { + for (int i = 0; i < 100000; ++i) + map.insert(i, str); + } +} + +void tst_QMap::insertion_string_int() +{ + QMap map; + QString str("Hello World"); + QBENCHMARK { + for (int i = 1; i < 100000; ++i) { + str[0] = QChar(i); + map.insert(str, i); + } + } +} + + +void tst_QMap::lookup_int_int() +{ + QMap map; + for (int i = 0; i < 100000; ++i) + map.insert(i, i); + + int sum = 0; + QBENCHMARK { + for (int i = 0; i < 100000; ++i) + sum += map.value(i); + } +} + +void tst_QMap::lookup_int_string() +{ + QMap map; + QString str("Hello World"); + for (int i = 0; i < 100000; ++i) + map.insert(i, str); + + QBENCHMARK { + for (int i = 0; i < 100000; ++i) + str += map.value(i); + } +} + +void tst_QMap::lookup_string_int() +{ + QMap map; + QString str("Hello World"); + for (int i = 1; i < 100000; ++i) { + str[0] = QChar(i); + map.insert(str, i); + } + + int sum = 0; + QBENCHMARK { + for (int i = 1; i < 100000; ++i) { + str[0] = QChar(i); + sum += map.value(str); + } + } +} + +// iteration speed doesn't depend on the type of the map. +void tst_QMap::iteration() +{ + QMap map; + for (int i = 0; i < 100000; ++i) + map.insert(i, i); + + int j = 0; + QBENCHMARK { + for (int i = 0; i < 100; ++i) { + QMap::const_iterator it = map.constBegin(); + QMap::const_iterator end = map.constEnd(); + while (it != end) { + j += *it; + ++it; + } + } + } +} + + +QTEST_MAIN(tst_QMap) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qmap/qmap.pro b/tests/benchmarks/corelib/tools/qmap/qmap.pro new file mode 100644 index 0000000000..6a0c8d62bd --- /dev/null +++ b/tests/benchmarks/corelib/tools/qmap/qmap.pro @@ -0,0 +1,5 @@ +TARGET = tst_qmap +QT = core testlib +INCLUDEPATH += . +SOURCES += main.cpp +CONFIG += release diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro index ea9059e759..7565b1a167 100644 --- a/tests/benchmarks/corelib/tools/tools.pro +++ b/tests/benchmarks/corelib/tools/tools.pro @@ -5,6 +5,7 @@ SUBDIRS = \ qbytearray \ qcontiguouscache \ qlist \ + qmap \ qrect \ qregexp \ qstring \ -- cgit v1.2.3 From 167af3b6cad5f40cafffafdc779f26ef63e62c81 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 6 Mar 2012 08:52:11 +0100 Subject: tst_qnetworkreply: don't inherit from QSharedPointer QSharedPointer isn't meant to be used as a base class. Instead of inheriting from it to add implicit conversions to and from QNetworkReply*, make QNetworkReplyPtr a typedef, overload two oft-used functions to take a QNetworkReplyPtr in addition to QNetworkReply*, and otherwise make the conversions explicit. Change-Id: I1eff1793a19f2d5bad1cce8de74c0786675a50f3 Reviewed-by: Shane Kearns --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 291 ++++++++++----------- .../access/qnetworkreply/tst_qnetworkreply.cpp | 34 +-- 2 files changed, 162 insertions(+), 163 deletions(-) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 438cf866aa..a5aaf6af25 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -102,15 +102,7 @@ Q_DECLARE_METATYPE(QList) // for multiparts Q_DECLARE_METATYPE(QSslConfiguration) #endif -class QNetworkReplyPtr: public QSharedPointer -{ -public: - inline QNetworkReplyPtr(QNetworkReply *ptr = 0) - : QSharedPointer(ptr) - { } - - inline operator QNetworkReply *() const { return data(); } -}; +typedef QSharedPointer QNetworkReplyPtr; class MyCookieJar; class tst_QNetworkReply: public QObject @@ -158,6 +150,12 @@ class tst_QNetworkReply: public QObject QScopedPointer networkSession; #endif + using QObject::connect; + static bool connect(const QNetworkReplyPtr &ptr, const char *signal, const QObject *receiver, const char *slot, Qt::ConnectionType ct = Qt::AutoConnection) + { return connect(ptr.data(), signal, receiver, slot, ct); } + bool connect(const QNetworkReplyPtr &ptr, const char *signal, const char *slot, Qt::ConnectionType ct = Qt::AutoConnection) + { return connect(ptr.data(), signal, slot, ct); } + public: tst_QNetworkReply(); ~tst_QNetworkReply(); @@ -742,6 +740,8 @@ public: QByteArray data; QIODevice *device; bool accumulate; + DataReader(const QNetworkReplyPtr &dev, bool acc = true) : totalBytes(0), device(dev.data()), accumulate(acc) + { connect(device, SIGNAL(readyRead()), SLOT(doRead()) ); } DataReader(QIODevice *dev, bool acc = true) : totalBytes(0), device(dev), accumulate(acc) { connect(device, SIGNAL(readyRead()), SLOT(doRead())); @@ -1178,15 +1178,15 @@ QString tst_QNetworkReply::runMultipartRequest(const QNetworkRequest &request, const QByteArray &verb) { if (verb == "POST") - reply = manager.post(request, multiPart); + reply.reset(manager.post(request, multiPart)); else - reply = manager.put(request, multiPart); + reply.reset(manager.put(request, multiPart)); // the code below is copied from tst_QNetworkReply::runSimpleRequest, see below reply->setParent(this); connect(reply, SIGNAL(finished()), SLOT(finished())); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(gotError())); - multiPart->setParent(reply); + multiPart->setParent(reply.data()); returnCode = Timeout; loop = new QEventLoop; @@ -1211,23 +1211,23 @@ QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op, { switch (op) { case QNetworkAccessManager::HeadOperation: - reply = manager.head(request); + reply.reset(manager.head(request)); break; case QNetworkAccessManager::GetOperation: - reply = manager.get(request); + reply.reset(manager.get(request)); break; case QNetworkAccessManager::PutOperation: - reply = manager.put(request, data); + reply.reset(manager.put(request, data)); break; case QNetworkAccessManager::PostOperation: - reply = manager.post(request, data); + reply.reset(manager.post(request, data)); break; case QNetworkAccessManager::DeleteOperation: - reply = manager.deleteResource(request); + reply.reset(manager.deleteResource(request)); break; default: @@ -1249,7 +1249,7 @@ QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op, int count = 0; loop = new QEventLoop; - QSignalSpy spy(reply, SIGNAL(downloadProgress(qint64,qint64))); + QSignalSpy spy(reply.data(), SIGNAL(downloadProgress(qint64,qint64))); while (!reply->isFinished()) { QTimer::singleShot(20000, loop, SLOT(quit())); code = loop->exec(); @@ -1277,7 +1277,7 @@ QString tst_QNetworkReply::runCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data) { - reply = manager.sendCustomRequest(request, verb, data); + reply.reset(manager.sendCustomRequest(request, verb, data)); reply->setParent(this); connect(reply, SIGNAL(finished()), SLOT(finished())); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(gotError())); @@ -1306,7 +1306,7 @@ int tst_QNetworkReply::waitForFinish(QNetworkReplyPtr &reply) connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(gotError())); returnCode = Success; loop = new QEventLoop; - QSignalSpy spy(reply, SIGNAL(downloadProgress(qint64,qint64))); + QSignalSpy spy(reply.data(), SIGNAL(downloadProgress(qint64,qint64))); while (!reply->isFinished()) { QTimer::singleShot(5000, loop, SLOT(quit())); if ( loop->exec() == Timeout && count == spy.count() && !reply->isFinished()) { @@ -1401,7 +1401,7 @@ void tst_QNetworkReply::stateChecking() { QUrl url = QUrl("file:///"); QNetworkRequest req(url); // you can't open this file, I know - QNetworkReplyPtr reply = manager.get(req); + QNetworkReplyPtr reply(manager.get(req)); QVERIFY(reply.data()); QVERIFY(reply->isOpen()); @@ -1568,7 +1568,7 @@ void tst_QNetworkReply::getFromFile() file.flush(); // run again - reply = 0; + reply.clear(); RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::GetOperation, request, reply)); QCOMPARE(reply->url(), request.url()); @@ -1806,7 +1806,7 @@ void tst_QNetworkReply::getErrors() } #endif - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); reply->setParent(this); // we have expect-fails if (!reply->isFinished()) @@ -2500,7 +2500,7 @@ void tst_QNetworkReply::connectToIPv6Address() url.setPort(server.serverPort()); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); QByteArray content = reply->readAll(); //qDebug() << server.receivedData; @@ -2581,7 +2581,7 @@ void tst_QNetworkReply::ioGetFromData() QUrl url = QUrl::fromEncoded(urlStr.toLatin1()); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); connect(reply, SIGNAL(finished()), @@ -2613,7 +2613,7 @@ void tst_QNetworkReply::ioGetFromFileSpecial() QNetworkRequest request; request.setUrl(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -2645,7 +2645,7 @@ void tst_QNetworkReply::ioGetFromFile() QCOMPARE(file.size(), qint64(data.size())); QNetworkRequest request(QUrl::fromLocalFile(file.fileName())); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(reply->isFinished()); // a file should immediately be done DataReader reader(reply); @@ -2679,7 +2679,7 @@ void tst_QNetworkReply::ioGetFromFtp() reference.open(QIODevice::ReadOnly); // will fail for bigfile QNetworkRequest request("ftp://" + QtNetworkSettings::serverName() + "/qtest/" + fileName); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); QVERIFY(waitForFinish(reply) == Success); @@ -2704,11 +2704,11 @@ void tst_QNetworkReply::ioGetFromFtpWithReuse() QNetworkRequest request(QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); // two concurrent (actually, consecutive) gets: - QNetworkReplyPtr reply1 = manager.get(request); + QNetworkReplyPtr reply1(manager.get(request)); DataReader reader1(reply1); - QNetworkReplyPtr reply2 = manager.get(request); + QNetworkReplyPtr reply2(manager.get(request)); DataReader reader2(reply2); - QSignalSpy spy(reply1, SIGNAL(finished())); + QSignalSpy spy(reply1.data(), SIGNAL(finished())); QVERIFY(waitForFinish(reply1) == Success); QVERIFY(waitForFinish(reply2) == Success); @@ -2734,7 +2734,7 @@ void tst_QNetworkReply::ioGetFromHttp() QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); QVERIFY(waitForFinish(reply) == Success); @@ -2755,11 +2755,11 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseParallel() QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); - QNetworkReplyPtr reply1 = manager.get(request); - QNetworkReplyPtr reply2 = manager.get(request); + QNetworkReplyPtr reply1(manager.get(request)); + QNetworkReplyPtr reply2(manager.get(request)); DataReader reader1(reply1); DataReader reader2(reply2); - QSignalSpy spy(reply1, SIGNAL(finished())); + QSignalSpy spy(reply1.data(), SIGNAL(finished())); QVERIFY(waitForFinish(reply2) == Success); QVERIFY(waitForFinish(reply1) == Success); @@ -2788,7 +2788,7 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseSequential() QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); { - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); QVERIFY(waitForFinish(reply) == Success); @@ -2806,7 +2806,7 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseSequential() reference.seek(0); // rinse and repeat: { - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); QVERIFY(waitForFinish(reply) == Success); @@ -2854,11 +2854,11 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() QFETCH(int, expectedAuth); QNetworkRequest request(url); { - QNetworkReplyPtr reply1 = manager.get(request); - QNetworkReplyPtr reply2 = manager.get(request); + QNetworkReplyPtr reply1(manager.get(request)); + QNetworkReplyPtr reply2(manager.get(request)); DataReader reader1(reply1); DataReader reader2(reply2); - QSignalSpy finishedspy(reply1, SIGNAL(finished())); + QSignalSpy finishedspy(reply1.data(), SIGNAL(finished())); QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), @@ -2881,7 +2881,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() // rinse and repeat: { - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -2907,7 +2907,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() true); QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QNetworkReplyPtr replySync = manager.get(request); + QNetworkReplyPtr replySync(manager.get(request)); QVERIFY(replySync->isFinished()); // synchronous if (expectedAuth) { // bad credentials in a synchronous request should just fail @@ -2933,7 +2933,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() true); QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QNetworkReplyPtr replySync = manager.get(request); + QNetworkReplyPtr replySync(manager.get(request)); QVERIFY(replySync->isFinished()); // synchronous if (expectedAuth) { // bad credentials in a synchronous request should just fail @@ -2962,7 +2962,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuthSynchronous() true); QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); - QNetworkReplyPtr replySync = manager.get(request); + QNetworkReplyPtr replySync(manager.get(request)); QVERIFY(replySync->isFinished()); // synchronous QCOMPARE(replySync->error(), QNetworkReply::AuthenticationRequiredError); QCOMPARE(authspy.count(), 0); @@ -2981,13 +2981,13 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); { manager.setProxy(proxy); - QNetworkReplyPtr reply1 = manager.get(request); - QNetworkReplyPtr reply2 = manager.get(request); + QNetworkReplyPtr reply1(manager.get(request)); + QNetworkReplyPtr reply2(manager.get(request)); manager.setProxy(QNetworkProxy()); DataReader reader1(reply1); DataReader reader2(reply2); - QSignalSpy finishedspy(reply1, SIGNAL(finished())); + QSignalSpy finishedspy(reply1.data(), SIGNAL(finished())); QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), @@ -3012,7 +3012,7 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() // rinse and repeat: { manager.setProxy(proxy); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); manager.setProxy(QNetworkProxy()); @@ -3039,7 +3039,7 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() true); QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - QNetworkReplyPtr replySync = manager.get(request); + QNetworkReplyPtr replySync(manager.get(request)); QVERIFY(replySync->isFinished()); // synchronous QCOMPARE(authspy.count(), 0); @@ -3065,7 +3065,7 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuthSynchronous() true); QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - QNetworkReplyPtr replySync = manager.get(request); + QNetworkReplyPtr replySync(manager.get(request)); manager.setProxy(QNetworkProxy()); // reset QVERIFY(replySync->isFinished()); // synchronous QCOMPARE(replySync->error(), QNetworkReply::ProxyAuthenticationRequiredError); @@ -3085,7 +3085,7 @@ void tst_QNetworkReply::ioGetFromHttpWithSocksProxy() QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); { manager.setProxy(proxy); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); manager.setProxy(QNetworkProxy()); @@ -3108,7 +3108,7 @@ void tst_QNetworkReply::ioGetFromHttpWithSocksProxy() proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1079); { manager.setProxy(proxy); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); manager.setProxy(QNetworkProxy()); @@ -3139,7 +3139,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslErrors() QVERIFY(reference.open(QIODevice::ReadOnly)); QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); QSignalSpy sslspy(&manager, SIGNAL(sslErrors(QNetworkReply*,QList))); @@ -3171,7 +3171,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithIgnoreSslErrors() QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); reply->ignoreSslErrors(); DataReader reader(reply); @@ -3196,7 +3196,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslHandshakeError() QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + ":80")); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); reply->ignoreSslErrors(); DataReader reader(reply); @@ -3258,8 +3258,8 @@ void tst_QNetworkReply::ioGetFromHttpBrokenServer() server.doClose = doDisconnect; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); - QSignalSpy spy(reply, SIGNAL(error(QNetworkReply::NetworkError))); + QNetworkReplyPtr reply(manager.get(request)); + QSignalSpy spy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); QVERIFY(waitForFinish(reply) == Failure); @@ -3289,7 +3289,7 @@ void tst_QNetworkReply::ioGetFromHttpStatus100() server.doClose = true; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -3312,7 +3312,7 @@ void tst_QNetworkReply::ioGetFromHttpNoHeaders() server.doClose = true; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -3482,7 +3482,7 @@ void tst_QNetworkReply::ioGetFromHttpWithCache() request.setRawHeader(header.toLatin1(), value.toLatin1()); // To latin1? Deal with it! } - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) != Timeout); @@ -3706,7 +3706,7 @@ void tst_QNetworkReply::ioGetWithManyProxies() QFETCH(QString, url); QUrl theUrl(url); QNetworkRequest request(theUrl); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply); QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -3774,7 +3774,7 @@ void tst_QNetworkReply::ioPutToFileFromFile() QUrl url = QUrl::fromLocalFile(targetFile.fileName()); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.put(request, &sourceFile); + QNetworkReplyPtr reply(manager.put(request, &sourceFile)); QVERIFY(waitForFinish(reply) == Success); @@ -3809,7 +3809,7 @@ void tst_QNetworkReply::ioPutToFileFromSocket() QVERIFY(socketpair.endPoints[0] && socketpair.endPoints[1]); socketpair.endPoints[0]->write(data); - QNetworkReplyPtr reply = manager.put(QNetworkRequest(url), socketpair.endPoints[1]); + QNetworkReplyPtr reply(manager.put(QNetworkRequest(url), socketpair.endPoints[1])); socketpair.endPoints[0]->close(); QVERIFY(waitForFinish(reply) == Success); @@ -3853,8 +3853,8 @@ void tst_QNetworkReply::ioPutToFileFromLocalSocket() QFETCH(QByteArray, data); active.write(data); active.close(); - QNetworkReplyPtr reply = manager.put(QNetworkRequest(url), passive); - passive->setParent(reply); + QNetworkReplyPtr reply(manager.put(QNetworkRequest(url), passive)); + passive->setParent(reply.data()); #ifdef Q_OS_WIN if (!data.isEmpty()) @@ -3906,7 +3906,7 @@ void tst_QNetworkReply::ioPutToFileFromProcess() process.write(data); process.closeWriteChannel(); - QNetworkReplyPtr reply = manager.put(QNetworkRequest(url), &process); + QNetworkReplyPtr reply(manager.put(QNetworkRequest(url), &process)); QVERIFY(waitForFinish(reply) == Success); @@ -3940,7 +3940,7 @@ void tst_QNetworkReply::ioPutToFtpFromFile() .arg(uniqueExtension)); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.put(request, &sourceFile); + QNetworkReplyPtr reply(manager.put(request, &sourceFile)); QVERIFY(waitForFinish(reply) == Success); @@ -3989,7 +3989,7 @@ void tst_QNetworkReply::ioPutToHttpFromFile() .arg(uniqueExtension)); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.put(request, &sourceFile); + QNetworkReplyPtr reply(manager.put(request, &sourceFile)); QVERIFY(waitForFinish(reply) == Success); @@ -4004,7 +4004,7 @@ void tst_QNetworkReply::ioPutToHttpFromFile() // download the file again from HTTP to make sure it was uploaded // correctly - reply = manager.get(request); + reply.reset(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -4030,7 +4030,7 @@ void tst_QNetworkReply::ioPostToHttpFromFile() QNetworkRequest request(url); request.setRawHeader("Content-Type", "application/octet-stream"); - QNetworkReplyPtr reply = manager.post(request, &sourceFile); + QNetworkReplyPtr reply(manager.post(request, &sourceFile)); QVERIFY(waitForFinish(reply) == Success); @@ -4103,7 +4103,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocket() request.setRawHeader("Content-Type", "application/octet-stream"); manager.setProxy(proxy); - QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]); + QNetworkReplyPtr reply(manager.post(request, socketpair.endPoints[1])); socketpair.endPoints[0]->close(); connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), @@ -4180,7 +4180,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocketSynchronous() QNetworkRequest::SynchronousRequestAttribute, true); - QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]); + QNetworkReplyPtr reply(manager.post(request, socketpair.endPoints[1])); QVERIFY(reply->isFinished()); socketpair.endPoints[0]->close(); @@ -4206,7 +4206,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileToEnd() QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); request.setRawHeader("Content-Type", "application/octet-stream"); - QNetworkReplyPtr reply = manager.post(request, &sourceFile); + QNetworkReplyPtr reply(manager.post(request, &sourceFile)); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -4235,7 +4235,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileFiveBytes() // only send 5 bytes request.setHeader(QNetworkRequest::ContentLengthHeader, 5); QVERIFY(request.header(QNetworkRequest::ContentLengthHeader).isValid()); - QNetworkReplyPtr reply = manager.post(request, &sourceFile); + QNetworkReplyPtr reply(manager.post(request, &sourceFile)); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -4263,7 +4263,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfQBufferFiveBytes() QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); request.setRawHeader("Content-Type", "application/octet-stream"); - QNetworkReplyPtr reply = manager.post(request, &uploadBuffer); + QNetworkReplyPtr reply(manager.post(request, &uploadBuffer)); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -4295,7 +4295,7 @@ void tst_QNetworkReply::ioPostToHttpNoBufferFlag() // disallow buffering request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, true); request.setHeader(QNetworkRequest::ContentLengthHeader, data.size()); - QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]); + QNetworkReplyPtr reply(manager.post(request, socketpair.endPoints[1])); socketpair.endPoints[0]->close(); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), @@ -4373,11 +4373,11 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() QNetworkRequest request(url); request.setRawHeader("Content-Type", "application/octet-stream"); - QNetworkReplyPtr reply = manager.post(request, sourceFile); + QNetworkReplyPtr reply(manager.post(request, sourceFile)); - QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); + QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newEncryptedConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); - connect(reply, SIGNAL(sslErrors(const QList&)), reply, SLOT(ignoreSslErrors())); + connect(reply, SIGNAL(sslErrors(const QList&)), reply.data(), SLOT(ignoreSslErrors())); // get the request started and the incoming socket connected QTestEventLoop::instance().enterLoop(10); @@ -4461,11 +4461,11 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp() .arg(https?"https":"http") .arg(server.serverPort())); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); reply->setReadBufferSize(bufferSize); reply->ignoreSslErrors(); const int rate = 200; // in kB per sec - RateControlledReader reader(server, reply, rate, bufferSize); + RateControlledReader reader(server, reply.data(), rate, bufferSize); QTime loopTime; loopTime.start(); @@ -4520,8 +4520,8 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); QNetworkRequest request(url); request.setRawHeader("Content-Type", "application/octet-stream"); - QNetworkReplyPtr reply = manager.post(request, &sourceFile); - QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); + QNetworkReplyPtr reply(manager.post(request, &sourceFile)); + QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); // get the request started and the incoming socket connected @@ -4580,8 +4580,8 @@ void tst_QNetworkReply::ioPostToHttpEmptyUploadProgress() QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); QNetworkRequest request(url); request.setRawHeader("Content-Type", "application/octet-stream"); - QNetworkReplyPtr reply = manager.post(request, &buffer); - QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); + QNetworkReplyPtr reply(manager.post(request, &buffer)); + QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -4620,7 +4620,7 @@ void tst_QNetworkReply::lastModifiedHeaderForFile() QUrl url = QUrl::fromLocalFile(fileInfo.filePath()); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.head(request); + QNetworkReplyPtr reply(manager.head(request)); QVERIFY(waitForFinish(reply) == Success); @@ -4634,7 +4634,7 @@ void tst_QNetworkReply::lastModifiedHeaderForHttp() QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/fluke.gif"; QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.head(request); + QNetworkReplyPtr reply(manager.head(request)); QVERIFY(waitForFinish(reply) == Success); @@ -4648,7 +4648,7 @@ void tst_QNetworkReply::lastModifiedHeaderForHttp() void tst_QNetworkReply::httpCanReadLine() { QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -4687,11 +4687,11 @@ void tst_QNetworkReply::rateControl() FastSender sender(20 * rate * 1024); QNetworkRequest request("debugpipe://localhost:" + QString::number(sender.serverPort())); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); reply->setReadBufferSize(32768); - QSignalSpy errorSpy(reply, SIGNAL(error(QNetworkReply::NetworkError))); + QSignalSpy errorSpy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); - RateControlledReader reader(sender, reply, rate, 20); + RateControlledReader reader(sender, reply.data(), rate, 20); // this test is designed to run for 25 seconds at most QTime loopTime; @@ -4739,8 +4739,8 @@ void tst_QNetworkReply::downloadProgress() QVERIFY(server.listen()); QNetworkRequest request("debugpipe://127.0.0.1:" + QString::number(server.serverPort()) + "/?bare=1"); - QNetworkReplyPtr reply = manager.get(request); - QSignalSpy spy(reply, SIGNAL(downloadProgress(qint64,qint64))); + QNetworkReplyPtr reply(manager.get(request)); + QSignalSpy spy(reply.data(), SIGNAL(downloadProgress(qint64,qint64))); connect(reply, SIGNAL(downloadProgress(qint64,qint64)), &QTestEventLoop::instance(), SLOT(exitLoop())); QVERIFY(spy.isValid()); @@ -4805,9 +4805,9 @@ void tst_QNetworkReply::uploadProgress() QVERIFY(server.listen()); QNetworkRequest request("debugpipe://127.0.0.1:" + QString::number(server.serverPort()) + "/?bare=1"); - QNetworkReplyPtr reply = manager.put(request, data); - QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); - QSignalSpy finished(reply, SIGNAL(finished())); + QNetworkReplyPtr reply(manager.put(request, data)); + QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); + QSignalSpy finished(reply.data(), SIGNAL(finished())); QVERIFY(spy.isValid()); QVERIFY(finished.isValid()); @@ -4848,12 +4848,12 @@ void tst_QNetworkReply::chaining() QCOMPARE(sourceFile.size(), qint64(data.size())); QNetworkRequest request(QUrl::fromLocalFile(sourceFile.fileName())); - QNetworkReplyPtr getReply = manager.get(request); + QNetworkReplyPtr getReply(manager.get(request)); QFile targetFile(testFileName); QUrl url = QUrl::fromLocalFile(targetFile.fileName()); request.setUrl(url); - QNetworkReplyPtr putReply = manager.put(request, getReply); + QNetworkReplyPtr putReply(manager.put(request, getReply.data())); QVERIFY(waitForFinish(putReply) == Success); @@ -5084,10 +5084,10 @@ void tst_QNetworkReply::nestedEventLoops() QUrl url("http://" + QtNetworkSettings::serverName()); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); - QSignalSpy finishedspy(reply, SIGNAL(finished())); - QSignalSpy errorspy(reply, SIGNAL(error(QNetworkReply::NetworkError))); + QSignalSpy finishedspy(reply.data(), SIGNAL(finished())); + QSignalSpy errorspy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); connect(reply, SIGNAL(finished()), SLOT(nestedEventLoops_slot())); QTestEventLoop::instance().enterLoop(20); @@ -5127,7 +5127,7 @@ void tst_QNetworkReply::httpProxyCommands() manager.setProxy(proxy); QNetworkRequest request(url); request.setRawHeader("User-Agent", "QNetworkReplyAutoTest/1.0"); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); //clearing the proxy here causes the test to fail. //the proxy isn't used until after the bearer has been started //which is correct in general, because system proxy isn't known until that time. @@ -5214,7 +5214,7 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous() QNetworkRequest::SynchronousRequestAttribute, true); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(reply->isFinished()); // synchronous manager.setProxy(QNetworkProxy()); @@ -5239,11 +5239,11 @@ void tst_QNetworkReply::proxyChange() proxyServer.doClose = false; manager.setProxy(dummyProxy); - QNetworkReplyPtr reply1 = manager.get(req); + QNetworkReplyPtr reply1(manager.get(req)); connect(reply1, SIGNAL(finished()), &helper, SLOT(finishedSlot())); manager.setProxy(QNetworkProxy()); - QNetworkReplyPtr reply2 = manager.get(req); + QNetworkReplyPtr reply2(manager.get(req)); connect(reply2, SIGNAL(finished()), &helper, SLOT(finishedSlot())); QTestEventLoop::instance().enterLoop(20); @@ -5267,7 +5267,7 @@ void tst_QNetworkReply::proxyChange() "Content-Length: 1\r\n\r\n1"; manager.setProxy(dummyProxy); - QNetworkReplyPtr reply3 = manager.get(req); + QNetworkReplyPtr reply3(manager.get(req)); QVERIFY(waitForFinish(reply3) == Failure); @@ -5297,12 +5297,12 @@ void tst_QNetworkReply::authorizationError() { QFETCH(QString, url); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QCOMPARE(reply->error(), QNetworkReply::NoError); - QSignalSpy errorSpy(reply, SIGNAL(error(QNetworkReply::NetworkError))); - QSignalSpy finishedSpy(reply, SIGNAL(finished())); + QSignalSpy errorSpy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); + QSignalSpy finishedSpy(reply.data(), SIGNAL(finished())); // now run the request: QVERIFY(waitForFinish(reply) == Failure); @@ -5549,7 +5549,7 @@ void tst_QNetworkReply::ignoreSslErrorsList() { QFETCH(QString, url); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QFETCH(QList, expectedSslErrors); reply->ignoreSslErrors(expectedSslErrors); @@ -5576,7 +5576,7 @@ void tst_QNetworkReply::ignoreSslErrorsListWithSlot() { QFETCH(QString, url); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QFETCH(QList, expectedSslErrors); // store the errors to ignore them later in the slot connected below @@ -5611,7 +5611,7 @@ void tst_QNetworkReply::sslConfiguration() QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/index.html")); QFETCH(QSslConfiguration, configuration); request.setSslConfiguration(configuration); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) != Timeout); @@ -5886,9 +5886,9 @@ void tst_QNetworkReply::getFromHttpIntoBuffer2() request.setAttribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute, 1024*1024*128); // 128 MB is max allowed QNetworkAccessManager manager; - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); - GetFromHttpIntoBuffer2Client client(reply, useDownloadBuffer, UploadSize); + GetFromHttpIntoBuffer2Client client(reply.data(), useDownloadBuffer, UploadSize); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); QTestEventLoop::instance().enterLoop(40); @@ -5906,7 +5906,7 @@ void tst_QNetworkReply::getFromHttpIntoBufferCanReadLine() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); request.setAttribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute, 1024*1024*128); // 128 MB is max allowed - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -5930,7 +5930,7 @@ void tst_QNetworkReply::ioGetFromHttpWithoutContentLength() server.doClose = true; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -5949,7 +5949,7 @@ void tst_QNetworkReply::ioGetFromHttpBrokenChunkedEncoding() server.doClose = false; // FIXME QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(10); @@ -5978,7 +5978,7 @@ void tst_QNetworkReply::qtbug12908compressedHttpReply() server.doClose = true; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -6001,7 +6001,7 @@ void tst_QNetworkReply::compressedHttpReplyBrokenGzip() server.doClose = true; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Failure); @@ -6014,7 +6014,7 @@ void tst_QNetworkReply::getFromUnreachableIp() QNetworkAccessManager manager; QNetworkRequest request(QUrl("http://255.255.255.255/42/23/narf/narf/narf")); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Failure); @@ -6028,11 +6028,11 @@ void tst_QNetworkReply::qtbug4121unknownAuthentication() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); QNetworkAccessManager manager; - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QSignalSpy authSpy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); QSignalSpy finishedSpy(&manager, SIGNAL(finished(QNetworkReply*))); - QSignalSpy errorSpy(reply, SIGNAL(error(QNetworkReply::NetworkError))); + QSignalSpy errorSpy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); QTestEventLoop::instance().enterLoop(10); @@ -6121,7 +6121,7 @@ void tst_QNetworkReply::authenticationCacheAfterCancel() QNetworkReplyPtr reply; if (proxyAuth) { //should fail due to no credentials - reply = manager.get(request); + reply.reset(manager.get(request)); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -6134,7 +6134,7 @@ void tst_QNetworkReply::authenticationCacheAfterCancel() //should fail due to bad credentials helper.proxyUserName = "qsockstest"; helper.proxyPassword = "badpassword"; - reply = manager.get(request); + reply.reset(manager.get(request)); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -6162,7 +6162,7 @@ void tst_QNetworkReply::authenticationCacheAfterCancel() } //should fail due to no credentials - reply = manager.get(request); + reply.reset(manager.get(request)); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -6178,7 +6178,7 @@ void tst_QNetworkReply::authenticationCacheAfterCancel() //should fail due to bad credentials helper.httpUserName = "baduser"; helper.httpPassword = "badpassword"; - reply = manager.get(request); + reply.reset(manager.get(request)); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -6196,7 +6196,7 @@ void tst_QNetworkReply::authenticationCacheAfterCancel() helper.httpUserName = "httptest"; helper.httpPassword = "httptest"; - reply = manager.get(request); + reply.reset(manager.get(request)); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -6211,7 +6211,7 @@ void tst_QNetworkReply::authenticationCacheAfterCancel() } //next auth should use cached credentials - reply = manager.get(request); + reply.reset(manager.get(request)); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -6320,7 +6320,7 @@ void tst_QNetworkReply::httpWithNoCredentialUsage() // Get with credentials, to preload authentication cache { QNetworkRequest request(QUrl("http://httptest:httptest@" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi")); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); // credentials in URL, so don't expect authentication signal QCOMPARE(authSpy.count(), 0); @@ -6331,7 +6331,7 @@ void tst_QNetworkReply::httpWithNoCredentialUsage() // Get with cached credentials (normal usage) { QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi")); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); // credentials in cache, so don't expect authentication signal QCOMPARE(authSpy.count(), 0); @@ -6343,9 +6343,9 @@ void tst_QNetworkReply::httpWithNoCredentialUsage() { QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi")); request.setAttribute(QNetworkRequest::AuthenticationReuseAttribute, QNetworkRequest::Manual); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); - QSignalSpy errorSpy(reply, SIGNAL(error(QNetworkReply::NetworkError))); + QSignalSpy errorSpy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError))); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); QTestEventLoop::instance().enterLoop(10); @@ -6367,7 +6367,7 @@ void tst_QNetworkReply::qtbug15311doubleContentLength() server.doClose = true; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -6386,7 +6386,7 @@ void tst_QNetworkReply::qtbug18232gzipContentLengthZero() server.doClose = true; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -6407,7 +6407,7 @@ void tst_QNetworkReply::qtbug22660gzipNoContentLengthEmptyContent() server.doClose = true; QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -6570,16 +6570,15 @@ void tst_QNetworkReply::httpAbort() // Abort after the first readyRead() QNetworkRequest request("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile"); - QNetworkReplyPtr reply; - reply = manager.get(request); - HttpAbortHelper replyHolder(reply); + QNetworkReplyPtr reply(manager.get(request)); + HttpAbortHelper replyHolder(reply.data()); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(reply->error(), QNetworkReply::OperationCanceledError); QVERIFY(reply->isFinished()); // Abort immediately after the get() - QNetworkReplyPtr reply2 = manager.get(request); + QNetworkReplyPtr reply2(manager.get(request)); connect(reply2, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); reply2->abort(); QCOMPARE(reply2->error(), QNetworkReply::OperationCanceledError); @@ -6587,7 +6586,7 @@ void tst_QNetworkReply::httpAbort() // Abort after the finished() QNetworkRequest request3("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); - QNetworkReplyPtr reply3 = manager.get(request3); + QNetworkReplyPtr reply3(manager.get(request3)); QVERIFY(waitForFinish(reply3) == Success); @@ -6618,7 +6617,7 @@ void tst_QNetworkReply::dontInsertPartialContentIntoTheCache() QNetworkRequest request(url); request.setRawHeader("Range", "bytes=2-6"); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -6635,7 +6634,7 @@ void tst_QNetworkReply::httpUserAgent() QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); request.setHeader(QNetworkRequest::UserAgentHeader, "abcDEFghi"); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(waitForFinish(reply) == Success); @@ -6688,7 +6687,7 @@ void tst_QNetworkReply::synchronousAuthenticationCache() QNetworkRequest request(url); request.setAttribute(QNetworkRequest::SynchronousRequestAttribute, true); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(reply->isFinished()); QCOMPARE(reply->error(), QNetworkReply::AuthenticationRequiredError); } @@ -6699,7 +6698,7 @@ void tst_QNetworkReply::synchronousAuthenticationCache() QNetworkRequest request(url); request.setAttribute(QNetworkRequest::SynchronousRequestAttribute, true); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(reply->isFinished()); QCOMPARE(reply->error(), QNetworkReply::NoError); QCOMPARE(reply->readAll().constData(), "OK"); @@ -6711,7 +6710,7 @@ void tst_QNetworkReply::synchronousAuthenticationCache() QNetworkRequest request(url); request.setAttribute(QNetworkRequest::SynchronousRequestAttribute, true); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QVERIFY(reply->isFinished()); QCOMPARE(reply->error(), QNetworkReply::NoError); QCOMPARE(reply->readAll().constData(), "OK"); @@ -6725,7 +6724,7 @@ void tst_QNetworkReply::pipelining() for (int a = 0; a < 20; a++) { QNetworkRequest request(urlString + QString::number(a)); request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, QVariant(true)); - replies.append(manager.get(request)); + replies.append(QNetworkReplyPtr(manager.get(request))); connect(replies.at(a), SIGNAL(finished()), this, SLOT(pipeliningHelperSlot())); } QTestEventLoop::instance().enterLoop(20); diff --git a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp index 16f9625eba..d6477475d3 100644 --- a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -122,16 +122,7 @@ protected: }; -class QNetworkReplyPtr: public QSharedPointer -{ -public: - inline QNetworkReplyPtr(QNetworkReply *ptr = 0) - : QSharedPointer(ptr) - { } - - inline operator QNetworkReply *() const { return data(); } -}; - +typedef QSharedPointer QNetworkReplyPtr; class DataReader: public QObject { @@ -141,6 +132,10 @@ public: QByteArray data; QIODevice *device; bool accumulate; + DataReader(const QNetworkReplyPtr &dev, bool acc = true) : totalBytes(0), device(dev.data()), accumulate(acc) + { + connect(device, SIGNAL(readyRead()), SLOT(doRead())); + } DataReader(QIODevice *dev, bool acc = true) : totalBytes(0), device(dev), accumulate(acc) { connect(device, SIGNAL(readyRead()), SLOT(doRead())); @@ -453,6 +448,11 @@ class tst_qnetworkreply : public QObject Q_OBJECT QNetworkAccessManager manager; + +public: + using QObject::connect; + bool connect(const QNetworkReplyPtr &sender, const char *signal, const QObject *receiver, const char *slot, Qt::ConnectionType ct = Qt::AutoConnection) + { return connect(sender.data(), signal, receiver, slot, ct); } private slots: void initTestCase(); void httpLatency(); @@ -531,7 +531,7 @@ void tst_qnetworkreply::downloadPerformance() // and measures how fast it was. TimedSender sender(5000); QNetworkRequest request(QUrl(QStringLiteral("debugpipe://127.0.0.1:") + QString::number(sender.serverPort()) + QStringLiteral("/?bare=1"))); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); DataReader reader(reply, false); QTime loopTime; @@ -553,7 +553,7 @@ void tst_qnetworkreply::uploadPerformance() QNetworkRequest request(QUrl(QStringLiteral("debugpipe://127.0.0.1:") + QString::number(reader.serverPort()) + QStringLiteral("/?bare=1"))); - QNetworkReplyPtr reply = manager.put(request, &generator); + QNetworkReplyPtr reply(manager.put(request, &generator)); generator.start(); connect(&reader, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTimer::singleShot(5000, &generator, SLOT(stop())); @@ -577,7 +577,7 @@ void tst_qnetworkreply::httpUploadPerformance() QNetworkRequest request(QUrl("http://127.0.0.1:" + QString::number(reader.serverPort()) + "/?bare=1")); request.setHeader(QNetworkRequest::ContentLengthHeader,UploadSize); - QNetworkReplyPtr reply = manager.put(request, &generator); + QNetworkReplyPtr reply(manager.put(request, &generator)); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -645,10 +645,10 @@ void tst_qnetworkreply::httpDownloadPerformance() HttpDownloadPerformanceServer server(UploadSize, serverSendsContentLength, chunkedEncoding); QNetworkRequest request(QUrl("http://127.0.0.1:" + QString::number(server.serverPort()) + "/?bare=1")); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); - HttpDownloadPerformanceClient client(reply); + HttpDownloadPerformanceClient client(reply.data()); QTime time; time.start(); @@ -734,9 +734,9 @@ void tst_qnetworkreply::httpDownloadPerformanceDownloadBuffer() request.setAttribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute, 1024*1024*128); // 128 MB is max allowed QNetworkAccessManager manager; - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); - HttpDownloadPerformanceClientDownloadBuffer client(reply, testType, UploadSize); + HttpDownloadPerformanceClientDownloadBuffer client(reply.data(), testType, UploadSize); QBENCHMARK_ONCE { QTestEventLoop::instance().enterLoop(40); -- cgit v1.2.3 From e5ef496b5bd6a4650d765622c0690cdf47d7defc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 6 Mar 2012 08:33:32 +0100 Subject: tst_qsharedpointer: don't inherit from QSharedPointer QSharedPointer is about to be made final. Instead of inheriting from it to gain access to the d-pointer, cast it to a layout-compatible struct and access the pointer from there. Assert liberally to ensure layout compatibility. Change-Id: Ifc0fa6a6608e861469286673844325663f4f7fcc Reviewed-by: Thiago Macieira --- .../tools/qsharedpointer/tst_qsharedpointer.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 5b697a3509..f8b9abb359 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -114,15 +114,19 @@ public: } }; -template -class RefCountHack: public Base +template static inline +QtSharedPointer::ExternalRefCountData *refCountData(const QtSharedPointer::ExternalRefCount &b) { -public: - using Base::d; -}; -template static inline -QtSharedPointer::ExternalRefCountData *refCountData(const Base &b) -{ return static_cast *>(&b)->d; } + // access d-pointer: + struct Dummy { + void* value; + QtSharedPointer::ExternalRefCountData* data; + }; + // sanity checks: + Q_STATIC_ASSERT(sizeof(QtSharedPointer::ExternalRefCount) == sizeof(Dummy)); + Q_ASSERT(static_cast(static_cast(&b))->value == b.data()); + return static_cast(static_cast(&b))->data; +} class Data { -- cgit v1.2.3 From 0defa2782ff94420da546ff36502cfea7fd64511 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 6 Mar 2012 11:46:02 +0100 Subject: tst_qsslsocket*: don't inherit from QSharedPointer QSharedPointer is about to become final. Instead of inheriting from it to add implicit conversions to and from QSslSocket*, make QSslSocketPtr a typedef, and make the conversions explicit. Change-Id: I4eebb262ab5aef348f4d676f9e839325d4ed13da Reviewed-by: Thiago Macieira --- .../auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 72 ++++++++++------------ .../tst_qsslsocket_onDemandCertificates_member.cpp | 18 ++---- .../tst_qsslsocket_onDemandCertificates_static.cpp | 18 ++---- 3 files changed, 42 insertions(+), 66 deletions(-) (limited to 'tests') diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 2f9ed0d089..23e87b7f3b 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -81,15 +81,7 @@ Q_DECLARE_METATYPE(QSslConfiguration) #endif #ifndef QT_NO_SSL -class QSslSocketPtr: public QSharedPointer -{ -public: - inline QSslSocketPtr(QSslSocket *ptr = 0) - : QSharedPointer(ptr) - { } - - inline operator QSslSocket *() const { return data(); } -}; +typedef QSharedPointer QSslSocketPtr; #endif class tst_QSslSocket : public QObject @@ -605,10 +597,10 @@ void tst_QSslSocket::connectToHostEncrypted() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); QVERIFY(socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"))); #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND - connect(socket, SIGNAL(sslErrors(QList)), + connect(socket.data(), SIGNAL(sslErrors(QList)), this, SLOT(untrustedWorkaroundSlot(QList))); #endif @@ -636,11 +628,11 @@ void tst_QSslSocket::connectToHostEncryptedWithVerificationPeerName() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")); #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND - connect(socket, SIGNAL(sslErrors(QList)), + connect(socket.data(), SIGNAL(sslErrors(QList)), this, SLOT(untrustedWorkaroundSlot(QList))); #endif @@ -662,8 +654,8 @@ void tst_QSslSocket::sessionCipher() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; - connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(ignoreErrorSlot())); + this->socket = socket.data(); + connect(socket.data(), SIGNAL(sslErrors(QList)), this, SLOT(ignoreErrorSlot())); QVERIFY(socket->sessionCipher().isNull()); socket->connectToHost(QtNetworkSettings::serverName(), 443 /* https */); QVERIFY(socket->waitForConnected(10000)); @@ -717,13 +709,13 @@ void tst_QSslSocket::peerCertificateChain() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); QList caCertificates = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")); QVERIFY(caCertificates.count() == 1); socket->addCaCertificates(caCertificates); #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND - connect(socket, SIGNAL(sslErrors(QList)), + connect(socket.data(), SIGNAL(sslErrors(QList)), this, SLOT(untrustedWorkaroundSlot(QList))); #endif @@ -806,7 +798,7 @@ void tst_QSslSocket::protocol() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); QList certs = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem"); socket->setCaCertificates(certs); @@ -1032,14 +1024,14 @@ void tst_QSslSocket::protocolServerSide() QEventLoop loop; QTimer::singleShot(5000, &loop, SLOT(quit())); - QSslSocketPtr client = new QSslSocket; - socket = client; + QSslSocketPtr client(new QSslSocket); + socket = client.data(); QFETCH(QSsl::SslProtocol, clientProtocol); socket->setProtocol(clientProtocol); // upon SSL wrong version error, error will be triggered, not sslErrors connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &loop, SLOT(quit())); connect(socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); - connect(client, SIGNAL(encrypted()), &loop, SLOT(quit())); + connect(socket, SIGNAL(encrypted()), &loop, SLOT(quit())); client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort()); @@ -1091,10 +1083,10 @@ void tst_QSslSocket::setSocketDescriptor() QEventLoop loop; QTimer::singleShot(5000, &loop, SLOT(quit())); - QSslSocketPtr client = new QSslSocket; - socket = client; + QSslSocketPtr client(new QSslSocket); + socket = client.data();; connect(socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); - connect(client, SIGNAL(encrypted()), &loop, SLOT(quit())); + connect(socket, SIGNAL(encrypted()), &loop, SLOT(quit())); client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort()); @@ -1131,7 +1123,7 @@ void tst_QSslSocket::setSslConfiguration() QSslSocketPtr socket = newSocket(); QFETCH(QSslConfiguration, configuration); socket->setSslConfiguration(configuration); - this->socket = socket; + this->socket = socket.data(); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); QFETCH(bool, works); QCOMPARE(socket->waitForEncrypted(10000), works); @@ -1147,9 +1139,9 @@ void tst_QSslSocket::waitForEncrypted() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); - connect(socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); + connect(this->socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); QVERIFY(socket->waitForEncrypted(10000)); @@ -1164,9 +1156,9 @@ void tst_QSslSocket::waitForEncryptedMinusOne() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); - connect(socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); + connect(this->socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); QVERIFY(socket->waitForEncrypted(-1)); @@ -1178,9 +1170,9 @@ void tst_QSslSocket::waitForConnectedEncryptedReadyRead() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); - connect(socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); + connect(this->socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 993); QVERIFY(socket->waitForConnected(10000)); @@ -1315,7 +1307,7 @@ void tst_QSslSocket::wildcard() // valid connection. This was broken in 4.3.0. QSslSocketPtr socket = newSocket(); socket->addCaCertificates(QLatin1String("certs/aspiriniks.ca.crt")); - this->socket = socket; + this->socket = socket.data(); #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(untrustedWorkaroundSlot(QList))); @@ -1520,7 +1512,7 @@ void tst_QSslSocket::setReadBufferSize_task_250027() // exit the event loop as soon as we receive a readyRead() SetReadBufferSize_task_250027_handler setReadBufferSize_task_250027_handler; - connect(socket, SIGNAL(readyRead()), &setReadBufferSize_task_250027_handler, SLOT(readyReadSlot())); + connect(socket.data(), SIGNAL(readyRead()), &setReadBufferSize_task_250027_handler, SLOT(readyReadSlot())); // provoke a response by sending a request socket->write("GET /qtest/fluke.gif HTTP/1.0\n"); // this file is 27 KB @@ -1532,13 +1524,13 @@ void tst_QSslSocket::setReadBufferSize_task_250027() socket->flush(); QTestEventLoop::instance().enterLoop(10); - setReadBufferSize_task_250027_handler.waitSomeMore(socket); + setReadBufferSize_task_250027_handler.waitSomeMore(socket.data()); QByteArray firstRead = socket->readAll(); // First read should be some data, but not the whole file QVERIFY(firstRead.size() > 0 && firstRead.size() < 20*1024); QTestEventLoop::instance().enterLoop(10); - setReadBufferSize_task_250027_handler.waitSomeMore(socket); + setReadBufferSize_task_250027_handler.waitSomeMore(socket.data()); QByteArray secondRead = socket->readAll(); // second read should be some more data QVERIFY(secondRead.size() > 0); @@ -1792,8 +1784,8 @@ void tst_QSslSocket::verifyDepth() void tst_QSslSocket::peerVerifyError() { QSslSocketPtr socket = newSocket(); - QSignalSpy sslErrorsSpy(socket, SIGNAL(sslErrors(QList))); - QSignalSpy peerVerifyErrorSpy(socket, SIGNAL(peerVerifyError(QSslError))); + QSignalSpy sslErrorsSpy(socket.data(), SIGNAL(sslErrors(QList))); + QSignalSpy peerVerifyErrorSpy(socket.data(), SIGNAL(peerVerifyError(QSslError))); socket->connectToHostEncrypted(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(), 443); QVERIFY(!socket->waitForEncrypted(10000)); @@ -1996,9 +1988,9 @@ void tst_QSslSocket::writeBigChunk() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); - connect(socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); + connect(this->socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); QByteArray data; @@ -2217,7 +2209,7 @@ void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last, QSslConfiguration::setDefaultConfiguration(emptyConf); QSslSocketPtr socket = newSocket(); - connect(socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); + connect(socket.data(), SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); QVERIFY2(!socket->waitForEncrypted(4000), qPrintable(socket->errorString())); } diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp index bc0e04a1f2..ed9ee3be3f 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp @@ -51,15 +51,7 @@ #include "../../../network-settings.h" #ifndef QT_NO_OPENSSL -class QSslSocketPtr: public QSharedPointer -{ -public: - inline QSslSocketPtr(QSslSocket *ptr = 0) - : QSharedPointer(ptr) - { } - - inline operator QSslSocket *() const { return data(); } -}; +typedef QSharedPointer QSslSocketPtr; #endif class tst_QSslSocket_onDemandCertificates_member : public QObject @@ -201,28 +193,28 @@ void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMe // not using any root certs -> should not work QSslSocketPtr socket2 = newSocket(); - this->socket = socket2; + this->socket = socket2.data(); socket2->setCaCertificates(QList()); socket2->connectToHostEncrypted(host, 443); QVERIFY(!socket2->waitForEncrypted()); // default: using on demand loading -> should work QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); socket->connectToHostEncrypted(host, 443); QEXPECT_FAIL("", "QTBUG-20983 fails", Abort); QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString())); // not using any root certs again -> should not work QSslSocketPtr socket3 = newSocket(); - this->socket = socket3; + this->socket = socket3.data(); socket3->setCaCertificates(QList()); socket3->connectToHostEncrypted(host, 443); QVERIFY(!socket3->waitForEncrypted()); // setting empty SSL configuration explicitly -> should not work QSslSocketPtr socket4 = newSocket(); - this->socket = socket4; + this->socket = socket4.data(); socket4->setSslConfiguration(QSslConfiguration()); socket4->connectToHostEncrypted(host, 443); QVERIFY(!socket4->waitForEncrypted()); diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp index dd01733fbe..ee038aa086 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp @@ -51,15 +51,7 @@ #include "../../../network-settings.h" #ifndef QT_NO_OPENSSL -class QSslSocketPtr: public QSharedPointer -{ -public: - inline QSslSocketPtr(QSslSocket *ptr = 0) - : QSharedPointer(ptr) - { } - - inline operator QSslSocket *() const { return data(); } -}; +typedef QSharedPointer QSslSocketPtr; #endif class tst_QSslSocket_onDemandCertificates_static : public QObject @@ -202,14 +194,14 @@ void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMe // not using any root certs -> should not work QSslSocket::setDefaultCaCertificates(QList()); QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); socket->connectToHostEncrypted(host, 443); QVERIFY(!socket->waitForEncrypted()); // using system root certs -> should work QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates()); QSslSocketPtr socket2 = newSocket(); - this->socket = socket2; + this->socket = socket2.data(); socket2->connectToHostEncrypted(host, 443); QEXPECT_FAIL("", "QTBUG-20983 fails", Abort); QVERIFY2(socket2->waitForEncrypted(), qPrintable(socket2->errorString())); @@ -217,7 +209,7 @@ void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMe // not using any root certs again -> should not work QSslSocket::setDefaultCaCertificates(QList()); QSslSocketPtr socket3 = newSocket(); - this->socket = socket3; + this->socket = socket3.data(); socket3->connectToHostEncrypted(host, 443); QVERIFY(!socket3->waitForEncrypted()); @@ -228,7 +220,7 @@ void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMe QSslConfiguration originalDefaultConf = QSslConfiguration::defaultConfiguration(); QSslConfiguration::setDefaultConfiguration(conf); QSslSocketPtr socket4 = newSocket(); - this->socket = socket4; + this->socket = socket4.data(); socket4->connectToHostEncrypted(host, 443); QVERIFY(!socket4->waitForEncrypted(4000)); QSslConfiguration::setDefaultConfiguration(originalDefaultConf); // restore old behaviour for run with proxies etc. -- cgit v1.2.3 From e20c4730192f312881591fb50e571af0a88fe421 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 5 Sep 2011 20:34:38 +0200 Subject: Move the UTF-8 data into a separate .cpp so I can use later This allows me to keep the UTF-8 invalid data in one safe place. I won't need to copy & paste it. Change-Id: Icb909d08b7f8d0e1ffbc28e01a0ba0c1fa9dccf0 Reviewed-by: David Faure --- tests/auto/corelib/codecs/utf8/tst_utf8.cpp | 117 +------------------- tests/auto/corelib/codecs/utf8/utf8.pro | 2 +- tests/auto/corelib/codecs/utf8/utf8data.cpp | 163 ++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 114 deletions(-) create mode 100644 tests/auto/corelib/codecs/utf8/utf8data.cpp (limited to 'tests') diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp index dd6774e101..025bb349d6 100644 --- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp +++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp @@ -206,88 +206,8 @@ void tst_Utf8::invalidUtf8_data() { QTest::addColumn("utf8"); - QTest::newRow("1char") << QByteArray("\x80"); - QTest::newRow("2chars-1") << QByteArray("\xC2\xC0"); - QTest::newRow("2chars-2") << QByteArray("\xC3\xDF"); - QTest::newRow("2chars-3") << QByteArray("\xC7\xF0"); - QTest::newRow("3chars-1") << QByteArray("\xE0\xA0\xC0"); - QTest::newRow("3chars-2") << QByteArray("\xE0\xC0\xA0"); - QTest::newRow("4chars-1") << QByteArray("\xF0\x90\x80\xC0"); - QTest::newRow("4chars-2") << QByteArray("\xF0\x90\xC0\x80"); - QTest::newRow("4chars-3") << QByteArray("\xF0\xC0\x80\x80"); - - // Surrogate pairs must now be present either - // U+D800: 1101 10 0000 00 0000 - // encoding: xxxz:1101 xz10:0000 xz00:0000 - QTest::newRow("hi-surrogate") << QByteArray("\xED\xA0\x80"); - // U+DC00: 1101 11 0000 00 0000 - // encoding: xxxz:1101 xz11:0000 xz00:0000 - QTest::newRow("lo-surrogate") << QByteArray("\xED\xB0\x80"); - - // not even in pair: - QTest::newRow("surrogate-pair") << QByteArray("\xED\xA0\x80\xED\xB0\x80"); - - // Characters outside the Unicode range: - // 0x110000: 00 0100 01 0000 00 0000 00 0000 - // encoding: xxxx:z100 xz01:0000 xz00:0000 xz00:0000 - QTest::newRow("non-unicode-1") << QByteArray("\xF4\x90\x80\x80"); - // 0x200000: 00 1000 00 0000 00 0000 00 0000 - // encoding: xxxx:xz00 xz00:1000 xz00:0000 xz00:0000 xz00:0000 - QTest::newRow("non-unicode-2") << QByteArray("\xF8\x88\x80\x80\x80"); - // 0x04000000: 0100 00 0000 00 0000 00 0000 00 0000 - // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001 - QTest::newRow("non-unicode-3") << QByteArray("\xFC\x84\x80\x80\x80\x80"); - // 0x7fffffff: 1 11 1111 11 1111 11 1111 11 1111 11 1111 - // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001 - QTest::newRow("non-unicode-4") << QByteArray("\xFD\xBF\xBF\xBF\xBF\xBF"); - - // As seen above, 0xFE and 0xFF never appear: - QTest::newRow("fe") << QByteArray("\xFE"); - QTest::newRow("fe-bis") << QByteArray("\xFE\xBF\xBF\xBF\xBF\xBF\xBF"); - QTest::newRow("ff") << QByteArray("\xFF"); - QTest::newRow("ff-bis") << QByteArray("\xFF\xBF\xBF\xBF\xBF\xBF\xBF\xBF"); - - // some combinations in UTF-8 are invalid even though they have the proper bits set - // these are known as overlong sequences - - // "A": U+0041: 01 00 0001 - // overlong 2: xxz0:0001 xz00:0001 - QTest::newRow("overlong-1-2") << QByteArray("\xC1\x81"); - // overlong 3: xxxz:0000 xz00:0001 xz00:0001 - QTest::newRow("overlong-1-3") << QByteArray("\xE0\x81\x81"); - // overlong 4: xxxx:z000 xz00:0000 xz00:0001 xz00:0001 - QTest::newRow("overlong-1-4") << QByteArray("\xF0\x80\x81\x81"); - // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0001 xz00:0001 - QTest::newRow("overlong-1-5") << QByteArray("\xF8\x80\x80\x81\x81"); - // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0001 xz00:0001 - QTest::newRow("overlong-1-6") << QByteArray("\xFC\x80\x80\x80\x81\x81"); - - // NBSP: U+00A0: 10 00 0000 - // proper encoding: xxz0:0010 xz00:0000 - // overlong 3: xxxz:0000 xz00:0010 xz00:0000 - QTest::newRow("overlong-2-3") << QByteArray("\xC0\x82\x80"); - // overlong 4: xxxx:z000 xz00:0000 xz00:0010 xz00:0000 - QTest::newRow("overlong-2-4") << QByteArray("\xF0\x80\x82\x80"); - // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0010 xz00:0000 - QTest::newRow("overlong-2-5") << QByteArray("\xF8\x80\x80\x82\x80"); - // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0010 xz00:0000 - QTest::newRow("overlong-2-6") << QByteArray("\xFC\x80\x80\x80\x82\x80"); - - // U+0800: 10 0000 00 0000 - // proper encoding: xxxz:0000 xz10:0000 xz00:0000 - // overlong 4: xxxx:z000 xz00:0000 xz10:0000 xz00:0000 - QTest::newRow("overlong-3-4") << QByteArray("\xF0\x80\xA0\x80"); - // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz10:0000 xz00:0000 - QTest::newRow("overlong-3-5") << QByteArray("\xF8\x80\x80\xA0\x80"); - // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz10:0000 xz00:0000 - QTest::newRow("overlong-3-6") << QByteArray("\xFC\x80\x80\x80\xA0\x80"); - - // U+010000: 00 0100 00 0000 00 0000 - // proper encoding: xxxx:z000 xz00:0100 xz00:0000 xz00:0000 - // overlong 5: xxxx:xz00 xz00:0000 xz00:0100 xz00:0000 xz00:0000 - QTest::newRow("overlong-4-5") << QByteArray("\xF8\x80\x84\x80\x80"); - // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0100 xz00:0000 xz00:0000 - QTest::newRow("overlong-4-6") << QByteArray("\xFC\x80\x80\x84\x80\x80"); + extern void loadInvalidUtf8Rows(); + loadInvalidUtf8Rows(); } void tst_Utf8::invalidUtf8() @@ -313,37 +233,8 @@ void tst_Utf8::nonCharacters_data() QTest::addColumn("utf8"); QTest::addColumn("utf16"); - // Unicode has a couple of "non-characters" that one can use internally, - // but are not allowed to be used for text interchange. - // - // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF, - // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and - // U+FDEF (inclusive) - - // U+FDD0 through U+FDEF - for (int i = 0; i < 16; ++i) { - char utf8[] = { char(0357), char(0267), char(0220 + i), 0 }; - QString utf16 = QChar(0xfdd0 + i); - QTest::newRow(qPrintable(QString::number(0xfdd0 + i, 16))) << QByteArray(utf8) << utf16; - } - - // the last two in Planes 1 through 16 - for (uint plane = 1; plane <= 16; ++plane) { - for (uint lower = 0xfffe; lower < 0x10000; ++lower) { - uint ucs4 = (plane << 16) | lower; - char utf8[] = { char(0xf0 | uchar(ucs4 >> 18)), - char(0x80 | (uchar(ucs4 >> 12) & 0x3f)), - char(0x80 | (uchar(ucs4 >> 6) & 0x3f)), - char(0x80 | (uchar(ucs4) & 0x3f)), - 0 }; - ushort utf16[] = { QChar::highSurrogate(ucs4), QChar::lowSurrogate(ucs4), 0 }; - - QTest::newRow(qPrintable(QString::number(ucs4, 16))) << QByteArray(utf8) << QString::fromUtf16(utf16); - } - } - - QTest::newRow("fffe") << QByteArray("\xEF\xBF\xBE") << QString(QChar(0xfffe)); - QTest::newRow("ffff") << QByteArray("\xEF\xBF\xBF") << QString(QChar(0xffff)); + extern void loadNonCharactersRows(); + loadNonCharactersRows(); } void tst_Utf8::nonCharacters() diff --git a/tests/auto/corelib/codecs/utf8/utf8.pro b/tests/auto/corelib/codecs/utf8/utf8.pro index 2d200e82a4..1df6ac7e50 100644 --- a/tests/auto/corelib/codecs/utf8/utf8.pro +++ b/tests/auto/corelib/codecs/utf8/utf8.pro @@ -1,5 +1,5 @@ CONFIG += testcase TARGET = tst_utf8 QT = core testlib -SOURCES += tst_utf8.cpp +SOURCES += tst_utf8.cpp utf8data.cpp CONFIG += parallel_test diff --git a/tests/auto/corelib/codecs/utf8/utf8data.cpp b/tests/auto/corelib/codecs/utf8/utf8data.cpp new file mode 100644 index 0000000000..2c0bae3e5d --- /dev/null +++ b/tests/auto/corelib/codecs/utf8/utf8data.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include + +void loadInvalidUtf8Rows() +{ + QTest::newRow("1char") << QByteArray("\x80"); + QTest::newRow("2chars-1") << QByteArray("\xC2\xC0"); + QTest::newRow("2chars-2") << QByteArray("\xC3\xDF"); + QTest::newRow("2chars-3") << QByteArray("\xC7\xF0"); + QTest::newRow("3chars-1") << QByteArray("\xE0\xA0\xC0"); + QTest::newRow("3chars-2") << QByteArray("\xE0\xC0\xA0"); + QTest::newRow("4chars-1") << QByteArray("\xF0\x90\x80\xC0"); + QTest::newRow("4chars-2") << QByteArray("\xF0\x90\xC0\x80"); + QTest::newRow("4chars-3") << QByteArray("\xF0\xC0\x80\x80"); + + // Surrogate pairs must now be present either + // U+D800: 1101 10 0000 00 0000 + // encoding: xxxz:1101 xz10:0000 xz00:0000 + QTest::newRow("hi-surrogate") << QByteArray("\xED\xA0\x80"); + // U+DC00: 1101 11 0000 00 0000 + // encoding: xxxz:1101 xz11:0000 xz00:0000 + QTest::newRow("lo-surrogate") << QByteArray("\xED\xB0\x80"); + + // not even in pair: + QTest::newRow("surrogate-pair") << QByteArray("\xED\xA0\x80\xED\xB0\x80"); + + // Characters outside the Unicode range: + // 0x110000: 00 0100 01 0000 00 0000 00 0000 + // encoding: xxxx:z100 xz01:0000 xz00:0000 xz00:0000 + QTest::newRow("non-unicode-1") << QByteArray("\xF4\x90\x80\x80"); + // 0x200000: 00 1000 00 0000 00 0000 00 0000 + // encoding: xxxx:xz00 xz00:1000 xz00:0000 xz00:0000 xz00:0000 + QTest::newRow("non-unicode-2") << QByteArray("\xF8\x88\x80\x80\x80"); + // 0x04000000: 0100 00 0000 00 0000 00 0000 00 0000 + // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001 + QTest::newRow("non-unicode-3") << QByteArray("\xFC\x84\x80\x80\x80\x80"); + // 0x7fffffff: 1 11 1111 11 1111 11 1111 11 1111 11 1111 + // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001 + QTest::newRow("non-unicode-4") << QByteArray("\xFD\xBF\xBF\xBF\xBF\xBF"); + + // As seen above, 0xFE and 0xFF never appear: + QTest::newRow("fe") << QByteArray("\xFE"); + QTest::newRow("fe-bis") << QByteArray("\xFE\xBF\xBF\xBF\xBF\xBF\xBF"); + QTest::newRow("ff") << QByteArray("\xFF"); + QTest::newRow("ff-bis") << QByteArray("\xFF\xBF\xBF\xBF\xBF\xBF\xBF\xBF"); + + // some combinations in UTF-8 are invalid even though they have the proper bits set + // these are known as overlong sequences + + // "A": U+0041: 01 00 0001 + // overlong 2: xxz0:0001 xz00:0001 + QTest::newRow("overlong-1-2") << QByteArray("\xC1\x81"); + // overlong 3: xxxz:0000 xz00:0001 xz00:0001 + QTest::newRow("overlong-1-3") << QByteArray("\xE0\x81\x81"); + // overlong 4: xxxx:z000 xz00:0000 xz00:0001 xz00:0001 + QTest::newRow("overlong-1-4") << QByteArray("\xF0\x80\x81\x81"); + // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0001 xz00:0001 + QTest::newRow("overlong-1-5") << QByteArray("\xF8\x80\x80\x81\x81"); + // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0001 xz00:0001 + QTest::newRow("overlong-1-6") << QByteArray("\xFC\x80\x80\x80\x81\x81"); + + // NBSP: U+00A0: 10 00 0000 + // proper encoding: xxz0:0010 xz00:0000 + // overlong 3: xxxz:0000 xz00:0010 xz00:0000 + QTest::newRow("overlong-2-3") << QByteArray("\xC0\x82\x80"); + // overlong 4: xxxx:z000 xz00:0000 xz00:0010 xz00:0000 + QTest::newRow("overlong-2-4") << QByteArray("\xF0\x80\x82\x80"); + // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0010 xz00:0000 + QTest::newRow("overlong-2-5") << QByteArray("\xF8\x80\x80\x82\x80"); + // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0010 xz00:0000 + QTest::newRow("overlong-2-6") << QByteArray("\xFC\x80\x80\x80\x82\x80"); + + // U+0800: 10 0000 00 0000 + // proper encoding: xxxz:0000 xz10:0000 xz00:0000 + // overlong 4: xxxx:z000 xz00:0000 xz10:0000 xz00:0000 + QTest::newRow("overlong-3-4") << QByteArray("\xF0\x80\xA0\x80"); + // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz10:0000 xz00:0000 + QTest::newRow("overlong-3-5") << QByteArray("\xF8\x80\x80\xA0\x80"); + // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz10:0000 xz00:0000 + QTest::newRow("overlong-3-6") << QByteArray("\xFC\x80\x80\x80\xA0\x80"); + + // U+010000: 00 0100 00 0000 00 0000 + // proper encoding: xxxx:z000 xz00:0100 xz00:0000 xz00:0000 + // overlong 5: xxxx:xz00 xz00:0000 xz00:0100 xz00:0000 xz00:0000 + QTest::newRow("overlong-4-5") << QByteArray("\xF8\x80\x84\x80\x80"); + // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0100 xz00:0000 xz00:0000 + QTest::newRow("overlong-4-6") << QByteArray("\xFC\x80\x80\x84\x80\x80"); + +} + +void loadNonCharactersRows() +{ + // Unicode has a couple of "non-characters" that one can use internally, + // but are not allowed to be used for text interchange. + // + // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF, + // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and + // U+FDEF (inclusive) + + // U+FDD0 through U+FDEF + for (int i = 0; i < 16; ++i) { + char utf8[] = { char(0357), char(0267), char(0220 + i), 0 }; + QString utf16 = QChar(0xfdd0 + i); + QTest::newRow(qPrintable(QString::number(0xfdd0 + i, 16))) << QByteArray(utf8) << utf16; + } + + // the last two in Planes 1 through 16 + for (uint plane = 1; plane <= 16; ++plane) { + for (uint lower = 0xfffe; lower < 0x10000; ++lower) { + uint ucs4 = (plane << 16) | lower; + char utf8[] = { char(0xf0 | uchar(ucs4 >> 18)), + char(0x80 | (uchar(ucs4 >> 12) & 0x3f)), + char(0x80 | (uchar(ucs4 >> 6) & 0x3f)), + char(0x80 | (uchar(ucs4) & 0x3f)), + 0 }; + ushort utf16[] = { QChar::highSurrogate(ucs4), QChar::lowSurrogate(ucs4), 0 }; + + QTest::newRow(qPrintable(QString::number(ucs4, 16))) << QByteArray(utf8) << QString::fromUtf16(utf16); + } + } + + QTest::newRow("fffe") << QByteArray("\xEF\xBF\xBE") << QString(QChar(0xfffe)); + QTest::newRow("ffff") << QByteArray("\xEF\xBF\xBF") << QString(QChar(0xffff)); +} -- cgit v1.2.3 From f31e614245e796c7f82ec33eed708902d4d01521 Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Sat, 17 Mar 2012 21:37:17 -0700 Subject: Cleanup Q3* items Cleanup Q3* items from QtCore and QtGui modules. Change-Id: Id214a077a50e99d820c84e96e34866492a0130d8 Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp index d8b2a800b9..19ff947a1c 100644 --- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp +++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp @@ -255,9 +255,6 @@ void tst_QLabel::setTextFormat() testWidget->setTextFormat( Qt::RichText ); QVERIFY( testWidget->textFormat() == Qt::RichText ); - testWidget->setTextFormat( Qt::LogText ); - QVERIFY( testWidget->textFormat() == Qt::LogText ); - testWidget->setTextFormat( Qt::AutoText ); QVERIFY( testWidget->textFormat() == Qt::AutoText ); } -- cgit v1.2.3 From 2f2b78321427daa8c7f0702140c297d22b0bf3c8 Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Tue, 20 Mar 2012 20:21:30 -0700 Subject: Remove QWorkspace. QWorkspace had been called Q3Workspace before Qt4.0 finally released. In a sense, it is a Qt3 support Widget. And QWorkspace has been deprecated and replaced by QMdiArea at Qt4.3. Change-Id: Iea1bf831c9960c23c2b21d51fdc7c13b303642ea Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- .../tst_exceptionsafety_objects.cpp | 4 +- .../other/qaccessibility/tst_qaccessibility.cpp | 29 +- .../auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 4 +- .../widgets/qmdisubwindow/tst_qmdisubwindow.cpp | 2 +- tests/auto/widgets/widgets/qworkspace/.gitignore | 1 - .../auto/widgets/widgets/qworkspace/qworkspace.pro | 4 - .../widgets/widgets/qworkspace/tst_qworkspace.cpp | 676 --------------------- tests/auto/widgets/widgets/widgets.pro | 1 - 8 files changed, 5 insertions(+), 716 deletions(-) delete mode 100644 tests/auto/widgets/widgets/qworkspace/.gitignore delete mode 100644 tests/auto/widgets/widgets/qworkspace/qworkspace.pro delete mode 100644 tests/auto/widgets/widgets/qworkspace/tst_qworkspace.cpp (limited to 'tests') diff --git a/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp index 14628b2c8b..126b41ed51 100644 --- a/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ b/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp @@ -449,7 +449,6 @@ void tst_ExceptionSafety_Objects::widgets_data() NEWROW(QToolButton); NEWROW(QTreeView); NEWROW(QTreeWidget); - NEWROW(QWorkspace); } void tst_ExceptionSafety_Objects::widgets() @@ -486,8 +485,7 @@ void tst_ExceptionSafety_Objects::widgets() || tag == QLatin1String("QToolBar") || tag == QLatin1String("QToolBox") || tag == QLatin1String("QTreeView") - || tag == QLatin1String("QTreeWidget") - || tag == QLatin1String("QWorkspace")) + || tag == QLatin1String("QTreeWidget")) QSKIP("This type of widget is not currently strongly exception safe"); if (tag == QLatin1String("QWidget")) diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index a72dac1b81..edd7a7aba4 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -252,7 +252,6 @@ private slots: void mdiAreaTest(); void mdiSubWindowTest(); void lineEditTest(); - void workspaceTest(); void dialogButtonBoxTest(); void dialTest(); void rubberBandTest(); @@ -587,7 +586,7 @@ static QWidget *createWidgets() /* Not in the list * QAbstractItemView, QGraphicsView, QScrollArea, * QToolButton, QDockWidget, QFocusFrame, QMainWindow, QMenu, QMenuBar, QSizeGrip, QSplashScreen, QSplitterHandle, - * QStatusBar, QSvgWidget, QTabBar, QToolBar, QWorkspace, QSplitter + * QStatusBar, QSvgWidget, QTabBar, QToolBar, QSplitter */ return w; } @@ -1818,32 +1817,6 @@ void tst_QAccessibility::lineEditTest() QTestAccessibility::clearEvents(); } -void tst_QAccessibility::workspaceTest() -{ - { - QWorkspace workspace; - workspace.resize(400,300); - workspace.show(); - const int subWindowCount = 3; - for (int i = 0; i < subWindowCount; ++i) { - QWidget *window = workspace.addWindow(new QWidget); - if (i > 0) - window->move(window->x() + 1, window->y()); - window->show(); - window->resize(70, window->height()); - } - - QWidgetList subWindows = workspace.windowList(); - QCOMPARE(subWindows.count(), subWindowCount); - - QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&workspace); - QVERIFY(interface); - QCOMPARE(interface->childCount(), subWindowCount); - - } - QTestAccessibility::clearEvents(); -} - bool accessibleInterfaceLeftOf(const QAccessibleInterface *a1, const QAccessibleInterface *a2) { return a1->rect().x() < a2->rect().x(); diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index e97b044dbc..eeb2eea9a1 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -199,7 +199,7 @@ static bool verifyArrangement(QMdiArea *mdiArea, Arrangement arrangement, const if (qobject_cast(firstSubWindow->style())) titleBarHeight -= 4; #endif - const QFontMetrics fontMetrics = QFontMetrics(QApplication::font("QWorkspaceTitleBar")); + const QFontMetrics fontMetrics = QFontMetrics(QApplication::font("QMdiSubWindowTitleBar")); const int dy = qMax(titleBarHeight - (titleBarHeight - fontMetrics.height()) / 2, 1); const int dx = 10; @@ -1823,7 +1823,7 @@ void tst_QMdiArea::cascadeAndTileSubWindows() // ### Remove this after the mac style has been fixed if (windows.at(1)->style()->inherits("QMacStyle")) titleBarHeight -= 4; - const QFontMetrics fontMetrics = QFontMetrics(QApplication::font("QWorkspaceTitleBar")); + const QFontMetrics fontMetrics = QFontMetrics(QApplication::font("QMdiSubWindowTitleBar")); const int dy = qMax(titleBarHeight - (titleBarHeight - fontMetrics.height()) / 2, 1); QCOMPARE(windows.at(2)->geometry().top() - windows.at(1)->geometry().top(), dy); diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp index 53e0a5494a..70823d92f0 100644 --- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp +++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp @@ -1824,7 +1824,7 @@ void tst_QMdiSubWindow::setFont() qt_x11_wait_for_window_manager(&mdiArea); #endif - const QFont originalFont = QApplication::font("QWorkspaceTitleBar"); + const QFont originalFont = QApplication::font("QMdiSubWindowTitleBar"); QStyleOptionTitleBar opt; opt.initFrom(subWindow); const int titleBarHeight = subWindow->style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt); diff --git a/tests/auto/widgets/widgets/qworkspace/.gitignore b/tests/auto/widgets/widgets/qworkspace/.gitignore deleted file mode 100644 index 73facc366e..0000000000 --- a/tests/auto/widgets/widgets/qworkspace/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tst_qworkspace diff --git a/tests/auto/widgets/widgets/qworkspace/qworkspace.pro b/tests/auto/widgets/widgets/qworkspace/qworkspace.pro deleted file mode 100644 index 02de0031fd..0000000000 --- a/tests/auto/widgets/widgets/qworkspace/qworkspace.pro +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG += testcase -TARGET = tst_qworkspace -QT += widgets testlib -SOURCES += tst_qworkspace.cpp diff --git a/tests/auto/widgets/widgets/qworkspace/tst_qworkspace.cpp b/tests/auto/widgets/widgets/qworkspace/tst_qworkspace.cpp deleted file mode 100644 index 582f56da17..0000000000 --- a/tests/auto/widgets/widgets/qworkspace/tst_qworkspace.cpp +++ /dev/null @@ -1,676 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include -#include -#include -#include -#include - -class tst_QWorkspace : public QObject -{ - Q_OBJECT - -public: - tst_QWorkspace(); - virtual ~tst_QWorkspace(); - - -protected slots: - void activeChanged( QWidget *w ); - void accelActivated(); - -public slots: - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); -private slots: - void getSetCheck(); - void windowActivated_data(); - void windowActivated(); - void windowActivatedWithMinimize(); - void showWindows(); - void changeWindowTitle(); - void changeModified(); - void childSize(); - void fixedSize(); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) - void nativeSubWindows(); -#endif - void task206368(); - -private: - QWidget *activeWidget; - bool accelPressed; -}; - -// Testing get/set functions -void tst_QWorkspace::getSetCheck() -{ - QWorkspace obj1; - // bool QWorkspace::scrollBarsEnabled() - // void QWorkspace::setScrollBarsEnabled(bool) - obj1.setScrollBarsEnabled(false); - QCOMPARE(false, obj1.scrollBarsEnabled()); - obj1.setScrollBarsEnabled(true); - QCOMPARE(true, obj1.scrollBarsEnabled()); -} - -tst_QWorkspace::tst_QWorkspace() - : activeWidget( 0 ) -{ -} - -tst_QWorkspace::~tst_QWorkspace() -{ - -} - -// initTestCase will be executed once before the first testfunction is executed. -void tst_QWorkspace::initTestCase() -{ - -} - -// cleanupTestCase will be executed once after the last testfunction is executed. -void tst_QWorkspace::cleanupTestCase() -{ -} - -// init() will be executed immediately before each testfunction is run. -void tst_QWorkspace::init() -{ -// TODO: Add testfunction specific initialization code here. -} - -// cleanup() will be executed immediately after each testfunction is run. -void tst_QWorkspace::cleanup() -{ -// TODO: Add testfunction specific cleanup code here. -} - -void tst_QWorkspace::activeChanged( QWidget *w ) -{ - activeWidget = w; -} - -void tst_QWorkspace::windowActivated_data() -{ - // define the test elements we're going to use - QTest::addColumn("count"); - - // create a first testdata instance and fill it with data - QTest::newRow( "data0" ) << 0; - QTest::newRow( "data1" ) << 1; - QTest::newRow( "data2" ) << 2; -} - -void tst_QWorkspace::windowActivated() -{ - QMainWindow mw(0, Qt::X11BypassWindowManagerHint); - mw.menuBar(); - QWorkspace *workspace = new QWorkspace(&mw); - workspace->setObjectName("testWidget"); - mw.setCentralWidget(workspace); - QSignalSpy spy(workspace, SIGNAL(windowActivated(QWidget*))); - connect( workspace, SIGNAL(windowActivated(QWidget*)), this, SLOT(activeChanged(QWidget*)) ); - mw.show(); - qApp->setActiveWindow(&mw); - - QFETCH( int, count ); - int i; - - for ( i = 0; i < count; ++i ) { - QWidget *widget = new QWidget(workspace, 0); - widget->setAttribute(Qt::WA_DeleteOnClose); - workspace->addWindow(widget); - widget->show(); - qApp->processEvents(); - QVERIFY( activeWidget == workspace->activeWindow() ); - QCOMPARE(spy.count(), 1); - spy.clear(); - } - - QWidgetList windows = workspace->windowList(); - QCOMPARE( (int)windows.count(), count ); - - for ( i = 0; i < count; ++i ) { - QWidget *window = windows.at(i); - window->showMinimized(); - qApp->processEvents(); - QVERIFY( activeWidget == workspace->activeWindow() ); - if ( i == 1 ) - QVERIFY( activeWidget == window ); - } - - for ( i = 0; i < count; ++i ) { - QWidget *window = windows.at(i); - window->showNormal(); - qApp->processEvents(); - QVERIFY( window == activeWidget ); - QVERIFY( activeWidget == workspace->activeWindow() ); - } - spy.clear(); - - while ( workspace->activeWindow() ) { - workspace->activeWindow()->close(); - qApp->processEvents(); - QVERIFY( activeWidget == workspace->activeWindow() ); - QCOMPARE(spy.count(), 1); - spy.clear(); - } - QVERIFY(activeWidget == 0); - QVERIFY(workspace->activeWindow() == 0); - QVERIFY(workspace->windowList().count() == 0); - - { - workspace->hide(); - QWidget *widget = new QWidget(workspace); - widget->setObjectName("normal"); - widget->setAttribute(Qt::WA_DeleteOnClose); - workspace->addWindow(widget); - widget->show(); - QCOMPARE(spy.count(), 0); - workspace->show(); - QCOMPARE(spy.count(), 1); - spy.clear(); - QVERIFY( activeWidget == widget ); - widget->close(); - qApp->processEvents(); - QCOMPARE(spy.count(), 1); - spy.clear(); - QVERIFY( activeWidget == 0 ); - } - - { - workspace->hide(); - QWidget *widget = new QWidget(workspace); - widget->setObjectName("maximized"); - widget->setAttribute(Qt::WA_DeleteOnClose); - workspace->addWindow(widget); - widget->showMaximized(); - qApp->sendPostedEvents(); -#ifdef Q_OS_MAC - QEXPECT_FAIL("", "This test has never passed on Mac. QWorkspace is obsoleted -> won't fix", Abort); -#endif - QCOMPARE(spy.count(), 0); - spy.clear(); - workspace->show(); - QCOMPARE(spy.count(), 1); - spy.clear(); - QVERIFY( activeWidget == widget ); - widget->close(); - qApp->processEvents(); - QCOMPARE(spy.count(), 1); - spy.clear(); - QVERIFY( activeWidget == 0 ); - } - - { - QWidget *widget = new QWidget(workspace); - widget->setObjectName("minimized"); - widget->setAttribute(Qt::WA_DeleteOnClose); - workspace->addWindow(widget); - widget->showMinimized(); - QCOMPARE(spy.count(), 1); - spy.clear(); - QVERIFY( activeWidget == widget ); - QVERIFY(workspace->activeWindow() == widget); - widget->close(); - qApp->processEvents(); - QCOMPARE(spy.count(), 1); - spy.clear(); - QVERIFY(workspace->activeWindow() == 0); - QVERIFY( activeWidget == 0 ); - } -} -void tst_QWorkspace::windowActivatedWithMinimize() -{ - QMainWindow mw(0, Qt::X11BypassWindowManagerHint) ; - mw.menuBar(); - QWorkspace *workspace = new QWorkspace(&mw); - workspace->setObjectName("testWidget"); - mw.setCentralWidget(workspace); - QSignalSpy spy(workspace, SIGNAL(windowActivated(QWidget*))); - connect( workspace, SIGNAL(windowActivated(QWidget*)), this, SLOT(activeChanged(QWidget*)) ); - mw.show(); - qApp->setActiveWindow(&mw); - QWidget *widget = new QWidget(workspace); - widget->setObjectName("minimized1"); - widget->setAttribute(Qt::WA_DeleteOnClose); - workspace->addWindow(widget); - QWidget *widget2 = new QWidget(workspace); - widget2->setObjectName("minimized2"); - widget2->setAttribute(Qt::WA_DeleteOnClose); - workspace->addWindow(widget2); - - widget->showMinimized(); - QVERIFY( activeWidget == widget ); - widget2->showMinimized(); - QVERIFY( activeWidget == widget2 ); - - widget2->close(); - qApp->processEvents(); - QVERIFY( activeWidget == widget ); - - widget->close(); - qApp->processEvents(); - QVERIFY(workspace->activeWindow() == 0); - QVERIFY( activeWidget == 0 ); - - QVERIFY( workspace->windowList().count() == 0 ); -} - -void tst_QWorkspace::accelActivated() -{ - accelPressed = true; -} - -void tst_QWorkspace::showWindows() -{ - QWorkspace *ws = new QWorkspace( 0 ); - - QWidget *widget = 0; - ws->show(); - - widget = new QWidget(ws); - widget->setObjectName("plain1"); - widget->show(); - QVERIFY( widget->isVisible() ); - - widget = new QWidget(ws); - widget->setObjectName("maximized1"); - widget->showMaximized(); - QVERIFY( widget->isMaximized() ); - widget->showNormal(); - QVERIFY( !widget->isMaximized() ); - - widget = new QWidget(ws); - widget->setObjectName("minimized1"); - widget->showMinimized(); - QVERIFY( widget->isMinimized() ); - widget->showNormal(); - QVERIFY( !widget->isMinimized() ); - - ws->hide(); - - widget = new QWidget(ws); - widget->setObjectName("plain2"); - ws->show(); - QVERIFY( widget->isVisible() ); - - ws->hide(); - - widget = new QWidget(ws); - widget->setObjectName("maximized2"); - widget->showMaximized(); - QVERIFY( widget->isMaximized() ); - ws->show(); - QVERIFY( widget->isVisible() ); - QVERIFY( widget->isMaximized() ); - ws->hide(); - - widget = new QWidget(ws); - widget->setObjectName("minimized2"); - widget->showMinimized(); - ws->show(); - QVERIFY( widget->isMinimized() ); - ws->hide(); - - delete ws; -} - - -//#define USE_SHOW - -void tst_QWorkspace::changeWindowTitle() -{ -#ifdef Q_OS_WINCE - QSKIP( "Test fails on Windows CE due to QWorkspace state handling"); -#endif - const QString mwc( "MainWindow's Caption" ); - const QString mwc2( "MainWindow's New Caption" ); - const QString wc( "Widget's Caption" ); - const QString wc2( "Widget's New Caption" ); - - QMainWindow *mw = new QMainWindow(0, Qt::X11BypassWindowManagerHint); - mw->setWindowTitle( mwc ); - QWorkspace *ws = new QWorkspace( mw ); - mw->setCentralWidget( ws ); - - - QWidget *widget = new QWidget( ws ); - widget->setWindowTitle( wc ); - ws->addWindow(widget); - - QCOMPARE( mw->windowTitle(), mwc ); - - -#ifdef USE_SHOW - widget->showMaximized(); -#else - widget->setWindowState(Qt::WindowMaximized); -#endif - QCOMPARE( mw->windowTitle(), QString("%1 - [%2]").arg(mwc).arg(wc) ); - -#ifdef USE_SHOW - widget->showNormal(); -#else - widget->setWindowState(Qt::WindowNoState); -#endif - qApp->processEvents(); - QCOMPARE( mw->windowTitle(), mwc ); - -#ifdef USE_SHOW - widget->showMaximized(); -#else - widget->setWindowState(Qt::WindowMaximized); -#endif - qApp->processEvents(); - QCOMPARE( mw->windowTitle(), QString("%1 - [%2]").arg(mwc).arg(wc) ); - widget->setWindowTitle( wc2 ); - QCOMPARE( mw->windowTitle(), QString("%1 - [%2]").arg(mwc).arg(wc2) ); - mw->setWindowTitle( mwc2 ); - QCOMPARE( mw->windowTitle(), QString("%1 - [%2]").arg(mwc2).arg(wc2) ); - - mw->show(); - qApp->setActiveWindow(mw); - -#ifdef USE_SHOW - mw->showFullScreen(); -#else - mw->setWindowState(Qt::WindowFullScreen); -#endif - - qApp->processEvents(); - QCOMPARE( mw->windowTitle(), QString("%1 - [%2]").arg(mwc2).arg(wc2) ); -#ifdef USE_SHOW - widget->showNormal(); -#else - widget->setWindowState(Qt::WindowNoState); -#endif - qApp->processEvents(); - QCOMPARE( mw->windowTitle(), mwc2 ); -#ifdef USE_SHOW - widget->showMaximized(); -#else - widget->setWindowState(Qt::WindowMaximized); -#endif - qApp->processEvents(); - QCOMPARE( mw->windowTitle(), QString("%1 - [%2]").arg(mwc2).arg(wc2) ); - -#ifdef USE_SHOW - mw->showNormal(); -#else - mw->setWindowState(Qt::WindowNoState); -#endif - qApp->processEvents(); - QCOMPARE( mw->windowTitle(), QString("%1 - [%2]").arg(mwc2).arg(wc2) ); -#ifdef USE_SHOW - widget->showNormal(); -#else - widget->setWindowState(Qt::WindowNoState); -#endif - QCOMPARE( mw->windowTitle(), mwc2 ); - - delete mw; -} - -void tst_QWorkspace::changeModified() -{ - const QString mwc( "MainWindow's Caption" ); - const QString wc( "Widget's Caption[*]" ); - - QMainWindow *mw = new QMainWindow(0, Qt::X11BypassWindowManagerHint); - mw->setWindowTitle( mwc ); - QWorkspace *ws = new QWorkspace( mw ); - mw->setCentralWidget( ws ); - - QWidget *widget = new QWidget( ws ); - widget->setWindowTitle( wc ); - ws->addWindow(widget); - - QCOMPARE( mw->isWindowModified(), false); - QCOMPARE( widget->isWindowModified(), false); - widget->setWindowState(Qt::WindowMaximized); - QCOMPARE( mw->isWindowModified(), false); - QCOMPARE( widget->isWindowModified(), false); - - widget->setWindowState(Qt::WindowNoState); - QCOMPARE( mw->isWindowModified(), false); - QCOMPARE( widget->isWindowModified(), false); - - widget->setWindowModified(true); - QCOMPARE( mw->isWindowModified(), false); - QCOMPARE( widget->isWindowModified(), true); - widget->setWindowState(Qt::WindowMaximized); - QCOMPARE( mw->isWindowModified(), true); - QCOMPARE( widget->isWindowModified(), true); - - widget->setWindowState(Qt::WindowNoState); - QCOMPARE( mw->isWindowModified(), false); - QCOMPARE( widget->isWindowModified(), true); - - widget->setWindowState(Qt::WindowMaximized); - QCOMPARE( mw->isWindowModified(), true); - QCOMPARE( widget->isWindowModified(), true); - - widget->setWindowModified(false); - QCOMPARE( mw->isWindowModified(), false); - QCOMPARE( widget->isWindowModified(), false); - - widget->setWindowModified(true); - QCOMPARE( mw->isWindowModified(), true); - QCOMPARE( widget->isWindowModified(), true); - - widget->setWindowState(Qt::WindowNoState); - QCOMPARE( mw->isWindowModified(), false); - QCOMPARE( widget->isWindowModified(), true); - - delete mw; -} - -class MyChild : public QWidget -{ -public: - MyChild(QWidget *parent = 0, Qt::WFlags f = 0) - : QWidget(parent, f) - { - } - - QSize sizeHint() const - { - return QSize(234, 123); - } -}; - -void tst_QWorkspace::childSize() -{ - QWorkspace ws; - - MyChild *child = new MyChild(&ws); - child->show(); - QCOMPARE(child->size(), child->sizeHint()); - delete child; - - child = new MyChild(&ws); - child->setFixedSize(200, 200); - child->show(); - QCOMPARE(child->size(), child->minimumSize()); - delete child; - - child = new MyChild(&ws); - child->resize(150, 150); - child->show(); - QCOMPARE(child->size(), QSize(150,150)); - delete child; -} - -void tst_QWorkspace::fixedSize() -{ - QWorkspace *ws = new QWorkspace; - int i; - - ws->resize(500, 500); -// ws->show(); - - QSize fixed(300, 300); - for (i = 0; i < 4; ++i) { - QWidget *child = new QWidget(ws); - child->setFixedSize(fixed); - child->show(); - } - - QWidgetList windows = ws->windowList(); - for (i = 0; i < (int)windows.count(); ++i) { - QWidget *child = windows.at(i); - QCOMPARE(child->size(), fixed); - QCOMPARE(child->visibleRegion().boundingRect().size(), fixed); - } - - ws->cascade(); - ws->resize(800, 800); - for (i = 0; i < (int)windows.count(); ++i) { - QWidget *child = windows.at(i); - QCOMPARE(child->size(), fixed); - QCOMPARE(child->visibleRegion().boundingRect().size(), fixed); - } - ws->resize(500, 500); - - ws->tile(); - ws->resize(800, 800); - for (i = 0; i < (int)windows.count(); ++i) { - QWidget *child = windows.at(i); - QCOMPARE(child->size(), fixed); - QCOMPARE(child->visibleRegion().boundingRect().size(), fixed); - } - ws->resize(500, 500); - - for (i = 0; i < (int)windows.count(); ++i) { - QWidget *child = windows.at(i); - delete child; - } - - delete ws; -} - -#if defined(Q_WS_WIN) || defined(Q_WS_X11) -void tst_QWorkspace::nativeSubWindows() -{ - { // Add native widgets after show. - QWorkspace workspace; - workspace.addWindow(new QWidget); - workspace.addWindow(new QWidget); - workspace.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&workspace); -#endif - - // No native widgets. - foreach (QWidget *subWindow, workspace.windowList()) - QVERIFY(!subWindow->parentWidget()->internalWinId()); - - QWidget *nativeWidget = new QWidget; - QVERIFY(nativeWidget->winId()); // enforce native window. - workspace.addWindow(nativeWidget); - - // All the sub-windows must be native. - foreach (QWidget *subWindow, workspace.windowList()) - QVERIFY(subWindow->parentWidget()->internalWinId()); - - // Add a non-native widget. This should become native. - QWidget *subWindow = workspace.addWindow(new QWidget); - QVERIFY(subWindow->parentWidget()->internalWinId()); - } - - { // Add native widgets before show. - QWorkspace workspace; - workspace.addWindow(new QWidget); - QWidget *nativeWidget = new QWidget; - (void)nativeWidget->winId(); - workspace.addWindow(nativeWidget); - workspace.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&workspace); -#endif - - // All the sub-windows must be native. - foreach (QWidget *subWindow, workspace.windowList()) - QVERIFY(subWindow->parentWidget()->internalWinId()); - } - - { // Make a sub-window native *after* it's added to the area. - QWorkspace workspace; - workspace.addWindow(new QWidget); - workspace.addWindow(new QWidget); - workspace.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&workspace); -#endif - - QWidget *nativeSubWindow = workspace.windowList().last()->parentWidget(); - QVERIFY(!nativeSubWindow->internalWinId()); - (void)nativeSubWindow->winId(); - - // All the sub-windows should be native at this point. - foreach (QWidget *subWindow, workspace.windowList()) - QVERIFY(subWindow->parentWidget()->internalWinId()); - } -} -#endif - -void tst_QWorkspace::task206368() -{ - // Make sure the internal list of iconified windows doesn't contain dangling pointers. - QWorkspace workspace; - QWidget *child = new QWidget; - QWidget *window = workspace.addWindow(child); - workspace.show(); - child->showMinimized(); - delete window; - // This shouldn't crash. - workspace.arrangeIcons(); -} - -QTEST_MAIN(tst_QWorkspace) -#include "tst_qworkspace.moc" diff --git a/tests/auto/widgets/widgets/widgets.pro b/tests/auto/widgets/widgets/widgets.pro index e77c311cde..0497cd205e 100644 --- a/tests/auto/widgets/widgets/widgets.pro +++ b/tests/auto/widgets/widgets/widgets.pro @@ -47,7 +47,6 @@ SUBDIRS=\ qtoolbar \ qtoolbox \ qtoolbutton \ - qworkspace \ # The following tests depend on private API: !contains(QT_CONFIG, private_tests): SUBDIRS -= \ -- cgit v1.2.3 From 98c3b8a44220096a4e2a3967a4e9742c3605a5cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 22 Mar 2012 09:44:17 +0100 Subject: Add test cases to tst_QByteArray MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Internally we construct QByteArrays from QStaticByteArrays. For example moc is generating QStaticByteArray structure for every string it saves. New test cases check if a QByteArray constructed from a QStaticByteArray behaves as a not statically constructed one. Change-Id: Ia4aa9a1a5bc0209507636c683a782dda00eae85c Reviewed-by: João Abecasis --- .../corelib/tools/qbytearray/tst_qbytearray.cpp | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 13a6b3d471..63900b0c55 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -91,8 +91,14 @@ private slots: void chop_data(); void chop(); void prepend(); + void prependExtended_data(); + void prependExtended(); void append(); + void appendExtended_data(); + void appendExtended(); void insert(); + void insertExtended_data(); + void insertExtended(); void remove_data(); void remove(); void replace_data(); @@ -130,11 +136,44 @@ private slots: void byteRefDetaching() const; void reserve(); + void reserveExtended_data(); + void reserveExtended(); void movablity_data(); void movablity(); void literals(); }; +struct StaticByteArrays { + struct Standard { + QByteArrayData data; + const char string[8]; + } standard; + struct NotNullTerminated { + QByteArrayData data; + const char string[8]; + } notNullTerminated; + struct Shifted { + QByteArrayData data; + const char dummy; // added to change offset of string + const char string[8]; + } shifted; + struct ShiftedNotNullTerminated { + QByteArrayData data; + const char dummy; // added to change offset of string + const char string[8]; + } shiftedNotNullTerminated; + +} statics = {{{ Q_REFCOUNT_INITIALIZE_STATIC, /* length = */ 4, 0, 0, sizeof(QByteArrayData) }, "data"} + ,{{ Q_REFCOUNT_INITIALIZE_STATIC, /* length = */ 4, 0, 0, sizeof(QByteArrayData) }, "dataBAD"} + ,{{ Q_REFCOUNT_INITIALIZE_STATIC, /* length = */ 4, 0, 0, sizeof(QByteArrayData) + sizeof(char) }, 0, "data"} + ,{{ Q_REFCOUNT_INITIALIZE_STATIC, /* length = */ 4, 0, 0, sizeof(QByteArrayData) + sizeof(char) }, 0, "dataBAD"} + }; + +static const QStaticByteArrayData<1> &staticStandard = reinterpret_cast &>(statics.standard); +static const QStaticByteArrayData<1> &staticNotNullTerminated = reinterpret_cast &>(statics.notNullTerminated); +static const QStaticByteArrayData<1> &staticShifted = reinterpret_cast &>(statics.shifted); +static const QStaticByteArrayData<1> &staticShiftedNotNullTerminated = reinterpret_cast &>(statics.shiftedNotNullTerminated); + tst_QByteArray::tst_QByteArray() { qRegisterMetaType("qulonglong"); @@ -701,6 +740,35 @@ void tst_QByteArray::prepend() QCOMPARE(ba.prepend("\0 ", 2), QByteArray::fromRawData("\0 321foo", 8)); } +void tst_QByteArray::prependExtended_data() +{ + QTest::addColumn("array"); + QTest::newRow("literal") << QByteArray(QByteArrayLiteral("data")); + QTest::newRow("standard") << QByteArray(staticStandard); + QTest::newRow("shifted") << QByteArray(staticShifted); + QTest::newRow("notNullTerminated") << QByteArray(staticNotNullTerminated); + QTest::newRow("shiftedNotNullTerminated") << QByteArray(staticShiftedNotNullTerminated); + QTest::newRow("non static data") << QByteArray("data"); + QTest::newRow("from raw data") << QByteArray::fromRawData("data", 4); + QTest::newRow("from raw data not terminated") << QByteArray::fromRawData("dataBAD", 4); +} + +void tst_QByteArray::prependExtended() +{ + QFETCH(QByteArray, array); + + QCOMPARE(QByteArray().prepend(array), QByteArray("data")); + QCOMPARE(QByteArray("").prepend(array), QByteArray("data")); + + QCOMPARE(array.prepend((char*)0), QByteArray("data")); + QCOMPARE(array.prepend(QByteArray()), QByteArray("data")); + QCOMPARE(array.prepend("1"), QByteArray("1data")); + QCOMPARE(array.prepend(QByteArray("2")), QByteArray("21data")); + QCOMPARE(array.prepend('3'), QByteArray("321data")); + QCOMPARE(array.prepend("\0 ", 2), QByteArray::fromRawData("\0 321data", 9)); + QCOMPARE(array.size(), 9); +} + void tst_QByteArray::append() { QByteArray ba("foo"); @@ -714,6 +782,28 @@ void tst_QByteArray::append() QCOMPARE(ba.size(), 7); } +void tst_QByteArray::appendExtended_data() +{ + prependExtended_data(); +} + +void tst_QByteArray::appendExtended() +{ + QFETCH(QByteArray, array); + + QCOMPARE(QByteArray().append(array), QByteArray("data")); + QCOMPARE(QByteArray("").append(array), QByteArray("data")); + + QCOMPARE(array.append((char*)0), QByteArray("data")); + QCOMPARE(array.append(QByteArray()), QByteArray("data")); + QCOMPARE(array.append("1"), QByteArray("data1")); + QCOMPARE(array.append(QByteArray("2")), QByteArray("data12")); + QCOMPARE(array.append('3'), QByteArray("data123")); + QCOMPARE(array.append("\0"), QByteArray("data123")); + QCOMPARE(array.append("\0", 1), QByteArray::fromRawData("data123\0", 8)); + QCOMPARE(array.size(), 8); +} + void tst_QByteArray::insert() { QByteArray ba("Meal"); @@ -736,6 +826,18 @@ void tst_QByteArray::insert() QCOMPARE(ba.size(), 5); } +void tst_QByteArray::insertExtended_data() +{ + prependExtended_data(); +} + +void tst_QByteArray::insertExtended() +{ + QFETCH(QByteArray, array); + QCOMPARE(array.insert(1, "i"), QByteArray("diata")); + QCOMPARE(array.size(), 5); +} + void tst_QByteArray::remove_data() { QTest::addColumn("src"); @@ -1456,6 +1558,23 @@ void tst_QByteArray::repeated_data() const << QByteArray(("abc")) << QByteArray(("abcabcabcabc")) << 4; + + QTest::newRow("static not null terminated") + << QByteArray(staticNotNullTerminated) + << QByteArray("datadatadatadata") + << 4; + QTest::newRow("static standard") + << QByteArray(staticStandard) + << QByteArray("datadatadatadata") + << 4; + QTest::newRow("static shifted not null terminated") + << QByteArray(staticShiftedNotNullTerminated) + << QByteArray("datadatadatadata") + << 4; + QTest::newRow("static shifted") + << QByteArray(staticShifted) + << QByteArray("datadatadatadata") + << 4; } void tst_QByteArray::byteRefDetaching() const @@ -1508,6 +1627,22 @@ void tst_QByteArray::reserve() nil2.reserve(0); } +void tst_QByteArray::reserveExtended_data() +{ + prependExtended_data(); +} + +void tst_QByteArray::reserveExtended() +{ + QFETCH(QByteArray, array); + array.reserve(1024); + QVERIFY(array.capacity() == 1024); + QCOMPARE(array, QByteArray("data")); + array.squeeze(); + QCOMPARE(array, QByteArray("data")); + QCOMPARE(array.capacity(), array.size()); +} + void tst_QByteArray::movablity_data() { QTest::addColumn("array"); @@ -1518,6 +1653,8 @@ void tst_QByteArray::movablity_data() QTest::newRow("empty") << QByteArray(""); QTest::newRow("null") << QByteArray(); QTest::newRow("sss") << QByteArray(3, 's'); + + prependExtended_data(); } void tst_QByteArray::movablity() -- cgit v1.2.3 From accfdc85e5cb1816b3eda02ec8d37474259c247e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 12 Mar 2012 17:14:48 +0100 Subject: Fallback implementation of Q_ALIGNOF For all practical purposes, the fallback introduced here returns the desired value. Having a fallback enables unconditional use of Q_ALIGNOF. For compilers that provide native support for it, Q_ALIGNOF is otherwise #defined in qcompilerdetection.h. Change-Id: Ie148ca8936cbbf8b80fe87771a14797c39a9d30c Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- tests/auto/corelib/global/qglobal/tst_qglobal.cpp | 111 +++++++++++++++++++++ .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 34 +------ 2 files changed, 115 insertions(+), 30 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index b3d76bef8a..529bafaa7a 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -56,6 +56,7 @@ private slots: void qstaticassert(); void qConstructorFunction(); void isEnum(); + void qAlignOf(); }; void tst_QGlobal::qIsNull() @@ -415,5 +416,115 @@ void tst_QGlobal::isEnum() #undef IS_ENUM_FALSE } +struct Empty {}; +template struct AlignmentInStruct { T dummy; }; + +typedef int (*fun) (); +typedef int (Empty::*memFun) (); + +#define TEST_AlignOf(type, alignment) \ + do { \ + TEST_AlignOf_impl(type, alignment); \ + \ + TEST_AlignOf_impl(type &, alignment); \ + TEST_AlignOf_RValueRef(type &&, alignment); \ + \ + TEST_AlignOf_impl(type [5], alignment); \ + TEST_AlignOf_impl(type (&) [5], alignment); \ + \ + TEST_AlignOf_impl(AlignmentInStruct, alignment); \ + \ + /* Some internal sanity validation, just for fun */ \ + TEST_AlignOf_impl(AlignmentInStruct, alignment); \ + TEST_AlignOf_impl(AlignmentInStruct, Q_ALIGNOF(void *)); \ + TEST_AlignOf_impl(AlignmentInStruct, \ + Q_ALIGNOF(void *)); \ + TEST_AlignOf_RValueRef(AlignmentInStruct, \ + Q_ALIGNOF(void *)); \ + } while (false) \ + /**/ + +#ifdef Q_COMPILER_RVALUE_REFS +#define TEST_AlignOf_RValueRef(type, alignment) \ + TEST_AlignOf_impl(type, alignment) +#else +#define TEST_AlignOf_RValueRef(type, alignment) do {} while (false) +#endif + +#define TEST_AlignOf_impl(type, alignment) \ + do { \ + QCOMPARE(Q_ALIGNOF(type), size_t(alignment)); \ + /* Compare to native operator for compilers that support it, + otherwise... erm... check consistency! :-) */ \ + QCOMPARE(QT_EMULATED_ALIGNOF(type), Q_ALIGNOF(type)); \ + } while (false) + /**/ + +void tst_QGlobal::qAlignOf() +{ + // Built-in types, except 64-bit integers and double + TEST_AlignOf(char, 1); + TEST_AlignOf(signed char, 1); + TEST_AlignOf(unsigned char, 1); + TEST_AlignOf(qint8, 1); + TEST_AlignOf(quint8, 1); + TEST_AlignOf(qint16, 2); + TEST_AlignOf(quint16, 2); + TEST_AlignOf(qint32, 4); + TEST_AlignOf(quint32, 4); + TEST_AlignOf(void *, sizeof(void *)); + + // Depends on platform and compiler, disabling test for now + // TEST_AlignOf(long double, 16); + + // Empty struct + TEST_AlignOf(Empty, 1); + + // Function pointers + TEST_AlignOf(fun, Q_ALIGNOF(void *)); + TEST_AlignOf(memFun, Q_ALIGNOF(void *)); + + + // 64-bit integers and double + TEST_AlignOf_impl(qint64, 8); + TEST_AlignOf_impl(quint64, 8); + TEST_AlignOf_impl(double, 8); + + TEST_AlignOf_impl(qint64 &, 8); + TEST_AlignOf_impl(quint64 &, 8); + TEST_AlignOf_impl(double &, 8); + + TEST_AlignOf_RValueRef(qint64 &&, 8); + TEST_AlignOf_RValueRef(quint64 &&, 8); + TEST_AlignOf_RValueRef(double &&, 8); + + // 32-bit x86 ABI idiosyncrasies +#if defined(Q_PROCESSOR_X86_32) && !defined(Q_OS_WIN) + TEST_AlignOf_impl(AlignmentInStruct, 4); +#else + TEST_AlignOf_impl(AlignmentInStruct, 8); +#endif + + TEST_AlignOf_impl(AlignmentInStruct, Q_ALIGNOF(AlignmentInStruct)); + TEST_AlignOf_impl(AlignmentInStruct, Q_ALIGNOF(AlignmentInStruct)); + + // 32-bit x86 ABI, Clang disagrees with gcc +#if !defined(Q_PROCESSOR_X86_32) || !defined(Q_CC_CLANG) + TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(qint64)); +#else + TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(AlignmentInStruct)); +#endif + + TEST_AlignOf_impl(qint64 (&) [5], Q_ALIGNOF(qint64 [5])); + TEST_AlignOf_impl(quint64 [5], Q_ALIGNOF(quint64 [5])); + TEST_AlignOf_impl(quint64 (&) [5], Q_ALIGNOF(quint64 [5])); + TEST_AlignOf_impl(double [5], Q_ALIGNOF(double [5])); + TEST_AlignOf_impl(double (&) [5], Q_ALIGNOF(double [5])); +} + +#undef TEST_AlignOf +#undef TEST_AlignOf_RValueRef +#undef TEST_AlignOf_impl + QTEST_MAIN(tst_QGlobal) #include "tst_qglobal.moc" diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 72ad3080d6..9f4944b44b 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -868,41 +868,15 @@ void tst_QMetaType::construct_data() create_data(); } -#ifndef Q_ALIGNOF -template -struct RoundToNextHighestPowerOfTwo -{ -private: - enum { V1 = N-1 }; - enum { V2 = V1 | (V1 >> 1) }; - enum { V3 = V2 | (V2 >> 2) }; - enum { V4 = V3 | (V3 >> 4) }; - enum { V5 = V4 | (V4 >> 8) }; - enum { V6 = V5 | (V5 >> 16) }; -public: - enum { Value = V6 + 1 }; -}; -#endif - -template -struct TypeAlignment -{ -#ifdef Q_ALIGNOF - enum { Value = Q_ALIGNOF(T) }; -#else - enum { Value = RoundToNextHighestPowerOfTwo::Value }; -#endif -}; - template static void testConstructHelper() { typedef typename MetaEnumToType::Type Type; QMetaType info(ID); int size = info.sizeOf(); - void *storage1 = qMallocAligned(size, TypeAlignment::Value); + void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type)); void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0); - void *storage2 = qMallocAligned(size, TypeAlignment::Value); + void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type)); void *actual2 = info.construct(storage2, /*copy=*/0); QCOMPARE(actual1, storage1); QCOMPARE(actual2, storage2); @@ -971,9 +945,9 @@ static void testConstructCopyHelper() QMetaType info(ID); int size = QMetaType::sizeOf(ID); QCOMPARE(info.sizeOf(), size); - void *storage1 = qMallocAligned(size, TypeAlignment::Value); + void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type)); void *actual1 = QMetaType::construct(ID, storage1, expected); - void *storage2 = qMallocAligned(size, TypeAlignment::Value); + void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type)); void *actual2 = info.construct(storage2, expected); QCOMPARE(actual1, storage1); QCOMPARE(actual2, storage2); -- cgit v1.2.3 From d8ddc8ae895e86decf55dd58a0e78f5a01c9a968 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Sep 2011 19:19:13 +0200 Subject: Add the Q_CORE_EXPORT macros to unit-test-exported code Change-Id: If21658bd5e4af0fdcc403b054fc1b8f46b5fcfb0 Reviewed-by: David Faure --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 3bff330db2..a1b7dbca0f 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2421,8 +2421,8 @@ void tst_QUrl::nameprep_testsuite_data() #ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE -extern void qt_nameprep(QString *source, int from); -extern bool qt_check_std3rules(const QChar *, int); +Q_CORE_EXPORT extern void qt_nameprep(QString *source, int from); +Q_CORE_EXPORT extern bool qt_check_std3rules(const QChar *, int); QT_END_NAMESPACE #endif -- cgit v1.2.3 From 552e162a67a1afcdc4e3e344100abaa6a69ab918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 22 Mar 2012 13:07:07 +0100 Subject: Update QLocale data from CLDR v1.8.1 to CLDR v1.9.1 Change-Id: Ic84bbc82b364b92605c1bba64b6ec815bff970cb Reviewed-by: Lars Knoll --- tests/auto/corelib/tools/qlocale/tst_qlocale.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index b3b573c64b..761d3ec928 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -1749,7 +1749,7 @@ void tst_QLocale::dayName_data() QTest::newRow("C narrow") << QString("C") << QString("7") << 7 << QLocale::NarrowFormat; QTest::newRow("ru_RU long") << QString("ru_RU") << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320\265\321\201\320\265\320\275\321\214\320\265") << 7 << QLocale::LongFormat; - QTest::newRow("ru_RU short") << QString("ru_RU") << QString::fromUtf8("\320\222\321\201") << 7 << QLocale::ShortFormat; + QTest::newRow("ru_RU short") << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat; QTest::newRow("ru_RU narrow") << QString("ru_RU") << QString::fromUtf8("\320\222") << 7 << QLocale::NarrowFormat; } -- cgit v1.2.3 From fe778b94bd58c12949d763f428d214e8c16d144e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 21 Mar 2012 18:09:09 +0100 Subject: Enable endianness conversions on q(u)int8 Lack of support for these types is not a real issue as endian conversions on byte-sized types are no-ops. Still, the conversions are useful as they facilitate writing of generic code. They can also be used explicitly as a way to document in code an endian-specific binary format: uchar *data; quint8 tag = qFromLittleEndian(data++); quint32 size = qFromLittleEndian(data); This commit also adds a test for functions documented in the QtEndian header. Change-Id: I2f6c876ce89d2adb8c03a1c8a25921d225bf6f92 Reviewed-by: Thiago Macieira --- tests/auto/corelib/global/global.pro | 3 +- tests/auto/corelib/global/qtendian/qtendian.pro | 4 + .../auto/corelib/global/qtendian/tst_qtendian.cpp | 146 +++++++++++++++++++++ 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 tests/auto/corelib/global/qtendian/qtendian.pro create mode 100644 tests/auto/corelib/global/qtendian/tst_qtendian.cpp (limited to 'tests') diff --git a/tests/auto/corelib/global/global.pro b/tests/auto/corelib/global/global.pro index d4293a896c..5489b8330d 100644 --- a/tests/auto/corelib/global/global.pro +++ b/tests/auto/corelib/global/global.pro @@ -6,4 +6,5 @@ SUBDIRS=\ qglobal \ qnumeric \ qrand \ - qlogging + qlogging \ + qtendian diff --git a/tests/auto/corelib/global/qtendian/qtendian.pro b/tests/auto/corelib/global/qtendian/qtendian.pro new file mode 100644 index 0000000000..caad0fc764 --- /dev/null +++ b/tests/auto/corelib/global/qtendian/qtendian.pro @@ -0,0 +1,4 @@ +CONFIG += testcase parallel_test +TARGET = tst_qtendian +QT = core testlib +SOURCES = tst_qtendian.cpp diff --git a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp new file mode 100644 index 0000000000..002060b0ef --- /dev/null +++ b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include + + +class tst_QtEndian: public QObject +{ + Q_OBJECT + +private slots: + void fromBigEndian(); + void fromLittleEndian(); + + void toBigEndian(); + void toLittleEndian(); +}; + +struct TestData +{ + quint64 data64; + quint32 data32; + quint16 data16; + quint8 data8; + + quint8 reserved; +}; + +union RawTestData +{ + uchar rawData[sizeof(TestData)]; + TestData data; +}; + +static const TestData inNativeEndian = { 0x0123456789abcdef, 0x00c0ffee, 0xcafe, 0xcf, '\0' }; +static const RawTestData inBigEndian = { "\x01\x23\x45\x67\x89\xab\xcd\xef" "\x00\xc0\xff\xee" "\xca\xfe" "\xcf" }; +static const RawTestData inLittleEndian = { "\xef\xcd\xab\x89\x67\x45\x23\x01" "\xee\xff\xc0\x00" "\xfe\xca" "\xcf" }; + +#define EXPAND_ENDIAN_TEST(endian) \ + do { \ + /* Unsigned tests */ \ + ENDIAN_TEST(endian, quint, 64); \ + ENDIAN_TEST(endian, quint, 32); \ + ENDIAN_TEST(endian, quint, 16); \ + ENDIAN_TEST(endian, quint, 8); \ + \ + /* Signed tests */ \ + ENDIAN_TEST(endian, qint, 64); \ + ENDIAN_TEST(endian, qint, 32); \ + ENDIAN_TEST(endian, qint, 16); \ + ENDIAN_TEST(endian, qint, 8); \ + } while (false) \ + /**/ + +#define ENDIAN_TEST(endian, type, size) \ + do { \ + QCOMPARE(qFrom ## endian ## Endian( \ + (type ## size)(in ## endian ## Endian.data.data ## size)), \ + (type ## size)(inNativeEndian.data ## size)); \ + QCOMPARE(qFrom ## endian ## Endian( \ + in ## endian ## Endian.rawData + offsetof(TestData, data ## size)), \ + (type ## size)(inNativeEndian.data ## size)); \ + } while (false) \ + /**/ + +void tst_QtEndian::fromBigEndian() +{ + EXPAND_ENDIAN_TEST(Big); +} + +void tst_QtEndian::fromLittleEndian() +{ + EXPAND_ENDIAN_TEST(Little); +} + +#undef ENDIAN_TEST + + +#define ENDIAN_TEST(endian, type, size) \ + do { \ + QCOMPARE(qTo ## endian ## Endian( \ + (type ## size)(inNativeEndian.data ## size)), \ + (type ## size)(in ## endian ## Endian.data.data ## size)); \ + \ + RawTestData test; \ + qTo ## endian ## Endian( \ + (type ## size)(inNativeEndian.data ## size), \ + test.rawData + offsetof(TestData, data ## size)); \ + QCOMPARE(test.data.data ## size, in ## endian ## Endian.data.data ## size ); \ + } while (false) \ + /**/ + +void tst_QtEndian::toBigEndian() +{ + EXPAND_ENDIAN_TEST(Big); +} + +void tst_QtEndian::toLittleEndian() +{ + EXPAND_ENDIAN_TEST(Little); +} + +#undef ENDIAN_TEST + +QTEST_MAIN(tst_QtEndian) +#include "tst_qtendian.moc" -- cgit v1.2.3 From 2e92714090f19c9a1f47565e8b6eecceb0a50425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 22 Mar 2012 01:38:48 +0100 Subject: Make QTranslator testcase independent of Widgets There isn't really a need for the dependency as LanguageChange events can be caught in QObject::eventFilter, directly. Change-Id: I39778fbe1663924d97705b514ae399cfd3749776 Reviewed-by: Oswald Buddenhagen --- tests/auto/corelib/kernel/qtranslator/qtranslator.pro | 4 ++-- tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro index c644f83a22..41c3dea924 100644 --- a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro +++ b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro @@ -1,6 +1,6 @@ -CONFIG += testcase +CONFIG += testcase parallel_test TARGET = tst_qtranslator -QT += widgets testlib +QT = core testlib SOURCES = tst_qtranslator.cpp RESOURCES += qtranslator.qrc diff --git a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp index 033d10001f..4689fc432a 100644 --- a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp +++ b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp @@ -40,18 +40,17 @@ ****************************************************************************/ #include -#include #include #include -class tst_QTranslator : public QWidget +class tst_QTranslator : public QObject { Q_OBJECT public: tst_QTranslator(); protected: - bool event(QEvent *event); + bool eventFilter(QObject *obj, QEvent *event); private slots: void initTestCase(); @@ -71,8 +70,7 @@ private: tst_QTranslator::tst_QTranslator() : languageChangeEventCounter(0) { - show(); - hide(); + qApp->installEventFilter(this); } void tst_QTranslator::initTestCase() @@ -83,11 +81,11 @@ void tst_QTranslator::initTestCase() QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir)); } -bool tst_QTranslator::event(QEvent *event) +bool tst_QTranslator::eventFilter(QObject *, QEvent *event) { if (event->type() == QEvent::LanguageChange) ++languageChangeEventCounter; - return QWidget::event(event); + return false; } void tst_QTranslator::load() -- cgit v1.2.3 From c3e1abad4e141e6e9d876e5cff194c473a2654eb Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 21 Mar 2012 20:41:57 +0100 Subject: Add USER properties to QDateEdit and QTimeEdit. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both classes had such components before, but there were issues with the NOTIFY signal not being in the same class as the Q_PROPERTY. This patch solves that problem by using a signal of a different name. Task-number: QTBUG-15731 Change-Id: Ibc7ce4dba8a6b88c05d62a90e14d0101c5cd3082 Reviewed-by: Olivier Goffart Reviewed-by: Thorbjørn Lund Martsum --- .../auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index 2b52f5f234..497cdfdeee 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -780,6 +780,9 @@ void tst_QItemDelegate::dateTimeEditor() QTimeEdit *timeEditor = qFindChild(widget.viewport()); QVERIFY(timeEditor); QCOMPARE(timeEditor->time(), time); + // The data must actually be different in order for the model + // to be updated. + timeEditor->setTime(time.addSecs(60)); widget.clearFocus(); qApp->setActiveWindow(&widget); @@ -791,6 +794,7 @@ void tst_QItemDelegate::dateTimeEditor() QDateEdit *dateEditor = qFindChild(widget.viewport()); QVERIFY(dateEditor); QCOMPARE(dateEditor->date(), date); + dateEditor->setDate(date.addDays(60)); widget.clearFocus(); widget.setFocus(); @@ -806,6 +810,12 @@ void tst_QItemDelegate::dateTimeEditor() QVERIFY(dateTimeEditor); QCOMPARE(dateTimeEditor->date(), date); QCOMPARE(dateTimeEditor->time(), time); + dateTimeEditor->setTime(time.addSecs(600)); + widget.clearFocus(); + + QVERIFY(item1->data(Qt::EditRole).userType() == QMetaType::QTime); + QVERIFY(item2->data(Qt::EditRole).userType() == QMetaType::QDate); + QVERIFY(item3->data(Qt::EditRole).userType() == QMetaType::QDateTime); } void tst_QItemDelegate::decoration_data() -- cgit v1.2.3 From dc6a1d186eb2060f549ef55b74711b54ed66ade7 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 21 Mar 2012 20:42:50 +0100 Subject: Remove workaround for QComboBox not having a USER property. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QComboBox does in fact have a user property since b1b87a73012342dc1619a8e907ea9954d59ca564. Change-Id: I24eb2ef267cec5d8a9f7348954b703fa6df04fa5 Reviewed-by: Girish Ramakrishnan Reviewed-by: Thorbjørn Lund Martsum Reviewed-by: David Faure --- .../itemviews/qitemdelegate/tst_qitemdelegate.cpp | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index 497cdfdeee..2ee166c4a2 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -228,6 +229,7 @@ private slots: void editorEvent(); void enterKey_data(); void enterKey(); + void comboBox(); void task257859_finalizeEdit(); void QTBUG4435_keepSelectionOnCheck(); @@ -1205,6 +1207,35 @@ void tst_QItemDelegate::QTBUG4435_keepSelectionOnCheck() QCOMPARE(model.item(0)->checkState(), Qt::Checked); } +void tst_QItemDelegate::comboBox() +{ + QTableWidgetItem *item1 = new QTableWidgetItem; + item1->setData(Qt::DisplayRole, true); + + QTableWidget widget(1, 1); + widget.setItem(0, 0, item1); + widget.show(); + + widget.editItem(item1); + + QTestEventLoop::instance().enterLoop(1); + + QComboBox *boolEditor = qFindChild(widget.viewport()); + QVERIFY(boolEditor); + QCOMPARE(boolEditor->currentIndex(), 1); // True is selected initially. + // The data must actually be different in order for the model + // to be updated. + boolEditor->setCurrentIndex(0); + QCOMPARE(boolEditor->currentIndex(), 0); // Changed to false. + + widget.clearFocus(); + widget.setFocus(); + + QVariant data = item1->data(Qt::EditRole); + QCOMPARE(data.userType(), (int)QMetaType::Bool); + QCOMPARE(data.toBool(), false); +} + // ### _not_ covered: -- cgit v1.2.3 From 2cf466312bce5fcb48d620c98ca81b2c1a40f674 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 31 Jul 2011 19:41:18 -0300 Subject: Unit-test the additional QBasicAtomicXXX expansions Test that they do expand properly and don't produce errors. This is templated code, so it doesn't get tested fully unless we instantiate them. Also check that the alignments are correct. Change-Id: I2a8ee2165167f54b652b4227411e209850974b8e Reviewed-by: Bradley T. Hughes --- .../corelib/thread/qatomicint/tst_qatomicint.cpp | 110 +++++++++++++++++++-- .../thread/qatomicpointer/tst_qatomicpointer.cpp | 10 ++ 2 files changed, 114 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp index a6d38ca078..c2dc8a4cc6 100644 --- a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp +++ b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp @@ -52,6 +52,7 @@ class tst_QAtomicInt : public QObject private slots: void warningFree(); + void alignment(); // QAtomicInt members void constructor_data(); @@ -92,33 +93,101 @@ private: static void warningFreeHelper(); }; -void tst_QAtomicInt::warningFreeHelper() +template +static inline void assemblyMarker(void *ptr = 0) { - qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only."); + puts((char *)ptr + I); +} - QBasicAtomicInt i = Q_BASIC_ATOMIC_INITIALIZER(0); +QT_BEGIN_NAMESPACE +template class QBasicAtomicInteger; // even if it this class isn't supported +QT_END_NAMESPACE - int expectedValue = 0; - int newValue = 0; - int valueToAdd = 0; +template +static void warningFreeHelperTemplate() +{ + T expectedValue = 0; + T newValue = 0; + T valueToAdd = 0; + + // the marker calls are here only to provide a divider for + // those reading the assembly output + assemblyMarker<0>(); + Atomic i = Q_BASIC_ATOMIC_INITIALIZER(0); + printf("%d\n", int(i.loadAcquire())); + assemblyMarker<1>(&i); + + // the loads sometimes generate no assembly output + i.load(); + assemblyMarker<11>(&i); + i.loadAcquire(); + assemblyMarker<12>(&i); + + i.store(newValue); + assemblyMarker<21>(&i); + i.storeRelease(newValue); + assemblyMarker<22>(&i); i.ref(); + assemblyMarker<31>(&i); i.deref(); + assemblyMarker<32>(&i); i.testAndSetRelaxed(expectedValue, newValue); + assemblyMarker<41>(&i); i.testAndSetAcquire(expectedValue, newValue); + assemblyMarker<42>(&i); i.testAndSetRelease(expectedValue, newValue); + assemblyMarker<43>(&i); i.testAndSetOrdered(expectedValue, newValue); + assemblyMarker<44>(&i); i.fetchAndStoreRelaxed(newValue); + assemblyMarker<51>(&i); i.fetchAndStoreAcquire(newValue); + assemblyMarker<52>(&i); i.fetchAndStoreRelease(newValue); + assemblyMarker<53>(&i); i.fetchAndStoreOrdered(newValue); + assemblyMarker<54>(&i); i.fetchAndAddRelaxed(valueToAdd); + assemblyMarker<61>(&i); i.fetchAndAddAcquire(valueToAdd); + assemblyMarker<62>(&i); i.fetchAndAddRelease(valueToAdd); + assemblyMarker<63>(&i); i.fetchAndAddOrdered(valueToAdd); + assemblyMarker<64>(&i); +} + +void tst_QAtomicInt::warningFreeHelper() +{ + qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only."); + warningFreeHelperTemplate(); + +#ifdef Q_ATOMIC_INT32_IS_SUPPORTED + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); +#endif + +#ifdef Q_ATOMIC_INT16_IS_SUPPORTED + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); +#endif + +#ifdef Q_ATOMIC_INT8_IS_SUPPORTED + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); +#endif + +#ifdef Q_ATOMIC_INT64_IS_SUPPORTED +#if !defined(__i386__) || (defined(Q_CC_GNU) && defined(__OPTIMIZE__)) + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); +#endif +#endif } void tst_QAtomicInt::warningFree() @@ -130,6 +199,35 @@ void tst_QAtomicInt::warningFree() (void)foo; } +template struct TypeInStruct { T type; }; + +void tst_QAtomicInt::alignment() +{ +#ifdef Q_ALIGNOF + // this will cause a build error if the alignment isn't the same + char dummy1[Q_ALIGNOF(QBasicAtomicInt) == Q_ALIGNOF(TypeInStruct) ? 1 : -1]; + char dummy2[Q_ALIGNOF(QAtomicInt) == Q_ALIGNOF(TypeInStruct) ? 1 : -1]; + (void)dummy1; (void)dummy2; + +#ifdef Q_ATOMIC_INT32_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger), Q_ALIGNOF(TypeInStruct)); +#endif + +#ifdef Q_ATOMIC_INT16_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger), Q_ALIGNOF(TypeInStruct)); +#endif + +#ifdef Q_ATOMIC_INT8_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger), Q_ALIGNOF(TypeInStruct)); +#endif + +#ifdef Q_ATOMIC_INT64_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger), Q_ALIGNOF(TypeInStruct)); +#endif + +#endif +} + void tst_QAtomicInt::constructor_data() { QTest::addColumn("value"); diff --git a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp index a8f7e037d0..ee6460d35c 100644 --- a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp +++ b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp @@ -49,6 +49,7 @@ class tst_QAtomicPointer : public QObject Q_OBJECT private slots: void warningFree(); + void alignment(); void constructor(); void copy_constructor(); @@ -114,6 +115,15 @@ void tst_QAtomicPointer::warningFree() (void)foo; } +void tst_QAtomicPointer::alignment() +{ +#ifdef Q_ALIGNOF + // this will cause a build error if the alignment isn't the same + char dummy[Q_ALIGNOF(QBasicAtomicPointer) == Q_ALIGNOF(void*) ? 1 : -1]; + (void)dummy; +#endif +} + void tst_QAtomicPointer::constructor() { void *one = this; -- cgit v1.2.3 From bc4f74f5863fc0d6cad891632019c37a9e38617d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 27 Mar 2012 12:14:14 -0300 Subject: Don't hardcode the order of elements in QHashes Instead use QMap if we want a stable order. Task-number: QTBUG-24995 Change-Id: I93f643df236f5078768f539615fa47163e5262e8 Reviewed-by: Giuseppe D'Angelo Reviewed-by: Stephen Kelly --- tests/auto/dbus/qdbusmarshall/common.h | 41 +++++++--------------- .../auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp | 6 ++-- 2 files changed, 15 insertions(+), 32 deletions(-) (limited to 'tests') diff --git a/tests/auto/dbus/qdbusmarshall/common.h b/tests/auto/dbus/qdbusmarshall/common.h index 025641531d..3efb8de499 100644 --- a/tests/auto/dbus/qdbusmarshall/common.h +++ b/tests/auto/dbus/qdbusmarshall/common.h @@ -85,8 +85,8 @@ Q_DECLARE_METATYPE(QList >) typedef QMap IntStringMap; typedef QMap StringStringMap; typedef QMap ObjectPathStringMap; -typedef QHash LLDateTimeMap; -typedef QHash SignatureStringMap; +typedef QMap LLDateTimeMap; +typedef QMap SignatureStringMap; Q_DECLARE_METATYPE(IntStringMap) Q_DECLARE_METATYPE(StringStringMap) Q_DECLARE_METATYPE(ObjectPathStringMap) @@ -209,8 +209,8 @@ void commonInit() qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); - qDBusRegisterMetaType >(); - qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); @@ -420,23 +420,6 @@ bool compare(const QMap &m1, const QMap &m2) return true; } -template -bool compare(const QHash &m1, const QHash &m2) -{ - if (m1.count() != m2.size()) - return false; - typename QHash::ConstIterator i1 = m1.constBegin(); - typename QHash::ConstIterator end = m1.constEnd(); - for ( ; i1 != end; ++i1) { - typename QHash::ConstIterator i2 = m2.find(i1.key()); - if (i2 == m2.constEnd()) - return false; - if (!compare(*i1, *i2)) - return false; - } - return true; -} - template inline bool compare(const QDBusArgument &arg, const QVariant &v2, T * = 0) { @@ -538,10 +521,10 @@ bool compareToArgument(const QDBusArgument &arg, const QVariant &v2) return compare >(arg, v2); else if (id == qMetaTypeId >()) return compare >(arg, v2); - else if (id == qMetaTypeId >()) - return compare >(arg, v2); - else if (id == qMetaTypeId >()) - return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); + else if (id == qMetaTypeId >()) + return compare >(arg, v2); else if (id == qMetaTypeId >()) return compare >(arg, v2); @@ -703,11 +686,11 @@ template<> bool compare(const QVariant &v1, const QVariant &v2) else if (id == qMetaTypeId >()) return compare(qvariant_cast >(v1), qvariant_cast >(v2)); - else if (id == qMetaTypeId >()) // lldtmap - return compare(qvariant_cast >(v1), qvariant_cast >(v2)); + else if (id == qMetaTypeId >()) // lldtmap + return compare(qvariant_cast >(v1), qvariant_cast >(v2)); - else if (id == qMetaTypeId >()) - return compare(qvariant_cast >(v1), qvariant_cast >(v2)); + else if (id == qMetaTypeId >()) + return compare(qvariant_cast >(v1), qvariant_cast >(v2)); else if (id == qMetaTypeId()) // (is) return qvariant_cast(v1) == qvariant_cast(v2); diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index e8f5b255ab..13f3bd2060 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -502,7 +502,7 @@ void tst_QDBusMarshall::sendMaps_data() QTest::newRow("os-map") << qVariantFromValue(osmap) << "a{os}" << "[Argument: a{os} {[ObjectPath: /] = \"root\", [ObjectPath: /bar/baz] = \"bar and baz\", [ObjectPath: /foo] = \"foo\"}]"; - QHash gsmap; + QMap gsmap; QTest::newRow("empty-gs-map") << qVariantFromValue(gsmap) << "a{gs}" << "[Argument: a{gs} {}]"; gsmap[QDBusSignature("i")] = "int32"; @@ -601,7 +601,7 @@ void tst_QDBusMarshall::sendComplex_data() QTest::newRow("datetimelist") << qVariantFromValue(dtlist) << "a((iii)(iiii)i)" << "[Argument: a((iii)(iiii)i) {[Argument: ((iii)(iiii)i) [Argument: (iii) 0, 0, 0], [Argument: (iiii) -1, -1, -1, -1], 0], [Argument: ((iii)(iiii)i) [Argument: (iii) 1977, 9, 13], [Argument: (iiii) 0, 0, 0, 0], 0], [Argument: ((iii)(iiii)i) [Argument: (iii) 2006, 6, 18], [Argument: (iiii) 13, 14, 0, 0], 0]}]"; - QHash lldtmap; + QMap lldtmap; QTest::newRow("empty-lldtmap") << qVariantFromValue(lldtmap) << "a{x((iii)(iiii)i)}" << "[Argument: a{x((iii)(iiii)i)} {}]"; lldtmap[0] = QDateTime(); @@ -621,7 +621,7 @@ void tst_QDBusMarshall::sendComplex_data() ssmap["c"] = "b"; ssmap["b"] = "c"; - QHash gsmap; + QMap gsmap; gsmap[QDBusSignature("i")] = "int32"; gsmap[QDBusSignature("s")] = "string"; gsmap[QDBusSignature("a{gs}")] = "array of dict_entry of (signature, string)"; -- cgit v1.2.3 From 9596f591b694babfa9a4afcee47b66ed318fee39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 22 Mar 2012 01:19:34 +0100 Subject: Fix loop conditions, after warnings from clang tst_qmap.cpp:697:43: warning: inequality comparison result unused tst_qmap.cpp:717:50: warning: inequality comparison result unused Change-Id: I300f9e10b7748306b99c3c8c38f3cc2661a569ad Reviewed-by: Lars Knoll --- tests/auto/corelib/tools/qmap/tst_qmap.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index ac75c0e5bd..a28ea94aa5 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -694,8 +694,9 @@ void tst_QMap::iterators() stlIt--; QVERIFY(stlIt.value() == "Teststring 3"); - for(stlIt = map.begin(), i = 1; stlIt != map.end(), i < 100; ++stlIt, ++i) + for(stlIt = map.begin(), i = 1; stlIt != map.end(); ++stlIt, ++i) QVERIFY(stlIt.value() == testString.arg(i)); + QCOMPARE(i, 100); //STL-Style const-iterators @@ -714,8 +715,9 @@ void tst_QMap::iterators() cstlIt--; QVERIFY(cstlIt.value() == "Teststring 3"); - for(cstlIt = map.constBegin(), i = 1; cstlIt != map.constEnd(), i < 100; ++cstlIt, ++i) + for(cstlIt = map.constBegin(), i = 1; cstlIt != map.constEnd(); ++cstlIt, ++i) QVERIFY(cstlIt.value() == testString.arg(i)); + QCOMPARE(i, 100); //Java-Style iterators -- cgit v1.2.3 From 049157f4f121d91b8702f998511a90a1adf0b71e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 22 Mar 2012 01:22:41 +0100 Subject: Silence unused comparison result warnings (clang) The intent is to force instantiation of template container classes and semantics or behaviour are otherwise irrelevant in this context. tst_collections.cpp:3036:15: warning: inequality comparison result unused tst_collections.cpp:3037:15: warning: equality comparison result unused tst_collections.cpp:3100:15: warning: inequality comparison result unused tst_collections.cpp:3101:15: warning: equality comparison result unused Change-Id: I70ad38b18dcbc43879e36a34b1da460aee5f7b07 Reviewed-by: Lars Knoll --- tests/auto/other/collections/tst_collections.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/other/collections/tst_collections.cpp b/tests/auto/other/collections/tst_collections.cpp index 973938594f..d4d70b5c36 100644 --- a/tests/auto/other/collections/tst_collections.cpp +++ b/tests/auto/other/collections/tst_collections.cpp @@ -3032,8 +3032,8 @@ void instantiateContainer() container.isEmpty(); container.size(); - container != constContainer; - container == constContainer; + Q_UNUSED((container != constContainer)); + Q_UNUSED((container == constContainer)); container = constContainer; } @@ -3097,8 +3097,8 @@ void instantiateAssociative() container.intersect(constContainer); container.subtract(constContainer); - container != constContainer; - container == constContainer; + Q_UNUSED((container != constContainer)); + Q_UNUSED((container == constContainer)); container & constContainer; container &= constContainer; container &= value; -- cgit v1.2.3 From 7c9e3455514576a48008d5150ffde45871716fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 22 Mar 2012 01:28:30 +0100 Subject: Improve output on test failures This adds checks to ensure Q_ALIGNOF is returning the desired alignment for explicitly-aligned types. The alignment check is now inlined in the test inside QCOMPARE so we get slightly more informative errors: FAIL! : tst_Collections::alignment() Compared values are not the same Actual (quintptr(&it.value()) % Value::PreferredAlignment): 64 Expected (quintptr(0)): 0 Loc: [tst_collections.cpp(3384)] In this case, this is enough to notice "non-native" alignments are being requested. Having test parameters otherwise hidden in template arguments doesn't help the situation. Change-Id: I05267fd25b71f183cfb98fb5b0a7dfd6c28da816 Reviewed-by: Lars Knoll --- tests/auto/other/collections/tst_collections.cpp | 30 +++++++++++------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'tests') diff --git a/tests/auto/other/collections/tst_collections.cpp b/tests/auto/other/collections/tst_collections.cpp index d4d70b5c36..a9cef635c7 100644 --- a/tests/auto/other/collections/tst_collections.cpp +++ b/tests/auto/other/collections/tst_collections.cpp @@ -3318,30 +3318,28 @@ class Q_DECL_ALIGN(4) Aligned4 char i; public: Aligned4(int i = 0) : i(i) {} - bool checkAligned() const - { - return (quintptr(this) & 3) == 0; - } + + 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) {} - bool checkAligned() const - { - return (quintptr(this) & 127) == 0; - } + + 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 void testVectorAlignment() @@ -3349,13 +3347,13 @@ void testVectorAlignment() typedef typename C::value_type Aligned; C container; container.append(Aligned()); - QVERIFY(container[0].checkAligned()); + 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) - QVERIFY(container.at(i).checkAligned()); + QCOMPARE(quintptr(&container.at(i)) % Aligned::PreferredAlignment, quintptr(0)); } template @@ -3364,13 +3362,13 @@ void testContiguousCacheAlignment() typedef typename C::value_type Aligned; C container(150); container.append(Aligned()); - QVERIFY(container[container.firstIndex()].checkAligned()); + 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) - QVERIFY(container.at(i).checkAligned()); + QCOMPARE(quintptr(&container.at(i)) % Aligned::PreferredAlignment, quintptr(0)); } template @@ -3382,8 +3380,8 @@ void testAssociativeContainerAlignment() container.insert(Key(), Value()); typename C::const_iterator it = container.constBegin(); - QVERIFY(it.key().checkAligned()); - QVERIFY(it.value().checkAligned()); + 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) @@ -3391,8 +3389,8 @@ void testAssociativeContainerAlignment() it = container.constBegin(); for ( ; it != container.constEnd(); ++it) { - QVERIFY(it.key().checkAligned()); - QVERIFY(it.value().checkAligned()); + QCOMPARE(quintptr(&it.key()) % Key::PreferredAlignment, quintptr(0)); + QCOMPARE(quintptr(&it.value()) % Value::PreferredAlignment, quintptr(0)); } } -- cgit v1.2.3 From a5a80da2238030b5ecbc7c5fba7ecd8cb5f2da1c Mon Sep 17 00:00:00 2001 From: David Faure Date: Sun, 25 Mar 2012 13:10:48 +0200 Subject: Allow auto tests to stay away from the user's configuration. QStandardPaths now knows a "test mode" which changes writable locations to point to test directories, in order to prevent auto tests from reading from or writing to the current user's configuration. This affects the locations into which test programs might write files: GenericDataLocation, DataLocation, ConfigLocation, GenericCacheLocation, CacheLocation. Other locations are not affected. Change-Id: I29606c2e74714360edd871a8c387a5c1ef7d1f54 Reviewed-by: Thiago Macieira Reviewed-by: Jason McDonald --- .../io/qstandardpaths/tst_qstandardpaths.cpp | 57 +++++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index a6eabbbed6..a389efa5ca 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -60,6 +60,7 @@ class tst_qstandardpaths : public QObject private slots: void testDefaultLocations(); void testCustomLocations(); + void enableTestMode(); void testLocateAll(); void testDataLocation(); void testFindExecutable(); @@ -69,6 +70,7 @@ private slots: void testAllWritableLocations(); private: +#ifdef Q_XDG_PLATFORM void setCustomLocations() { m_localConfigDir = m_localConfigTempDir.path(); m_globalConfigDir = m_globalConfigTempDir.path(); @@ -80,13 +82,12 @@ private: qputenv("XDG_DATA_DIRS", QFile::encodeName(m_globalAppDir)); } void setDefaultLocations() { -#ifdef Q_XDG_PLATFORM qputenv("XDG_CONFIG_HOME", QByteArray()); qputenv("XDG_CONFIG_DIRS", QByteArray()); qputenv("XDG_DATA_HOME", QByteArray()); qputenv("XDG_DATA_DIRS", QByteArray()); -#endif } +#endif // Config dirs QString m_localConfigDir; @@ -156,6 +157,58 @@ void tst_qstandardpaths::testCustomLocations() #endif } +void tst_qstandardpaths::enableTestMode() +{ + QStandardPaths::enableTestMode(true); + +#ifdef Q_XDG_PLATFORM + setCustomLocations(); // for the global config dir + const QString qttestDir = QDir::homePath() + QLatin1String("/.qttest"); + + // ConfigLocation + const QString configDir = qttestDir + QLatin1String("/config"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), configDir); + const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation); + QCOMPARE(confDirs, QStringList() << configDir << m_globalConfigDir); + + // GenericDataLocation + const QString dataDir = qttestDir + QLatin1String("/share"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), dataDir); + const QStringList gdDirs = QStandardPaths::standardLocations(QStandardPaths::DataLocation); + QCOMPARE(gdDirs, QStringList() << dataDir << m_globalAppDir); + + // CacheLocation + const QString cacheDir = qttestDir + QLatin1String("/cache"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::CacheLocation), cacheDir); + const QStringList cacheDirs = QStandardPaths::standardLocations(QStandardPaths::CacheLocation); + QCOMPARE(cacheDirs, QStringList() << cacheDir); +#endif + + // On all platforms, we want to ensure that the writableLocation is different in test mode and real mode. + // Check this for locations where test programs typically write. Not desktop, download, music etc... + typedef QHash LocationHash; + LocationHash testLocations; + testLocations.insert(QStandardPaths::DataLocation, QStandardPaths::writableLocation(QStandardPaths::DataLocation)); + testLocations.insert(QStandardPaths::GenericDataLocation, QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)); + testLocations.insert(QStandardPaths::ConfigLocation, QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + testLocations.insert(QStandardPaths::CacheLocation, QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); + testLocations.insert(QStandardPaths::GenericCacheLocation, QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)); + // On Windows, what should "Program Files" become, in test mode? + //testLocations.insert(QStandardPaths::ApplicationsLocation, QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)); + + QStandardPaths::enableTestMode(false); + + for (LocationHash::const_iterator it = testLocations.constBegin(); it != testLocations.constEnd(); ++it) + QVERIFY2(QStandardPaths::writableLocation(it.key()) != it.value(), qPrintable(it.value())); + + // Check that this is also true with no env vars set +#ifdef Q_XDG_PLATFORM + setDefaultLocations(); + for (LocationHash::const_iterator it = testLocations.constBegin(); it != testLocations.constEnd(); ++it) + QVERIFY2(QStandardPaths::writableLocation(it.key()) != it.value(), qPrintable(it.value())); +#endif +} + void tst_qstandardpaths::testLocateAll() { #ifdef Q_XDG_PLATFORM -- cgit v1.2.3 From d2b1c2ef1f1fea3200d8dee5c58fe79649fd13bb Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Fri, 23 Mar 2012 18:19:27 -0700 Subject: Remove WA_PaintOutsidePaintEvent WA_PaintOutsidePaintEvent is only suggested to be used when porting Qt3 code to Qt 4 under X11 platform. and it has been broken now. Change-Id: Ie4297b2a449f1055ca10ada9efb930e6018b1efb Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- .../qgraphicswidget/tst_qgraphicswidget.cpp | 3 -- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 39 ---------------------- 2 files changed, 42 deletions(-) (limited to 'tests') diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp index c6b2b49d98..3c98f8936c 100644 --- a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp @@ -1384,7 +1384,6 @@ void tst_QGraphicsWidget::setAttribute_data() QTest::newRow("WA_RightToLeft") << Qt::WA_RightToLeft << true; QTest::newRow("WA_SetStyle") << Qt::WA_SetStyle << true; QTest::newRow("WA_Resized") << Qt::WA_Resized << true; - QTest::newRow("unsupported") << Qt::WA_PaintOutsidePaintEvent << false; } // void setAttribute(Qt::WidgetAttribute attribute, bool on = true) public @@ -1393,8 +1392,6 @@ void tst_QGraphicsWidget::setAttribute() QFETCH(Qt::WidgetAttribute, attribute); QFETCH(bool, supported); SubQGraphicsWidget widget; - if (attribute == Qt::WA_PaintOutsidePaintEvent) - QTest::ignoreMessage(QtWarningMsg, "QGraphicsWidget::setAttribute: unsupported attribute 13"); widget.setAttribute(attribute); QCOMPARE(widget.testAttribute(attribute), supported); } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 975c88db05..0c769d55da 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -377,9 +377,6 @@ private slots: #endif void windowFlags(); void initialPosForDontShowOnScreenWidgets(); -#ifdef Q_WS_X11 - void paintOutsidePaintEvent(); -#endif void updateOnDestroyedSignal(); void toplevelLineEditFocus(); void inputFocus_task257832(); @@ -8711,42 +8708,6 @@ void tst_QWidget::initialPosForDontShowOnScreenWidgets() } } -#ifdef Q_WS_X11 -void tst_QWidget::paintOutsidePaintEvent() -{ - QWidget widget; - widget.resize(200, 200); - - QWidget child1(&widget); - child1.resize(100, 100); - child1.setPalette(Qt::red); - child1.setAutoFillBackground(true); - - QWidget child2(&widget); - child2.setGeometry(50, 50, 100, 100); - child2.setPalette(Qt::blue); - child2.setAutoFillBackground(true); - - widget.show(); - QTest::qWaitForWindowShown(&widget); - QTest::qWait(60); - - const QPixmap before = QPixmap::grabWindow(widget.winId()); - - // Child 1 should be clipped by child 2, so nothing should change. - child1.setAttribute(Qt::WA_PaintOutsidePaintEvent); - QPainter painter(&child1); - painter.fillRect(child1.rect(), Qt::red); - painter.end(); - XSync(QX11Info::display(), false); // Flush output buffer. - QTest::qWait(60); - - const QPixmap after = QPixmap::grabWindow(widget.winId()); - - QCOMPARE(before, after); -} -#endif - class MyEvilObject : public QObject { Q_OBJECT -- cgit v1.2.3 From 70db6233e7685e1b76e038f9baf25d1c70baa9aa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 13 Oct 2011 22:49:19 +0200 Subject: Add a function to parse IPv4 addresses in QtCore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the unit test, check against inet_aton on Linux with GLIBC only. Other platforms have this function too, but they sometimes have different behaviour, so don't try to test them equally. Change-Id: I1a77e405ac7e713d4cf1cee03ea5ce17fb47feef Reviewed-by: João Abecasis Reviewed-by: Shane Kearns --- tests/auto/corelib/io/io.pro | 4 +- tests/auto/corelib/io/qipaddress/qipaddress.pro | 4 + .../auto/corelib/io/qipaddress/tst_qipaddress.cpp | 218 +++++++++++++++++++++ 3 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 tests/auto/corelib/io/qipaddress/qipaddress.pro create mode 100644 tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp (limited to 'tests') diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro index 84a885f5b6..7e0cb5e8ca 100644 --- a/tests/auto/corelib/io/io.pro +++ b/tests/auto/corelib/io/io.pro @@ -12,6 +12,7 @@ SUBDIRS=\ qfilesystementry \ qfilesystemwatcher \ qiodevice \ + qipaddress \ qnodebug \ qprocess \ qprocessenvironment \ @@ -31,7 +32,8 @@ SUBDIRS=\ !contains(QT_CONFIG, private_tests): SUBDIRS -= \ qabstractfileengine \ - qfileinfo + qfileinfo \ + qipaddress win32:!contains(QT_CONFIG, private_tests): SUBDIRS -= \ qfilesystementry diff --git a/tests/auto/corelib/io/qipaddress/qipaddress.pro b/tests/auto/corelib/io/qipaddress/qipaddress.pro new file mode 100644 index 0000000000..41fa55aa15 --- /dev/null +++ b/tests/auto/corelib/io/qipaddress/qipaddress.pro @@ -0,0 +1,4 @@ +SOURCES += tst_qipaddress.cpp +TARGET = tst_qipaddress +QT = core core-private testlib +CONFIG += testcase parallel_test diff --git a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp new file mode 100644 index 0000000000..73cbbdea0e --- /dev/null +++ b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Intel Corporation. +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#ifdef __GLIBC__ +#include +#include +#include +#endif + +class tst_QIpAddress : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void parseIp4_data(); + void parseIp4(); + void invalidParseIp4_data(); + void invalidParseIp4(); + void ip4ToString_data(); + void ip4ToString(); +}; + +void tst_QIpAddress::parseIp4_data() +{ + QTest::addColumn("data"); + QTest::addColumn("ip"); + + // valid strings + QTest::newRow("0.0.0.0") << "0.0.0.0" << 0u; + QTest::newRow("10.0.0.1") << "10.0.0.1" << 0x0a000001u; + QTest::newRow("127.0.0.1") << "127.0.0.1" << 0x7f000001u; + QTest::newRow("172.16.0.1") << "172.16.0.1" << 0xac100001u; + QTest::newRow("172.16.16.1") << "172.16.16.1" << 0xac101001u; + QTest::newRow("172.16.16.16") << "172.16.16.16" << 0xac101010u; + QTest::newRow("192.168.0.1") << "192.168.0.1" << 0xc0a80001u; + QTest::newRow("192.168.16.1") << "192.168.16.1" << 0xc0a81001u; + QTest::newRow("192.168.16.16") << "192.168.16.16" << 0xc0a81010u; + QTest::newRow("192.168.192.1") << "192.168.192.1" << 0xc0a8c001u; + QTest::newRow("192.168.192.16") << "192.168.192.16" << 0xc0a8c010u; + QTest::newRow("192.168.192.255") << "192.168.192.255" << 0xc0a8c0ffu; + QTest::newRow("224.0.0.1") << "224.0.0.1" << 0xe0000001u; + QTest::newRow("239.255.255.255") << "239.255.255.255" << 0xefffffffu; + QTest::newRow("255.255.255.255") << "255.255.255.255" << uint(-1); + + // still valid but unusual + QTest::newRow("000.000.000.000") << "000.000.000.000" << 0u; + QTest::newRow("000001.000002.000000003.000000000004") << "000001.000002.000000003.000000000004" << 0x01020304u; + + // octals: + QTest::newRow("012.0250.0377.0377") << "012.0250.0377.0377" << 0x0aa8ffffu; + QTest::newRow("0000000000012.00000000000250.000000000000377.0000000000000000000000000000000000000377") + << "0000000000012.00000000000250.000000000000377.0000000000000000000000000000000000000377" << 0x0aa8ffffu; + + // hex: + QTest::newRow("0xa.0xa.0x7f.0xff") << "0xa.0xa.0x7f.0xff" << 0x0a0a7fffu; + + // dots missing, less than 255: + QTest::newRow("1.2.3") << "1.2.3" << 0x01020003u; + QTest::newRow("1.2") << "1.2" << 0x01000002u; + QTest::newRow("1") << "1" << 1u; + + // dots missing, more than 255, no overwrite + QTest::newRow("1.2.257") << "1.2.257" << 0x01020101u; + QTest::newRow("1.0x010101") << "1.0x010101" << 0x01010101u; + QTest::newRow("2130706433") << "2130706433" << 0x7f000001u; +} + +void tst_QIpAddress::parseIp4() +{ + QFETCH(QString, data); + QFETCH(QIPAddressUtils::IPv4Address, ip); + +#ifdef __GLIBC__ + { + in_addr inet_result; + int inet_ok = inet_aton(data.toLatin1(), &inet_result); + QVERIFY(inet_ok); + QCOMPARE(ntohl(inet_result.s_addr), ip); + } +#endif + + QIPAddressUtils::IPv4Address result; + bool ok = QIPAddressUtils::parseIp4(result, data.constBegin(), data.constEnd()); + QVERIFY(ok); + QCOMPARE(result, ip); +} + +void tst_QIpAddress::invalidParseIp4_data() +{ + QTest::addColumn("data"); + + // too many dots + QTest::newRow(".") << "."; + QTest::newRow("..") << ".."; + QTest::newRow("...") << "..."; + QTest::newRow("....") << "...."; + QTest::newRow("1.") << "1."; + QTest::newRow("1.2.") << "1.2."; + QTest::newRow("1.2.3.") << "1.2.3."; + QTest::newRow("1.2.3.4.") << "1.2.3.4."; + QTest::newRow("1.2.3..4") << "1.2.3..4"; + + // octet more than 255 + QTest::newRow("2.2.2.257") << "2.2.2.257"; + QTest::newRow("2.2.257.2") << "2.2.257.2"; + QTest::newRow("2.257.2.2") << "2.257.2.2"; + QTest::newRow("257.2.2.2") << "257.2.2.2"; + + // number more than field available + QTest::newRow("2.2.0x01010101") << "2.2.0x01010101"; + QTest::newRow("2.0x01010101") << "2.0x01010101"; + QTest::newRow("4294967296") << "4294967296"; + + // bad octals + QTest::newRow("09") << "09"; + + // bad hex + QTest::newRow("0x1g") << "0x1g"; + + // letters + QTest::newRow("abc") << "abc"; + QTest::newRow("1.2.3a.4") << "1.2.3a.4"; + QTest::newRow("a.2.3.4") << "a.2.3.4"; + QTest::newRow("1.2.3.4a") << "1.2.3.4a"; +} + +void tst_QIpAddress::invalidParseIp4() +{ + QFETCH(QString, data); + +#ifdef __GLIBC__ + { + in_addr inet_result; + int inet_ok = inet_aton(data.toLatin1(), &inet_result); +# ifdef Q_OS_DARWIN + QEXPECT_FAIL("4294967296", "Mac's library does parse this one", Continue); +# endif + QVERIFY(!inet_ok); + } +#endif + + QIPAddressUtils::IPv4Address result; + bool ok = QIPAddressUtils::parseIp4(result, data.constBegin(), data.constEnd()); + QVERIFY(!ok); +} + +void tst_QIpAddress::ip4ToString_data() +{ + QTest::addColumn("ip"); + QTest::addColumn("expected"); + + QTest::newRow("0.0.0.0") << 0u << "0.0.0.0"; + QTest::newRow("1.2.3.4") << 0x01020304u << "1.2.3.4"; + QTest::newRow("111.222.33.44") << 0x6fde212cu << "111.222.33.44"; + QTest::newRow("255.255.255.255") << 0xffffffffu << "255.255.255.255"; +} + +void tst_QIpAddress::ip4ToString() +{ + QFETCH(QIPAddressUtils::IPv4Address, ip); + QFETCH(QString, expected); + +#ifdef __GLIBC__ + in_addr inet_ip; + inet_ip.s_addr = htonl(ip); + QCOMPARE(QString(inet_ntoa(inet_ip)), expected); +#endif + + QString result; + QIPAddressUtils::toString(result, ip); + QCOMPARE(result, expected); +} + +QTEST_APPLESS_MAIN(tst_QIpAddress) + +#include "tst_qipaddress.moc" -- cgit v1.2.3 From 826c0723c1dbca9742f3b8b0cb6d31df21f17664 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 14 Oct 2011 17:12:34 +0200 Subject: Add support for IPv6 parsing and reconstructing the address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similarly, only test against the libc function on Linux, as other OS sometimes have different behaviour. Change-Id: I9b8ef9a3d660a59882396d695202865ca307e528 Reviewed-by: João Abecasis Reviewed-by: Shane Kearns --- .../auto/corelib/io/qipaddress/tst_qipaddress.cpp | 285 +++++++++++++++++++++ 1 file changed, 285 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp index 73cbbdea0e..bad18fabef 100644 --- a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp +++ b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp @@ -60,7 +60,65 @@ private Q_SLOTS: void invalidParseIp4(); void ip4ToString_data(); void ip4ToString(); + + void parseIp6_data(); + void parseIp6(); + void invalidParseIp6_data(); + void invalidParseIp6(); + void ip6ToString_data(); + void ip6ToString(); +}; + +struct Ip6 +{ + QIPAddressUtils::IPv6Address u8; + Ip6() { *this = Ip6(0,0,0,0, 0,0,0,0); } + Ip6(quint16 p1, quint16 p2, quint16 p3, quint16 p4, + quint16 p5, quint16 p6, quint16 p7, quint16 p8) + { + u8[0] = p1 >> 8; + u8[2] = p2 >> 8; + u8[4] = p3 >> 8; + u8[6] = p4 >> 8; + u8[8] = p5 >> 8; + u8[10] = p6 >> 8; + u8[12] = p7 >> 8; + u8[14] = p8 >> 8; + + u8[1] = p1 & 0xff; + u8[3] = p2 & 0xff; + u8[5] = p3 & 0xff; + u8[7] = p4 & 0xff; + u8[9] = p5 & 0xff; + u8[11] = p6 & 0xff; + u8[13] = p7 & 0xff; + u8[15] = p8 & 0xff; + } + + bool operator==(const Ip6 &other) const + { return memcmp(u8, other.u8, sizeof u8) == 0; } }; +Q_DECLARE_METATYPE(Ip6) + +QT_BEGIN_NAMESPACE +namespace QTest { + template<> + char *toString(const Ip6 &ip6) + { + char buf[sizeof "1111:2222:3333:4444:5555:6666:7777:8888" + 2]; + sprintf(buf, "%x:%x:%x:%x:%x:%x:%x:%x", + ip6.u8[0] << 8 | ip6.u8[1], + ip6.u8[2] << 8 | ip6.u8[3], + ip6.u8[4] << 8 | ip6.u8[5], + ip6.u8[6] << 8 | ip6.u8[7], + ip6.u8[8] << 8 | ip6.u8[9], + ip6.u8[10] << 8 | ip6.u8[11], + ip6.u8[12] << 8 | ip6.u8[13], + ip6.u8[14] << 8 | ip6.u8[15]); + return strdup(buf); + } +} +QT_END_NAMESPACE void tst_QIpAddress::parseIp4_data() { @@ -213,6 +271,233 @@ void tst_QIpAddress::ip4ToString() QCOMPARE(result, expected); } +void tst_QIpAddress::parseIp6_data() +{ + qRegisterMetaType(); + QTest::addColumn("address"); + QTest::addColumn("expected"); + + // 7 colons, no :: + QTest::newRow("0:0:0:0:0:0:0:0") << "0:0:0:0:0:0:0:0" << Ip6(0,0,0,0,0,0,0,0); + QTest::newRow("0:0:0:0:0:0:0:1") << "0:0:0:0:0:0:0:1" << Ip6(0,0,0,0,0,0,0,1); + QTest::newRow("0:0:0:0:0:0:1:1") << "0:0:0:0:0:0:1:1" << Ip6(0,0,0,0,0,0,1,1); + QTest::newRow("0:0:0:0:0:0:0:103") << "0:0:0:0:0:0:0:103" << Ip6(0,0,0,0,0,0,0,0x103); + QTest::newRow("1:2:3:4:5:6:7:8") << "1:2:3:4:5:6:7:8" << Ip6(1,2,3,4,5,6,7,8); + QTest::newRow("ffee:ddcc:bbaa:9988:7766:5544:3322:1100") + << "ffee:ddcc:bbaa:9988:7766:5544:3322:1100" + << Ip6(0xffee, 0xddcc, 0xbbaa, 0x9988, 0x7766, 0x5544, 0x3322, 0x1100); + + // too many zeroes + QTest::newRow("0:0:0:0:0:0:0:00103") << "0:0:0:0:0:0:0:00103" << Ip6(0,0,0,0,0,0,0,0x103); + + // double-colon + QTest::newRow("::1:2:3:4:5:6:7") << "::1:2:3:4:5:6:7" << Ip6(0,1,2,3,4,5,6,7); + QTest::newRow("1:2:3:4:5:6:7::") << "1:2:3:4:5:6:7::" << Ip6(1,2,3,4,5,6,7,0); + + QTest::newRow("1::2:3:4:5:6:7") << "1::2:3:4:5:6:7" << Ip6(1,0,2,3,4,5,6,7); + QTest::newRow("1:2::3:4:5:6:7") << "1:2::3:4:5:6:7" << Ip6(1,2,0,3,4,5,6,7); + QTest::newRow("1:2:3::4:5:6:7") << "1:2:3::4:5:6:7" << Ip6(1,2,3,0,4,5,6,7); + QTest::newRow("1:2:3:4::5:6:7") << "1:2:3:4::5:6:7" << Ip6(1,2,3,4,0,5,6,7); + QTest::newRow("1:2:3:4:5::6:7") << "1:2:3:4:5::6:7" << Ip6(1,2,3,4,5,0,6,7); + QTest::newRow("1:2:3:4:5:6::7") << "1:2:3:4:5:6::7" << Ip6(1,2,3,4,5,6,0,7); + + QTest::newRow("::1:2:3:4:5:6") << "::1:2:3:4:5:6" << Ip6(0,0,1,2,3,4,5,6); + QTest::newRow("1:2:3:4:5:6::") << "1:2:3:4:5:6::" << Ip6(1,2,3,4,5,6,0,0); + + QTest::newRow("1::2:3:4:5:6") << "1::2:3:4:5:6" << Ip6(1,0,0,2,3,4,5,6); + QTest::newRow("1:2::3:4:5:6") << "1:2::3:4:5:6" << Ip6(1,2,0,0,3,4,5,6); + QTest::newRow("1:2:3::4:5:6") << "1:2:3::4:5:6" << Ip6(1,2,3,0,0,4,5,6); + QTest::newRow("1:2:3:4::5:6") << "1:2:3:4::5:6" << Ip6(1,2,3,4,0,0,5,6); + QTest::newRow("1:2:3:4:5::6") << "1:2:3:4:5::6" << Ip6(1,2,3,4,5,0,0,6); + + QTest::newRow("::1:2:3:4:5") << "::1:2:3:4:5" << Ip6(0,0,0,1,2,3,4,5); + QTest::newRow("1:2:3:4:5::") << "1:2:3:4:5::" << Ip6(1,2,3,4,5,0,0,0); + + QTest::newRow("1::2:3:4:5") << "1::2:3:4:5" << Ip6(1,0,0,0,2,3,4,5); + QTest::newRow("1:2::3:4:5") << "1:2::3:4:5" << Ip6(1,2,0,0,0,3,4,5); + QTest::newRow("1:2:3::4:5") << "1:2:3::4:5" << Ip6(1,2,3,0,0,0,4,5); + QTest::newRow("1:2:3:4::5") << "1:2:3:4::5" << Ip6(1,2,3,4,0,0,0,5); + + QTest::newRow("::1:2:3:4") << "::1:2:3:4" << Ip6(0,0,0,0,1,2,3,4); + QTest::newRow("1:2:3:4::") << "1:2:3:4::" << Ip6(1,2,3,4,0,0,0,0); + + QTest::newRow("1::2:3:4") << "1::2:3:4" << Ip6(1,0,0,0,0,2,3,4); + QTest::newRow("1:2::3:4") << "1:2::3:4" << Ip6(1,2,0,0,0,0,3,4); + QTest::newRow("1:2:3::4") << "1:2:3::4" << Ip6(1,2,3,0,0,0,0,4); + + QTest::newRow("::1:2:3") << "::1:2:3" << Ip6(0,0,0,0,0,1,2,3); + QTest::newRow("1:2:3::") << "1:2:3::" << Ip6(1,2,3,0,0,0,0,0); + + QTest::newRow("1::2:3") << "1::2:3" << Ip6(1,0,0,0,0,0,2,3); + QTest::newRow("1:2::3") << "1:2::3" << Ip6(1,2,0,0,0,0,0,3); + + QTest::newRow("::1:2") << "::1:2" << Ip6(0,0,0,0,0,0,1,2); + QTest::newRow("1:2::") << "1:2::" << Ip6(1,2,0,0,0,0,0,0); + + QTest::newRow("1::2") << "1::2" << Ip6(1,0,0,0,0,0,0,2); + + QTest::newRow("::1") << "::1" << Ip6(0,0,0,0,0,0,0,1); + QTest::newRow("1::") << "1::" << Ip6(1,0,0,0,0,0,0,0); + + QTest::newRow("::") << "::" << Ip6(0,0,0,0,0,0,0,0); + + // embedded IPv4 + QTest::newRow("1:2:3:4:5:6:10.0.16.1") << "1:2:3:4:5:6:10.0.16.1" << Ip6(1,2,3,4,5,6,0xa00,0x1001); + QTest::newRow("1::10.0.16.1") << "1::10.0.16.1" << Ip6(1,0,0,0,0,0,0xa00,0x1001); + QTest::newRow("::10.0.16.1") << "::10.0.16.1" << Ip6(0,0,0,0,0,0,0xa00,0x1001); + QTest::newRow("::0.0.0.0") << "::0.0.0.0" << Ip6(0,0,0,0,0,0,0,0); +} + +void tst_QIpAddress::parseIp6() +{ + QFETCH(QString, address); + QFETCH(Ip6, expected); + +#if defined(__GLIBC__) && defined(AF_INET6) + Ip6 inet_result; + bool inet_ok = inet_pton(AF_INET6, address.toLatin1(), &inet_result.u8); + QVERIFY(inet_ok); + QCOMPARE(inet_result, expected); +#endif + + Ip6 result; + bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd()); + QVERIFY(ok); + QCOMPARE(result, expected); +} + +void tst_QIpAddress::invalidParseIp6_data() +{ + QTest::addColumn("address"); + + // too many colons + QTest::newRow("0:0:0:0::0:0:0:0") << "0:0:0:0::0:0:0:0"; + QTest::newRow("0:::") << "0:::"; QTest::newRow(":::0") << ":::0"; + QTest::newRow("16:::::::::::::::::::::::") << "16:::::::::::::::::::::::"; + + // non-hex + QTest::newRow("a:b:c:d:e:f:g:h") << "a:b:c:d:e:f:g:h"; + + // too big number + QTest::newRow("0:0:0:0:0:0:0:10103") << "0:0:0:0:0:0:0:10103"; + + // too short + QTest::newRow("0:0:0:0:0:0:0:") << "0:0:0:0:0:0:0:"; + QTest::newRow("0:0:0:0:0:0:0") << "0:0:0:0:0:0:0"; + QTest::newRow("0:0:0:0:0:0:") << "0:0:0:0:0:0:"; + QTest::newRow("0:0:0:0:0:0") << "0:0:0:0:0:0"; + QTest::newRow("0:0:0:0:0:") << "0:0:0:0:0:"; + QTest::newRow("0:0:0:0:0") << "0:0:0:0:0"; + QTest::newRow("0:0:0:0:") << "0:0:0:0:"; + QTest::newRow("0:0:0:0") << "0:0:0:0"; + QTest::newRow("0:0:0:") << "0:0:0:"; + QTest::newRow("0:0:0") << "0:0:0"; + QTest::newRow("0:0:") << "0:0:"; + QTest::newRow("0:0") << "0:0"; + QTest::newRow("0:") << "0:"; + QTest::newRow("0") << "0"; + QTest::newRow(":0") << ":0"; + QTest::newRow(":0:0") << ":0:0"; + QTest::newRow(":0:0:0") << ":0:0:0"; + QTest::newRow(":0:0:0:0") << ":0:0:0:0"; + QTest::newRow(":0:0:0:0:0") << ":0:0:0:0:0"; + QTest::newRow(":0:0:0:0:0:0") << ":0:0:0:0:0:0"; + QTest::newRow(":0:0:0:0:0:0:0") << ":0:0:0:0:0:0:0"; + + // IPv4 + QTest::newRow("1.2.3.4") << "1.2.3.4"; + + // embedded IPv4 in the wrong position + QTest::newRow("1.2.3.4::") << "1.2.3.4::"; + QTest::newRow("f:1.2.3.4::") << "f:1.2.3.4::"; + QTest::newRow("f:e:d:c:b:1.2.3.4:0") << "f:e:d:c:b:1.2.3.4:0"; + + // bad embedded IPv4 + QTest::newRow("::1.2.3") << "::1.2.3"; + QTest::newRow("::1.2.257") << "::1.2.257"; + QTest::newRow("::1.2") << "::1.2"; + QTest::newRow("::0250.0x10101") << "::0250.0x10101"; + QTest::newRow("::1.2.3.0250") << "::1.2.3.0250"; + QTest::newRow("::1.2.3.0xff") << "::1.2.3.0xff"; + QTest::newRow("::1.2.3.07") << "::1.2.3.07"; + QTest::newRow("::1.2.3.010") << "::1.2.3.010"; + + // separated by something else + QTest::newRow("1.2.3.4.5.6.7.8") << "1.2.3.4.5.6.7.8"; + QTest::newRow("1,2,3,4,5,6,7,8") << "1,2,3,4,5,6,7,8"; + QTest::newRow("1..2") << "1..2"; + QTest::newRow("1:.2") << "1:.2"; + QTest::newRow("1.:2") << "1.:2"; +} + +void tst_QIpAddress::invalidParseIp6() +{ + QFETCH(QString, address); + +#if defined(__GLIBC__) && defined(AF_INET6) + Ip6 inet_result; + bool inet_ok = inet_pton(AF_INET6, address.toLatin1(), &inet_result.u8); + QVERIFY(!inet_ok); +#endif + + Ip6 result; + bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd()); + QVERIFY(!ok); +} + +void tst_QIpAddress::ip6ToString_data() +{ + qRegisterMetaType(); + QTest::addColumn("ip"); + QTest::addColumn("expected"); + + QTest::newRow("1:2:3:4:5:6:7:8") << Ip6(1,2,3,4,5,6,7,8) << "1:2:3:4:5:6:7:8"; + QTest::newRow("1:2:3:4:5:6:7:88") << Ip6(1,2,3,4,5,6,7,0x88) << "1:2:3:4:5:6:7:88"; + QTest::newRow("1:2:3:4:5:6:7:888") << Ip6(1,2,3,4,5,6,7,0x888) << "1:2:3:4:5:6:7:888"; + QTest::newRow("1:2:3:4:5:6:7:8888") << Ip6(1,2,3,4,5,6,7,0x8888) << "1:2:3:4:5:6:7:8888"; + QTest::newRow("1:2:3:4:5:6:7:8880") << Ip6(1,2,3,4,5,6,7,0x8880) << "1:2:3:4:5:6:7:8880"; + QTest::newRow("1:2:3:4:5:6:7:8808") << Ip6(1,2,3,4,5,6,7,0x8808) << "1:2:3:4:5:6:7:8808"; + QTest::newRow("1:2:3:4:5:6:7:8088") << Ip6(1,2,3,4,5,6,7,0x8088) << "1:2:3:4:5:6:7:8088"; + + QTest::newRow("1:2:3:4:5:6:7:0") << Ip6(1,2,3,4,5,6,7,0) << "1:2:3:4:5:6:7:0"; + QTest::newRow("0:1:2:3:4:5:6:7") << Ip6(0,1,2,3,4,5,6,7) << "0:1:2:3:4:5:6:7"; + + QTest::newRow("1:2:3:4:5:6::") << Ip6(1,2,3,4,5,6,0,0) << "1:2:3:4:5:6::"; + QTest::newRow("::1:2:3:4:5:6") << Ip6(0,0,1,2,3,4,5,6) << "::1:2:3:4:5:6"; + QTest::newRow("1:0:0:2::3") << Ip6(1,0,0,2,0,0,0,3) << "1:0:0:2::3"; + QTest::newRow("1:::2:0:0:3") << Ip6(1,0,0,0,2,0,0,3) << "1::2:0:0:3"; + QTest::newRow("1::2:0:0:0") << Ip6(1,0,0,0,2,0,0,0) << "1::2:0:0:0"; + QTest::newRow("0:0:0:1::") << Ip6(0,0,0,1,0,0,0,0) << "0:0:0:1::"; + QTest::newRow("::1:0:0:0") << Ip6(0,0,0,0,1,0,0,0) << "::1:0:0:0"; + QTest::newRow("ff02::1") << Ip6(0xff02,0,0,0,0,0,0,1) << "ff02::1"; + QTest::newRow("1::1") << Ip6(1,0,0,0,0,0,0,1) << "1::1"; + QTest::newRow("::1") << Ip6(0,0,0,0,0,0,0,1) << "::1"; + QTest::newRow("1::") << Ip6(1,0,0,0,0,0,0,0) << "1::"; + QTest::newRow("::") << Ip6(0,0,0,0,0,0,0,0) << "::"; + + QTest::newRow("::1.2.3.4") << Ip6(0,0,0,0,0,0,0x102,0x304) << "::1.2.3.4"; + QTest::newRow("::ffff:1.2.3.4") << Ip6(0,0,0,0,0,0xffff,0x102,0x304) << "::ffff:1.2.3.4"; +} + +void tst_QIpAddress::ip6ToString() +{ + QFETCH(Ip6, ip); + QFETCH(QString, expected); + +#if defined(__GLIBC__) && defined(AF_INET6) + { + char buf[INET6_ADDRSTRLEN]; + bool ok = inet_ntop(AF_INET6, ip.u8, buf, sizeof buf) != 0; + QVERIFY(ok); + QCOMPARE(QString(buf), expected); + } +#endif + + QString result; + QIPAddressUtils::toString(result, ip.u8); + QCOMPARE(result, expected); +} + QTEST_APPLESS_MAIN(tst_QIpAddress) #include "tst_qipaddress.moc" -- cgit v1.2.3 From 4fc7474805fbcbb979d485183f336a3172e86df5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 17 Oct 2011 13:41:19 +0200 Subject: Port QHostAddress to use the new IP utilities in QtCore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new code now generates lowercase hex instead of uppercase, so adapt the unit tests to pass. Also, "123.0.0" is now considered valid (compatibility with inet_aton). Change-Id: I07b5125abf60106dc5e706033d60836fb690a41f Reviewed-by: João Abecasis Reviewed-by: Shane Kearns --- .../kernel/qhostaddress/tst_qhostaddress.cpp | 32 ++++++++++++---------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'tests') diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index d74e1b1e89..a0403e5550 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Intel Corporation. ** Contact: http://www.qt-project.org/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -39,7 +40,6 @@ ** ****************************************************************************/ - #include #include #include @@ -165,24 +165,25 @@ void tst_QHostAddress::setAddress_QString_data() QTest::newRow("ip4_03") << QString(" 255.3.2.1") << true << QString("255.3.2.1") << 4; QTest::newRow("ip4_04") << QString("255.3.2.1\r ") << true << QString("255.3.2.1") << 4; QTest::newRow("ip4_05") << QString("0.0.0.0") << true << QString("0.0.0.0") << 4; + QTest::newRow("ip4_06") << QString("123.0.0") << true << QString("123.0.0.0") << 4; // for the format of IPv6 addresses see also RFC 5952 - QTest::newRow("ip6_00") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << true << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << 6; - QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << true << QString("1080::8:800:200C:417A") << 6; - QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << true << QString("1080::8:800:200C:417A") << 6; - QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << true << QString("1080::8:800:200C:417A") << 6; - QTest::newRow("ip6_04") << QString("FF01::43") << true << QString("FF01::43") << 6; + QTest::newRow("ip6_00") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << true << QString("fedc:ba98:7654:3210:fedc:ba98:7654:3210") << 6; + QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6; + QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6; + QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6; + QTest::newRow("ip6_04") << QString("FF01::43") << true << QString("ff01::43") << 6; QTest::newRow("ip6_05") << QString("::1") << true << QString("::1") << 6; QTest::newRow("ip6_06") << QString("1::") << true << QString("1::") << 6; QTest::newRow("ip6_07") << QString("::") << true << QString("::") << 6; - QTest::newRow("ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << true << QString("::D01:4403") << 6; - QTest::newRow("ip6_09") << QString("::13.1.68.3") << true << QString("::D01:4403") << 6; - QTest::newRow("ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << true << QString("::FFFF:8190:3426") << 6; - QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << true << QString("::FFFF:8190:3426") << 6; - QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << true << QString("1::FFFF:8190:3426") << 6; - QTest::newRow("ip6_13") << QString("A:B::D:E") << true << QString("A:B::D:E") << 6; - QTest::newRow("ip6_14") << QString("1080:0:1:0:8:800:200C:417A") << true << QString("1080:0:1:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_15") << QString("1080:0:1:0:8:800:200C:0") << true << QString("1080:0:1:0:8:800:200C:0") << 6; + QTest::newRow("ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << true << QString("::13.1.68.3") << 6; + QTest::newRow("ip6_09") << QString("::13.1.68.3") << true << QString("::13.1.68.3") << 6; + QTest::newRow("ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << true << QString("::ffff:129.144.52.38") << 6; + QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << true << QString("::ffff:129.144.52.38") << 6; + QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << true << QString("1::ffff:8190:3426") << 6; + QTest::newRow("ip6_13") << QString("A:B::D:E") << true << QString("a:b::d:e") << 6; + QTest::newRow("ip6_14") << QString("1080:0:1:0:8:800:200C:417A") << true << QString("1080:0:1:0:8:800:200c:417a") << 6; + QTest::newRow("ip6_15") << QString("1080:0:1:0:8:800:200C:0") << true << QString("1080:0:1:0:8:800:200c:0") << 6; QTest::newRow("ip6_16") << QString("1080:0:1:0:8:800:0:0") << true << QString("1080:0:1:0:8:800::") << 6; QTest::newRow("ip6_17") << QString("1080:0:0:0:8:800:0:0") << true << QString("1080::8:800:0:0") << 6; QTest::newRow("ip6_18") << QString("0:1:1:1:8:800:0:0") << true << QString("0:1:1:1:8:800::") << 6; @@ -196,7 +197,8 @@ void tst_QHostAddress::setAddress_QString_data() QTest::newRow("error_ip4_00") << QString("256.9.9.9") << false << QString() << 0; QTest::newRow("error_ip4_01") << QString("-1.9.9.9") << false << QString() << 0; - QTest::newRow("error_ip4_02") << QString("123.0.0") << false << QString() << 0; + //QTest::newRow("error_ip4_02") << QString("123.0.0") << false << QString() << 0; // no longer invalid in Qt5 + QTest::newRow("error_ip4_02") << QString("123.0.0.") << false << QString() << 0; QTest::newRow("error_ip4_03") << QString("123.0.0.0.0") << false << QString() << 0; QTest::newRow("error_ip4_04") << QString("255.2 3.2.1") << false << QString() << 0; -- cgit v1.2.3 From d78fe5f8d361c203e43908ddc0bd64f667c83204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 27 Mar 2012 12:27:54 +0200 Subject: Make QArrayData::shared_null zero terminated. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is expected by QByteArray and QString Change-Id: Ib668b144bdc0d2c793018c8f8d794f249eaf935c Reviewed-by: João Abecasis --- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 9bfbac0017..4bd04f9bc3 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -50,9 +50,9 @@ struct SharedNullVerifier { SharedNullVerifier() { - Q_ASSERT(QArrayData::shared_null.ref.isStatic()); - Q_ASSERT(QArrayData::shared_null.ref.isShared()); - Q_ASSERT(QArrayData::shared_null.ref.isSharable()); + Q_ASSERT(QArrayData::shared_null[0].ref.isStatic()); + Q_ASSERT(QArrayData::shared_null[0].ref.isShared()); + Q_ASSERT(QArrayData::shared_null[0].ref.isSharable()); } }; @@ -159,7 +159,7 @@ void tst_QArrayData::referenceCounting() void tst_QArrayData::sharedNullEmpty() { - QArrayData *null = const_cast(&QArrayData::shared_null); + QArrayData *null = const_cast(QArrayData::shared_null); QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0); QVERIFY(null->ref.isStatic()); -- cgit v1.2.3 From 8fa2a41bd5fb0e21c3cbda3d76eba77a922bded2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Sep 2011 20:09:35 +0200 Subject: Move the QByteArray-based percent-encoding activities to QByteArray MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copy the unit tests that related to percent-encoding to tst_qbytearray.cpp and use public functions to execute QUrl::fromPercentEncoded and QUrl::toPercentEncoded. Change-Id: I6639ea566d82dabeb91280177a854e89e18f6f8d Reviewed-by: João Abecasis Reviewed-by: David Faure --- .../corelib/tools/qbytearray/tst_qbytearray.cpp | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 63900b0c55..2c8aa4d62a 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -123,6 +123,12 @@ private slots: void toFromHex_data(); void toFromHex(); void toFromPercentEncoding(); + void fromPercentEncoding_data(); + void fromPercentEncoding(); + void toPercentEncoding_data(); + void toPercentEncoding(); + void toPercentEncoding2_data(); + void toPercentEncoding2(); void compare_data(); void compare(); @@ -1340,6 +1346,91 @@ void tst_QByteArray::toFromPercentEncoding() QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isNull()); } +void tst_QByteArray::fromPercentEncoding_data() +{ + QTest::addColumn("encodedString"); + QTest::addColumn("decodedString"); + + QTest::newRow("NormalString") << QByteArray("filename") << QByteArray("filename"); + QTest::newRow("NormalStringEncoded") << QByteArray("file%20name") << QByteArray("file name"); + QTest::newRow("JustEncoded") << QByteArray("%20") << QByteArray(" "); + QTest::newRow("HTTPUrl") << QByteArray("http://qt.nokia.com") << QByteArray("http://qt.nokia.com"); + QTest::newRow("HTTPUrlEncoded") << QByteArray("http://qt%20nokia%20com") << QByteArray("http://qt nokia com"); + QTest::newRow("EmptyString") << QByteArray("") << QByteArray(""); + QTest::newRow("Task27166") << QByteArray("Fran%C3%A7aise") << QByteArray("Française"); +} + +void tst_QByteArray::fromPercentEncoding() +{ + QFETCH(QByteArray, encodedString); + QFETCH(QByteArray, decodedString); + + QCOMPARE(QByteArray::fromPercentEncoding(encodedString), decodedString); +} + +void tst_QByteArray::toPercentEncoding_data() +{ + QTest::addColumn("decodedString"); + QTest::addColumn("encodedString"); + + QTest::newRow("NormalString") << QByteArray("filename") << QByteArray("filename"); + QTest::newRow("NormalStringEncoded") << QByteArray("file name") << QByteArray("file%20name"); + QTest::newRow("JustEncoded") << QByteArray(" ") << QByteArray("%20"); + QTest::newRow("HTTPUrl") << QByteArray("http://qt.nokia.com") << QByteArray("http%3A//qt.nokia.com"); + QTest::newRow("HTTPUrlEncoded") << QByteArray("http://qt nokia com") << QByteArray("http%3A//qt%20nokia%20com"); + QTest::newRow("EmptyString") << QByteArray("") << QByteArray(""); + QTest::newRow("Task27166") << QByteArray("Française") << QByteArray("Fran%C3%A7aise"); +} + +void tst_QByteArray::toPercentEncoding() +{ + QFETCH(QByteArray, decodedString); + QFETCH(QByteArray, encodedString); + + QCOMPARE(decodedString.toPercentEncoding("/.").constData(), encodedString.constData()); +} + +void tst_QByteArray::toPercentEncoding2_data() +{ + QTest::addColumn("original"); + QTest::addColumn("encoded"); + QTest::addColumn("excludeInEncoding"); + QTest::addColumn("includeInEncoding"); + + QTest::newRow("test_01") << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~") + << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~") + << QByteArray("") + << QByteArray(""); + QTest::newRow("test_02") << QByteArray("{\t\n\r^\"abc}") + << QByteArray("%7B%09%0A%0D%5E%22abc%7D") + << QByteArray("") + << QByteArray(""); + QTest::newRow("test_03") << QByteArray("://?#[]@!$&'()*+,;=") + << QByteArray("%3A%2F%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D") + << QByteArray("") + << QByteArray(""); + QTest::newRow("test_04") << QByteArray("://?#[]@!$&'()*+,;=") + << QByteArray("%3A%2F%2F%3F%23%5B%5D%40!$&'()*+,;=") + << QByteArray("!$&'()*+,;=") + << QByteArray(""); + QTest::newRow("test_05") << QByteArray("abcd") + << QByteArray("a%62%63d") + << QByteArray("") + << QByteArray("bc"); +} + +void tst_QByteArray::toPercentEncoding2() +{ + QFETCH(QByteArray, original); + QFETCH(QByteArray, encoded); + QFETCH(QByteArray, excludeInEncoding); + QFETCH(QByteArray, includeInEncoding); + + QByteArray encodedData = original.toPercentEncoding(excludeInEncoding, includeInEncoding); + QCOMPARE(encodedData.constData(), encoded.constData()); + QCOMPARE(original, QByteArray::fromPercentEncoding(encodedData)); +} + void tst_QByteArray::compare_data() { QTest::addColumn("str1"); -- cgit v1.2.3 From 4c7e950aad0ed7b2bc114b3ffd5c73f7a433af52 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Sep 2011 20:43:50 +0200 Subject: Mark QUrl::{to,from}Punycode as deprecated since 5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These functions are now aliases to {to,from}Ace, which are usually what you want. The original functions from Qt 4.0 had the wrong semantics and wrong name. The new ones from Qt 4.2 execute the ACE processing from IDNA (specifically, the ToASCII and ToUnicode operations described in the RFC). But so as not to be without tests, export the tests in unit testing environment and test the punycode roundtrip. Note that the tst_QUrl::idna_test_suite test tests *only* the Punycode roundtrip, not the nameprepping. Change-Id: I9b95b4bd07b4425344a5c6ef5cce7cfcb9846d3e Reviewed-by: João Abecasis Reviewed-by: Lars Knoll Reviewed-by: David Faure --- tests/auto/corelib/io/qurl/qurl.pro | 2 +- tests/auto/corelib/io/qurl/tst_qurl.cpp | 709 ------------------- .../auto/corelib/io/qurlinternal/qurlinternal.pro | 5 + .../corelib/io/qurlinternal/tst_qurlinternal.cpp | 750 +++++++++++++++++++++ 4 files changed, 756 insertions(+), 710 deletions(-) create mode 100644 tests/auto/corelib/io/qurlinternal/qurlinternal.pro create mode 100644 tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/qurl.pro b/tests/auto/corelib/io/qurl/qurl.pro index 84538c0859..b475bdb4d7 100644 --- a/tests/auto/corelib/io/qurl/qurl.pro +++ b/tests/auto/corelib/io/qurl/qurl.pro @@ -1,4 +1,4 @@ CONFIG += testcase parallel_test TARGET = tst_qurl -QT = core-private testlib +QT = core testlib SOURCES = tst_qurl.cpp diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index a1b7dbca0f..7ca7fbb81d 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -48,28 +48,7 @@ #include #include #include -#include "private/qtldurl_p.h" -// For testsuites -#define IDNA_ACE_PREFIX "xn--" -#define IDNA_SUCCESS 1 -#define STRINGPREP_NO_UNASSIGNED 1 -#define STRINGPREP_CONTAINS_UNASSIGNED 2 -#define STRINGPREP_CONTAINS_PROHIBITED 3 -#define STRINGPREP_BIDI_BOTH_L_AND_RAL 4 -#define STRINGPREP_BIDI_LEADTRAIL_NOT_RAL 5 - -struct ushortarray { - ushortarray(unsigned short *array = 0) - { - if (array) - memcpy(points, array, sizeof(points)); - } - - unsigned short points[100]; -}; - -Q_DECLARE_METATYPE(ushortarray) Q_DECLARE_METATYPE(QUrl::FormattingOptions) class tst_QUrl : public QObject @@ -89,8 +68,6 @@ private slots: void setUrl(); void i18n_data(); void i18n(); - void punycode_data(); - void punycode(); void resolving_data(); void resolving(); void toString_data(); @@ -152,18 +129,6 @@ private slots: void correctEncodedMistakes(); void correctDecodedMistakes_data(); void correctDecodedMistakes(); - void idna_testsuite_data(); - void idna_testsuite(); - void nameprep_testsuite_data(); - void nameprep_testsuite(); - void nameprep_highcodes_data(); - void nameprep_highcodes(); - void ace_testsuite_data(); - void ace_testsuite(); - void std3violations_data(); - void std3violations(); - void std3deviations_data(); - void std3deviations(); void tldRestrictions_data(); void tldRestrictions(); void emptyQueryOrFragment(); @@ -1549,26 +1514,6 @@ void tst_QUrl::moreIpv6() QCOMPARE(QString::fromLatin1(waba1.toEncoded()), QString::fromLatin1("http://[::ffff:129.144.52.38]/cgi/test.cgi")); } -void tst_QUrl::punycode_data() -{ - QTest::addColumn("original"); - QTest::addColumn("encoded"); - - QTest::newRow("øl") << QString::fromUtf8("øl") << QByteArray("xn--l-4ga"); - QTest::newRow("Bühler") << QString::fromUtf8("Bühler") << QByteArray("xn--Bhler-kva"); - QTest::newRow("räksmörgås") << QString::fromUtf8("räksmörgås") << QByteArray("xn--rksmrgs-5wao1o"); -} - -void tst_QUrl::punycode() -{ - QFETCH(QString, original); - QFETCH(QByteArray, encoded); - - QCOMPARE(QUrl::fromPunycode(encoded), original); - QCOMPARE(QUrl::fromPunycode(QUrl::toPunycode(original)), original); - QCOMPARE(QUrl::toPunycode(original).constData(), encoded.constData()); -} - void tst_QUrl::isRelative_data() { QTest::addColumn("url"); @@ -2025,660 +1970,6 @@ void tst_QUrl::correctDecodedMistakes() } } -void tst_QUrl::idna_testsuite_data() -{ - QTest::addColumn("numchars"); - QTest::addColumn("unicode"); - QTest::addColumn("punycode"); - QTest::addColumn("allowunassigned"); - QTest::addColumn("usestd3asciirules"); - QTest::addColumn("toasciirc"); - QTest::addColumn("tounicoderc"); - - unsigned short d1[] = { 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, - 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, - 0x061F }; - QTest::newRow("Arabic (Egyptian)") << 17 << ushortarray(d1) - << QByteArray(IDNA_ACE_PREFIX "egbpdaj6bu4bxfgehfvwxn") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d2[] = { 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, - 0x6587 }; - QTest::newRow("Chinese (simplified)") << 9 << ushortarray(d2) - << QByteArray(IDNA_ACE_PREFIX "ihqwcrb4cv8a8dqg056pqjye") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d3[] = { 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, - 0x6587 }; - QTest::newRow("Chinese (traditional)") << 9 << ushortarray(d3) - << QByteArray(IDNA_ACE_PREFIX "ihqwctvzc91f659drss3x8bo0yb") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d4[] = { 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, - 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, - 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079 }; - QTest::newRow("Czech") << 22 << ushortarray(d4) - << QByteArray(IDNA_ACE_PREFIX "Proprostnemluvesky-uyb24dma41a") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d5[] = { 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, - 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, - 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA }; - QTest::newRow("Hebrew") << 22 << ushortarray(d5) - << QByteArray(IDNA_ACE_PREFIX "4dbcagdahymbxekheh6e0a7fei0b") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d6[] = { 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, - 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, - 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, - 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902 }; - QTest::newRow("Hindi (Devanagari)") << 30 << ushortarray(d6) - << QByteArray(IDNA_ACE_PREFIX "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd") - << 0 << 0 << IDNA_SUCCESS; - - unsigned short d7[] = { 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, - 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, - 0x306E, 0x304B }; - QTest::newRow("Japanese (kanji and hiragana)") << 18 << ushortarray(d7) - << QByteArray(IDNA_ACE_PREFIX "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa") - << 0 << 0 << IDNA_SUCCESS; - - unsigned short d8[] = { 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, - 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, - 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, - 0x0441, 0x0441, 0x043A, 0x0438 }; - QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d8) - << QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d9[] = { 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, - 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, - 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, - 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065, - 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C }; - QTest::newRow("Spanish") << 40 << ushortarray(d9) - << QByteArray(IDNA_ACE_PREFIX "PorqunopuedensimplementehablarenEspaol-fmd56a") - << 0 << 0 << IDNA_SUCCESS; - - unsigned short d10[] = { 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, - 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, - 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, - 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074 }; - QTest::newRow("Vietnamese") << 31 << ushortarray(d10) - << QByteArray(IDNA_ACE_PREFIX "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g") - << 0 << 0 << IDNA_SUCCESS; - - unsigned short d11[] = { 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F }; - QTest::newRow("Japanese") << 8 << ushortarray(d11) - << QByteArray(IDNA_ACE_PREFIX "3B-ww4c5e180e575a65lsy2b") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d12[] = { 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, - 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, - 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053 }; - QTest::newRow("Japanese2") << 24 << ushortarray(d12) - << QByteArray(IDNA_ACE_PREFIX "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n") - << 0 << 0 << IDNA_SUCCESS; - - unsigned short d13[] = { 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, - 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, - 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, - 0x6240 }; - QTest::newRow("Japanese3") << 25 << ushortarray(d13) - << QByteArray(IDNA_ACE_PREFIX "Hello-Another-Way--fc4qua05auwb3674vfr0b") - << 0 << 0 << IDNA_SUCCESS; - - unsigned short d14[] = { 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032 }; - QTest::newRow("Japanese4") << 8 << ushortarray(d14) - << QByteArray(IDNA_ACE_PREFIX "2-u9tlzr9756bt3uc0v") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d15[] = { 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, - 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D }; - QTest::newRow("Japanese5") << 13 << ushortarray(d15) - << QByteArray(IDNA_ACE_PREFIX "MajiKoi5-783gue6qz075azm5e") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d16[] = { 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0 }; - QTest::newRow("Japanese6") << 9 << ushortarray(d16) - << QByteArray(IDNA_ACE_PREFIX "de-jg4avhby1noc0d") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d17[] = { 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067 }; - QTest::newRow("Japanese7") << 7 << ushortarray(d17) - << QByteArray(IDNA_ACE_PREFIX "d9juau41awczczp") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d18[] = { 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac }; - QTest::newRow("Greek") << 8 << ushortarray(d18) - << QByteArray(IDNA_ACE_PREFIX "hxargifdar") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d19[] = { 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127, - 0x0127, 0x0061 }; - QTest::newRow("Maltese (Malti)") << 10 << ushortarray(d19) - << QByteArray(IDNA_ACE_PREFIX "bonusaa-5bb1da") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; - - unsigned short d20[] = {0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435, - 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432, - 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443, - 0x0441, 0x0441, 0x043a, 0x0438 }; - QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d20) - << QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l") - << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; -} - -void tst_QUrl::idna_testsuite() -{ - QFETCH(int, numchars); - QFETCH(ushortarray, unicode); - QFETCH(QByteArray, punycode); - - QString s = QString::fromUtf16(unicode.points, numchars); - QCOMPARE(punycode, QUrl::toPunycode(s)); -} - -void tst_QUrl::nameprep_testsuite_data() -{ - QTest::addColumn("in"); - QTest::addColumn("out"); - QTest::addColumn("profile"); - QTest::addColumn("flags"); - QTest::addColumn("rc"); - - QTest::newRow("Map to nothing") - << QString::fromUtf8("foo\xC2\xAD\xCD\x8F\xE1\xA0\x86\xE1\xA0\x8B" - "bar""\xE2\x80\x8B\xE2\x81\xA0""baz\xEF\xB8\x80\xEF\xB8\x88" - "\xEF\xB8\x8F\xEF\xBB\xBF") - << QString::fromUtf8("foobarbaz") - << QString() << 0 << 0; - - QTest::newRow("Case folding ASCII U+0043 U+0041 U+0046 U+0045") - << QString::fromUtf8("CAFE") - << QString::fromUtf8("cafe") - << QString() << 0 << 0; - - QTest::newRow("Case folding 8bit U+00DF (german sharp s)") - << QString::fromUtf8("\xC3\x9F") - << QString("ss") - << QString() << 0 << 0; - - QTest::newRow("Case folding U+0130 (turkish capital I with dot)") - << QString::fromUtf8("\xC4\xB0") - << QString::fromUtf8("i\xcc\x87") - << QString() << 0 << 0; - - QTest::newRow("Case folding multibyte U+0143 U+037A") - << QString::fromUtf8("\xC5\x83\xCD\xBA") - << QString::fromUtf8("\xC5\x84 \xCE\xB9") - << QString() << 0 << 0; - - QTest::newRow("Case folding U+2121 U+33C6 U+1D7BB") - << QString::fromUtf8("\xE2\x84\xA1\xE3\x8F\x86\xF0\x9D\x9E\xBB") - << QString::fromUtf8("telc\xE2\x88\x95""kg\xCF\x83") - << QString() << 0 << 0; - - QTest::newRow("Normalization of U+006a U+030c U+00A0 U+00AA") - << QString::fromUtf8("\x6A\xCC\x8C\xC2\xA0\xC2\xAA") - << QString::fromUtf8("\xC7\xB0 a") - << QString() << 0 << 0; - - QTest::newRow("Case folding U+1FB7 and normalization") - << QString::fromUtf8("\xE1\xBE\xB7") - << QString::fromUtf8("\xE1\xBE\xB6\xCE\xB9") - << QString() << 0 << 0; - - QTest::newRow("Self-reverting case folding U+01F0 and normalization") -// << QString::fromUtf8("\xC7\xF0") ### typo in the original testsuite - << QString::fromUtf8("\xC7\xB0") - << QString::fromUtf8("\xC7\xB0") - << QString() << 0 << 0; - - QTest::newRow("Self-reverting case folding U+0390 and normalization") - << QString::fromUtf8("\xCE\x90") - << QString::fromUtf8("\xCE\x90") - << QString() << 0 << 0; - - QTest::newRow("Self-reverting case folding U+03B0 and normalization") - << QString::fromUtf8("\xCE\xB0") - << QString::fromUtf8("\xCE\xB0") - << QString() << 0 << 0; - - QTest::newRow("Self-reverting case folding U+1E96 and normalization") - << QString::fromUtf8("\xE1\xBA\x96") - << QString::fromUtf8("\xE1\xBA\x96") - << QString() << 0 << 0; - - QTest::newRow("Self-reverting case folding U+1F56 and normalization") - << QString::fromUtf8("\xE1\xBD\x96") - << QString::fromUtf8("\xE1\xBD\x96") - << QString() << 0 << 0; - - QTest::newRow("ASCII space character U+0020") - << QString::fromUtf8("\x20") - << QString::fromUtf8("\x20") - << QString() << 0 << 0; - - QTest::newRow("Non-ASCII 8bit space character U+00A0") - << QString::fromUtf8("\xC2\xA0") - << QString::fromUtf8("\x20") - << QString() << 0 << 0; - - QTest::newRow("Non-ASCII multibyte space character U+1680") - << QString::fromUtf8("\xE1\x9A\x80") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Non-ASCII multibyte space character U+2000") - << QString::fromUtf8("\xE2\x80\x80") - << QString::fromUtf8("\x20") - << QString() << 0 << 0; - - QTest::newRow("Zero Width Space U+200b") - << QString::fromUtf8("\xE2\x80\x8b") - << QString() - << QString() << 0 << 0; - - QTest::newRow("Non-ASCII multibyte space character U+3000") - << QString::fromUtf8("\xE3\x80\x80") - << QString::fromUtf8("\x20") - << QString() << 0 << 0; - - QTest::newRow("ASCII control characters U+0010 U+007F") - << QString::fromUtf8("\x10\x7F") - << QString::fromUtf8("\x10\x7F") - << QString() << 0 << 0; - - QTest::newRow("Non-ASCII 8bit control character U+0085") - << QString::fromUtf8("\xC2\x85") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Non-ASCII multibyte control character U+180E") - << QString::fromUtf8("\xE1\xA0\x8E") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Zero Width No-Break Space U+FEFF") - << QString::fromUtf8("\xEF\xBB\xBF") - << QString() - << QString() << 0 << 0; - - QTest::newRow("Non-ASCII control character U+1D175") - << QString::fromUtf8("\xF0\x9D\x85\xB5") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Plane 0 private use character U+F123") - << QString::fromUtf8("\xEF\x84\xA3") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Plane 15 private use character U+F1234") - << QString::fromUtf8("\xF3\xB1\x88\xB4") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Plane 16 private use character U+10F234") - << QString::fromUtf8("\xF4\x8F\x88\xB4") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Non-character code point U+8FFFE") - << QString::fromUtf8("\xF2\x8F\xBF\xBE") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Non-character code point U+10FFFF") - << QString::fromUtf8("\xF4\x8F\xBF\xBF") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Surrogate code U+DF42") - << QString::fromUtf8("\xED\xBD\x82") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Non-plain text character U+FFFD") - << QString::fromUtf8("\xEF\xBF\xBD") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Ideographic description character U+2FF5") - << QString::fromUtf8("\xE2\xBF\xB5") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Display property character U+0341") - << QString::fromUtf8("\xCD\x81") - << QString::fromUtf8("\xCC\x81") - << QString() << 0 << 0; - - QTest::newRow("Left-to-right mark U+200E") - << QString::fromUtf8("\xE2\x80\x8E") - << QString::fromUtf8("\xCC\x81") - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Deprecated U+202A") - << QString::fromUtf8("\xE2\x80\xAA") - << QString::fromUtf8("\xCC\x81") - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Language tagging character U+E0001") - << QString::fromUtf8("\xF3\xA0\x80\x81") - << QString::fromUtf8("\xCC\x81") - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Language tagging character U+E0042") - << QString::fromUtf8("\xF3\xA0\x81\x82") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; - - QTest::newRow("Bidi: RandALCat character U+05BE and LCat characters") - << QString::fromUtf8("foo\xD6\xBE""bar") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL; - - QTest::newRow("Bidi: RandALCat character U+FD50 and LCat characters") - << QString::fromUtf8("foo\xEF\xB5\x90""bar") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL; - - QTest::newRow("Bidi: RandALCat character U+FB38 and LCat characters") - << QString::fromUtf8("foo\xEF\xB9\xB6""bar") - << QString::fromUtf8("foo \xd9\x8e""bar") - << QString() << 0 << 0; - - QTest::newRow("Bidi: RandALCat without trailing RandALCat U+0627 U+0031") - << QString::fromUtf8("\xD8\xA7\x31") - << QString() - << QString("Nameprep") << 0 << STRINGPREP_BIDI_LEADTRAIL_NOT_RAL; - - QTest::newRow("Bidi: RandALCat character U+0627 U+0031 U+0628") - << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8") - << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8") - << QString() << 0 << 0; - - QTest::newRow("Unassigned code point U+E0002") - << QString::fromUtf8("\xF3\xA0\x80\x82") - << QString() - << QString("Nameprep") << STRINGPREP_NO_UNASSIGNED << STRINGPREP_CONTAINS_UNASSIGNED; - - QTest::newRow("Larger test (shrinking)") - << QString::fromUtf8("X\xC2\xAD\xC3\x9F\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2" - "\xaa\xce\xb0\xe2\x80\x80") - << QString::fromUtf8("xssi\xcc\x87""tel\xc7\xb0 a\xce\xb0 ") - << QString("Nameprep") << 0 << 0; - - QTest::newRow("Larger test (expanding)") - << QString::fromUtf8("X\xC3\x9F\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80") - << QString::fromUtf8("xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88" - "\xe3\x83\xab""i\xcc\x87""tel\x28""d\x29\xe3\x82\xa2\xe3\x83\x91" - "\xe3\x83\xbc\xe3\x83\x88") - << QString() << 0 << 0; -} - -#ifdef QT_BUILD_INTERNAL -QT_BEGIN_NAMESPACE -Q_CORE_EXPORT extern void qt_nameprep(QString *source, int from); -Q_CORE_EXPORT extern bool qt_check_std3rules(const QChar *, int); -QT_END_NAMESPACE -#endif - -void tst_QUrl::nameprep_testsuite() -{ -#ifdef QT_BUILD_INTERNAL - QFETCH(QString, in); - QFETCH(QString, out); - QFETCH(QString, profile); - - QEXPECT_FAIL("Left-to-right mark U+200E", - "Investigate further", Continue); - QEXPECT_FAIL("Deprecated U+202A", - "Investigate further", Continue); - QEXPECT_FAIL("Language tagging character U+E0001", - "Investigate further", Continue); - qt_nameprep(&in, 0); - QCOMPARE(in, out); -#endif -} - -void tst_QUrl::nameprep_highcodes_data() -{ - QTest::addColumn("in"); - QTest::addColumn("out"); - QTest::addColumn("profile"); - QTest::addColumn("flags"); - QTest::addColumn("rc"); - - { - QChar st[] = { '-', 0xd801, 0xdc1d, 'a' }; - QChar se[] = { '-', 0xd801, 0xdc45, 'a' }; - QTest::newRow("highcodes (U+1041D)") - << QString(st, sizeof(st)/sizeof(st[0])) - << QString(se, sizeof(se)/sizeof(se[0])) - << QString() << 0 << 0; - } - { - QChar st[] = { 0x011C, 0xd835, 0xdf6e, 0x0110 }; - QChar se[] = { 0x011D, 0x03C9, 0x0111 }; - QTest::newRow("highcodes (U+1D76E)") - << QString(st, sizeof(st)/sizeof(st[0])) - << QString(se, sizeof(se)/sizeof(se[0])) - << QString() << 0 << 0; - } - { - QChar st[] = { 'D', 0xdb40, 0xdc20, 'o', 0xd834, 0xdd7a, '\'', 0x2060, 'h' }; - QChar se[] = { 'd', 'o', '\'', 'h' }; - QTest::newRow("highcodes (D, U+E0020, o, U+1D17A, ', U+2060, h)") - << QString(st, sizeof(st)/sizeof(st[0])) - << QString(se, sizeof(se)/sizeof(se[0])) - << QString() << 0 << 0; - } -} - -void tst_QUrl::nameprep_highcodes() -{ -#ifdef QT_BUILD_INTERNAL - QFETCH(QString, in); - QFETCH(QString, out); - QFETCH(QString, profile); - - qt_nameprep(&in, 0); - QCOMPARE(in, out); -#endif -} - -void tst_QUrl::ace_testsuite_data() -{ - QTest::addColumn("in"); - QTest::addColumn("toace"); - QTest::addColumn("fromace"); - QTest::addColumn("unicode"); - - QTest::newRow("ascii-lower") << "fluke" << "fluke" << "fluke" << "fluke"; - QTest::newRow("ascii-mixed") << "FLuke" << "fluke" << "fluke" << "fluke"; - QTest::newRow("ascii-upper") << "FLUKE" << "fluke" << "fluke" << "fluke"; - - QTest::newRow("asciifolded") << QString::fromLatin1("stra\337e") << "strasse" << "." << "strasse"; - QTest::newRow("asciifolded-dotcom") << QString::fromLatin1("stra\337e.example.com") << "strasse.example.com" << "." << "strasse.example.com"; - QTest::newRow("greek-mu") << QString::fromLatin1("\265V") - <<"xn--v-lmb" - << "." - << QString::fromUtf8("\316\274v"); - - QTest::newRow("non-ascii-lower") << QString::fromLatin1("alqualond\353") - << "xn--alqualond-34a" - << "." - << QString::fromLatin1("alqualond\353"); - QTest::newRow("non-ascii-mixed") << QString::fromLatin1("Alqualond\353") - << "xn--alqualond-34a" - << "." - << QString::fromLatin1("alqualond\353"); - QTest::newRow("non-ascii-upper") << QString::fromLatin1("ALQUALOND\313") - << "xn--alqualond-34a" - << "." - << QString::fromLatin1("alqualond\353"); - - QTest::newRow("idn-lower") << "xn--alqualond-34a" << "xn--alqualond-34a" - << QString::fromLatin1("alqualond\353") - << QString::fromLatin1("alqualond\353"); - QTest::newRow("idn-mixed") << "Xn--alqualond-34a" << "xn--alqualond-34a" - << QString::fromLatin1("alqualond\353") - << QString::fromLatin1("alqualond\353"); - QTest::newRow("idn-mixed2") << "XN--alqualond-34a" << "xn--alqualond-34a" - << QString::fromLatin1("alqualond\353") - << QString::fromLatin1("alqualond\353"); - QTest::newRow("idn-mixed3") << "xn--ALQUALOND-34a" << "xn--alqualond-34a" - << QString::fromLatin1("alqualond\353") - << QString::fromLatin1("alqualond\353"); - QTest::newRow("idn-mixed4") << "xn--alqualond-34A" << "xn--alqualond-34a" - << QString::fromLatin1("alqualond\353") - << QString::fromLatin1("alqualond\353"); - QTest::newRow("idn-upper") << "XN--ALQUALOND-34A" << "xn--alqualond-34a" - << QString::fromLatin1("alqualond\353") - << QString::fromLatin1("alqualond\353"); - - QTest::newRow("separator-3002") << QString::fromUtf8("example\343\200\202com") - << "example.com" << "." << "example.com"; - - QString egyptianIDN = - QString::fromUtf8("\331\210\330\262\330\247\330\261\330\251\055\330\247\331\204\330" - "\243\330\252\330\265\330\247\331\204\330\247\330\252.\331\205" - "\330\265\330\261"); - QTest::newRow("egyptian-tld-ace") - << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" - << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" - << "." - << egyptianIDN; - QTest::newRow("egyptian-tld-unicode") - << egyptianIDN - << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" - << "." - << egyptianIDN; - QTest::newRow("egyptian-tld-mix1") - << QString::fromUtf8("\331\210\330\262\330\247\330\261\330\251\055\330\247\331\204\330" - "\243\330\252\330\265\330\247\331\204\330\247\330\252.xn--wgbh1c") - << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" - << "." - << egyptianIDN; - QTest::newRow("egyptian-tld-mix2") - << QString::fromUtf8("xn----rmckbbajlc6dj7bxne2c.\331\205\330\265\330\261") - << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" - << "." - << egyptianIDN; -} - -void tst_QUrl::ace_testsuite() -{ - static const char canonsuffix[] = ".troll.no"; - QFETCH(QString, in); - QFETCH(QString, toace); - QFETCH(QString, fromace); - QFETCH(QString, unicode); - - const char *suffix = canonsuffix; - if (toace.contains('.')) - suffix = 0; - - QString domain = in + suffix; - QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); - if (fromace != ".") - QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); - QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); - - domain = in + (suffix ? ".troll.No" : ""); - QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); - if (fromace != ".") - QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); - QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); - - domain = in + (suffix ? ".troll.NO" : ""); - QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); - if (fromace != ".") - QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); - QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); -} - -void tst_QUrl::std3violations_data() -{ - QTest::addColumn("source"); - QTest::addColumn("validUrl"); - - QTest::newRow("too-long") << "this-domain-is-far-too-long-for-its-own-good-and-should-have-been-limited-to-63-chars" << false; - QTest::newRow("dash-begin") << "-x-foo" << false; - QTest::newRow("dash-end") << "x-foo-" << false; - QTest::newRow("dash-begin-end") << "-foo-" << false; - - QTest::newRow("control") << "\033foo" << false; - QTest::newRow("bang") << "foo!" << false; - QTest::newRow("plus") << "foo+bar" << false; - QTest::newRow("dot") << "foo.bar"; - QTest::newRow("startingdot") << ".bar" << false; - QTest::newRow("startingdot2") << ".example.com" << false; - QTest::newRow("slash") << "foo/bar" << true; - QTest::newRow("colon") << "foo:80" << true; - QTest::newRow("question") << "foo?bar" << true; - QTest::newRow("at") << "foo@bar" << true; - QTest::newRow("backslash") << "foo\\bar" << false; - - // these characters are transformed by NFKC to non-LDH characters - QTest::newRow("dot-like") << QString::fromUtf8("foo\342\200\244bar") << false; // U+2024 ONE DOT LEADER - QTest::newRow("slash-like") << QString::fromUtf8("foo\357\274\217bar") << false; // U+FF0F FULLWIDTH SOLIDUS - - // The following should be invalid but isn't - // the DIVISON SLASH doesn't case-fold to a slash - // is this a problem with RFC 3490? - //QTest::newRow("slash-like2") << QString::fromUtf8("foo\342\210\225bar") << false; // U+2215 DIVISION SLASH -} - -void tst_QUrl::std3violations() -{ - QFETCH(QString, source); - -#ifdef QT_BUILD_INTERNAL - { - QString prepped = source; - qt_nameprep(&prepped, 0); - QVERIFY(!qt_check_std3rules(prepped.constData(), prepped.length())); - } -#endif - - if (source.contains('.')) - return; // this test ends here - - QUrl url; - url.setHost(source); - QVERIFY(url.host().isEmpty()); - - QFETCH(bool, validUrl); - if (validUrl) - return; // test ends here for these cases - - url = QUrl("http://" + source + "/some/path"); - QVERIFY(!url.isValid()); -} - -void tst_QUrl::std3deviations_data() -{ - QTest::addColumn("source"); - - QTest::newRow("ending-dot") << "example.com."; - QTest::newRow("ending-dot3002") << QString("example.com") + QChar(0x3002); - QTest::newRow("underline") << "foo_bar"; //QTBUG-7434 -} - -void tst_QUrl::std3deviations() -{ - QFETCH(QString, source); - QVERIFY(!QUrl::toAce(source).isEmpty()); - - QUrl url; - url.setHost(source); - QVERIFY(!url.host().isEmpty()); -} - void tst_QUrl::tldRestrictions_data() { QTest::addColumn("tld"); diff --git a/tests/auto/corelib/io/qurlinternal/qurlinternal.pro b/tests/auto/corelib/io/qurlinternal/qurlinternal.pro new file mode 100644 index 0000000000..117ad96446 --- /dev/null +++ b/tests/auto/corelib/io/qurlinternal/qurlinternal.pro @@ -0,0 +1,5 @@ +CONFIG += testcase +TARGET = tst_qurlinternal +SOURCES += tst_qurlinternal.cpp ../../codecs/utf8/utf8data.cpp +QT = core core-private testlib +CONFIG += parallel_test diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp new file mode 100644 index 0000000000..10c4736f68 --- /dev/null +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -0,0 +1,750 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "private/qtldurl_p.h" + +QT_BEGIN_NAMESPACE +Q_CORE_EXPORT extern void qt_nameprep(QString *source, int from); +Q_CORE_EXPORT extern bool qt_check_std3rules(const QChar *, int); +Q_CORE_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString *output); +Q_CORE_EXPORT QString qt_punycodeDecoder(const QString &pc); +QT_END_NAMESPACE + +// For testsuites +#define IDNA_ACE_PREFIX "xn--" +#define IDNA_SUCCESS 1 +#define STRINGPREP_NO_UNASSIGNED 1 +#define STRINGPREP_CONTAINS_UNASSIGNED 2 +#define STRINGPREP_CONTAINS_PROHIBITED 3 +#define STRINGPREP_BIDI_BOTH_L_AND_RAL 4 +#define STRINGPREP_BIDI_LEADTRAIL_NOT_RAL 5 + +struct ushortarray { + ushortarray(unsigned short *array = 0) + { + if (array) + memcpy(points, array, sizeof(points)); + } + + unsigned short points[100]; +}; + +Q_DECLARE_METATYPE(ushortarray) +Q_DECLARE_METATYPE(QUrl::FormattingOptions) + +class tst_QUrlInternal : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + // IDNA internals + void idna_testsuite_data(); + void idna_testsuite(); + void nameprep_testsuite_data(); + void nameprep_testsuite(); + void nameprep_highcodes_data(); + void nameprep_highcodes(); + void ace_testsuite_data(); + void ace_testsuite(); + void std3violations_data(); + void std3violations(); + void std3deviations_data(); + void std3deviations(); +}; + +void tst_QUrlInternal::idna_testsuite_data() +{ + QTest::addColumn("numchars"); + QTest::addColumn("unicode"); + QTest::addColumn("punycode"); + QTest::addColumn("allowunassigned"); + QTest::addColumn("usestd3asciirules"); + QTest::addColumn("toasciirc"); + QTest::addColumn("tounicoderc"); + + unsigned short d1[] = { 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, + 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, + 0x061F }; + QTest::newRow("Arabic (Egyptian)") << 17 << ushortarray(d1) + << QByteArray(IDNA_ACE_PREFIX "egbpdaj6bu4bxfgehfvwxn") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d2[] = { 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, + 0x6587 }; + QTest::newRow("Chinese (simplified)") << 9 << ushortarray(d2) + << QByteArray(IDNA_ACE_PREFIX "ihqwcrb4cv8a8dqg056pqjye") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d3[] = { 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, + 0x6587 }; + QTest::newRow("Chinese (traditional)") << 9 << ushortarray(d3) + << QByteArray(IDNA_ACE_PREFIX "ihqwctvzc91f659drss3x8bo0yb") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d4[] = { 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, + 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, + 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079 }; + QTest::newRow("Czech") << 22 << ushortarray(d4) + << QByteArray(IDNA_ACE_PREFIX "Proprostnemluvesky-uyb24dma41a") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d5[] = { 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, + 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, + 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA }; + QTest::newRow("Hebrew") << 22 << ushortarray(d5) + << QByteArray(IDNA_ACE_PREFIX "4dbcagdahymbxekheh6e0a7fei0b") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d6[] = { 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, + 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, + 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, + 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902 }; + QTest::newRow("Hindi (Devanagari)") << 30 << ushortarray(d6) + << QByteArray(IDNA_ACE_PREFIX "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd") + << 0 << 0 << IDNA_SUCCESS; + + unsigned short d7[] = { 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, + 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, + 0x306E, 0x304B }; + QTest::newRow("Japanese (kanji and hiragana)") << 18 << ushortarray(d7) + << QByteArray(IDNA_ACE_PREFIX "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa") + << 0 << 0 << IDNA_SUCCESS; + + unsigned short d8[] = { 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, + 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, + 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, + 0x0441, 0x0441, 0x043A, 0x0438 }; + QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d8) + << QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d9[] = { 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, + 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, + 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, + 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065, + 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C }; + QTest::newRow("Spanish") << 40 << ushortarray(d9) + << QByteArray(IDNA_ACE_PREFIX "PorqunopuedensimplementehablarenEspaol-fmd56a") + << 0 << 0 << IDNA_SUCCESS; + + unsigned short d10[] = { 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, + 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, + 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, + 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074 }; + QTest::newRow("Vietnamese") << 31 << ushortarray(d10) + << QByteArray(IDNA_ACE_PREFIX "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g") + << 0 << 0 << IDNA_SUCCESS; + + unsigned short d11[] = { 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F }; + QTest::newRow("Japanese") << 8 << ushortarray(d11) + << QByteArray(IDNA_ACE_PREFIX "3B-ww4c5e180e575a65lsy2b") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + // this test does NOT include nameprepping, so the capitals will remain + unsigned short d12[] = { 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, + 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, + 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053 }; + QTest::newRow("Japanese2") << 24 << ushortarray(d12) + << QByteArray(IDNA_ACE_PREFIX "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n") + << 0 << 0 << IDNA_SUCCESS; + + unsigned short d13[] = { 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, + 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, + 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, + 0x6240 }; + QTest::newRow("Japanese3") << 25 << ushortarray(d13) + << QByteArray(IDNA_ACE_PREFIX "Hello-Another-Way--fc4qua05auwb3674vfr0b") + << 0 << 0 << IDNA_SUCCESS; + + unsigned short d14[] = { 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032 }; + QTest::newRow("Japanese4") << 8 << ushortarray(d14) + << QByteArray(IDNA_ACE_PREFIX "2-u9tlzr9756bt3uc0v") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d15[] = { 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, + 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D }; + QTest::newRow("Japanese5") << 13 << ushortarray(d15) + << QByteArray(IDNA_ACE_PREFIX "MajiKoi5-783gue6qz075azm5e") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d16[] = { 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0 }; + QTest::newRow("Japanese6") << 9 << ushortarray(d16) + << QByteArray(IDNA_ACE_PREFIX "de-jg4avhby1noc0d") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d17[] = { 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067 }; + QTest::newRow("Japanese7") << 7 << ushortarray(d17) + << QByteArray(IDNA_ACE_PREFIX "d9juau41awczczp") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d18[] = { 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac }; + QTest::newRow("Greek") << 8 << ushortarray(d18) + << QByteArray(IDNA_ACE_PREFIX "hxargifdar") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d19[] = { 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127, + 0x0127, 0x0061 }; + QTest::newRow("Maltese (Malti)") << 10 << ushortarray(d19) + << QByteArray(IDNA_ACE_PREFIX "bonusaa-5bb1da") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; + + unsigned short d20[] = {0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435, + 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432, + 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443, + 0x0441, 0x0441, 0x043a, 0x0438 }; + QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d20) + << QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l") + << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS; +} + +void tst_QUrlInternal::idna_testsuite() +{ +#ifdef QT_BUILD_INTERNAL + QFETCH(int, numchars); + QFETCH(ushortarray, unicode); + QFETCH(QByteArray, punycode); + + QString result; + qt_punycodeEncoder((QChar*)unicode.points, numchars, &result); + QCOMPARE(result.toLatin1(), punycode); + QCOMPARE(qt_punycodeDecoder(result), QString::fromUtf16(unicode.points, numchars)); +#endif +} + +void tst_QUrlInternal::nameprep_testsuite_data() +{ + QTest::addColumn("in"); + QTest::addColumn("out"); + QTest::addColumn("profile"); + QTest::addColumn("flags"); + QTest::addColumn("rc"); + + QTest::newRow("Map to nothing") + << QString::fromUtf8("foo\xC2\xAD\xCD\x8F\xE1\xA0\x86\xE1\xA0\x8B" + "bar""\xE2\x80\x8B\xE2\x81\xA0""baz\xEF\xB8\x80\xEF\xB8\x88" + "\xEF\xB8\x8F\xEF\xBB\xBF") + << QString::fromUtf8("foobarbaz") + << QString() << 0 << 0; + + QTest::newRow("Case folding ASCII U+0043 U+0041 U+0046 U+0045") + << QString::fromUtf8("CAFE") + << QString::fromUtf8("cafe") + << QString() << 0 << 0; + + QTest::newRow("Case folding 8bit U+00DF (german sharp s)") + << QString::fromUtf8("\xC3\x9F") + << QString("ss") + << QString() << 0 << 0; + + QTest::newRow("Case folding U+0130 (turkish capital I with dot)") + << QString::fromUtf8("\xC4\xB0") + << QString::fromUtf8("i\xcc\x87") + << QString() << 0 << 0; + + QTest::newRow("Case folding multibyte U+0143 U+037A") + << QString::fromUtf8("\xC5\x83\xCD\xBA") + << QString::fromUtf8("\xC5\x84 \xCE\xB9") + << QString() << 0 << 0; + + QTest::newRow("Case folding U+2121 U+33C6 U+1D7BB") + << QString::fromUtf8("\xE2\x84\xA1\xE3\x8F\x86\xF0\x9D\x9E\xBB") + << QString::fromUtf8("telc\xE2\x88\x95""kg\xCF\x83") + << QString() << 0 << 0; + + QTest::newRow("Normalization of U+006a U+030c U+00A0 U+00AA") + << QString::fromUtf8("\x6A\xCC\x8C\xC2\xA0\xC2\xAA") + << QString::fromUtf8("\xC7\xB0 a") + << QString() << 0 << 0; + + QTest::newRow("Case folding U+1FB7 and normalization") + << QString::fromUtf8("\xE1\xBE\xB7") + << QString::fromUtf8("\xE1\xBE\xB6\xCE\xB9") + << QString() << 0 << 0; + + QTest::newRow("Self-reverting case folding U+01F0 and normalization") +// << QString::fromUtf8("\xC7\xF0") ### typo in the original testsuite + << QString::fromUtf8("\xC7\xB0") + << QString::fromUtf8("\xC7\xB0") + << QString() << 0 << 0; + + QTest::newRow("Self-reverting case folding U+0390 and normalization") + << QString::fromUtf8("\xCE\x90") + << QString::fromUtf8("\xCE\x90") + << QString() << 0 << 0; + + QTest::newRow("Self-reverting case folding U+03B0 and normalization") + << QString::fromUtf8("\xCE\xB0") + << QString::fromUtf8("\xCE\xB0") + << QString() << 0 << 0; + + QTest::newRow("Self-reverting case folding U+1E96 and normalization") + << QString::fromUtf8("\xE1\xBA\x96") + << QString::fromUtf8("\xE1\xBA\x96") + << QString() << 0 << 0; + + QTest::newRow("Self-reverting case folding U+1F56 and normalization") + << QString::fromUtf8("\xE1\xBD\x96") + << QString::fromUtf8("\xE1\xBD\x96") + << QString() << 0 << 0; + + QTest::newRow("ASCII space character U+0020") + << QString::fromUtf8("\x20") + << QString::fromUtf8("\x20") + << QString() << 0 << 0; + + QTest::newRow("Non-ASCII 8bit space character U+00A0") + << QString::fromUtf8("\xC2\xA0") + << QString::fromUtf8("\x20") + << QString() << 0 << 0; + + QTest::newRow("Non-ASCII multibyte space character U+1680") + << QString::fromUtf8("\xE1\x9A\x80") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Non-ASCII multibyte space character U+2000") + << QString::fromUtf8("\xE2\x80\x80") + << QString::fromUtf8("\x20") + << QString() << 0 << 0; + + QTest::newRow("Zero Width Space U+200b") + << QString::fromUtf8("\xE2\x80\x8b") + << QString() + << QString() << 0 << 0; + + QTest::newRow("Non-ASCII multibyte space character U+3000") + << QString::fromUtf8("\xE3\x80\x80") + << QString::fromUtf8("\x20") + << QString() << 0 << 0; + + QTest::newRow("ASCII control characters U+0010 U+007F") + << QString::fromUtf8("\x10\x7F") + << QString::fromUtf8("\x10\x7F") + << QString() << 0 << 0; + + QTest::newRow("Non-ASCII 8bit control character U+0085") + << QString::fromUtf8("\xC2\x85") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Non-ASCII multibyte control character U+180E") + << QString::fromUtf8("\xE1\xA0\x8E") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Zero Width No-Break Space U+FEFF") + << QString::fromUtf8("\xEF\xBB\xBF") + << QString() + << QString() << 0 << 0; + + QTest::newRow("Non-ASCII control character U+1D175") + << QString::fromUtf8("\xF0\x9D\x85\xB5") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Plane 0 private use character U+F123") + << QString::fromUtf8("\xEF\x84\xA3") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Plane 15 private use character U+F1234") + << QString::fromUtf8("\xF3\xB1\x88\xB4") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Plane 16 private use character U+10F234") + << QString::fromUtf8("\xF4\x8F\x88\xB4") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Non-character code point U+8FFFE") + << QString::fromUtf8("\xF2\x8F\xBF\xBE") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Non-character code point U+10FFFF") + << QString::fromUtf8("\xF4\x8F\xBF\xBF") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Surrogate code U+DF42") + << QString::fromUtf8("\xED\xBD\x82") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Non-plain text character U+FFFD") + << QString::fromUtf8("\xEF\xBF\xBD") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Ideographic description character U+2FF5") + << QString::fromUtf8("\xE2\xBF\xB5") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Display property character U+0341") + << QString::fromUtf8("\xCD\x81") + << QString::fromUtf8("\xCC\x81") + << QString() << 0 << 0; + + QTest::newRow("Left-to-right mark U+200E") + << QString::fromUtf8("\xE2\x80\x8E") + << QString::fromUtf8("\xCC\x81") + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Deprecated U+202A") + << QString::fromUtf8("\xE2\x80\xAA") + << QString::fromUtf8("\xCC\x81") + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Language tagging character U+E0001") + << QString::fromUtf8("\xF3\xA0\x80\x81") + << QString::fromUtf8("\xCC\x81") + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Language tagging character U+E0042") + << QString::fromUtf8("\xF3\xA0\x81\x82") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED; + + QTest::newRow("Bidi: RandALCat character U+05BE and LCat characters") + << QString::fromUtf8("foo\xD6\xBE""bar") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL; + + QTest::newRow("Bidi: RandALCat character U+FD50 and LCat characters") + << QString::fromUtf8("foo\xEF\xB5\x90""bar") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL; + + QTest::newRow("Bidi: RandALCat character U+FB38 and LCat characters") + << QString::fromUtf8("foo\xEF\xB9\xB6""bar") + << QString::fromUtf8("foo \xd9\x8e""bar") + << QString() << 0 << 0; + + QTest::newRow("Bidi: RandALCat without trailing RandALCat U+0627 U+0031") + << QString::fromUtf8("\xD8\xA7\x31") + << QString() + << QString("Nameprep") << 0 << STRINGPREP_BIDI_LEADTRAIL_NOT_RAL; + + QTest::newRow("Bidi: RandALCat character U+0627 U+0031 U+0628") + << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8") + << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8") + << QString() << 0 << 0; + + QTest::newRow("Unassigned code point U+E0002") + << QString::fromUtf8("\xF3\xA0\x80\x82") + << QString() + << QString("Nameprep") << STRINGPREP_NO_UNASSIGNED << STRINGPREP_CONTAINS_UNASSIGNED; + + QTest::newRow("Larger test (shrinking)") + << QString::fromUtf8("X\xC2\xAD\xC3\x9F\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2" + "\xaa\xce\xb0\xe2\x80\x80") + << QString::fromUtf8("xssi\xcc\x87""tel\xc7\xb0 a\xce\xb0 ") + << QString("Nameprep") << 0 << 0; + + QTest::newRow("Larger test (expanding)") + << QString::fromUtf8("X\xC3\x9F\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80") + << QString::fromUtf8("xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88" + "\xe3\x83\xab""i\xcc\x87""tel\x28""d\x29\xe3\x82\xa2\xe3\x83\x91" + "\xe3\x83\xbc\xe3\x83\x88") + << QString() << 0 << 0; +} + +void tst_QUrlInternal::nameprep_testsuite() +{ +#ifdef QT_BUILD_INTERNAL + QFETCH(QString, in); + QFETCH(QString, out); + QFETCH(QString, profile); + + QEXPECT_FAIL("Left-to-right mark U+200E", + "Investigate further", Continue); + QEXPECT_FAIL("Deprecated U+202A", + "Investigate further", Continue); + QEXPECT_FAIL("Language tagging character U+E0001", + "Investigate further", Continue); + qt_nameprep(&in, 0); + QCOMPARE(in, out); +#endif +} + +void tst_QUrlInternal::nameprep_highcodes_data() +{ + QTest::addColumn("in"); + QTest::addColumn("out"); + QTest::addColumn("profile"); + QTest::addColumn("flags"); + QTest::addColumn("rc"); + + { + QChar st[] = { '-', 0xd801, 0xdc1d, 'a' }; + QChar se[] = { '-', 0xd801, 0xdc45, 'a' }; + QTest::newRow("highcodes (U+1041D)") + << QString(st, sizeof(st)/sizeof(st[0])) + << QString(se, sizeof(se)/sizeof(se[0])) + << QString() << 0 << 0; + } + { + QChar st[] = { 0x011C, 0xd835, 0xdf6e, 0x0110 }; + QChar se[] = { 0x011D, 0x03C9, 0x0111 }; + QTest::newRow("highcodes (U+1D76E)") + << QString(st, sizeof(st)/sizeof(st[0])) + << QString(se, sizeof(se)/sizeof(se[0])) + << QString() << 0 << 0; + } + { + QChar st[] = { 'D', 0xdb40, 0xdc20, 'o', 0xd834, 0xdd7a, '\'', 0x2060, 'h' }; + QChar se[] = { 'd', 'o', '\'', 'h' }; + QTest::newRow("highcodes (D, U+E0020, o, U+1D17A, ', U+2060, h)") + << QString(st, sizeof(st)/sizeof(st[0])) + << QString(se, sizeof(se)/sizeof(se[0])) + << QString() << 0 << 0; + } +} + +void tst_QUrlInternal::nameprep_highcodes() +{ +#ifdef QT_BUILD_INTERNAL + QFETCH(QString, in); + QFETCH(QString, out); + QFETCH(QString, profile); + + qt_nameprep(&in, 0); + QCOMPARE(in, out); +#endif +} + +void tst_QUrlInternal::ace_testsuite_data() +{ + QTest::addColumn("in"); + QTest::addColumn("toace"); + QTest::addColumn("fromace"); + QTest::addColumn("unicode"); + + QTest::newRow("ascii-lower") << "fluke" << "fluke" << "fluke" << "fluke"; + QTest::newRow("ascii-mixed") << "FLuke" << "fluke" << "fluke" << "fluke"; + QTest::newRow("ascii-upper") << "FLUKE" << "fluke" << "fluke" << "fluke"; + + QTest::newRow("asciifolded") << QString::fromLatin1("stra\337e") << "strasse" << "." << "strasse"; + QTest::newRow("asciifolded-dotcom") << QString::fromLatin1("stra\337e.example.com") << "strasse.example.com" << "." << "strasse.example.com"; + QTest::newRow("greek-mu") << QString::fromLatin1("\265V") + <<"xn--v-lmb" + << "." + << QString::fromUtf8("\316\274v"); + + QTest::newRow("non-ascii-lower") << QString::fromLatin1("alqualond\353") + << "xn--alqualond-34a" + << "." + << QString::fromLatin1("alqualond\353"); + QTest::newRow("non-ascii-mixed") << QString::fromLatin1("Alqualond\353") + << "xn--alqualond-34a" + << "." + << QString::fromLatin1("alqualond\353"); + QTest::newRow("non-ascii-upper") << QString::fromLatin1("ALQUALOND\313") + << "xn--alqualond-34a" + << "." + << QString::fromLatin1("alqualond\353"); + + QTest::newRow("idn-lower") << "xn--alqualond-34a" << "xn--alqualond-34a" + << QString::fromLatin1("alqualond\353") + << QString::fromLatin1("alqualond\353"); + QTest::newRow("idn-mixed") << "Xn--alqualond-34a" << "xn--alqualond-34a" + << QString::fromLatin1("alqualond\353") + << QString::fromLatin1("alqualond\353"); + QTest::newRow("idn-mixed2") << "XN--alqualond-34a" << "xn--alqualond-34a" + << QString::fromLatin1("alqualond\353") + << QString::fromLatin1("alqualond\353"); + QTest::newRow("idn-mixed3") << "xn--ALQUALOND-34a" << "xn--alqualond-34a" + << QString::fromLatin1("alqualond\353") + << QString::fromLatin1("alqualond\353"); + QTest::newRow("idn-mixed4") << "xn--alqualond-34A" << "xn--alqualond-34a" + << QString::fromLatin1("alqualond\353") + << QString::fromLatin1("alqualond\353"); + QTest::newRow("idn-upper") << "XN--ALQUALOND-34A" << "xn--alqualond-34a" + << QString::fromLatin1("alqualond\353") + << QString::fromLatin1("alqualond\353"); + + QTest::newRow("separator-3002") << QString::fromUtf8("example\343\200\202com") + << "example.com" << "." << "example.com"; + + QString egyptianIDN = + QString::fromUtf8("\331\210\330\262\330\247\330\261\330\251\055\330\247\331\204\330" + "\243\330\252\330\265\330\247\331\204\330\247\330\252.\331\205" + "\330\265\330\261"); + QTest::newRow("egyptian-tld-ace") + << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" + << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" + << "." + << egyptianIDN; + QTest::newRow("egyptian-tld-unicode") + << egyptianIDN + << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" + << "." + << egyptianIDN; + QTest::newRow("egyptian-tld-mix1") + << QString::fromUtf8("\331\210\330\262\330\247\330\261\330\251\055\330\247\331\204\330" + "\243\330\252\330\265\330\247\331\204\330\247\330\252.xn--wgbh1c") + << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" + << "." + << egyptianIDN; + QTest::newRow("egyptian-tld-mix2") + << QString::fromUtf8("xn----rmckbbajlc6dj7bxne2c.\331\205\330\265\330\261") + << "xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c" + << "." + << egyptianIDN; +} + +void tst_QUrlInternal::ace_testsuite() +{ + static const char canonsuffix[] = ".troll.no"; + QFETCH(QString, in); + QFETCH(QString, toace); + QFETCH(QString, fromace); + QFETCH(QString, unicode); + + const char *suffix = canonsuffix; + if (toace.contains('.')) + suffix = 0; + + QString domain = in + suffix; + QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); + if (fromace != ".") + QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); + QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); + + domain = in + (suffix ? ".troll.No" : ""); + QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); + if (fromace != ".") + QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); + QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); + + domain = in + (suffix ? ".troll.NO" : ""); + QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); + if (fromace != ".") + QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); + QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); +} + +void tst_QUrlInternal::std3violations_data() +{ + QTest::addColumn("source"); + QTest::addColumn("validUrl"); + + QTest::newRow("too-long") << "this-domain-is-far-too-long-for-its-own-good-and-should-have-been-limited-to-63-chars" << false; + QTest::newRow("dash-begin") << "-x-foo" << false; + QTest::newRow("dash-end") << "x-foo-" << false; + QTest::newRow("dash-begin-end") << "-foo-" << false; + + QTest::newRow("control") << "\033foo" << false; + QTest::newRow("bang") << "foo!" << false; + QTest::newRow("plus") << "foo+bar" << false; + QTest::newRow("dot") << "foo.bar"; + QTest::newRow("startingdot") << ".bar" << false; + QTest::newRow("startingdot2") << ".example.com" << false; + QTest::newRow("slash") << "foo/bar" << true; + QTest::newRow("colon") << "foo:80" << true; + QTest::newRow("question") << "foo?bar" << true; + QTest::newRow("at") << "foo@bar" << true; + QTest::newRow("backslash") << "foo\\bar" << false; + + // these characters are transformed by NFKC to non-LDH characters + QTest::newRow("dot-like") << QString::fromUtf8("foo\342\200\244bar") << false; // U+2024 ONE DOT LEADER + QTest::newRow("slash-like") << QString::fromUtf8("foo\357\274\217bar") << false; // U+FF0F FULLWIDTH SOLIDUS + + // The following should be invalid but isn't + // the DIVISON SLASH doesn't case-fold to a slash + // is this a problem with RFC 3490? + //QTest::newRow("slash-like2") << QString::fromUtf8("foo\342\210\225bar") << false; // U+2215 DIVISION SLASH +} + +void tst_QUrlInternal::std3violations() +{ + QFETCH(QString, source); + +#ifdef QT_BUILD_INTERNAL + { + QString prepped = source; + qt_nameprep(&prepped, 0); + QVERIFY(!qt_check_std3rules(prepped.constData(), prepped.length())); + } +#endif + + if (source.contains('.')) + return; // this test ends here + + QUrl url; + url.setHost(source); + QVERIFY(url.host().isEmpty()); + + QFETCH(bool, validUrl); + if (validUrl) + return; // test ends here for these cases + + url = QUrl("http://" + source + "/some/path"); + QVERIFY(!url.isValid()); +} + +void tst_QUrlInternal::std3deviations_data() +{ + QTest::addColumn("source"); + + QTest::newRow("ending-dot") << "example.com."; + QTest::newRow("ending-dot3002") << QString("example.com") + QChar(0x3002); + QTest::newRow("underline") << "foo_bar"; //QTBUG-7434 +} + +void tst_QUrlInternal::std3deviations() +{ + QFETCH(QString, source); + QVERIFY(!QUrl::toAce(source).isEmpty()); + + QUrl url; + url.setHost(source); + QVERIFY(!url.host().isEmpty()); +} + +QTEST_APPLESS_MAIN(tst_QUrlInternal) + +#include "tst_qurlinternal.moc" -- cgit v1.2.3 From 6028efa3ff56b58ce70d5b8fdb53030185149028 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 5 Sep 2011 23:17:21 +0200 Subject: Add the code that recodes URLs. This one function is an all-in-one: - UTF-8 encoder - UTF-8 decoder - percent encoder - percent decoder The next step is add the ability to modify the behaviour, by telling the function what else it must encode or decode and what it should leave untouched. Change-Id: I997eccfd2f9ad8487305670b18d6c806f4cf6717 Reviewed-by: Lars Knoll --- .../corelib/io/qurlinternal/tst_qurlinternal.cpp | 215 +++++++++++++++++++++ 1 file changed, 215 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 10c4736f68..c71acef148 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Intel Corporation. ** Contact: http://www.qt-project.org/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -49,6 +50,9 @@ Q_CORE_EXPORT extern void qt_nameprep(QString *source, int from); Q_CORE_EXPORT extern bool qt_check_std3rules(const QChar *, int); Q_CORE_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString *output); Q_CORE_EXPORT QString qt_punycodeDecoder(const QString &pc); +Q_CORE_EXPORT QString qt_tolerantParsePercentEncoding(const QString &url); +Q_CORE_EXPORT QString qt_urlRecode(const QString &component, QUrl::ComponentFormattingOptions encoding, + const ushort *tableModifications = 0); QT_END_NAMESPACE // For testsuites @@ -72,6 +76,7 @@ struct ushortarray { Q_DECLARE_METATYPE(ushortarray) Q_DECLARE_METATYPE(QUrl::FormattingOptions) +Q_DECLARE_METATYPE(QUrl::ComponentFormattingOptions) class tst_QUrlInternal : public QObject { @@ -91,6 +96,14 @@ private Q_SLOTS: void std3violations(); void std3deviations_data(); void std3deviations(); + + // percent-encoding internals + void correctEncodedMistakes_data(); + void correctEncodedMistakes(); + void encodingRecode_data(); + void encodingRecode(); + void encodingRecodeInvalidUtf8_data(); + void encodingRecodeInvalidUtf8(); }; void tst_QUrlInternal::idna_testsuite_data() @@ -745,6 +758,208 @@ void tst_QUrlInternal::std3deviations() QVERIFY(!url.host().isEmpty()); } +void tst_QUrlInternal::correctEncodedMistakes_data() +{ + QTest::addColumn("input"); + QTest::addColumn("expected"); + + QTest::newRow("null") << QString() << QString(); + QTest::newRow("empty") << "" << ""; + + // these contain one invalid percent + QTest::newRow("%") << QString("%") << QString("%25"); + QTest::newRow("3%") << QString("3%") << QString("3%25"); + QTest::newRow("13%") << QString("13%") << QString("13%25"); + QTest::newRow("13%!") << QString("13%!") << QString("13%25!"); + QTest::newRow("13%!!") << QString("13%!!") << QString("13%25!!"); + QTest::newRow("13%a") << QString("13%a") << QString("13%25a"); + QTest::newRow("13%az") << QString("13%az") << QString("13%25az"); + + // two invalid percents + QTest::newRow("13%%") << "13%%" << "13%25%25"; + QTest::newRow("13%a%a") << "13%a%a" << "13%25a%25a"; + QTest::newRow("13%az%az") << "13%az%az" << "13%25az%25az"; + + // these are correct (idempotent) + QTest::newRow("13%25") << QString("13%25") << QString("13%25"); + QTest::newRow("13%25%25") << QString("13%25%25") << QString("13%25%25"); + + // these contain one invalid and one valid + // the code assumes they are all invalid + QTest::newRow("13%13..%") << "13%13..%" << "13%2513..%25"; + QTest::newRow("13%..%13") << "13%..%13" << "13%25..%2513"; + + // three percents, one invalid + QTest::newRow("%01%02%3") << "%01%02%3" << "%2501%2502%253"; +} + +void tst_QUrlInternal::correctEncodedMistakes() +{ + QFETCH(QString, input); + QFETCH(QString, expected); + + QString output = qt_tolerantParsePercentEncoding(input); + QCOMPARE(output, expected); + QCOMPARE(output.isNull(), expected.isNull()); +} + +static void addUtf8Data(const char *name, const char *data) +{ + QString encoded = QByteArray(data).toPercentEncoding(); + QString decoded = QString::fromUtf8(data); + + QTest::newRow(QByteArray("decode-") + name) << encoded << QUrl::ComponentFormattingOptions(QUrl::DecodeUnicode) << decoded; + QTest::newRow(QByteArray("encode-") + name) << decoded << QUrl::ComponentFormattingOptions(QUrl::FullyEncoded) << encoded; +} + +void tst_QUrlInternal::encodingRecode_data() +{ + typedef QUrl::ComponentFormattingOptions F; + QTest::addColumn("input"); + QTest::addColumn("encodingMode"); + QTest::addColumn("expected"); + + // -- idempotent tests -- + for (int i = 0; i < 0x10; ++i) { + QByteArray code = QByteArray::number(i, 16); + F mode = QUrl::ComponentFormattingOption(i << 12); + + QTest::newRow("null-0x" + code) << QString() << mode << QString(); + QTest::newRow("empty-0x" + code) << "" << mode << ""; + + // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + // Unreserved characters are never encoded + QTest::newRow("alpha-0x" + code) << "abcABCZZzz" << mode << "abcABCZZzz"; + QTest::newRow("digits-0x" + code) << "01234567890" << mode << "01234567890"; + QTest::newRow("otherunreserved-0x" + code) << "-._~" << mode << "-._~"; + + // Control characters are always encoded + // Use uppercase because the output is also uppercased + QTest::newRow("control-nul-0x" + code) << "%00" << mode << "%00"; + QTest::newRow("control-0x" + code) << "%0D%0A%1F%1A%7F" << mode << "%0D%0A%1F%1A%7F"; + + // The percent is always encoded + QTest::newRow("percent-0x" + code) << "25%2525" << mode << "25%2525"; + + // mixed control and unreserved + QTest::newRow("control-unreserved-0x" + code) << "Foo%00Bar%0D%0Abksp%7F" << mode << "Foo%00Bar%0D%0Abksp%7F"; + } + + // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + // / "*" / "+" / "," / ";" / "=" + // in the default operation, delimiters don't get encoded or decoded + static const char delimiters[] = ":/?#[]@" "!$&'()*+,;="; + for (const char *c = delimiters; *c; ++c) { + QByteArray code = QByteArray::number(*c, 16); + QString encoded = QString("abc%") + code.toUpper() + "def" ; + QString decoded = QString("abc") + *c + "def" ; + QTest::newRow("delimiter-encoded-" + code) << encoded << F(QUrl::FullyEncoded) << encoded; + QTest::newRow("delimiter-decoded-" + code) << decoded << F(QUrl::FullyEncoded) << decoded; + } + + // encode control characters + QTest::newRow("encode-control") << "\1abc\2\033esc" << F(QUrl::MostDecoded) << "%01abc%02%1Besc"; + QTest::newRow("encode-nul") << QString::fromLatin1("abc\0def", 7) << F(QUrl::MostDecoded) << "abc%00def"; + + // space + QTest::newRow("space-leave-decoded") << "Hello World " << F(QUrl::DecodeSpaces) << "Hello World "; + QTest::newRow("space-leave-encoded") << "Hello%20World%20" << F(QUrl::FullyEncoded) << "Hello%20World%20"; + QTest::newRow("space-encode") << "Hello World " << F(QUrl::FullyEncoded) << "Hello%20World%20"; + QTest::newRow("space-decode") << "Hello%20World%20" << F(QUrl::DecodeSpaces) << "Hello World "; + + // decode unreserved + QTest::newRow("unreserved-decode") << "%66%6f%6f%42a%72" << F(QUrl::FullyEncoded) << "fooBar"; + + // mix encoding with decoding + QTest::newRow("encode-control-decode-space") << "\1\2%200" << F(QUrl::DecodeSpaces) << "%01%02 0"; + QTest::newRow("decode-space-encode-control") << "%20\1\2" << F(QUrl::DecodeSpaces) << " %01%02"; + + // decode and encode valid UTF-8 data + // invalid is tested in encodingRecodeInvalidUtf8 + addUtf8Data("utf8-2char-1", "\xC2\x80"); // U+0080 + addUtf8Data("utf8-2char-2", "\xDF\xBF"); // U+07FF + addUtf8Data("utf8-3char-1", "\xE0\xA0\x80"); // U+0800 + addUtf8Data("utf8-3char-2", "\xED\x9F\xBF"); // U+D7FF + addUtf8Data("utf8-3char-3", "\xEE\x80\x80"); // U+E000 + addUtf8Data("utf8-3char-4", "\xEF\xBF\xBD"); // U+FFFD + addUtf8Data("utf8-2char-1", "\xF0\x90\x80\x80"); // U+10000 + addUtf8Data("utf8-4char-2", "\xF4\x8F\xBF\xBD"); // U+10FFFD + + // longer UTF-8 sequences, mixed with unreserved + addUtf8Data("utf8-string-1", "R\xc3\xa9sum\xc3\xa9"); + addUtf8Data("utf8-string-2", "\xDF\xBF\xE0\xA0\x80""A"); + addUtf8Data("utf8-string-3", "\xE0\xA0\x80\xDF\xBF..."); + + // special cases: stuff we can encode, but not decode + QTest::newRow("unicode-noncharacter") << QString(QChar(0xffff)) << F(QUrl::FullyEncoded) << "%EF%BF%BF"; + QTest::newRow("unicode-lo-surrogate") << QString(QChar(0xD800)) << F(QUrl::FullyEncoded) << "%ED%A0%80"; + QTest::newRow("unicode-hi-surrogate") << QString(QChar(0xDC00)) << F(QUrl::FullyEncoded) << "%ED%B0%80"; + + // a couple of Unicode strings with leading spaces + QTest::newRow("space-unicode") << QString::fromUtf8(" \xc2\xa0") << F(QUrl::FullyEncoded) << "%20%C2%A0"; + QTest::newRow("space-space-unicode") << QString::fromUtf8(" \xc2\xa0") << F(QUrl::FullyEncoded) << "%20%20%C2%A0"; + QTest::newRow("space-space-space-unicode") << QString::fromUtf8(" \xc2\xa0") << F(QUrl::FullyEncoded) << "%20%20%20%C2%A0"; + + // hex case testing + QTest::newRow("FF") << "%FF" << F(QUrl::FullyEncoded) << "%FF"; + QTest::newRow("Ff") << "%Ff" << F(QUrl::FullyEncoded) << "%FF"; + QTest::newRow("fF") << "%fF" << F(QUrl::FullyEncoded) << "%FF"; + QTest::newRow("ff") << "%ff" << F(QUrl::FullyEncoded) << "%FF"; + + // decode UTF-8 mixed with non-UTF-8 and unreserved + QTest::newRow("utf8-mix-1") << "%80%C2%80" << F(QUrl::DecodeUnicode) << QString::fromUtf8("%80\xC2\x80"); + QTest::newRow("utf8-mix-2") << "%C2%C2%80" << F(QUrl::DecodeUnicode) << QString::fromUtf8("%C2\xC2\x80"); + QTest::newRow("utf8-mix-3") << "%E0%C2%80" << F(QUrl::DecodeUnicode) << QString::fromUtf8("%E0\xC2\x80"); + QTest::newRow("utf8-mix-3") << "A%C2%80" << F(QUrl::DecodeUnicode) << QString::fromUtf8("A\xC2\x80"); + QTest::newRow("utf8-mix-3") << "%C2%80A" << F(QUrl::DecodeUnicode) << QString::fromUtf8("\xC2\x80""A"); +} + +void tst_QUrlInternal::encodingRecode() +{ + QFETCH(QString, input); + QFETCH(QString, expected); + QFETCH(QUrl::ComponentFormattingOptions, encodingMode); + + // ensure the string is properly percent-encoded + QVERIFY2(input == qt_tolerantParsePercentEncoding(input), "Test data is not properly encoded"); + QVERIFY2(expected == qt_tolerantParsePercentEncoding(expected), "Test data is not properly encoded"); + + QString output = qt_urlRecode(input, encodingMode); + QCOMPARE(output, expected); + QCOMPARE(output.isNull(), expected.isNull()); +} + +void tst_QUrlInternal::encodingRecodeInvalidUtf8_data() +{ + QTest::addColumn("utf8"); + QTest::addColumn("utf16"); + + extern void loadInvalidUtf8Rows(); + loadInvalidUtf8Rows(); + + extern void loadNonCharactersRows(); + loadNonCharactersRows(); + + QTest::newRow("utf8-mix-4") << QByteArray("\xE0!A2\x80"); + QTest::newRow("utf8-mix-5") << QByteArray("\xE0\xA2!80"); + QTest::newRow("utf8-mix-5") << QByteArray("\xE0\xA2\x33"); +} + +void tst_QUrlInternal::encodingRecodeInvalidUtf8() +{ + QFETCH(QByteArray, utf8); + QString input = utf8.toPercentEncoding(); + + QString output; + output = qt_urlRecode(input, QUrl::DecodeUnicode); + QCOMPARE(output, input); + + // this is just control + output = qt_urlRecode(input, QUrl::FullyEncoded); + QCOMPARE(output, input); +} + QTEST_APPLESS_MAIN(tst_QUrlInternal) #include "tst_qurlinternal.moc" -- cgit v1.2.3 From 73e16b15a6b3dc9838763407665d5797ba5618b2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 Sep 2011 20:36:28 +0200 Subject: Remove the tolerant parsing function and make the recoder tolerant The reason for this change is that the strict parser made little sense to exist. What would the recoder do if it was passed an invalid string? I believe that the tolerant recoder is more efficient than the correcting code followed by the strict recoder. This makes the recoder more complex and probably a little less efficient, but it's better in the common case (tolerant that doesn't need fixes) and in the worst case (needs fixes). Change-Id: I68a0c9fda6765de05914cbd6ba7d3cea560a7cd6 Reviewed-by: Lars Knoll --- .../auto/corelib/io/qurlinternal/tst_qurlinternal.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index c71acef148..3761603c28 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -50,7 +50,6 @@ Q_CORE_EXPORT extern void qt_nameprep(QString *source, int from); Q_CORE_EXPORT extern bool qt_check_std3rules(const QChar *, int); Q_CORE_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString *output); Q_CORE_EXPORT QString qt_punycodeDecoder(const QString &pc); -Q_CORE_EXPORT QString qt_tolerantParsePercentEncoding(const QString &url); Q_CORE_EXPORT QString qt_urlRecode(const QString &component, QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications = 0); QT_END_NAMESPACE @@ -791,6 +790,17 @@ void tst_QUrlInternal::correctEncodedMistakes_data() // three percents, one invalid QTest::newRow("%01%02%3") << "%01%02%3" << "%2501%2502%253"; + + // now mix bad percents with Unicode decoding + QTest::newRow("%C2%") << "%C2%" << "%25C2%25"; + QTest::newRow("%C2%A") << "%C2%A" << "%25C2%25A"; + QTest::newRow("%C2%Az") << "%C2%Az" << "%25C2%25Az"; + QTest::newRow("%E2%A0%") << "%E2%A0%" << "%25E2%25A0%25"; + QTest::newRow("%E2%A0%A") << "%E2%A0%A" << "%25E2%25A0%25A"; + QTest::newRow("%E2%A0%Az") << "%E2%A0%Az" << "%25E2%25A0%25Az"; + QTest::newRow("%F2%A0%A0%") << "%F2%A0%A0%" << "%25F2%25A0%25A0%25"; + QTest::newRow("%F2%A0%A0%A") << "%F2%A0%A0%A" << "%25F2%25A0%25A0%25A"; + QTest::newRow("%F2%A0%A0%Az") << "%F2%A0%A0%Az" << "%25F2%25A0%25A0%25Az"; } void tst_QUrlInternal::correctEncodedMistakes() @@ -798,7 +808,7 @@ void tst_QUrlInternal::correctEncodedMistakes() QFETCH(QString, input); QFETCH(QString, expected); - QString output = qt_tolerantParsePercentEncoding(input); + QString output = qt_urlRecode(input, QUrl::DecodeUnicode); QCOMPARE(output, expected); QCOMPARE(output.isNull(), expected.isNull()); } @@ -921,10 +931,6 @@ void tst_QUrlInternal::encodingRecode() QFETCH(QString, expected); QFETCH(QUrl::ComponentFormattingOptions, encodingMode); - // ensure the string is properly percent-encoded - QVERIFY2(input == qt_tolerantParsePercentEncoding(input), "Test data is not properly encoded"); - QVERIFY2(expected == qt_tolerantParsePercentEncoding(expected), "Test data is not properly encoded"); - QString output = qt_urlRecode(input, encodingMode); QCOMPARE(output, expected); QCOMPARE(output.isNull(), expected.isNull()); -- cgit v1.2.3 From b75aa795feb476111a0706c52a8ebea8dff7640d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 8 Sep 2011 17:40:36 +0200 Subject: Refactor the URL recoder a little Change it to operate on QChar pointers, which gains a little in performance. This also avoids unnecessary detaching in the QString source. In addition, make the output be appended to an existing QString. This will be useful later when we're reconstructing a URL from its components. Change-Id: I7e2f64028277637bd329af5f98001ace253a50c7 Reviewed-by: Lars Knoll --- .../corelib/io/qurlinternal/tst_qurlinternal.cpp | 38 ++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 3761603c28..34b9c94865 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -50,8 +50,8 @@ Q_CORE_EXPORT extern void qt_nameprep(QString *source, int from); Q_CORE_EXPORT extern bool qt_check_std3rules(const QChar *, int); Q_CORE_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString *output); Q_CORE_EXPORT QString qt_punycodeDecoder(const QString &pc); -Q_CORE_EXPORT QString qt_urlRecode(const QString &component, QUrl::ComponentFormattingOptions encoding, - const ushort *tableModifications = 0); +Q_CORE_EXPORT int qt_urlRecode(QString &appendTo, const QChar *input, const QChar *end, + QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications = 0); QT_END_NAMESPACE // For testsuites @@ -762,7 +762,6 @@ void tst_QUrlInternal::correctEncodedMistakes_data() QTest::addColumn("input"); QTest::addColumn("expected"); - QTest::newRow("null") << QString() << QString(); QTest::newRow("empty") << "" << ""; // these contain one invalid percent @@ -808,9 +807,13 @@ void tst_QUrlInternal::correctEncodedMistakes() QFETCH(QString, input); QFETCH(QString, expected); - QString output = qt_urlRecode(input, QUrl::DecodeUnicode); + // prepend some data to be sure that it remains there + QString output = QTest::currentDataTag(); + expected.prepend(output); + + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::DecodeUnicode)) + output += input; QCOMPARE(output, expected); - QCOMPARE(output.isNull(), expected.isNull()); } static void addUtf8Data(const char *name, const char *data) @@ -893,7 +896,7 @@ void tst_QUrlInternal::encodingRecode_data() addUtf8Data("utf8-3char-2", "\xED\x9F\xBF"); // U+D7FF addUtf8Data("utf8-3char-3", "\xEE\x80\x80"); // U+E000 addUtf8Data("utf8-3char-4", "\xEF\xBF\xBD"); // U+FFFD - addUtf8Data("utf8-2char-1", "\xF0\x90\x80\x80"); // U+10000 + addUtf8Data("utf8-4char-1", "\xF0\x90\x80\x80"); // U+10000 addUtf8Data("utf8-4char-2", "\xF4\x8F\xBF\xBD"); // U+10FFFD // longer UTF-8 sequences, mixed with unreserved @@ -931,9 +934,13 @@ void tst_QUrlInternal::encodingRecode() QFETCH(QString, expected); QFETCH(QUrl::ComponentFormattingOptions, encodingMode); - QString output = qt_urlRecode(input, encodingMode); + // prepend some data to be sure that it remains there + QString output = QTest::currentDataTag(); + expected.prepend(output); + + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), encodingMode)) + output += input; QCOMPARE(output, expected); - QCOMPARE(output.isNull(), expected.isNull()); } void tst_QUrlInternal::encodingRecodeInvalidUtf8_data() @@ -957,13 +964,18 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8() QFETCH(QByteArray, utf8); QString input = utf8.toPercentEncoding(); - QString output; - output = qt_urlRecode(input, QUrl::DecodeUnicode); - QCOMPARE(output, input); + // prepend some data to be sure that it remains there + QString output = QTest::currentDataTag(); + + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::DecodeUnicode)) + output += input; + QCOMPARE(output, QTest::currentDataTag() + input); // this is just control - output = qt_urlRecode(input, QUrl::FullyEncoded); - QCOMPARE(output, input); + output = QTest::currentDataTag(); + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyEncoded)) + output += input; + QCOMPARE(output, QTest::currentDataTag() + input); } QTEST_APPLESS_MAIN(tst_QUrlInternal) -- cgit v1.2.3 From 1aeb18038661d8da6d37fa278e37e315e35c5c42 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 3 Sep 2011 15:05:56 +0200 Subject: Long live QUrlQuery This class is meant to replace the QUrl functionality that handled key-value pairs in the query part of an URL. We therefore split the URL parsing code from the code dealing with the pairs: QUrl now only needs to deal with one encoded string, without knowing what it is. Since it doesn't know how to decode the query, QUrl also becomes limited in what it can decode. Following the letter of the RFC, queries will not encode "gen-delims" nor "sub-delims" nor the plus sign (+), thus allowing the most common delimiters options to remain unchanged. QUrlQuery has some undefined behaviour when it comes to empty query keys. It may drop them or keep them; it may merge them, etc. Change-Id: Ia61096fe5060b486196ffb8532e7494eff58fec1 Reviewed-by: Lars Knoll --- tests/auto/corelib/io/qurlquery/qurlquery.pro | 5 + tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp | 695 ++++++++++++++++++++++ 2 files changed, 700 insertions(+) create mode 100644 tests/auto/corelib/io/qurlquery/qurlquery.pro create mode 100644 tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp (limited to 'tests') diff --git a/tests/auto/corelib/io/qurlquery/qurlquery.pro b/tests/auto/corelib/io/qurlquery/qurlquery.pro new file mode 100644 index 0000000000..d344e48337 --- /dev/null +++ b/tests/auto/corelib/io/qurlquery/qurlquery.pro @@ -0,0 +1,5 @@ +QT = core core-private testlib +TARGET = tst_qurlquery +CONFIG += parallel_test testcase +SOURCES += tst_qurlquery.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp new file mode 100644 index 0000000000..4ce621c4ba --- /dev/null +++ b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp @@ -0,0 +1,695 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Intel Corporation. +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +typedef QList > QueryItems; +Q_DECLARE_METATYPE(QueryItems) +Q_DECLARE_METATYPE(QUrl::ComponentFormattingOptions) + +class tst_QUrlQuery : public QObject +{ + Q_OBJECT + +public: + tst_QUrlQuery() + { + qRegisterMetaType(); + } + +private Q_SLOTS: + void constructing(); + void addRemove(); + void multiAddRemove(); + void multiplyAddSamePair(); + void setQueryItems_data(); + void setQueryItems(); + void basicParsing_data(); + void basicParsing(); + void reconstructQuery_data(); + void reconstructQuery(); + void encodedSetQueryItems_data(); + void encodedSetQueryItems(); + void encodedParsing_data(); + void encodedParsing(); + void differentDelimiters(); +}; + +static QString prettyElement(const QString &key, const QString &value) +{ + QString result; + if (key.isNull()) + result += "null -> "; + else + result += '"' % key % "\" -> "; + if (value.isNull()) + result += "null"; + else + result += '"' % value % '"'; + return result; +} + +static QString prettyPair(QList >::const_iterator it) +{ + return prettyElement(it->first, it->second); +} + +template +static QByteArray prettyList(const T &items) +{ + QString result = "("; + bool first = true; + typename T::const_iterator it = items.constBegin(); + for ( ; it != items.constEnd(); ++it) { + if (!first) + result += ", "; + first = false; + result += prettyPair(it); + } + result += ")"; + return result.toLocal8Bit(); +} + +static bool compare(const QList > &actual, const QueryItems &expected, + const char *actualStr, const char *expectedStr, const char *file, int line) +{ + return QTest::compare_helper(actual == expected, "Compared values are not the same", + qstrdup(prettyList(actual)), qstrdup(prettyList(expected).data()), + actualStr, expectedStr, file, line); +} + +#define COMPARE_ITEMS(actual, expected) \ + do { \ + if (!compare(actual, expected, #actual, #expected, __FILE__, __LINE__)) \ + return; \ + } while (0) + +inline QueryItems operator+(QueryItems items, const QPair &pair) +{ + // items is already a copy + items.append(pair); + return items; +} + +inline QueryItems operator+(const QPair &pair, QueryItems items) +{ + // items is already a copy + items.prepend(pair); + return items; +} + +inline QPair qItem(const QString &first, const QString &second) +{ + return qMakePair(first, second); +} + +inline QPair qItem(const char *first, const QString &second) +{ + return qMakePair(QString::fromUtf8(first), second); +} + +inline QPair qItem(const char *first, const char *second) +{ + return qMakePair(QString::fromUtf8(first), QString::fromUtf8(second)); +} + +inline QPair qItem(const QString &first, const char *second) +{ + return qMakePair(first, QString::fromUtf8(second)); +} + +static QUrlQuery emptyQuery() +{ + return QUrlQuery(); +} + +void tst_QUrlQuery::constructing() +{ + QUrlQuery empty; + QVERIFY(empty.isEmpty()); + QCOMPARE(empty.queryPairDelimiter(), QUrlQuery::defaultQueryPairDelimiter()); + QCOMPARE(empty.queryValueDelimiter(), QUrlQuery::defaultQueryValueDelimiter()); + // undefined whether it is detached, but don't crash + QVERIFY(empty.isDetached() || !empty.isDetached()); + + empty.clear(); + QVERIFY(empty.isEmpty()); + + { + QUrlQuery copy(empty); + QVERIFY(copy.isEmpty()); + QVERIFY(!copy.isDetached()); + QVERIFY(copy == empty); + QVERIFY(!(copy != empty)); + + copy = empty; + QVERIFY(copy == empty); + + copy = QUrlQuery(); + QVERIFY(copy == empty); + } + { + QUrlQuery copy(emptyQuery()); + QVERIFY(copy == empty); + } + + QVERIFY(!empty.hasQueryItem("a")); + QVERIFY(empty.queryItemValue("a").isEmpty()); + QVERIFY(empty.allQueryItemValues("a").isEmpty()); + + QVERIFY(!empty.hasQueryItem("")); + QVERIFY(empty.queryItemValue("").isEmpty()); + QVERIFY(empty.allQueryItemValues("").isEmpty()); + + QVERIFY(!empty.hasQueryItem(QString())); + QVERIFY(empty.queryItemValue(QString()).isEmpty()); + QVERIFY(empty.allQueryItemValues(QString()).isEmpty()); + + QVERIFY(empty.queryItems().isEmpty()); + + QUrlQuery other; + other.addQueryItem("a", "b"); + QVERIFY(!other.isEmpty()); + QVERIFY(other.isDetached()); + QVERIFY(other != empty); + QVERIFY(!(other == empty)); + + QUrlQuery copy(other); + QVERIFY(copy == other); + + copy.clear(); + QVERIFY(copy.isEmpty()); + QVERIFY(copy != other); + + copy = other; + QVERIFY(!copy.isEmpty()); + QVERIFY(copy == other); + + copy = QUrlQuery(); + QVERIFY(copy.isEmpty()); + + empty.setQueryDelimiters('(', ')'); + QCOMPARE(empty.queryValueDelimiter(), QChar(QLatin1Char('('))); + QCOMPARE(empty.queryPairDelimiter(), QChar(QLatin1Char(')'))); +} + +void tst_QUrlQuery::addRemove() +{ + QUrlQuery query; + + { + // one item + query.addQueryItem("a", "b"); + QVERIFY(!query.isEmpty()); + QVERIFY(query.hasQueryItem("a")); + QCOMPARE(query.queryItemValue("a"), QString("b")); + QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b"); + + QList > allItems = query.queryItems(); + QCOMPARE(allItems.count(), 1); + QCOMPARE(allItems.at(0).first, QString("a")); + QCOMPARE(allItems.at(0).second, QString("b")); + } + + QUrlQuery original = query; + + { + // two items + query.addQueryItem("c", "d"); + QVERIFY(query.hasQueryItem("a")); + QCOMPARE(query.queryItemValue("a"), QString("b")); + QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b"); + QVERIFY(query.hasQueryItem("c")); + QCOMPARE(query.queryItemValue("c"), QString("d")); + QCOMPARE(query.allQueryItemValues("c"), QStringList() << "d"); + + QList > allItems = query.queryItems(); + QCOMPARE(allItems.count(), 2); + QVERIFY(allItems.contains(qItem("a", "b"))); + QVERIFY(allItems.contains(qItem("c", "d"))); + + QVERIFY(query != original); + QVERIFY(!(query == original)); + } + + { + // remove an item that isn't there + QUrlQuery copy = query; + query.removeQueryItem("e"); + QCOMPARE(query, copy); + } + + { + // remove an item + query.removeQueryItem("c"); + QVERIFY(query.hasQueryItem("a")); + QCOMPARE(query.queryItemValue("a"), QString("b")); + QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b"); + + QList > allItems = query.queryItems(); + QCOMPARE(allItems.count(), 1); + QCOMPARE(allItems.at(0).first, QString("a")); + QCOMPARE(allItems.at(0).second, QString("b")); + + QVERIFY(query == original); + QVERIFY(!(query != original)); + } + + { + // add an item with en empty value + QString emptyButNotNull(0, Qt::Uninitialized); + QVERIFY(emptyButNotNull.isEmpty()); + QVERIFY(!emptyButNotNull.isNull()); + + query.addQueryItem("e", ""); + QVERIFY(query.hasQueryItem("a")); + QCOMPARE(query.queryItemValue("a"), QString("b")); + QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b"); + QVERIFY(query.hasQueryItem("e")); + QCOMPARE(query.queryItemValue("e"), emptyButNotNull); + QCOMPARE(query.allQueryItemValues("e"), QStringList() << emptyButNotNull); + + QList > allItems = query.queryItems(); + QCOMPARE(allItems.count(), 2); + QVERIFY(allItems.contains(qItem("a", "b"))); + QVERIFY(allItems.contains(qItem("e", emptyButNotNull))); + + QVERIFY(query != original); + QVERIFY(!(query == original)); + } + + { + // remove the items + query.removeQueryItem("a"); + query.removeQueryItem("e"); + QVERIFY(query.isEmpty()); + } +} + +void tst_QUrlQuery::multiAddRemove() +{ + QUrlQuery query; + + { + // one item, two values + query.addQueryItem("a", "b"); + query.addQueryItem("a", "c"); + QVERIFY(!query.isEmpty()); + QVERIFY(query.hasQueryItem("a")); + + // returns the first one + QVERIFY(query.queryItemValue("a") == "b"); + + // order is the order we set them in + QVERIFY(query.allQueryItemValues("a") == QStringList() << "b" << "c"); + } + + { + // add another item, two values + query.addQueryItem("A", "B"); + query.addQueryItem("A", "C"); + QVERIFY(query.hasQueryItem("A")); + QVERIFY(query.hasQueryItem("a")); + + QVERIFY(query.queryItemValue("a") == "b"); + QVERIFY(query.allQueryItemValues("a") == QStringList() << "b" << "c"); + QVERIFY(query.queryItemValue("A") == "B"); + QVERIFY(query.allQueryItemValues("A") == QStringList() << "B" << "C"); + } + + { + // remove one of the original items + query.removeQueryItem("a"); + QVERIFY(query.hasQueryItem("a")); + + // it must have removed the first one + QVERIFY(query.queryItemValue("a") == "c"); + } + + { + // remove the items we added later + query.removeAllQueryItems("A"); + QVERIFY(!query.isEmpty()); + QVERIFY(!query.hasQueryItem("A")); + } + + { + // add one element to the current, then remove them + query.addQueryItem("a", "d"); + query.removeAllQueryItems("a"); + QVERIFY(!query.hasQueryItem("a")); + QVERIFY(query.isEmpty()); + } +} + +void tst_QUrlQuery::multiplyAddSamePair() +{ + QUrlQuery query; + query.addQueryItem("a", "a"); + query.addQueryItem("a", "a"); + QCOMPARE(query.allQueryItemValues("a"), QStringList() << "a" << "a"); + + query.addQueryItem("a", "a"); + QCOMPARE(query.allQueryItemValues("a"), QStringList() << "a" << "a" << "a"); + + query.removeQueryItem("a"); + QCOMPARE(query.allQueryItemValues("a"), QStringList() << "a" << "a"); +} + +void tst_QUrlQuery::setQueryItems_data() +{ + QTest::addColumn("items"); + QString emptyButNotNull(0, Qt::Uninitialized); + + QTest::newRow("empty") << QueryItems(); + QTest::newRow("1-novalue") << (QueryItems() << qItem("a", QString())); + QTest::newRow("1-emptyvalue") << (QueryItems() << qItem("a", emptyButNotNull)); + + QueryItems list; + list << qItem("a", "b"); + QTest::newRow("1-value") << list; + QTest::newRow("1-multi") << (list + qItem("a", "c")); + QTest::newRow("1-duplicated") << (list + qItem("a", "b")); + + list << qItem("c", "d"); + QTest::newRow("2") << list; + + list << qItem("c", "e"); + QTest::newRow("2-multi") << list; +} + +void tst_QUrlQuery::setQueryItems() +{ + QFETCH(QueryItems, items); + QUrlQuery query; + + QueryItems::const_iterator it = items.constBegin(); + for ( ; it != items.constEnd(); ++it) + query.addQueryItem(it->first, it->second); + COMPARE_ITEMS(query.queryItems(), items); + + query.clear(); + + query.setQueryItems(items); + COMPARE_ITEMS(query.queryItems(), items); +} + +void tst_QUrlQuery::basicParsing_data() +{ + QTest::addColumn("queryString"); + QTest::addColumn("items"); + QString emptyButNotNull(0, Qt::Uninitialized); + + QTest::newRow("null") << QString() << QueryItems(); + QTest::newRow("empty") << "" << QueryItems(); + + QTest::newRow("1-novalue") << "a" << (QueryItems() << qItem("a", QString())); + QTest::newRow("1-emptyvalue") << "a=" << (QueryItems() << qItem("a", emptyButNotNull)); + QTest::newRow("1-value") << "a=b" << (QueryItems() << qItem("a", "b")); + + // some longer keys + QTest::newRow("1-longkey-novalue") << "thisisalongkey" << (QueryItems() << qItem("thisisalongkey", QString())); + QTest::newRow("1-longkey-emptyvalue") << "thisisalongkey=" << (QueryItems() << qItem("thisisalongkey", emptyButNotNull)); + QTest::newRow("1-longkey-value") << "thisisalongkey=b" << (QueryItems() << qItem("thisisalongkey", "b")); + + // longer values + QTest::newRow("1-longvalue-value") << "a=thisisalongreasonablyvalue" + << (QueryItems() << qItem("a", "thisisalongreasonablyvalue")); + QTest::newRow("1-longboth-value") << "thisisalongkey=thisisalongreasonablyvalue" + << (QueryItems() << qItem("thisisalongkey", "thisisalongreasonablyvalue")); + + // two or more entries + QueryItems baselist; + baselist << qItem("a", "b") << qItem("c", "d"); + QTest::newRow("2-ab-cd") << "a=b&c=d" << baselist; + QTest::newRow("2-cd-ab") << "c=d&a=b" << (QueryItems() << qItem("c", "d") << qItem("a", "b")); + + // the same entry multiply defined + QTest::newRow("2-a-a") << "a&a" << (QueryItems() << qItem("a", QString()) << qItem("a", QString())); + QTest::newRow("2-ab-a") << "a=b&a" << (QueryItems() << qItem("a", "b") << qItem("a", QString())); + QTest::newRow("2-ab-ab") << "a=b&a=b" << (QueryItems() << qItem("a", "b") << qItem("a", "b")); + QTest::newRow("2-ab-ac") << "a=b&a=c" << (QueryItems() << qItem("a", "b") << qItem("a", "c")); + + QPair novalue = qItem("somekey", QString()); + QueryItems list2 = baselist + novalue; + QTest::newRow("3-novalue-ab-cd") << "somekey&a=b&c=d" << (novalue + baselist); + QTest::newRow("3-ab-novalue-cd") << "a=b&somekey&c=d" << (QueryItems() << qItem("a", "b") << novalue << qItem("c", "d")); + QTest::newRow("3-ab-cd-novalue") << "a=b&c=d&somekey" << list2; + + list2 << qItem("otherkeynovalue", QString()); + QTest::newRow("4-ab-cd-novalue-novalue") << "a=b&c=d&somekey&otherkeynovalue" << list2; + + QPair emptyvalue = qItem("somekey", emptyButNotNull); + list2 = baselist + emptyvalue; + QTest::newRow("3-emptyvalue-ab-cd") << "somekey=&a=b&c=d" << (emptyvalue + baselist); + QTest::newRow("3-ab-emptyvalue-cd") << "a=b&somekey=&c=d" << (QueryItems() << qItem("a", "b") << emptyvalue << qItem("c", "d")); + QTest::newRow("3-ab-cd-emptyvalue") << "a=b&c=d&somekey=" << list2; +} + +void tst_QUrlQuery::basicParsing() +{ + QFETCH(QString, queryString); + QFETCH(QueryItems, items); + + QUrlQuery query(queryString); + QCOMPARE(query.isEmpty(), items.isEmpty()); + COMPARE_ITEMS(query.queryItems(), items); +} + +void tst_QUrlQuery::reconstructQuery_data() +{ + QTest::addColumn("queryString"); + QTest::addColumn("items"); + QString emptyButNotNull(0, Qt::Uninitialized); + + QTest::newRow("null") << QString() << QueryItems(); + QTest::newRow("empty") << "" << QueryItems(); + + QTest::newRow("1-novalue") << "a" << (QueryItems() << qItem("a", QString())); + QTest::newRow("1-emptyvalue") << "a=" << (QueryItems() << qItem("a", emptyButNotNull)); + QTest::newRow("1-value") << "a=b" << (QueryItems() << qItem("a", "b")); + + // some longer keys + QTest::newRow("1-longkey-novalue") << "thisisalongkey" << (QueryItems() << qItem("thisisalongkey", QString())); + QTest::newRow("1-longkey-emptyvalue") << "thisisalongkey=" << (QueryItems() << qItem("thisisalongkey", emptyButNotNull)); + QTest::newRow("1-longkey-value") << "thisisalongkey=b" << (QueryItems() << qItem("thisisalongkey", "b")); + + // longer values + QTest::newRow("1-longvalue-value") << "a=thisisalongreasonablyvalue" + << (QueryItems() << qItem("a", "thisisalongreasonablyvalue")); + QTest::newRow("1-longboth-value") << "thisisalongkey=thisisalongreasonablyvalue" + << (QueryItems() << qItem("thisisalongkey", "thisisalongreasonablyvalue")); + + // two or more entries + QueryItems baselist; + baselist << qItem("a", "b") << qItem("c", "d"); + QTest::newRow("2-ab-cd") << "a=b&c=d" << baselist; + + // the same entry multiply defined + QTest::newRow("2-a-a") << "a&a" << (QueryItems() << qItem("a", QString()) << qItem("a", QString())); + QTest::newRow("2-ab-ab") << "a=b&a=b" << (QueryItems() << qItem("a", "b") << qItem("a", "b")); + QTest::newRow("2-ab-ac") << "a=b&a=c" << (QueryItems() << qItem("a", "b") << qItem("a", "c")); + QTest::newRow("2-ac-ab") << "a=c&a=b" << (QueryItems() << qItem("a", "c") << qItem("a", "b")); + QTest::newRow("2-ab-cd") << "a=b&c=d" << (QueryItems() << qItem("a", "b") << qItem("c", "d")); + QTest::newRow("2-cd-ab") << "c=d&a=b" << (QueryItems() << qItem("c", "d") << qItem("a", "b")); + + QueryItems list2 = baselist + qItem("somekey", QString()); + QTest::newRow("3-ab-cd-novalue") << "a=b&c=d&somekey" << list2; + + list2 << qItem("otherkeynovalue", QString()); + QTest::newRow("4-ab-cd-novalue-novalue") << "a=b&c=d&somekey&otherkeynovalue" << list2; + + list2 = baselist + qItem("somekey", emptyButNotNull); + QTest::newRow("3-ab-cd-emptyvalue") << "a=b&c=d&somekey=" << list2; +} + +void tst_QUrlQuery::reconstructQuery() +{ + QFETCH(QString, queryString); + QFETCH(QueryItems, items); + + QUrlQuery query; + + // add the items + for (QueryItems::ConstIterator it = items.constBegin(); it != items.constEnd(); ++it) { + query.addQueryItem(it->first, it->second); + } + QCOMPARE(query.query(), queryString); +} + +void tst_QUrlQuery::encodedSetQueryItems_data() +{ + QTest::addColumn("queryString"); + QTest::addColumn("key"); + QTest::addColumn("value"); + QTest::addColumn("encoding"); + QTest::addColumn("expectedQuery"); + QTest::addColumn("expectedKey"); + QTest::addColumn("expectedValue"); + typedef QUrl::ComponentFormattingOptions F; + + QTest::newRow("nul") << "f%00=bar%00" << "f%00" << "bar%00" << F(QUrl::PrettyDecoded) + << "f%00=bar%00" << "f%00" << "bar%00"; + QTest::newRow("non-decodable-1") << "foo%01%7f=b%1ar" << "foo%01%7f" << "b%1ar" << F(QUrl::PrettyDecoded) + << "foo%01%7F=b%1Ar" << "foo%01%7F" << "b%1Ar"; + QTest::newRow("non-decodable-2") << "foo\x01\x7f=b\x1ar" << "foo\x01\x7f" << "b\x1Ar" << F(QUrl::PrettyDecoded) + << "foo%01%7F=b%1Ar" << "foo%01%7F" << "b%1Ar"; + + QTest::newRow("space") << "%20=%20" << "%20" << "%20" << F(QUrl::PrettyDecoded) + << " = " << " " << " "; + QTest::newRow("encode-space") << " = " << " " << " " << F(QUrl::FullyEncoded) + << "%20=%20" << "%20" << "%20"; + + QTest::newRow("non-delimiters") << "%3C%5C%3E=%7B%7C%7D%5E%60" << "%3C%5C%3E" << "%7B%7C%7D%5E%60" << F(QUrl::PrettyDecoded) + << "<\\>={|}^`" << "<\\>" << "{|}^`"; + QTest::newRow("encode-non-delimiters") << "<\\>={|}^`" << "<\\>" << "{|}^`" << F(QUrl::FullyEncoded) + << "%3C%5C%3E=%7B%7C%7D%5E%60" << "%3C%5C%3E" << "%7B%7C%7D%5E%60"; + + QTest::newRow("equals") << "%3D=%3D" << "%3D" << "%3D" << F(QUrl::PrettyDecoded) + << "%3D=%3D" << "=" << "="; + QTest::newRow("equals-2") << "%3D==" << "=" << "=" << F(QUrl::PrettyDecoded) + << "%3D=%3D" << "=" << "="; + QTest::newRow("ampersand") << "%26=%26" << "%26" << "%26" << F(QUrl::PrettyDecoded) + << "%26=%26" << "&" << "&"; + QTest::newRow("hash") << "#=#" << "%23" << "%23" << F(QUrl::PrettyDecoded) + << "%23=%23" << "#" << "#"; + QTest::newRow("decode-hash") << "%23=%23" << "%23" << "%23" << F(QUrl::DecodeAllDelimiters) + << "#=#" << "#" << "#"; + + QTest::newRow("percent") << "%25=%25" << "%25" << "%25" << F(QUrl::PrettyDecoded) + << "%25=%25" << "%25" << "%25"; + QTest::newRow("bad-percent-1") << "%=%" << "%" << "%" << F(QUrl::PrettyDecoded) + << "%25=%25" << "%25" << "%25"; + QTest::newRow("bad-percent-2") << "%2=%2" << "%2" << "%2" << F(QUrl::PrettyDecoded) + << "%252=%252" << "%252" << "%252"; + + QTest::newRow("plus") << "+=+" << "+" << "+" << F(QUrl::PrettyDecoded) + << "+=+" << "+" << "+"; + QTest::newRow("2b") << "%2b=%2b" << "%2b" << "%2b" << F(QUrl::PrettyDecoded) + << "%2B=%2B" << "%2B" << "%2B"; + // plus signs must not be touched + QTest::newRow("encode-plus") << "+=+" << "+" << "+" << F(QUrl::FullyEncoded) + << "+=+" << "+" << "+"; + QTest::newRow("decode-2b") << "%2b=%2b" << "%2b" << "%2b" << F(QUrl::DecodeAllDelimiters) + << "%2B=%2B" << "%2B" << "%2B"; + + + QTest::newRow("unicode") << "q=R%C3%a9sum%c3%A9" << "q" << "R%C3%a9sum%c3%A9" << F(QUrl::PrettyDecoded) + << QString::fromUtf8("q=R\xc3\xa9sum\xc3\xa9") << "q" << QString::fromUtf8("R\xc3\xa9sum\xc3\xa9"); + QTest::newRow("encode-unicode") << QString::fromUtf8("q=R\xc3\xa9sum\xc3\xa9") << "q" << QString::fromUtf8("R\xc3\xa9sum\xc3\xa9") + << F(QUrl::FullyEncoded) + << "q=R%C3%A9sum%C3%A9" << "q" << "R%C3%A9sum%C3%A9"; +} + +void tst_QUrlQuery::encodedSetQueryItems() +{ + QFETCH(QString, key); + QFETCH(QString, value); + QFETCH(QString, expectedQuery); + QFETCH(QString, expectedKey); + QFETCH(QString, expectedValue); + QFETCH(QUrl::ComponentFormattingOptions, encoding); + QUrlQuery query; + + query.addQueryItem(key, value); + COMPARE_ITEMS(query.queryItems(encoding), QueryItems() << qItem(expectedKey, expectedValue)); + QCOMPARE(query.query(encoding), expectedQuery); +} + +void tst_QUrlQuery::encodedParsing_data() +{ + encodedSetQueryItems_data(); +} + +void tst_QUrlQuery::encodedParsing() +{ + QFETCH(QString, queryString); + QFETCH(QString, expectedQuery); + QFETCH(QString, expectedKey); + QFETCH(QString, expectedValue); + QFETCH(QUrl::ComponentFormattingOptions, encoding); + + QUrlQuery query(queryString); + COMPARE_ITEMS(query.queryItems(encoding), QueryItems() << qItem(expectedKey, expectedValue)); + QCOMPARE(query.query(encoding), expectedQuery); +} + +void tst_QUrlQuery::differentDelimiters() +{ + QUrlQuery query; + query.setQueryDelimiters('(', ')'); + + { + // parse: + query.setQuery("foo(bar)hello(world)"); + + QueryItems expected; + expected << qItem("foo", "bar") << qItem("hello", "world"); + COMPARE_ITEMS(query.queryItems(), expected); + COMPARE_ITEMS(query.queryItems(QUrl::FullyEncoded), expected); + COMPARE_ITEMS(query.queryItems(QUrl::DecodeAllDelimiters), expected); + } + + { + // reconstruct: + // note the final ')' is missing because there are no further items + QCOMPARE(query.query(), QString("foo(bar)hello(world")); + } + + { + // set items containing the new delimiters and the old ones + query.clear(); + query.addQueryItem("z(=)", "y(&)"); + QCOMPARE(query.query(), QString("z%28=%29(y%28&%29")); + + QUrlQuery copy = query; + QCOMPARE(query.query(), QString("z%28=%29(y%28&%29")); + + copy.setQueryDelimiters(QUrlQuery::defaultQueryValueDelimiter(), + QUrlQuery::defaultQueryPairDelimiter()); + QCOMPARE(copy.query(), QString("z(%3D)=y(%26)")); + } +} + +QTEST_APPLESS_MAIN(tst_QUrlQuery) + +#include "tst_qurlquery.moc" -- cgit v1.2.3 From 1c2144c39fa0069bf496e8f77389a9c2f8a31acf Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 8 Sep 2011 22:05:42 +0200 Subject: Forward the methods dealing with the break down of query to QUrlQuery Now that QUrlQuery exists, these methods are no longer necessary in QUrl itself. Manipulation of the items should be done using the new class. They are now implemented using a temporary QUrlQuery. This is hardly efficient but it works. Change-Id: I34820b3101424593d0715841a2057ac3f74d74f0 Reviewed-by: Lars Knoll --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 101 ------------------ tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp | 120 ++++++++++++++++++++++ 2 files changed, 120 insertions(+), 101 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 7ca7fbb81d..900d0b7644 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -114,11 +114,8 @@ private slots: void isRelative_data(); void isRelative(); void setQueryItems(); - void queryItems(); void hasQuery_data(); void hasQuery(); - void hasQueryItem_data(); - void hasQueryItem(); void nameprep(); void isValid(); void schemeValidator_data(); @@ -157,8 +154,6 @@ private slots: void toEncodedNotUsingUninitializedPath(); void emptyAuthorityRemovesExistingAuthority(); void acceptEmptyAuthoritySegments(); - void removeAllEncodedQueryItems_data(); - void removeAllEncodedQueryItems(); }; // Testing get/set functions @@ -1416,8 +1411,6 @@ void tst_QUrl::symmetry() QCOMPARE(url.path(), QString::fromLatin1("/pub")); // this will be encoded ... QCOMPARE(url.encodedQuery().constData(), QString::fromLatin1("a=b&a=d%C3%B8&a=f").toLatin1().constData()); - // unencoded - QCOMPARE(url.allQueryItemValues("a").join(""), QString::fromUtf8("bdøf")); QCOMPARE(url.fragment(), QString::fromUtf8("vræl")); QUrl onlyHost("//qt.nokia.com"); @@ -1577,56 +1570,6 @@ void tst_QUrl::setQueryItems() "/ole&du>anne+jørgen=sant/prosent>%25#top")); } -void tst_QUrl::queryItems() -{ - QUrl url; - QVERIFY(!url.hasQuery()); - - QList > newItems; - newItems += qMakePair(QString("2"), QString("b")); - newItems += qMakePair(QString("1"), QString("a")); - newItems += qMakePair(QString("3"), QString("c")); - newItems += qMakePair(QString("4"), QString("a b")); - newItems += qMakePair(QString("5"), QString("&")); - newItems += qMakePair(QString("foo bar"), QString("hello world")); - newItems += qMakePair(QString("foo+bar"), QString("hello+world")); - newItems += qMakePair(QString("tex"), QString("a + b = c")); - url.setQueryItems(newItems); - QVERIFY(url.hasQuery()); - - QList > setItems = url.queryItems(); - QVERIFY(newItems == setItems); - - url.addQueryItem("1", "z"); - - QVERIFY(url.hasQueryItem("1")); - QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "a"); - - url.addQueryItem("1", "zz"); - - QStringList expected; - expected += "a"; - expected += "z"; - expected += "zz"; - QCOMPARE(expected, url.allQueryItemValues("1")); - - url.removeQueryItem("1"); - QCOMPARE(url.allQueryItemValues("1").size(), 2); - QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "z"); - - url.removeAllQueryItems("1"); - QVERIFY(!url.hasQueryItem("1")); - - QCOMPARE(url.queryItemValue("4").toLatin1().constData(), "a b"); - QCOMPARE(url.queryItemValue("5").toLatin1().constData(), "&"); - QCOMPARE(url.queryItemValue("tex").toLatin1().constData(), "a + b = c"); - QCOMPARE(url.queryItemValue("foo bar").toLatin1().constData(), "hello world"); - url.setUrl("http://www.google.com/search?q=a+b"); - QCOMPARE(url.queryItemValue("q"), QString("a+b")); - url.setUrl("http://www.google.com/search?q=a=b"); // invalid, but should be tolerated - QCOMPARE(url.queryItemValue("q"), QString("a=b")); -} - void tst_QUrl::hasQuery_data() { QTest::addColumn("url"); @@ -1656,27 +1599,6 @@ void tst_QUrl::hasQuery() QCOMPARE(qurl.encodedQuery().isNull(), !trueFalse); } -void tst_QUrl::hasQueryItem_data() -{ - QTest::addColumn("url"); - QTest::addColumn("item"); - QTest::addColumn("trueFalse"); - - QTest::newRow("no query items") << "http://www.foo.bar" << "baz" << false; - QTest::newRow("query item: hello") << "http://www.foo.bar?hello=world" << "hello" << true; - QTest::newRow("no query item: world") << "http://www.foo.bar?hello=world" << "world" << false; - QTest::newRow("query item: qt") << "http://www.foo.bar?hello=world&qt=rocks" << "qt" << true; -} - -void tst_QUrl::hasQueryItem() -{ - QFETCH(QString, url); - QFETCH(QString, item); - QFETCH(bool, trueFalse); - - QCOMPARE(QUrl(url).hasQueryItem(item), trueFalse); -} - void tst_QUrl::nameprep() { QUrl url(QString::fromUtf8("http://www.fu""\xc3""\x9f""ball.de/")); @@ -2568,28 +2490,5 @@ void tst_QUrl::effectiveTLDs() QCOMPARE(domain.topLevelDomain(), TLD); } -void tst_QUrl::removeAllEncodedQueryItems_data() -{ - QTest::addColumn("url"); - QTest::addColumn("key"); - QTest::addColumn("result"); - - QTest::newRow("test1") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("bbb") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&ccc=c"); - QTest::newRow("test2") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("aaa") << QUrl::fromEncoded("http://qt.nokia.com/foo?bbb=b&ccc=c"); -// QTest::newRow("test3") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("ccc") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b"); - QTest::newRow("test4") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("b%62b") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c"); - QTest::newRow("test5") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&b%62b=b&ccc=c") << QByteArray("b%62b") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&ccc=c"); - QTest::newRow("test6") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&b%62b=b&ccc=c") << QByteArray("bbb") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&b%62b=b&ccc=c"); -} - -void tst_QUrl::removeAllEncodedQueryItems() -{ - QFETCH(QUrl, url); - QFETCH(QByteArray, key); - QFETCH(QUrl, result); - url.removeAllEncodedQueryItems(key); - QCOMPARE(url, result); -} - QTEST_MAIN(tst_QUrl) #include "tst_qurl.moc" diff --git a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp index 4ce621c4ba..ec9170bd7d 100644 --- a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp +++ b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp @@ -72,6 +72,12 @@ private Q_SLOTS: void encodedParsing_data(); void encodedParsing(); void differentDelimiters(); + + // old tests from tst_qurl.cpp + // add new tests above + void old_queryItems(); + void old_hasQueryItem_data(); + void old_hasQueryItem(); }; static QString prettyElement(const QString &key, const QString &value) @@ -230,6 +236,14 @@ void tst_QUrlQuery::constructing() empty.setQueryDelimiters('(', ')'); QCOMPARE(empty.queryValueDelimiter(), QChar(QLatin1Char('('))); QCOMPARE(empty.queryPairDelimiter(), QChar(QLatin1Char(')'))); + + QList > query; + query += qMakePair(QString("type"), QString("login")); + query += qMakePair(QString("name"), QString::fromUtf8("åge nissemannsen")); + query += qMakePair(QString("ole&du"), QString::fromUtf8("anne+jørgen=sant")); + query += qMakePair(QString("prosent"), QString("%")); + copy.setQueryItems(query); + QVERIFY(!copy.isEmpty()); } void tst_QUrlQuery::addRemove() @@ -690,6 +704,112 @@ void tst_QUrlQuery::differentDelimiters() } } +void tst_QUrlQuery::old_queryItems() +{ + // test imported from old tst_qurl.cpp + QUrlQuery url; + + QList > newItems; + newItems += qMakePair(QString("1"), QString("a")); + newItems += qMakePair(QString("2"), QString("b")); + newItems += qMakePair(QString("3"), QString("c")); + newItems += qMakePair(QString("4"), QString("a b")); + newItems += qMakePair(QString("5"), QString("&")); + newItems += qMakePair(QString("foo bar"), QString("hello world")); + newItems += qMakePair(QString("foo+bar"), QString("hello+world")); + newItems += qMakePair(QString("tex"), QString("a + b = c")); + url.setQueryItems(newItems); + QVERIFY(!url.isEmpty()); + + QList > setItems = url.queryItems(); + QVERIFY(newItems == setItems); + + url.addQueryItem("1", "z"); + +#if 0 + // undefined behaviour in the new QUrlQuery + + QVERIFY(url.hasQueryItem("1")); + QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "a"); + + url.addQueryItem("1", "zz"); + + QStringList expected; + expected += "a"; + expected += "z"; + expected += "zz"; + QCOMPARE(url.allQueryItemValues("1"), expected); + + url.removeQueryItem("1"); + QCOMPARE(url.allQueryItemValues("1").size(), 2); + QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "z"); +#endif + + url.removeAllQueryItems("1"); + QVERIFY(!url.hasQueryItem("1")); + + QCOMPARE(url.queryItemValue("4").toLatin1().constData(), "a b"); + QCOMPARE(url.queryItemValue("5").toLatin1().constData(), "&"); + QCOMPARE(url.queryItemValue("tex").toLatin1().constData(), "a + b = c"); + QCOMPARE(url.queryItemValue("foo bar").toLatin1().constData(), "hello world"); + + //url.setUrl("http://www.google.com/search?q=a+b"); + url.setQuery("q=a+b"); + QCOMPARE(url.queryItemValue("q"), QString("a+b")); + + //url.setUrl("http://www.google.com/search?q=a=b"); // invalid, but should be tolerated + url.setQuery("q=a=b"); + QCOMPARE(url.queryItemValue("q"), QString("a=b")); +} + +void tst_QUrlQuery::old_hasQueryItem_data() +{ + QTest::addColumn("url"); + QTest::addColumn("item"); + QTest::addColumn("trueFalse"); + + // the old tests started with "http://www.foo.bar" + QTest::newRow("no query items") << "" << "baz" << false; + QTest::newRow("query item: hello") << "hello=world" << "hello" << true; + QTest::newRow("no query item: world") << "hello=world" << "world" << false; + QTest::newRow("query item: qt") << "hello=world&qt=rocks" << "qt" << true; +} + +void tst_QUrlQuery::old_hasQueryItem() +{ + QFETCH(QString, url); + QFETCH(QString, item); + QFETCH(bool, trueFalse); + + QCOMPARE(QUrlQuery(url).hasQueryItem(item), trueFalse); +} + +#if 0 +// this test doesn't make sense anymore +void tst_QUrl::removeAllEncodedQueryItems_data() +{ + QTest::addColumn("url"); + QTest::addColumn("key"); + QTest::addColumn("result"); + + QTest::newRow("test1") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("bbb") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&ccc=c"); + QTest::newRow("test2") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("aaa") << QUrl::fromEncoded("http://qt.nokia.com/foo?bbb=b&ccc=c"); +// QTest::newRow("test3") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("ccc") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b"); + QTest::newRow("test4") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c") << QByteArray("b%62b") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&bbb=b&ccc=c"); + QTest::newRow("test5") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&b%62b=b&ccc=c") << QByteArray("b%62b") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&ccc=c"); + QTest::newRow("test6") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&b%62b=b&ccc=c") << QByteArray("bbb") << QUrl::fromEncoded("http://qt.nokia.com/foo?aaa=a&b%62b=b&ccc=c"); +} + +void tst_QUrl::removeAllEncodedQueryItems() +{ + QFETCH(QUrl, url); + QFETCH(QByteArray, key); + QFETCH(QUrl, result); + url.removeAllEncodedQueryItems(key); + QCOMPARE(url, result); +} +#endif + QTEST_APPLESS_MAIN(tst_QUrlQuery) #include "tst_qurlquery.moc" -- cgit v1.2.3 From 1372d60bde04a31c8036601076d1093a67c6bd46 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 8 Sep 2011 22:06:17 +0200 Subject: Long live the new QUrl implementation. Also say hello to QUrl's constructor and QUrl::toString being allowed again. QUrl operates now on UTF-16 encoded data, where a Unicode character matches its UTF-8 percent-encoded form (as per RFC 3987). The data may exist in different levels of encoding, but it is always in encoded form (a percent is always "%25"). For that reason, the previously dangerous methods are no longer dangerous. The QUrl parser is much more lenient now. Instead of blindly following the grammar from RFC 3986, we try to use common-sense. Hopefully, this will also mean the code is faster. It also operates on QStrings and, for the common case, will not perform any memory allocations it doesn't keep (i.e., it allocates only for the data that is stored in QUrlPrivate). The Null/Empty behaviour that fragments and queries had in Qt4 are now extended to the scheme, username, password and host parts. This means QUrl can remember the difference between "http://@example.com" and "http://example.com". Missing from this commit: - more unit tests, for the new functionality - the implementation of the StrictMode parser - errorString() support - normalisation Change-Id: I6d340b19c1a11b98a48145152513ffec58fb3fe3 Reviewed-by: Lars Knoll --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 319 ++++++++++++++++---------------- 1 file changed, 155 insertions(+), 164 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 900d0b7644..1c34d8a114 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -39,13 +39,15 @@ ** ****************************************************************************/ +#define QT_DEPRECATED +#define QT_DISABLE_DEPRECATED_BEFORE 0 +#include #include #include #include #include -#include #include #include @@ -113,7 +115,6 @@ private slots: void toPercentEncoding(); void isRelative_data(); void isRelative(); - void setQueryItems(); void hasQuery_data(); void hasQuery(); void nameprep(); @@ -200,7 +201,7 @@ void tst_QUrl::getSetCheck() void tst_QUrl::constructing() { QUrl url; - QVERIFY(!url.isValid()); + QVERIFY(url.isValid()); QVERIFY(url.isEmpty()); QCOMPARE(url.port(), -1); QCOMPARE(url.toString(), QString()); @@ -219,18 +220,20 @@ void tst_QUrl::hashInPath() { QUrl withHashInPath; withHashInPath.setPath(QString::fromLatin1("hi#mum.txt")); - QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi#mum.txt")); - QCOMPARE(withHashInPath.toEncoded(), QByteArray("hi%23mum.txt")); - QCOMPARE(withHashInPath.toString(), QString("hi%23mum.txt")); + QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi%23mum.txt")); + QCOMPARE(withHashInPath.path(QUrl::MostDecoded), QString::fromLatin1("hi#mum.txt")); + QCOMPARE(withHashInPath.toString(QUrl::FullyEncoded), QString("hi%23mum.txt")); QCOMPARE(withHashInPath.toDisplayString(QUrl::PreferLocalFile), QString("hi%23mum.txt")); QUrl fromHashInPath = QUrl::fromEncoded(withHashInPath.toEncoded()); QVERIFY(withHashInPath == fromHashInPath); const QUrl localWithHash = QUrl::fromLocalFile("/hi#mum.txt"); - QCOMPARE(localWithHash.path(), QString::fromLatin1("/hi#mum.txt")); QCOMPARE(localWithHash.toEncoded(), QByteArray("file:///hi%23mum.txt")); QCOMPARE(localWithHash.toString(), QString("file:///hi%23mum.txt")); + QEXPECT_FAIL("", "Regression in the new QUrl, will fix soon", Abort); + QCOMPARE(localWithHash.path(), QString::fromLatin1("/hi#mum.txt")); + QCOMPARE(localWithHash.toString(QUrl::PreferLocalFile), QString("/hi#mum.txt")); QCOMPARE(localWithHash.toDisplayString(QUrl::PreferLocalFile), QString("/hi#mum.txt")); } @@ -269,7 +272,8 @@ void tst_QUrl::comparison() // 6.2.2 Syntax-based Normalization QUrl url3 = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D"); QUrl url4 = QUrl::fromEncoded("eXAMPLE://a/./b/../b/%63/%7bfoo%7d"); - QVERIFY(url3 == url4); + QEXPECT_FAIL("", "Broken, FIXME", Continue); + QCOMPARE(url3, url4); // 6.2.2.1 Make sure hexdecimal characters in percent encoding are // treated case-insensitively @@ -278,13 +282,6 @@ void tst_QUrl::comparison() QUrl url6; url6.setEncodedQuery("a=%2A"); QVERIFY(url5 == url6); - - // ensure that encoded characters in the query do not match - QUrl url7; - url7.setEncodedQuery("a=%63"); - QUrl url8; - url8.setEncodedQuery("a=c"); - QVERIFY(url7 != url8); } void tst_QUrl::copying() @@ -325,7 +322,7 @@ void tst_QUrl::setUrl() { QUrl url("hTTp://www.foo.bar:80"); QVERIFY(url.isValid()); - QCOMPARE(url.scheme(), QString::fromLatin1("http")); + QCOMPARE(url.scheme(), QString::fromLatin1("hTTp")); QCOMPARE(url.path(), QString()); QVERIFY(url.encodedQuery().isEmpty()); QVERIFY(url.userInfo().isEmpty()); @@ -333,12 +330,12 @@ void tst_QUrl::setUrl() QCOMPARE(url.host(), QString::fromLatin1("www.foo.bar")); QCOMPARE(url.authority(), QString::fromLatin1("www.foo.bar:80")); QCOMPARE(url.port(), 80); - QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar:80")); - QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://www.foo.bar:80")); - QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("http://www.foo.bar:80")); + QCOMPARE(url.toString(), QString::fromLatin1("hTTp://www.foo.bar:80")); + QCOMPARE(url.toDisplayString(), QString::fromLatin1("hTTp://www.foo.bar:80")); + QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("hTTp://www.foo.bar:80")); QUrl url2("//www1.foo.bar"); - QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www1.foo.bar")); + QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("hTTp://www1.foo.bar")); } { @@ -349,11 +346,11 @@ void tst_QUrl::setUrl() QVERIFY(url.encodedQuery().isEmpty()); QCOMPARE(url.userInfo(), QString::fromLatin1("user:pass")); QVERIFY(url.fragment().isEmpty()); - QCOMPARE(url.host(), QString::fromLatin1("56::56:56:56:127.0.0.1")); - QCOMPARE(url.authority(), QString::fromLatin1("user:pass@[56::56:56:56:127.0.0.1]:99")); + QCOMPARE(url.host(), QString::fromLatin1("56::56:56:56:7f00:1")); + QCOMPARE(url.authority(), QString::fromLatin1("user:pass@[56::56:56:56:7f00:1]:99")); QCOMPARE(url.port(), 99); - QCOMPARE(url.url(), QString::fromLatin1("http://user:pass@[56::56:56:56:127.0.0.1]:99")); - QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://user@[56::56:56:56:127.0.0.1]:99")); + QCOMPARE(url.url(), QString::fromLatin1("http://user:pass@[56::56:56:56:7f00:1]:99")); + QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://user@[56::56:56:56:7f00:1]:99")); } { @@ -510,30 +507,31 @@ void tst_QUrl::setUrl() QUrl url15582("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.html"); QCOMPARE(url15582.toString(), QString::fromLatin1("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html")); - QCOMPARE(url15582.toEncoded(), QByteArray("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html")); + QCOMPARE(url15582.toString(QUrl::FullyEncoded), QString("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html")); } { QUrl carsten; carsten.setPath("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18"); - QCOMPARE(carsten.path(), QString::fromLatin1("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18")); + QCOMPARE(carsten.path(), QString::fromLatin1("/home/gis/src/kde/kdelibs/kfile/.%23kfiledetailview.cpp.1.18")); QUrl charles; charles.setPath("/home/charles/foo%20moo"); - QCOMPARE(charles.path(), QString::fromLatin1("/home/charles/foo%20moo")); + QCOMPARE(charles.path(), QString::fromLatin1("/home/charles/foo moo")); + QCOMPARE(charles.path(QUrl::FullyEncoded), QString::fromLatin1("/home/charles/foo%20moo")); QUrl charles2("file:/home/charles/foo%20moo"); QCOMPARE(charles2.path(), QString::fromLatin1("/home/charles/foo moo")); + QCOMPARE(charles2.path(QUrl::FullyEncoded), QString::fromLatin1("/home/charles/foo%20moo")); } { QUrl udir; - QCOMPARE(udir.toEncoded(), QByteArray()); - QVERIFY(!udir.isValid()); + QCOMPARE(udir.toString(QUrl::FullyEncoded), QString()); udir = QUrl::fromLocalFile("/home/dfaure/file.txt"); QCOMPARE(udir.path(), QString::fromLatin1("/home/dfaure/file.txt")); - QCOMPARE(udir.toEncoded(), QByteArray("file:///home/dfaure/file.txt")); + QCOMPARE(udir.toString(QUrl::FullyEncoded), QString("file:///home/dfaure/file.txt")); } { @@ -591,7 +589,7 @@ void tst_QUrl::setUrl() QCOMPARE(url.scheme(), QString("data")); QCOMPARE(url.host(), QString()); QCOMPARE(url.path(), QString("text/javascript,d5 = 'five\\u0027s';")); - QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20%3D%20'five%5Cu0027s'%3B"); + QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20=%20'five%5Cu0027s';"); } { //check it calls detach @@ -1163,7 +1161,7 @@ void tst_QUrl::compat_isValid_01() QFETCH( bool, res ); QUrl url( urlStr ); - QVERIFY( url.isValid() == res ); + QCOMPARE( url.isValid(), res ); } void tst_QUrl::compat_isValid_02_data() @@ -1178,6 +1176,7 @@ void tst_QUrl::compat_isValid_02_data() QString n = ""; + QTest::newRow( "ok_00" ) << n << n << n << n << -1 << n << (bool)true; QTest::newRow( "ok_01" ) << n << n << n << n << -1 << QString("path") << (bool)true; QTest::newRow( "ok_02" ) << QString("ftp") << n << n << QString("ftp.qt.nokia.com") << -1 << n << (bool)true; QTest::newRow( "ok_03" ) << QString("ftp") << QString("foo") << n << QString("ftp.qt.nokia.com") << -1 << n << (bool)true; @@ -1186,7 +1185,6 @@ void tst_QUrl::compat_isValid_02_data() QTest::newRow( "ok_06" ) << QString("ftp") << QString("foo") << n << QString("ftp.qt.nokia.com") << -1 << QString("path") << (bool)true; QTest::newRow( "ok_07" ) << QString("ftp") << QString("foo") << QString("bar") << QString("ftp.qt.nokia.com") << -1 << QString("path")<< (bool)true; - QTest::newRow( "err_01" ) << n << n << n << n << -1 << n << (bool)false; QTest::newRow( "err_02" ) << QString("ftp") << n << n << n << -1 << n << (bool)true; QTest::newRow( "err_03" ) << n << QString("foo") << n << n << -1 << n << (bool)true; QTest::newRow( "err_04" ) << n << n << QString("bar") << n << -1 << n << (bool)true; @@ -1441,40 +1439,58 @@ void tst_QUrl::ipv6_data() { QTest::addColumn("ipv6Auth"); QTest::addColumn("isValid"); + QTest::addColumn("output"); - QTest::newRow("case 1") << QString::fromLatin1("//[56:56:56:56:56:56:56:56]") << true; - QTest::newRow("case 2") << QString::fromLatin1("//[::56:56:56:56:56:56:56]") << true; - QTest::newRow("case 3") << QString::fromLatin1("//[56::56:56:56:56:56:56]") << true; - QTest::newRow("case 4") << QString::fromLatin1("//[56:56::56:56:56:56:56]") << true; - QTest::newRow("case 5") << QString::fromLatin1("//[56:56:56::56:56:56:56]") << true; - QTest::newRow("case 6") << QString::fromLatin1("//[56:56:56:56::56:56:56]") << true; - QTest::newRow("case 7") << QString::fromLatin1("//[56:56:56:56:56::56:56]") << true; - QTest::newRow("case 8") << QString::fromLatin1("//[56:56:56:56:56:56::56]") << true; - QTest::newRow("case 9") << QString::fromLatin1("//[56:56:56:56:56:56:56::]") << true; - QTest::newRow("case 4 with one less") << QString::fromLatin1("//[56::56:56:56:56:56]") << true; - QTest::newRow("case 4 with less and ip4") << QString::fromLatin1("//[56::56:56:56:127.0.0.1]") << true; - QTest::newRow("case 7 with one and ip4") << QString::fromLatin1("//[56::255.0.0.0]") << true; - QTest::newRow("case 2 with ip4") << QString::fromLatin1("//[::56:56:56:56:56:0.0.0.255]") << true; - QTest::newRow("case 2 with half ip4") << QString::fromLatin1("//[::56:56:56:56:56:56:0.255]") << false; - QTest::newRow("case 4 with less and ip4 and port and useinfo") << QString::fromLatin1("//user:pass@[56::56:56:56:127.0.0.1]:99") << true; - QTest::newRow("case :,") << QString::fromLatin1("//[:,]") << false; - QTest::newRow("case ::bla") << QString::fromLatin1("//[::bla]") << false; + QTest::newRow("case 1") << QString::fromLatin1("//[56:56:56:56:56:56:56:56]") << true + << "//[56:56:56:56:56:56:56:56]"; + QTest::newRow("case 2") << QString::fromLatin1("//[::56:56:56:56:56:56:56]") << true + << "//[0:56:56:56:56:56:56:56]"; + QTest::newRow("case 3") << QString::fromLatin1("//[56::56:56:56:56:56:56]") << true + << "//[56:0:56:56:56:56:56:56]"; + QTest::newRow("case 4") << QString::fromLatin1("//[56:56::56:56:56:56:56]") << true + << "//[56:56:0:56:56:56:56:56]"; + QTest::newRow("case 5") << QString::fromLatin1("//[56:56:56::56:56:56:56]") << true + << "//[56:56:56:0:56:56:56:56]"; + QTest::newRow("case 6") << QString::fromLatin1("//[56:56:56:56::56:56:56]") << true + << "//[56:56:56:56:0:56:56:56]"; + QTest::newRow("case 7") << QString::fromLatin1("//[56:56:56:56:56::56:56]") << true + << "//[56:56:56:56:56:0:56:56]"; + QTest::newRow("case 8") << QString::fromLatin1("//[56:56:56:56:56:56::56]") << true + << "//[56:56:56:56:56:56:0:56]"; + QTest::newRow("case 9") << QString::fromLatin1("//[56:56:56:56:56:56:56::]") << true + << "//[56:56:56:56:56:56:56:0]"; + QTest::newRow("case 4 with one less") << QString::fromLatin1("//[56::56:56:56:56:56]") << true + << "//[56::56:56:56:56:56]"; + QTest::newRow("case 4 with less and ip4") << QString::fromLatin1("//[56::56:56:56:127.0.0.1]") << true + << "//[56::56:56:56:7f00:1]"; + QTest::newRow("case 7 with one and ip4") << QString::fromLatin1("//[56::255.0.0.0]") << true + << "//[56::ff00:0]"; + QTest::newRow("case 2 with ip4") << QString::fromLatin1("//[::56:56:56:56:56:0.0.0.255]") << true + << "//[0:56:56:56:56:56:0:ff]"; + QTest::newRow("case 2 with half ip4") << QString::fromLatin1("//[::56:56:56:56:56:56:0.255]") << false << ""; + QTest::newRow("case 4 with less and ip4 and port and useinfo") + << QString::fromLatin1("//user:pass@[56::56:56:56:127.0.0.1]:99") << true + << "//user:pass@[56::56:56:56:7f00:1]:99"; + QTest::newRow("case :,") << QString::fromLatin1("//[:,]") << false << ""; + QTest::newRow("case ::bla") << QString::fromLatin1("//[::bla]") << false << ""; + QTest::newRow("case v4-mapped") << "//[0:0:0:0:0:ffff:7f00:1]" << true << "//[::ffff:127.0.0.1]"; } void tst_QUrl::ipv6() { QFETCH(QString, ipv6Auth); QFETCH(bool, isValid); + QFETCH(QString, output); QUrl url(ipv6Auth); QCOMPARE(url.isValid(), isValid); if (url.isValid()) { - QCOMPARE(url.toString(), ipv6Auth); + QCOMPARE(url.toString(), output); url.setHost(url.host()); - QCOMPARE(url.toString(), ipv6Auth); + QCOMPARE(url.toString(), output); } -}; +} void tst_QUrl::ipv6_2_data() { @@ -1520,7 +1536,7 @@ void tst_QUrl::isRelative_data() QTest::newRow("man: URL, is relative") << "man:mmap" << false; QTest::newRow("javascript: URL, is relative") << "javascript:doSomething()" << false; QTest::newRow("file: URL, is relative") << "file:/blah" << false; - QTest::newRow("/path, is relative") << "/path" << true; + QTest::newRow("/path, is relative") << "/path" << false; QTest::newRow("something, is relative") << "something" << true; // end kde } @@ -1533,43 +1549,6 @@ void tst_QUrl::isRelative() QCOMPARE(QUrl(url).isRelative(), trueFalse); } -void tst_QUrl::setQueryItems() -{ - QUrl url; - - QList > query; - query += qMakePair(QString("type"), QString("login")); - query += qMakePair(QString("name"), QString::fromUtf8("åge nissemannsen")); - query += qMakePair(QString("ole&du"), QString::fromUtf8("anne+jørgen=sant")); - query += qMakePair(QString("prosent"), QString("%")); - url.setQueryItems(query); - QVERIFY(!url.isEmpty()); - - QCOMPARE(url.encodedQuery().constData(), - QByteArray("type=login&name=%C3%A5ge%20nissemannsen&ole%26du=" - "anne+j%C3%B8rgen%3Dsant&prosent=%25").constData()); - - url.setQueryDelimiters('>', '/'); - url.setQueryItems(query); - - QCOMPARE(url.encodedQuery(), - QByteArray("type>login/name>%C3%A5ge%20nissemannsen/ole&du>" - "anne+j%C3%B8rgen=sant/prosent>%25")); - - url.setFragment(QString::fromLatin1("top")); - QCOMPARE(url.fragment(), QString::fromLatin1("top")); - - url.setScheme("http"); - url.setHost("qt.nokia.com"); - - QCOMPARE(url.toEncoded().constData(), - "http://qt.nokia.com?type>login/name>%C3%A5ge%20nissemannsen/ole&du>" - "anne+j%C3%B8rgen=sant/prosent>%25#top"); - QCOMPARE(url.toString(), - QString::fromUtf8("http://qt.nokia.com?type>login/name>åge nissemannsen" - "/ole&du>anne+jørgen=sant/prosent>%25#top")); -} - void tst_QUrl::hasQuery_data() { QTest::addColumn("url"); @@ -1614,6 +1593,7 @@ void tst_QUrl::isValid() } { QUrl url = QUrl::fromEncoded("http://strange@ok-hostname/", QUrl::StrictMode); + QEXPECT_FAIL("", "StrictMode not implemented yet", Continue); QVERIFY(!url.isValid()); // < and > are not allowed in userinfo in strict mode url.setUserName("normal_username"); @@ -1634,6 +1614,7 @@ void tst_QUrl::isValid() QVERIFY(url.isValid()); url.setAuthority("strange;hostname"); QVERIFY(!url.isValid()); + QEXPECT_FAIL("", "QUrl::errorString not reimplemented", Continue); QVERIFY(url.errorString().contains("invalid hostname")); } @@ -1647,6 +1628,7 @@ void tst_QUrl::isValid() QVERIFY(url.isValid()); url.setHost("stuff;1"); QVERIFY(!url.isValid()); + QEXPECT_FAIL("", "QUrl::errorString not reimplemented", Continue); QVERIFY(url.errorString().contains("invalid hostname")); } @@ -1658,7 +1640,7 @@ void tst_QUrl::schemeValidator_data() QTest::addColumn("result"); QTest::addColumn("toString"); - QTest::newRow("empty") << QByteArray() << false << QString(); + QTest::newRow("empty") << QByteArray() << true << QString(); // ftp QTest::newRow("ftp:") << QByteArray("ftp:") << true << QString("ftp:"); @@ -1691,6 +1673,8 @@ void tst_QUrl::schemeValidator() QFETCH(QString, toString); QUrl url = QUrl::fromEncoded(encodedUrl); + QEXPECT_FAIL("ftp:/index.html", "high-level URL validation not reimplemented yet", Continue); + QEXPECT_FAIL("mailto://smtp.trolltech.com/ole@bull.name", "high-level URL validation not reimplemented yet", Continue); QCOMPARE(url.isValid(), result); } @@ -1698,27 +1682,26 @@ void tst_QUrl::invalidSchemeValidator() { // test that if scheme does not start with an ALPHA, QUrl::isValid() returns false { - QUrl url("1http://qt.nokia.com", QUrl::StrictMode); - QCOMPARE(url.isValid(), false); + QUrl url("1http://qt.nokia.com"); + QVERIFY(url.scheme().isEmpty()); + QVERIFY(url.path().startsWith("1http")); } { QUrl url("http://qt.nokia.com"); url.setScheme("111http://qt.nokia.com"); QCOMPARE(url.isValid(), false); } - { - QUrl url = QUrl::fromEncoded("1http://qt.nokia.com", QUrl::StrictMode); - QCOMPARE(url.isValid(), false); - } - // non-ALPHA character at other positions in the scheme are ok { QUrl url("ht111tp://qt.nokia.com", QUrl::StrictMode); QVERIFY(url.isValid()); + QCOMPARE(url.scheme(), QString("ht111tp")); } { QUrl url("http://qt.nokia.com"); url.setScheme("ht123tp://qt.nokia.com"); + QVERIFY(!url.isValid()); + url.setScheme("http"); QVERIFY(url.isValid()); } { @@ -1733,15 +1716,19 @@ void tst_QUrl::tolerantParser() QUrl url("http://www.example.com/path%20with spaces.html"); QVERIFY(url.isValid()); QCOMPARE(url.path(), QString("/path with spaces.html")); - QCOMPARE(url.toEncoded(), QByteArray("http://www.example.com/path%20with%20spaces.html")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%20with%20spaces.html")); url.setUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode); + QEXPECT_FAIL("", "StrictMode not implemented yet", Continue); QVERIFY(!url.isValid()); + QEXPECT_FAIL("", "StrictMode not implemented yet", Continue); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%2520with%20spaces.html")); } { QUrl url = QUrl::fromEncoded("http://www.example.com/path%20with spaces.html"); QVERIFY(url.isValid()); QCOMPARE(url.path(), QString("/path with spaces.html")); url.setEncodedUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode); + QEXPECT_FAIL("", "StrictMode not implemented yet", Continue); QVERIFY(!url.isValid()); } @@ -1755,58 +1742,62 @@ void tst_QUrl::tolerantParser() QUrl webkit22616 = QUrl::fromEncoded("http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%20r152:t:%u0442%u0435%u0441%u0442"); QVERIFY(webkit22616.isValid()); + + // Qt 5 behaviour change: one broken % means all % are considered broken +// QCOMPARE(webkit22616.toEncoded().constData(), +// "http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%20r152:t:%25u0442%25u0435%25u0441%25u0442"); QCOMPARE(webkit22616.toEncoded().constData(), - "http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%20r152:t:%25u0442%25u0435%25u0441%25u0442"); + "http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%2520r152:t:%25u0442%25u0435%25u0441%25u0442"); } { QUrl url; url.setUrl("http://foo.bar/[image][1].jpg"); QVERIFY(url.isValid()); - QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); url.setUrl("[].jpg"); - QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%5B%5D.jpg")); url.setUrl("/some/[path]/[]"); - QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("/some/%5Bpath%5D/%5B%5D")); url.setUrl("//[::56:56:56:56:56:56:56]"); - QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]")); url.setUrl("//[::56:56:56:56:56:56:56]#[]"); - QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]#%5B%5D")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D")); url.setUrl("//[::56:56:56:56:56:56:56]?[]"); - QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]?%5B%5D")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?%5B%5D")); url.setUrl("%hello.com/f%"); - QCOMPARE(url.toEncoded(), QByteArray("%25hello.com/f%25")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%25hello.com/f%25")); url.setEncodedUrl("http://www.host.com/foo.php?P0=[2006-3-8]"); QVERIFY(url.isValid()); url.setEncodedUrl("http://foo.bar/[image][1].jpg"); QVERIFY(url.isValid()); - QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); url.setEncodedUrl("[].jpg"); - QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%5B%5D.jpg")); url.setEncodedUrl("/some/[path]/[]"); - QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("/some/%5Bpath%5D/%5B%5D")); url.setEncodedUrl("//[::56:56:56:56:56:56:56]"); - QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]")); url.setEncodedUrl("//[::56:56:56:56:56:56:56]#[]"); - QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]#%5B%5D")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D")); url.setEncodedUrl("//[::56:56:56:56:56:56:56]?[]"); - QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]?%5B%5D")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?%5B%5D")); url.setEncodedUrl("data:text/css,div%20{%20border-right:%20solid;%20}"); - QCOMPARE(url.toEncoded(), QByteArray("data:text/css,div%20%7B%20border-right:%20solid;%20%7D")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("data:text/css,div%20%7B%20border-right:%20solid;%20%7D")); } { @@ -1831,16 +1822,15 @@ void tst_QUrl::correctEncodedMistakes_data() QTest::addColumn("encodedUrl"); QTest::addColumn("result"); QTest::addColumn("toDecoded"); - QTest::addColumn("toEncoded"); - QTest::newRow("%") << QByteArray("%") << true << QString("%") << QByteArray("%25"); - QTest::newRow("3%") << QByteArray("3%") << true << QString("3%") << QByteArray("3%25"); - QTest::newRow("13%") << QByteArray("13%") << true << QString("13%") << QByteArray("13%25"); - QTest::newRow("13%!") << QByteArray("13%!") << true << QString("13%!") << QByteArray("13%25!"); - QTest::newRow("13%!!") << QByteArray("13%!!") << true << QString("13%!!") << QByteArray("13%25!!"); - QTest::newRow("13%a") << QByteArray("13%a") << true << QString("13%a") << QByteArray("13%25a"); - QTest::newRow("13%az") << QByteArray("13%az") << true << QString("13%az") << QByteArray("13%25az"); - QTest::newRow("13%25") << QByteArray("13%25") << true << QString("13%") << QByteArray("13%25"); + QTest::newRow("%") << QByteArray("%") << true << QString("%25"); + QTest::newRow("3%") << QByteArray("3%") << true << QString("3%25"); + QTest::newRow("13%") << QByteArray("13%") << true << QString("13%25"); + QTest::newRow("13%!") << QByteArray("13%!") << true << QString("13%25!"); + QTest::newRow("13%!!") << QByteArray("13%!!") << true << QString("13%25!!"); + QTest::newRow("13%a") << QByteArray("13%a") << true << QString("13%25a"); + QTest::newRow("13%az") << QByteArray("13%az") << true << QString("13%25az"); + QTest::newRow("13%25") << QByteArray("13%25") << true << QString("13%25"); } void tst_QUrl::correctEncodedMistakes() @@ -1848,14 +1838,11 @@ void tst_QUrl::correctEncodedMistakes() QFETCH(QByteArray, encodedUrl); QFETCH(bool, result); QFETCH(QString, toDecoded); - QFETCH(QByteArray, toEncoded); QUrl url = QUrl::fromEncoded(encodedUrl); QCOMPARE(url.isValid(), result); if (url.isValid()) { - Q_UNUSED(toDecoded); // no full-decoding available at the moment - QCOMPARE(url.toString(), QString::fromLatin1(toEncoded)); - QCOMPARE(url.toEncoded(), toEncoded); + QCOMPARE(url.toString(), toDecoded); } } @@ -1864,16 +1851,14 @@ void tst_QUrl::correctDecodedMistakes_data() QTest::addColumn("decodedUrl"); QTest::addColumn("result"); QTest::addColumn("toDecoded"); - QTest::addColumn("toEncoded"); - QTest::newRow("%") << QString("%") << true << QString("%") << QByteArray("%25"); - QTest::newRow("3%") << QString("3%") << true << QString("3%") << QByteArray("3%25"); - QTest::newRow("13%") << QString("13%") << true << QString("13%") << QByteArray("13%25"); - QTest::newRow("13%!") << QString("13%!") << true << QString("13%!") << QByteArray("13%25!"); - QTest::newRow("13%!!") << QString("13%!!") << true << QString("13%!!") << QByteArray("13%25!!"); - QTest::newRow("13%a") << QString("13%a") << true << QString("13%a") << QByteArray("13%25a"); - QTest::newRow("13%az") << QString("13%az") << true << QString("13%az") << QByteArray("13%25az"); - QTest::newRow("13%25") << QString("13%25") << true << QString("13%25") << QByteArray("13%25"); + QTest::newRow("%") << QString("%") << true << QString("%25"); + QTest::newRow("3%") << QString("3%") << true << QString("3%25"); + QTest::newRow("13%") << QString("13%") << true << QString("13%25"); + QTest::newRow("13%!") << QString("13%!") << true << QString("13%25!"); + QTest::newRow("13%!!") << QString("13%!!") << true << QString("13%25!!"); + QTest::newRow("13%a") << QString("13%a") << true << QString("13%25a"); + QTest::newRow("13%az") << QString("13%az") << true << QString("13%25az"); } void tst_QUrl::correctDecodedMistakes() @@ -1881,14 +1866,11 @@ void tst_QUrl::correctDecodedMistakes() QFETCH(QString, decodedUrl); QFETCH(bool, result); QFETCH(QString, toDecoded); - QFETCH(QByteArray, toEncoded); QUrl url(decodedUrl); QCOMPARE(url.isValid(), result); if (url.isValid()) { - Q_UNUSED(toDecoded); // no full-decoding available at the moment - QCOMPARE(url.toString(), QString::fromLatin1(toEncoded)); - QCOMPARE(url.toEncoded(), toEncoded); + QCOMPARE(url.toString(), toDecoded); } } @@ -1999,13 +1981,13 @@ void tst_QUrl::emptyQueryOrFragment() QVERIFY(url.encodedQuery().isNull()); // add encodedQuery - url.setEncodedQuery("abc=def"); + url.setQuery("abc=def"); QVERIFY(url.hasQuery()); - QCOMPARE(QString(url.encodedQuery()), QString(QLatin1String("abc=def"))); + QCOMPARE(url.query(), QString(QLatin1String("abc=def"))); QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?abc=def"))); // remove encodedQuery - url.setEncodedQuery(0); + url.setQuery(QString()); QVERIFY(!url.hasQuery()); QVERIFY(url.encodedQuery().isNull()); QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz"))); @@ -2077,8 +2059,8 @@ void tst_QUrl::setEncodedFragment() void tst_QUrl::fromEncoded() { QUrl qurl2 = QUrl::fromEncoded("print:/specials/Print%20To%20File%20(PDF%252FAcrobat)", QUrl::TolerantMode); - QCOMPARE(qurl2.path(), QString::fromLatin1("/specials/Print To File (PDF%2FAcrobat)")); - QCOMPARE(QFileInfo(qurl2.path()).fileName(), QString::fromLatin1("Print To File (PDF%2FAcrobat)")); + QCOMPARE(qurl2.path(), QString::fromLatin1("/specials/Print To File (PDF%252FAcrobat)")); + QCOMPARE(QFileInfo(qurl2.path()).fileName(), QString::fromLatin1("Print To File (PDF%252FAcrobat)")); QCOMPARE(qurl2.toEncoded().constData(), "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)"); QUrl qurl = QUrl::fromEncoded("http://\303\244.de"); @@ -2118,10 +2100,10 @@ void tst_QUrl::hosts_data() QTest::newRow("empty3") << QString("http:///file") << QString(""); QTest::newRow("empty4") << QString("http:/file") << QString(""); - // numeric hostnames - QTest::newRow("http://123/") << QString("http://123/") << QString("123"); - QTest::newRow("http://456/") << QString("http://456/") << QString("456"); - QTest::newRow("http://1000/") << QString("http://1000/") << QString("1000"); + // numeric hostnames -> decoded as IPv4 as per inet_aton(3) + QTest::newRow("http://123/") << QString("http://123/") << QString("0.0.0.123"); + QTest::newRow("http://456/") << QString("http://456/") << QString("0.0.1.200"); + QTest::newRow("http://1000/") << QString("http://1000/") << QString("0.0.3.232"); // IP literals QTest::newRow("normal-ip-literal") << QString("http://1.2.3.4") << QString("1.2.3.4"); @@ -2135,12 +2117,18 @@ void tst_QUrl::hosts_data() << QString("2001:200:0:8002:203:47ff:fea5:3085"); QTest::newRow("ipv6-literal-v4compat") << QString("http://[::255.254.253.252]") << QString("::255.254.253.252"); - QTest::newRow("ipv6-literal-v4compat-2") << QString("http://[1000::ffff:127.128.129.1]") - << QString("1000::ffff:127.128.129.1"); - QTest::newRow("long-ipv6-literal-v4compat") << QString("http://[fec0:8000::8002:1000:ffff:200.100.50.250]") - << QString("fec0:8000::8002:1000:ffff:200.100.50.250"); - QTest::newRow("longer-ipv6-literal-v4compat") << QString("http://[fec0:8000:4000:8002:1000:ffff:200.100.50.250]") - << QString("fec0:8000:4000:8002:1000:ffff:200.100.50.250"); + QTest::newRow("ipv6-literal-v4mapped") << QString("http://[::ffff:255.254.253.252]") + << QString("::ffff:255.254.253.252"); + QTest::newRow("ipv6-literal-v4mapped-2") << QString("http://[::ffff:fffe:fdfc]") + << QString("::ffff:255.254.253.252"); + + // no embedded v4 unless the cases above + QTest::newRow("ipv6-literal-v4decoded") << QString("http://[1000::ffff:127.128.129.1]") + << QString("1000::ffff:7f80:8101"); + QTest::newRow("long-ipv6-literal-v4decoded") << QString("http://[fec0:8000::8002:1000:ffff:200.100.50.250]") + << QString("fec0:8000:0:8002:1000:ffff:c864:32fa"); + QTest::newRow("longer-ipv6-literal-v4decoded") << QString("http://[fec0:8000:4000:8002:1000:ffff:200.100.50.250]") + << QString("fec0:8000:4000:8002:1000:ffff:c864:32fa"); // normal hostnames QTest::newRow("normal") << QString("http://intern") << QString("intern"); @@ -2163,12 +2151,14 @@ void tst_QUrl::setPort() { QUrl url; QVERIFY(url.toString().isEmpty()); + url.setHost("a"); url.setPort(80); QCOMPARE(url.port(), 80); - QCOMPARE(url.toString(), QString::fromLatin1("//:80")); + QCOMPARE(url.toString(), QString::fromLatin1("//a:80")); url.setPort(-1); + url.setHost(QString()); QCOMPARE(url.port(), -1); - QVERIFY(url.toString().isEmpty()); + QCOMPARE(url.toString(), QString()); url.setPort(80); QTest::ignoreMessage(QtWarningMsg, "QUrl::setPort: Out of range"); url.setPort(65536); @@ -2220,15 +2210,16 @@ void tst_QUrl::setAuthority() void tst_QUrl::errorString() { + QUrl v; + QCOMPARE(v.errorString(), QString()); + QUrl u = QUrl::fromEncoded("http://strange@bad_hostname/", QUrl::StrictMode); + QEXPECT_FAIL("", "StrictMode not implemented yet", Abort); QVERIFY(!u.isValid()); QString errorString = "Invalid URL \"http://strange@bad_hostname/\": " "error at position 14: expected end of URL, but found '<'"; + QEXPECT_FAIL("", "errorString not implemented yet", Abort); QCOMPARE(u.errorString(), errorString); - - QUrl v; - errorString = "Invalid URL \"\": "; - QCOMPARE(v.errorString(), errorString); } void tst_QUrl::clear() @@ -2259,7 +2250,7 @@ void tst_QUrl::binaryData_data() QTest::newRow("file-hash") << "http://foo/abc%23_def"; QTest::newRow("file-question") << "http://foo/abc%3F_def"; QTest::newRow("file-nonutf8") << "http://foo/abc%E1_def"; - QTest::newRow("file-slash") << "http://foo/abc%2f_def"; + QTest::newRow("file-slash") << "http://foo/abc%2F_def"; QTest::newRow("ref") << "http://foo/file#a%01%0D%0A%7F"; QTest::newRow("ref-nul") << "http://foo/file#abc%00_def"; @@ -2334,7 +2325,7 @@ void tst_QUrl::fromUserInput_data() portUrl.setPort(80); QTest::newRow("port-0") << "example.org:80" << portUrl; QTest::newRow("port-1") << "http://example.org:80" << portUrl; - portUrl.setPath("path"); + portUrl.setPath("/path"); QTest::newRow("port-2") << "example.org:80/path" << portUrl; QTest::newRow("port-3") << "http://example.org:80/path" << portUrl; -- cgit v1.2.3 From 2591545ee1ffa29236900d4cc08724c9f0dd7107 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 19 Oct 2011 20:31:46 +0200 Subject: QUrl: Always lowercase the scheme Change-Id: I8d467014d22384f1be15fdd746e20b1153a82a4e Reviewed-by: Lars Knoll --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 1c34d8a114..680cc3b137 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -155,6 +155,7 @@ private slots: void toEncodedNotUsingUninitializedPath(); void emptyAuthorityRemovesExistingAuthority(); void acceptEmptyAuthoritySegments(); + void lowercasesScheme(); }; // Testing get/set functions @@ -320,9 +321,9 @@ void tst_QUrl::setUrl() } { - QUrl url("hTTp://www.foo.bar:80"); + QUrl url("http://www.foo.bar:80"); QVERIFY(url.isValid()); - QCOMPARE(url.scheme(), QString::fromLatin1("hTTp")); + QCOMPARE(url.scheme(), QString::fromLatin1("http")); QCOMPARE(url.path(), QString()); QVERIFY(url.encodedQuery().isEmpty()); QVERIFY(url.userInfo().isEmpty()); @@ -330,12 +331,12 @@ void tst_QUrl::setUrl() QCOMPARE(url.host(), QString::fromLatin1("www.foo.bar")); QCOMPARE(url.authority(), QString::fromLatin1("www.foo.bar:80")); QCOMPARE(url.port(), 80); - QCOMPARE(url.toString(), QString::fromLatin1("hTTp://www.foo.bar:80")); - QCOMPARE(url.toDisplayString(), QString::fromLatin1("hTTp://www.foo.bar:80")); - QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("hTTp://www.foo.bar:80")); + QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar:80")); + QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://www.foo.bar:80")); + QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("http://www.foo.bar:80")); QUrl url2("//www1.foo.bar"); - QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("hTTp://www1.foo.bar")); + QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www1.foo.bar")); } { @@ -2481,5 +2482,12 @@ void tst_QUrl::effectiveTLDs() QCOMPARE(domain.topLevelDomain(), TLD); } +void tst_QUrl::lowercasesScheme() +{ + QUrl url; + url.setScheme("HELLO"); + QCOMPARE(url.scheme(), QString("hello")); +} + QTEST_MAIN(tst_QUrl) #include "tst_qurl.moc" -- cgit v1.2.3 From 74d2dba46041448c70dbd3049ae2a8277770baf6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 13 Oct 2011 19:56:28 +0200 Subject: Port to the new QUrl API The use of any broken-down components of the query now needs QUrlQuery. The QUrl constructor and toString() are now rehabilitated and the preferred forms. Use toEncoded() and fromEncoded() now only when we need to store data in a QByteArray or the data comes from a QByteArray anyway. Change to toString() or the constructor if the data was in a QString. Change-Id: I9d761a628bef9c70185a48e927a61779a1642342 Reviewed-by: Lars Knoll --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 2 +- .../other/networkselftest/tst_networkselftest.cpp | 3 ++- tests/benchmarks/corelib/io/qurl/main.cpp | 23 ---------------------- 3 files changed, 3 insertions(+), 25 deletions(-) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index a5aaf6af25..150f5c4616 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -6742,7 +6742,7 @@ void tst_QNetworkReply::pipeliningHelperSlot() { pipeliningWasUsed = true; // check that the contents match (the response to echo.cgi?3 should return 3 etc.) - QString urlQueryString = reply->url().queryItems().at(0).first; + QString urlQueryString = reply->url().query(); QString content = reply->readAll(); QVERIFY2(urlQueryString == content, "data corruption with pipelining detected"); diff --git a/tests/auto/other/networkselftest/tst_networkselftest.cpp b/tests/auto/other/networkselftest/tst_networkselftest.cpp index ebb8443748..8575b11fca 100644 --- a/tests/auto/other/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/other/networkselftest/tst_networkselftest.cpp @@ -659,9 +659,10 @@ void tst_NetworkSelfTest::httpServerFiles() { QFETCH(QString, uri); QFETCH(int, size); + QUrl url(uri); QList chat; - chat << Chat::send("HEAD " + QUrl::toPercentEncoding(uri, "/") + " HTTP/1.0\r\n" + chat << Chat::send("HEAD " + url.toEncoded() + " HTTP/1.0\r\n" "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" "Connection: close\r\n" "Authorization: Basic cXNvY2tzdGVzdDpwYXNzd29yZA==\r\n" diff --git a/tests/benchmarks/corelib/io/qurl/main.cpp b/tests/benchmarks/corelib/io/qurl/main.cpp index dc236e7120..32cd13ad12 100644 --- a/tests/benchmarks/corelib/io/qurl/main.cpp +++ b/tests/benchmarks/corelib/io/qurl/main.cpp @@ -56,8 +56,6 @@ private slots: void toLocalFile(); void toString_data(); void toString(); - void toEncoded_data(); - void toEncoded(); void resolved_data(); void resolved(); void equality_data(); @@ -160,27 +158,6 @@ void tst_qurl::toString() } } -void tst_qurl::toEncoded_data() -{ - generateFirstRunData(); -} - -void tst_qurl::toEncoded() -{ - QFETCH(bool, firstRun); - if(firstRun) { - QBENCHMARK { - QUrl url("pics/avatar.png"); - url.toEncoded(QUrl::FormattingOption(0x100)); - } - } else { - QUrl url("pics/avatar.png"); - QBENCHMARK { - url.toEncoded(QUrl::FormattingOption(0x100)); - } - } -} - void tst_qurl::resolved_data() { generateFirstRunData(); -- cgit v1.2.3 From cff38329aa8635ac8a0696b0aa78782fe5605d16 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 20 Oct 2011 16:23:41 +0200 Subject: Re-introduce support for QUrl::errorString() Note that QUrl can only remember one error. If the URL contains more than one error condition, only the latest (in whichever parsing order URL decides to use) will be reported. I don't want too keep too much data in QUrlPrivate for validation, so let's use 4 bytes only. Change-Id: I2afbf80734d3633f41f779984ab76b3a5ba293a2 Reviewed-by: Lars Knoll --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 680cc3b137..259e7570fa 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -1615,8 +1615,7 @@ void tst_QUrl::isValid() QVERIFY(url.isValid()); url.setAuthority("strange;hostname"); QVERIFY(!url.isValid()); - QEXPECT_FAIL("", "QUrl::errorString not reimplemented", Continue); - QVERIFY(url.errorString().contains("invalid hostname")); + QVERIFY(url.errorString().contains("Hostname contains invalid characters")); } { @@ -1629,8 +1628,8 @@ void tst_QUrl::isValid() QVERIFY(url.isValid()); url.setHost("stuff;1"); QVERIFY(!url.isValid()); - QEXPECT_FAIL("", "QUrl::errorString not reimplemented", Continue); - QVERIFY(url.errorString().contains("invalid hostname")); + QVERIFY2(url.errorString().contains("Hostname contains invalid characters"), + qPrintable(url.errorString())); } } @@ -2164,6 +2163,7 @@ void tst_QUrl::setPort() QTest::ignoreMessage(QtWarningMsg, "QUrl::setPort: Out of range"); url.setPort(65536); QCOMPARE(url.port(), -1); + QVERIFY(url.errorString().contains("out of range")); } } @@ -2219,7 +2219,6 @@ void tst_QUrl::errorString() QVERIFY(!u.isValid()); QString errorString = "Invalid URL \"http://strange@bad_hostname/\": " "error at position 14: expected end of URL, but found '<'"; - QEXPECT_FAIL("", "errorString not implemented yet", Abort); QCOMPARE(u.errorString(), errorString); } -- cgit v1.2.3 From 329ee8cedc78de5304a84e0b205b08f39e439411 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 28 Dec 2011 15:59:47 -0200 Subject: Reimplement the StrictMode URL parsing The strict mode check is now implemented after the tolerant parser has finished, and only if the tolerant parser has not found any errors. We catch the use of disallowed characters (control characters plus a few not permitted anywhere) and broken percent encodings. We do not catch the use of Unicode characters, as they are permitted in IRIs. In the tests, remove the old errorString test since it makes little sense. Change-Id: I8261a2ccad031ad68fc6377a206e59c9db89fb38 Reviewed-by: Lars Knoll --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 75 ++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 20 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 259e7570fa..7e06dd4e88 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -122,6 +122,8 @@ private slots: void schemeValidator_data(); void schemeValidator(); void invalidSchemeValidator(); + void strictParser_data(); + void strictParser(); void tolerantParser(); void correctEncodedMistakes_data(); void correctEncodedMistakes(); @@ -143,7 +145,6 @@ private slots: void toEncoded(); void setAuthority_data(); void setAuthority(); - void errorString(); void clear(); void resolvedWithAbsoluteSchemes() const; void resolvedWithAbsoluteSchemes_data() const; @@ -1594,7 +1595,6 @@ void tst_QUrl::isValid() } { QUrl url = QUrl::fromEncoded("http://strange@ok-hostname/", QUrl::StrictMode); - QEXPECT_FAIL("", "StrictMode not implemented yet", Continue); QVERIFY(!url.isValid()); // < and > are not allowed in userinfo in strict mode url.setUserName("normal_username"); @@ -1604,6 +1604,7 @@ void tst_QUrl::isValid() QUrl url = QUrl::fromEncoded("http://strange@ok-hostname/"); QVERIFY(url.isValid()); // < and > are allowed in tolerant mode + QCOMPARE(url.toEncoded(), QByteArray("http://strange%3Cusername%3E@ok-hostname/")); } { QUrl url = QUrl::fromEncoded("http://strange;hostname/here"); @@ -1710,6 +1711,55 @@ void tst_QUrl::invalidSchemeValidator() } } +void tst_QUrl::strictParser_data() +{ + QTest::addColumn("input"); + QTest::addColumn("needle"); + + // cannot test bad schemes here, as they are parsed as paths instead + //QTest::newRow("invalid-scheme") << "ht%://example.com" << "Invalid scheme"; + //QTest::newRow("empty-scheme") << ":/" << "Empty scheme"; + + QTest::newRow("invalid-user1") << "http://bad@ok-hostname" << "Invalid user name"; + QTest::newRow("invalid-user2") << "http://bad%@ok-hostname" << "Invalid user name"; + + QTest::newRow("invalid-password") << "http://user:pass\x7F@ok-hostname" << "Invalid password"; + + QTest::newRow("invalid-regname") << "http://bad" << "Hostname contains invalid characters"; + QTest::newRow("invalid-ipv6") << "http://[:::]" << "Invalid IPv6 address"; + QTest::newRow("invalid-ipvfuture-1") << "http://[v7]" << "Invalid IPvFuture address"; + QTest::newRow("invalid-ipvfuture-2") << "http://[v7.]" << "Invalid IPvFuture address"; + QTest::newRow("invalid-ipvfuture-3") << "http://[v789]" << "Invalid IPvFuture address"; + QTest::newRow("unbalanced-brackets") << "http://[ff02::1" << "Expected ']'"; + + QTest::newRow("empty-port") << "http://example.com:" << "Invalid port"; + QTest::newRow("invalid-port-1") << "http://example.com:-1" << "Invalid port"; + QTest::newRow("invalid-port-2") << "http://example.com:abc" << "Invalid port"; + QTest::newRow("invalid-port-3") << "http://example.com:9a" << "Invalid port"; + QTest::newRow("port-range") << "http://example.com:65536" << "out of range"; + + QTest::newRow("invalid-path") << "foo:/path%\x1F" << "Invalid path"; + // not yet checked: + //QTest::newRow("path-colon-before-slash") << "foo::/" << "':' before any '/'"; + + QTest::newRow("invalid-query") << "foo:?\\#" << "Invalid query"; + + QTest::newRow("invalid-fragment") << "#{}" << "Invalid fragment"; +} + +void tst_QUrl::strictParser() +{ + QFETCH(QString, input); + QFETCH(QString, needle); + + QUrl url(input, QUrl::StrictMode); + QVERIFY(!url.isValid()); + QVERIFY(!url.errorString().isEmpty()); + if (!url.errorString().contains(needle)) + qWarning("Error string changed and does not contain \"%s\" anymore: %s", + qPrintable(needle), qPrintable(url.errorString())); +} + void tst_QUrl::tolerantParser() { { @@ -1718,18 +1768,16 @@ void tst_QUrl::tolerantParser() QCOMPARE(url.path(), QString("/path with spaces.html")); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%20with%20spaces.html")); url.setUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode); - QEXPECT_FAIL("", "StrictMode not implemented yet", Continue); QVERIFY(!url.isValid()); - QEXPECT_FAIL("", "StrictMode not implemented yet", Continue); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%2520with%20spaces.html")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%20with%20spaces.html")); } { QUrl url = QUrl::fromEncoded("http://www.example.com/path%20with spaces.html"); QVERIFY(url.isValid()); QCOMPARE(url.path(), QString("/path with spaces.html")); url.setEncodedUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode); - QEXPECT_FAIL("", "StrictMode not implemented yet", Continue); - QVERIFY(!url.isValid()); + QVERIFY(url.isValid()); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%20with%20spaces.html")); } { @@ -2209,19 +2257,6 @@ void tst_QUrl::setAuthority() QCOMPARE(u.toString(), url); } -void tst_QUrl::errorString() -{ - QUrl v; - QCOMPARE(v.errorString(), QString()); - - QUrl u = QUrl::fromEncoded("http://strange@bad_hostname/", QUrl::StrictMode); - QEXPECT_FAIL("", "StrictMode not implemented yet", Abort); - QVERIFY(!u.isValid()); - QString errorString = "Invalid URL \"http://strange@bad_hostname/\": " - "error at position 14: expected end of URL, but found '<'"; - QCOMPARE(u.errorString(), errorString); -} - void tst_QUrl::clear() { QUrl url("a"); -- cgit v1.2.3 From 64a10879cb1f3a48b4b44c2e3a46694efb3bec0a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 28 Dec 2011 16:02:44 -0200 Subject: Disallow spaces in URLs when parsing in StrictMode. Change-Id: I16de68aff2b9e84cc800734c5875aaee9a2ea565 Reviewed-by: Lars Knoll --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 7e06dd4e88..5c9e20b9b4 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -1769,15 +1769,13 @@ void tst_QUrl::tolerantParser() QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%20with%20spaces.html")); url.setUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode); QVERIFY(!url.isValid()); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%20with%20spaces.html")); } { QUrl url = QUrl::fromEncoded("http://www.example.com/path%20with spaces.html"); QVERIFY(url.isValid()); QCOMPARE(url.path(), QString("/path with spaces.html")); url.setEncodedUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode); - QVERIFY(url.isValid()); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%20with%20spaces.html")); + QVERIFY(!url.isValid()); } { -- cgit v1.2.3 From 66df11f4d109ca3d97fed8985d6bbc6dcf90733d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 28 Mar 2012 19:31:45 -0300 Subject: Fix QUrl operator== and operator< Don't crash when either side is null but not both sides. Also make sure operator< is working properly and satisfies the basic conditions of a type (such as that if A < B, then !(B < A)). Change-Id: Idd9e9fc593e1a7781d9f4f2b13a1024b643926fd Reviewed-by: Giuseppe D'Angelo Reviewed-by: Lars Knoll --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 5c9e20b9b4..f0081df765 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -66,6 +66,8 @@ private slots: void unc(); void assignment(); void comparison(); + void comparison2_data(); + void comparison2(); void copying(); void setUrl(); void i18n_data(); @@ -286,6 +288,55 @@ void tst_QUrl::comparison() QVERIFY(url5 == url6); } +void tst_QUrl::comparison2_data() +{ + QTest::addColumn("url1"); + QTest::addColumn("url2"); + QTest::addColumn("ordering"); // like strcmp + + QTest::newRow("null-null") << QUrl() << QUrl() << 0; + + QUrl empty; + empty.setPath("/hello"); // ensure it has detached + empty.setPath(QString()); + QTest::newRow("null-empty") << QUrl() << empty << 0; + + QTest::newRow("scheme-null") << QUrl("x:") << QUrl() << 1; + QTest::newRow("samescheme") << QUrl("x:") << QUrl("x:") << 0; + + // the following three are by choice + // the order could be the opposite and it would still be correct + QTest::newRow("scheme-path") << QUrl("x:") << QUrl("/tmp") << +1; + QTest::newRow("fragment-path") << QUrl("#foo") << QUrl("/tmp") << -1; + QTest::newRow("fragment-scheme") << QUrl("#foo") << QUrl("x:") << -1; + + QTest::newRow("noport-zeroport") << QUrl("http://example.com") << QUrl("http://example.com:0") << -1; +} + +void tst_QUrl::comparison2() +{ + QFETCH(QUrl, url1); + QFETCH(QUrl, url2); + QFETCH(int, ordering); + + QCOMPARE(url1.toString() == url2.toString(), ordering == 0); + QCOMPARE(url1 == url2, ordering == 0); + QCOMPARE(url1 != url2, ordering != 0); + if (ordering == 0) + QCOMPARE(qHash(url1), qHash(url2)); + + QCOMPARE(url1 < url2, ordering < 0); + QCOMPARE(!(url1 < url2), ordering >= 0); + + QCOMPARE(url2 < url1, ordering > 0); + QCOMPARE(!(url2 < url1), ordering <= 0); + + // redundant checks (the above should catch these) + QCOMPARE(url1 < url2 || url2 < url1, ordering != 0); + QVERIFY(!(url1 < url2 && url2 < url1)); + QVERIFY(url1 < url2 || url1 == url2 || url2 < url1); +} + void tst_QUrl::copying() { QUrl url("http://qt.nokia.com/"); -- cgit v1.2.3 From c9b78026f575361f09b2fac1b1d4abba6a3c2f7d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Mar 2012 11:27:10 -0300 Subject: Fix the license headers for the files in the new-qurl branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I469fed8b72111905e31553d0c82e62ced4009d75 Reviewed-by: João Abecasis --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index f0081df765..12344f9909 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Intel Corporation. ** Contact: http://www.qt-project.org/ ** ** This file is part of the test suite of the Qt Toolkit. -- cgit v1.2.3 From 7f20dce264c6f982e84c3b5d60f3ffbf6341c908 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Mar 2012 12:10:47 -0300 Subject: Move the #include "tst_qurlinternal.moc" up to workaround a bug I don't know if the bug is in moc or in qmake. But it bails out trying to parse the .cpp file after the tst_QUrlInternal::nameprep_testsuite_data function. If the #include is placed above, it works. If it's placed below, it doesn't. Change-Id: Ide554aa5aa3f1999e29604ba6d25ccdb09f6ef28 Reviewed-by: Marius Storm-Olsen Reviewed-by: Oswald Buddenhagen --- tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 34b9c94865..f853bab9e5 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -104,6 +104,7 @@ private Q_SLOTS: void encodingRecodeInvalidUtf8_data(); void encodingRecodeInvalidUtf8(); }; +#include "tst_qurlinternal.moc" void tst_QUrlInternal::idna_testsuite_data() { @@ -979,5 +980,3 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8() } QTEST_APPLESS_MAIN(tst_QUrlInternal) - -#include "tst_qurlinternal.moc" -- cgit v1.2.3 From ffd20af339c64bf3af7983d20b029724a67f0734 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Mar 2012 17:32:58 -0300 Subject: Revert to Qt4 behaviour that QUrl().isValid() == false There are probably lots of places that rely on that behaviour, so go back to what it was. Change-Id: I4d1503a0ee105a50cdfaab52d9a5862a02c70757 Reviewed-by: David Faure --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 12344f9909..852eb0ab97 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -206,7 +206,7 @@ void tst_QUrl::getSetCheck() void tst_QUrl::constructing() { QUrl url; - QVERIFY(url.isValid()); + QVERIFY(!url.isValid()); QVERIFY(url.isEmpty()); QCOMPARE(url.port(), -1); QCOMPARE(url.toString(), QString()); @@ -1230,7 +1230,6 @@ void tst_QUrl::compat_isValid_02_data() QString n = ""; - QTest::newRow( "ok_00" ) << n << n << n << n << -1 << n << (bool)true; QTest::newRow( "ok_01" ) << n << n << n << n << -1 << QString("path") << (bool)true; QTest::newRow( "ok_02" ) << QString("ftp") << n << n << QString("ftp.qt.nokia.com") << -1 << n << (bool)true; QTest::newRow( "ok_03" ) << QString("ftp") << QString("foo") << n << QString("ftp.qt.nokia.com") << -1 << n << (bool)true; @@ -1239,6 +1238,7 @@ void tst_QUrl::compat_isValid_02_data() QTest::newRow( "ok_06" ) << QString("ftp") << QString("foo") << n << QString("ftp.qt.nokia.com") << -1 << QString("path") << (bool)true; QTest::newRow( "ok_07" ) << QString("ftp") << QString("foo") << QString("bar") << QString("ftp.qt.nokia.com") << -1 << QString("path")<< (bool)true; + QTest::newRow( "err_01" ) << n << n << n << n << -1 << n << (bool)false; QTest::newRow( "err_02" ) << QString("ftp") << n << n << n << -1 << n << (bool)true; QTest::newRow( "err_03" ) << n << QString("foo") << n << n << -1 << n << (bool)true; QTest::newRow( "err_04" ) << n << n << QString("bar") << n << -1 << n << (bool)true; @@ -1693,7 +1693,7 @@ void tst_QUrl::schemeValidator_data() QTest::addColumn("result"); QTest::addColumn("toString"); - QTest::newRow("empty") << QByteArray() << true << QString(); + QTest::newRow("empty") << QByteArray() << false << QString(); // ftp QTest::newRow("ftp:") << QByteArray("ftp:") << true << QString("ftp:"); -- cgit v1.2.3 From 4ef5a6269c1465662ea3872596ba284a13cce25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 29 Mar 2012 00:24:50 +0200 Subject: Add tests to verify QByteArray's zero termination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For data allocated and maintained by QByteArray, there's a guarantee that data() is null-terminated. This holds true even for null and empty, where logically the terminating character should never be dereferenced. For tests that modify or generate QByteArrays, this ensures the invariant is kept. In the toFromHex() text, const-ness of temporary variables was dropped to enable the test macro to be used, as the qualification didn't add much to the test otherwise. Change-Id: I7ee52e79e3a9df7de18c743f3698dab688e6bf0e Reviewed-by: Jędrzej Nowacki --- .../corelib/tools/qbytearray/tst_qbytearray.cpp | 128 ++++++++++++++++++++- 1 file changed, 123 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 2c8aa4d62a..fe9b5f67c4 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -147,8 +147,40 @@ private slots: void movablity_data(); void movablity(); void literals(); + + void zeroTermination_data(); + void zeroTermination(); }; +// Except for QByteArrays initialized with fromRawData(), QByteArray ensures +// that data() is null-terminated. VERIFY_ZERO_TERMINATION checks that +// invariant and goes further by testing that the null-character is in writable +// memory allocated by QByteArray. If the invariant is broken, tools like +// valgrind should be able to detect this. +#define VERIFY_ZERO_TERMINATION(ba) \ + do { \ + /* Statics could be anything, as can fromRawData() strings */ \ + QByteArray::DataPtr baDataPtr = ba.data_ptr(); \ + if (!baDataPtr->ref.isStatic() \ + && baDataPtr->offset == QByteArray().data_ptr()->offset) { \ + int baSize = ba.size(); \ + QCOMPARE(ba.constData()[baSize], '\0'); \ + \ + QByteArray baCopy(ba.constData(), baSize); \ + if (!baDataPtr->ref.isShared()) { \ + /* Don't detach, assumes no setSharable support */ \ + char *baData = ba.data(); \ + baData[baSize] = 'x'; \ + \ + QCOMPARE(ba.constData()[baSize], 'x'); \ + QCOMPARE(ba, baCopy); \ + \ + baData[baSize] = '\0'; /* Sanity restored */ \ + } \ + } \ + } while (false) \ + /**/ + struct StaticByteArrays { struct Standard { QByteArrayData data; @@ -224,8 +256,13 @@ void tst_QByteArray::qCompress_data() void tst_QByteArray::qCompress() { QFETCH( QByteArray, ba ); + QByteArray compressed = ::qCompress( ba ); - QTEST( ::qUncompress( compressed ), "ba" ); + QByteArray uncompressed = ::qUncompress(compressed); + + QCOMPARE(uncompressed, ba); + VERIFY_ZERO_TERMINATION(compressed); + VERIFY_ZERO_TERMINATION(uncompressed); } void tst_QByteArray::qUncompressCorruptedData_data() @@ -257,9 +294,11 @@ void tst_QByteArray::qUncompressCorruptedData() QByteArray res; res = ::qUncompress(in); QCOMPARE(res, QByteArray()); + VERIFY_ZERO_TERMINATION(res); res = ::qUncompress(in + "blah"); QCOMPARE(res, QByteArray()); + VERIFY_ZERO_TERMINATION(res); #else QSKIP("This test freezes on this platform"); #endif @@ -269,7 +308,7 @@ void tst_QByteArray::qCompressionZeroTermination() { QString s = "Hello, I'm a string."; QByteArray ba = ::qUncompress(::qCompress(s.toLocal8Bit())); - QVERIFY((int) *(ba.data() + ba.size()) == 0); + VERIFY_ZERO_TERMINATION(ba); } #endif @@ -289,6 +328,7 @@ void tst_QByteArray::constByteArray() QVERIFY(cba.constData()[1] == 'b'); QVERIFY(cba.constData()[2] == 'c'); QVERIFY(cba.constData()[3] == '\0'); + VERIFY_ZERO_TERMINATION(cba); } void tst_QByteArray::leftJustified() @@ -506,9 +546,11 @@ void tst_QByteArray::base64() QByteArray arr = QByteArray::fromBase64(base64); QCOMPARE(arr, rawdata); + VERIFY_ZERO_TERMINATION(arr); QByteArray arr64 = rawdata.toBase64(); QCOMPARE(arr64, base64); + VERIFY_ZERO_TERMINATION(arr64); } //different from the previous test as the input are invalid @@ -733,17 +775,24 @@ void tst_QByteArray::chop() src.chop(choplength); QCOMPARE(src, expected); + VERIFY_ZERO_TERMINATION(src); } void tst_QByteArray::prepend() { QByteArray ba("foo"); QCOMPARE(ba.prepend((char*)0), QByteArray("foo")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend(QByteArray()), QByteArray("foo")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend("1"), QByteArray("1foo")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend(QByteArray("2")), QByteArray("21foo")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend('3'), QByteArray("321foo")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend("\0 ", 2), QByteArray::fromRawData("\0 321foo", 8)); + VERIFY_ZERO_TERMINATION(ba); } void tst_QByteArray::prependExtended_data() @@ -767,11 +816,17 @@ void tst_QByteArray::prependExtended() QCOMPARE(QByteArray("").prepend(array), QByteArray("data")); QCOMPARE(array.prepend((char*)0), QByteArray("data")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend(QByteArray()), QByteArray("data")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend("1"), QByteArray("1data")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend(QByteArray("2")), QByteArray("21data")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend('3'), QByteArray("321data")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend("\0 ", 2), QByteArray::fromRawData("\0 321data", 9)); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.size(), 9); } @@ -779,12 +834,19 @@ void tst_QByteArray::append() { QByteArray ba("foo"); QCOMPARE(ba.append((char*)0), QByteArray("foo")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append(QByteArray()), QByteArray("foo")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append("1"), QByteArray("foo1")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append(QByteArray("2")), QByteArray("foo12")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append('3'), QByteArray("foo123")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append("\0"), QByteArray("foo123")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append("\0", 1), QByteArray::fromRawData("foo123\0", 7)); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.size(), 7); } @@ -801,12 +863,19 @@ void tst_QByteArray::appendExtended() QCOMPARE(QByteArray("").append(array), QByteArray("data")); QCOMPARE(array.append((char*)0), QByteArray("data")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append(QByteArray()), QByteArray("data")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append("1"), QByteArray("data1")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append(QByteArray("2")), QByteArray("data12")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append('3'), QByteArray("data123")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append("\0"), QByteArray("data123")); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append("\0", 1), QByteArray::fromRawData("data123\0", 8)); + VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.size(), 8); } @@ -814,22 +883,28 @@ void tst_QByteArray::insert() { QByteArray ba("Meal"); QCOMPARE(ba.insert(1, QByteArray("ontr")), QByteArray("Montreal")); + VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.insert(ba.size(), "foo"), QByteArray("Montrealfoo")); + VERIFY_ZERO_TERMINATION(ba); ba = QByteArray("13"); QCOMPARE(ba.insert(1, QByteArray("2")), QByteArray("123")); + VERIFY_ZERO_TERMINATION(ba); ba = "ac"; QCOMPARE(ba.insert(1, 'b'), QByteArray("abc")); QCOMPARE(ba.size(), 3); + VERIFY_ZERO_TERMINATION(ba); ba = "ikl"; QCOMPARE(ba.insert(1, "j"), QByteArray("ijkl")); QCOMPARE(ba.size(), 4); + VERIFY_ZERO_TERMINATION(ba); ba = "ab"; QCOMPARE(ba.insert(1, "\0X\0", 3), QByteArray::fromRawData("a\0X\0b", 5)); QCOMPARE(ba.size(), 5); + VERIFY_ZERO_TERMINATION(ba); } void tst_QByteArray::insertExtended_data() @@ -842,6 +917,7 @@ void tst_QByteArray::insertExtended() QFETCH(QByteArray, array); QCOMPARE(array.insert(1, "i"), QByteArray("diata")); QCOMPARE(array.size(), 5); + VERIFY_ZERO_TERMINATION(array); } void tst_QByteArray::remove_data() @@ -872,6 +948,7 @@ void tst_QByteArray::remove() QFETCH(int, length); QFETCH(QByteArray, expected); QCOMPARE(src.remove(position, length), expected); + VERIFY_ZERO_TERMINATION(src); } void tst_QByteArray::replace_data() @@ -913,6 +990,8 @@ void tst_QByteArray::replace() QCOMPARE(str1.replace(pos, len, after).constData(), expected.constData()); QCOMPARE(str2.replace(pos, len, after.data()), expected); + VERIFY_ZERO_TERMINATION(str1); + VERIFY_ZERO_TERMINATION(str2); } void tst_QByteArray::replaceWithSpecifiedLength() @@ -925,6 +1004,7 @@ void tst_QByteArray::replaceWithSpecifiedLength() const char _expected[] = "zxc\0vbcdefghjk"; QByteArray expected(_expected,sizeof(_expected)-1); QCOMPARE(ba,expected); + VERIFY_ZERO_TERMINATION(ba); } void tst_QByteArray::indexOf_data() @@ -1227,6 +1307,7 @@ void tst_QByteArray::appendAfterFromRawData() data[0] = 'Y'; } QVERIFY(arr.at(0) == 'X'); + VERIFY_ZERO_TERMINATION(arr); } void tst_QByteArray::toFromHex_data() @@ -1298,15 +1379,17 @@ void tst_QByteArray::toFromHex() QFETCH(QByteArray, hex_alt1); { - const QByteArray th = str.toHex(); + QByteArray th = str.toHex(); QCOMPARE(th.size(), hex.size()); QCOMPARE(th, hex); + VERIFY_ZERO_TERMINATION(th); } { - const QByteArray fh = QByteArray::fromHex(hex); + QByteArray fh = QByteArray::fromHex(hex); QCOMPARE(fh.size(), str.size()); QCOMPARE(fh, str); + VERIFY_ZERO_TERMINATION(fh); } QCOMPARE(QByteArray::fromHex(hex_alt1), str); @@ -1319,14 +1402,17 @@ void tst_QByteArray::toFromPercentEncoding() QByteArray data = arr.toPercentEncoding(); QCOMPARE(QString(data), QString("Qt%20is%20great%21")); QCOMPARE(QByteArray::fromPercentEncoding(data), arr); + VERIFY_ZERO_TERMINATION(data); data = arr.toPercentEncoding("! ", "Qt"); QCOMPARE(QString(data), QString("%51%74 is grea%74!")); QCOMPARE(QByteArray::fromPercentEncoding(data), arr); + VERIFY_ZERO_TERMINATION(data); data = arr.toPercentEncoding(QByteArray(), "abcdefghijklmnopqrstuvwxyz", 'Q'); QCOMPARE(QString(data), QString("Q51Q74Q20Q69Q73Q20Q67Q72Q65Q61Q74Q21")); QCOMPARE(QByteArray::fromPercentEncoding(data, 'Q'), arr); + VERIFY_ZERO_TERMINATION(data); // verify that to/from percent encoding preserves nullity arr = ""; @@ -1336,6 +1422,7 @@ void tst_QByteArray::toFromPercentEncoding() QVERIFY(!arr.toPercentEncoding().isNull()); QVERIFY(QByteArray::fromPercentEncoding("").isEmpty()); QVERIFY(!QByteArray::fromPercentEncoding("").isNull()); + VERIFY_ZERO_TERMINATION(arr); arr = QByteArray(); QVERIFY(arr.isEmpty()); @@ -1344,6 +1431,7 @@ void tst_QByteArray::toFromPercentEncoding() QVERIFY(arr.toPercentEncoding().isNull()); QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isEmpty()); QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isNull()); + VERIFY_ZERO_TERMINATION(arr); } void tst_QByteArray::fromPercentEncoding_data() @@ -1585,6 +1673,9 @@ void tst_QByteArray::repeated() const QFETCH(int, count); QCOMPARE(string.repeated(count), expected); + + QByteArray repeats = string.repeated(count); + VERIFY_ZERO_TERMINATION(repeats); } void tst_QByteArray::repeated_data() const @@ -1676,6 +1767,7 @@ void tst_QByteArray::byteRefDetaching() const copy[0] = 'S'; QCOMPARE(str, QByteArray("str")); + VERIFY_ZERO_TERMINATION(copy); } { @@ -1684,6 +1776,7 @@ void tst_QByteArray::byteRefDetaching() const str[0] = 'S'; QCOMPARE(buf[0], char('s')); + VERIFY_ZERO_TERMINATION(str); } { @@ -1694,6 +1787,7 @@ void tst_QByteArray::byteRefDetaching() const str[0] = 'S'; QCOMPARE(buf[0], char('s')); + VERIFY_ZERO_TERMINATION(str); } } @@ -1703,19 +1797,25 @@ void tst_QByteArray::reserve() QByteArray qba; qba.reserve(capacity); QVERIFY(qba.capacity() == capacity); - char *data = qba.data(); + VERIFY_ZERO_TERMINATION(qba); + char *data = qba.data(); for (int i = 0; i < capacity; i++) { qba.resize(i); QVERIFY(capacity == qba.capacity()); QVERIFY(data == qba.data()); + VERIFY_ZERO_TERMINATION(qba); } QByteArray nil1, nil2; nil1.reserve(0); + VERIFY_ZERO_TERMINATION(nil1); nil2.squeeze(); + VERIFY_ZERO_TERMINATION(nil2); nil1.squeeze(); + VERIFY_ZERO_TERMINATION(nil1); nil2.reserve(0); + VERIFY_ZERO_TERMINATION(nil2); } void tst_QByteArray::reserveExtended_data() @@ -1726,12 +1826,16 @@ void tst_QByteArray::reserveExtended_data() void tst_QByteArray::reserveExtended() { QFETCH(QByteArray, array); + array.reserve(1024); QVERIFY(array.capacity() == 1024); QCOMPARE(array, QByteArray("data")); + VERIFY_ZERO_TERMINATION(array); + array.squeeze(); QCOMPARE(array, QByteArray("data")); QCOMPARE(array.capacity(), array.size()); + VERIFY_ZERO_TERMINATION(array); } void tst_QByteArray::movablity_data() @@ -1824,6 +1928,7 @@ void tst_QByteArray::literals() QVERIFY(str == "abcd"); QVERIFY(str.data_ptr()->ref.isStatic()); QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData)); + VERIFY_ZERO_TERMINATION(str); const char *s = str.constData(); QByteArray str2 = str; @@ -1831,14 +1936,27 @@ void tst_QByteArray::literals() // detach on non const access QVERIFY(str.data() != s); + VERIFY_ZERO_TERMINATION(str); QVERIFY(str2.constData() == s); QVERIFY(str2.data() != s); + VERIFY_ZERO_TERMINATION(str2); #else QSKIP("Only tested on c++0x compliant compiler or gcc"); #endif } +void tst_QByteArray::zeroTermination_data() +{ + movablity_data(); +} + +void tst_QByteArray::zeroTermination() +{ + QFETCH(QByteArray, array); + VERIFY_ZERO_TERMINATION(array); +} + const char globalChar = '1'; QTEST_APPLESS_MAIN(tst_QByteArray) -- cgit v1.2.3 From 47728445a5e7317ed2123a8824c54a012eeee142 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Thu, 22 Mar 2012 21:44:13 +0100 Subject: Remove all calls to, and deprecate qMalloc, qRealloc and qFree. Callers should just call the standard allocation functions directly. Adding an extra function call onto all basic memory management for the sake of making it instrumentable in rare cases isn't really fair to everyone else. What's more, this wasn't completely reliable, as not everything was using them in a number of places. Memory management can still be overridden using tricks like LD_PRELOAD if needed. Their aligned equivilents cannot be deprecated, as no standard equivilents exist, although investigation into posix_memalign(3) is a possibility for the future. Change-Id: Ic5f74b14be33f8bc188fe7236c55e15c36a23fc7 Reviewed-by: Lars Knoll --- .../auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 4 ++-- tests/auto/testlib/selftests/badxml/tst_badxml.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 0649d1e1d8..4b0a64ab54 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -774,7 +774,7 @@ void tst_QMetaObjectBuilder::variantProperty() QCOMPARE(QMetaType::Type(prop.userType()), QMetaType::QVariant); QCOMPARE(QByteArray(prop.typeName()), QByteArray("QVariant")); - qFree(meta); + free(meta); } void tst_QMetaObjectBuilder::notifySignal() @@ -1414,7 +1414,7 @@ TestObject::TestObject(QObject *parent) TestObject::~TestObject() { - qFree(m_metaObject); + free(m_metaObject); } QMetaObject *TestObject::buildMetaObject() diff --git a/tests/auto/testlib/selftests/badxml/tst_badxml.cpp b/tests/auto/testlib/selftests/badxml/tst_badxml.cpp index 2fb9e5ea90..8c75602842 100644 --- a/tests/auto/testlib/selftests/badxml/tst_badxml.cpp +++ b/tests/auto/testlib/selftests/badxml/tst_badxml.cpp @@ -76,7 +76,7 @@ class tst_BadXmlSub : public tst_BadXml public: tst_BadXmlSub() : className("tst_BadXml"), mo(0) {} - ~tst_BadXmlSub() { qFree(mo); } + ~tst_BadXmlSub() { free(mo); } const QMetaObject* metaObject() const; @@ -88,7 +88,7 @@ private: const QMetaObject* tst_BadXmlSub::metaObject() const { if (!mo || (mo->className() != className)) { - qFree(mo); + free(mo); QMetaObjectBuilder builder(&EmptyClass::staticMetaObject); builder.setClassName(className); const_cast(this)->mo = builder.toMetaObject(); -- cgit v1.2.3 From 646dc6c5daeefa99c9af070802c39bc66dc4f1f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Feb 2012 23:27:07 +0100 Subject: Introduce QArrayDataOps::appendInitialize Adds given number of default-initialized elements at end of array. For POD types, initialization is reduced to a single memset call. Other types get default constructed in place. As part of adding a test for the new functionality the arrayOps test was extended to verify objects are being constructed and assigned as desired. Change-Id: I9fb2afe0d92667e76993313fcd370fe129d72b90 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 7 ++ .../corelib/tools/qarraydata/tst_qarraydata.cpp | 74 +++++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index fe8108bff2..0cc7561b46 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -63,6 +63,13 @@ public: { } + explicit SimpleVector(size_t n) + : d(Data::allocate(n)) + { + if (n) + d->appendInitialize(n); + } + SimpleVector(size_t n, const T &t) : d(Data::allocate(n)) { diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 4bd04f9bc3..6d3bbf046f 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -81,6 +81,7 @@ private slots: void typedData(); void gccBug43247(); void arrayOps(); + void appendInitialize(); void setSharable_data(); void setSharable(); void fromRawData(); @@ -894,11 +895,15 @@ struct CountedObject { CountedObject() : id(liveCount++) + , flags(DefaultConstructed) { } CountedObject(const CountedObject &other) : id(other.id) + , flags(other.flags == DefaultConstructed + ? ObjectFlags(CopyConstructed | DefaultConstructed) + : CopyConstructed) { ++liveCount; } @@ -910,6 +915,7 @@ struct CountedObject CountedObject &operator=(const CountedObject &other) { + flags = ObjectFlags(other.flags | CopyAssigned); id = other.id; return *this; } @@ -930,7 +936,15 @@ struct CountedObject const size_t previousLiveCount; }; + enum ObjectFlags { + DefaultConstructed = 1, + CopyConstructed = 2, + CopyAssigned = 4 + }; + size_t id; // not unique + ObjectFlags flags; + static size_t liveCount; }; @@ -968,7 +982,10 @@ void tst_QArrayData::arrayOps() for (int i = 0; i < 5; ++i) { QCOMPARE(vi[i], intArray[i]); QVERIFY(vs[i].isSharedWith(stringArray[i])); + QCOMPARE(vo[i].id, objArray[i].id); + QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed + | CountedObject::DefaultConstructed); } //////////////////////////////////////////////////////////////////////////// @@ -997,7 +1014,10 @@ void tst_QArrayData::arrayOps() for (int i = 0; i < 5; ++i) { QCOMPARE(vi[i], referenceInt); QVERIFY(vs[i].isSharedWith(referenceString)); + QCOMPARE(vo[i].id, referenceObject.id); + QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed + | CountedObject::DefaultConstructed); } //////////////////////////////////////////////////////////////////////////// @@ -1042,28 +1062,80 @@ void tst_QArrayData::arrayOps() QCOMPARE(vo.size(), size_t(30)); QCOMPARE(CountedObject::liveCount, size_t(36)); - for (int i = 0; i < 15; ++i) { + for (int i = 0; i < 5; ++i) { + QCOMPARE(vi[i], intArray[i % 5]); + QVERIFY(vs[i].isSharedWith(stringArray[i % 5])); + + QCOMPARE(vo[i].id, objArray[i % 5].id); + QCOMPARE(int(vo[i].flags), CountedObject::DefaultConstructed + | CountedObject::CopyAssigned); + } + + for (int i = 5; i < 15; ++i) { QCOMPARE(vi[i], intArray[i % 5]); QVERIFY(vs[i].isSharedWith(stringArray[i % 5])); + QCOMPARE(vo[i].id, objArray[i % 5].id); + QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed + | CountedObject::CopyAssigned); } for (int i = 15; i < 20; ++i) { QCOMPARE(vi[i], referenceInt); QVERIFY(vs[i].isSharedWith(referenceString)); + QCOMPARE(vo[i].id, referenceObject.id); + QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed + | CountedObject::CopyAssigned); } for (int i = 20; i < 25; ++i) { QCOMPARE(vi[i], intArray[i % 5]); QVERIFY(vs[i].isSharedWith(stringArray[i % 5])); + QCOMPARE(vo[i].id, objArray[i % 5].id); + + // Originally inserted as (DefaultConstructed | CopyAssigned), later + // get shuffled into place by std::rotate (SimpleVector::insert, + // overlapping mode). + // Depending on implementation of rotate, final assignment can be: + // - straight from source: DefaultConstructed | CopyAssigned + // - through a temporary: CopyConstructed | CopyAssigned + QCOMPARE(vo[i].flags & CountedObject::CopyAssigned, + int(CountedObject::CopyAssigned)); } for (int i = 25; i < 30; ++i) { QCOMPARE(vi[i], referenceInt); QVERIFY(vs[i].isSharedWith(referenceString)); + QCOMPARE(vo[i].id, referenceObject.id); + QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed + | CountedObject::CopyAssigned); + } +} + +void tst_QArrayData::appendInitialize() +{ + CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker) + + //////////////////////////////////////////////////////////////////////////// + // appendInitialize + SimpleVector vi(5); + SimpleVector vs(5); + SimpleVector vo(5); + + QCOMPARE(vi.size(), size_t(5)); + QCOMPARE(vs.size(), size_t(5)); + QCOMPARE(vo.size(), size_t(5)); + + QCOMPARE(CountedObject::liveCount, size_t(5)); + for (size_t i = 0; i < 5; ++i) { + QCOMPARE(vi[i], 0); + QVERIFY(vs[i].isNull()); + + QCOMPARE(vo[i].id, i); + QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed)); } } -- cgit v1.2.3 From 8c413f3eff2de761ae038294195831de753b9252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 5 Mar 2012 17:43:34 +0100 Subject: Introduce QArrayData::detachCapacity This follows QArrayData::detachFlags's lead. Given the (known) size for a detached container, the function helps determine capacity, ensuring the capacityReserved flag is respected. This further helps aggregating behaviour on detach in QArrayData itself. SimpleVector was previously using qMax(capacity(), newSize), but there's no reason to pin the previous capacity value if reserve() wasn't requested. It now uses detachCapacity(). Change-Id: Ide2d99ea7ecd2cd98ae4c1aa397b4475d09c8485 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 6 +++--- tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 14 ++++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 0cc7561b46..54c9fae589 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -184,7 +184,7 @@ public: if (d->ref.isShared() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( - qMax(capacity(), size() + (last - first)), + d->detachCapacity(size() + (last - first)), d->detachFlags() | Data::Grow)); detached.d->copyAppend(first, last); @@ -205,7 +205,7 @@ public: if (d->ref.isShared() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( - qMax(capacity(), size() + (last - first)), + d->detachCapacity(size() + (last - first)), d->detachFlags() | Data::Grow)); if (d->size) { @@ -245,7 +245,7 @@ public: if (d->ref.isShared() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( - qMax(capacity(), size() + (last - first)), + d->detachCapacity(size() + (last - first)), d->detachFlags() | Data::Grow)); if (position) diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 6d3bbf046f..b3b8040b1c 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -1175,8 +1175,10 @@ void tst_QArrayData::setSharable_data() QArrayDataPointer emptyReserved(QTypedArrayData::allocate(5, QArrayData::CapacityReserved)); - QArrayDataPointer nonEmpty(QTypedArrayData::allocate(10, + QArrayDataPointer nonEmpty(QTypedArrayData::allocate(5, QArrayData::Default)); + QArrayDataPointer nonEmptyExtraCapacity( + QTypedArrayData::allocate(10, QArrayData::Default)); QArrayDataPointer nonEmptyReserved(QTypedArrayData::allocate(15, QArrayData::CapacityReserved)); QArrayDataPointer staticArray( @@ -1185,13 +1187,15 @@ void tst_QArrayData::setSharable_data() QTypedArrayData::fromRawData(staticArrayData.data, 10)); nonEmpty->copyAppend(5, 1); + nonEmptyExtraCapacity->copyAppend(5, 1); nonEmptyReserved->copyAppend(7, 2); QTest::newRow("shared-null") << null << size_t(0) << size_t(0) << false << 0; QTest::newRow("shared-empty") << empty << size_t(0) << size_t(0) << false << 0; // unsharable-empty implicitly tested in shared-empty QTest::newRow("empty-reserved") << emptyReserved << size_t(0) << size_t(5) << true << 0; - QTest::newRow("non-empty") << nonEmpty << size_t(5) << size_t(10) << false << 1; + QTest::newRow("non-empty") << nonEmpty << size_t(5) << size_t(5) << false << 1; + QTest::newRow("non-empty-extra-capacity") << nonEmptyExtraCapacity << size_t(5) << size_t(10) << false << 1; QTest::newRow("non-empty-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2; QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3; QTest::newRow("raw-data") << rawData << size_t(10) << size_t(0) << false << 3; @@ -1229,8 +1233,10 @@ void tst_QArrayData::setSharable() // Unshare, must detach array.setSharable(false); - // Immutability (alloc == 0) is lost on detach - if (capacity == 0 && size != 0) + // Immutability (alloc == 0) is lost on detach, as is additional capacity + // if capacityReserved flag is not set. + if ((capacity == 0 && size != 0) + || (!isCapacityReserved && capacity > size)) capacity = size; QVERIFY(!array->ref.isShared()); -- cgit v1.2.3 From 15e3ae6b9da9b32236d3e3348ede86c3acf06fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Feb 2012 23:27:44 +0100 Subject: Introduce QArrayDataOps::truncate This enables a truncating resize() to be implemented. It is similar to destroyAll(), but updates the size() as it goes, so it is safe to use outside a container's destructor (and doesn't necessarily destroy all elements). The appendInitialize test was repurposed and now doubles as an additional test for QArrayDataOps as well as exercising SimpleVector's resize(). Change-Id: Iee94a685c9ea436c6af5b1b77486734a38c49ca1 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 30 ++++++++++ .../corelib/tools/qarraydata/tst_qarraydata.cpp | 67 +++++++++++++++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 54c9fae589..641516e0d0 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -170,6 +170,36 @@ public: detached.swap(*this); } + void resize(size_t newSize) + { + if (size() == newSize) + return; + + if (d->ref.isShared() || newSize > capacity()) { + SimpleVector detached(Data::allocate( + d->detachCapacity(newSize), d->detachFlags())); + if (newSize) { + if (newSize < size()) { + const T *const begin = constBegin(); + detached.d->copyAppend(begin, begin + newSize); + } else { + if (size()) { + const T *const begin = constBegin(); + detached.d->copyAppend(begin, begin + size()); + } + detached.d->appendInitialize(newSize); + } + } + detached.swap(*this); + return; + } + + if (newSize > size()) + d->appendInitialize(newSize); + else + d->truncate(newSize); + } + void prepend(const_iterator first, const_iterator last) { if (!d->size) { diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index b3b8040b1c..53217b2222 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -81,7 +81,7 @@ private slots: void typedData(); void gccBug43247(); void arrayOps(); - void appendInitialize(); + void arrayOps2(); void setSharable_data(); void setSharable(); void fromRawData(); @@ -1115,7 +1115,7 @@ void tst_QArrayData::arrayOps() } } -void tst_QArrayData::appendInitialize() +void tst_QArrayData::arrayOps2() { CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker) @@ -1137,6 +1137,69 @@ void tst_QArrayData::appendInitialize() QCOMPARE(vo[i].id, i); QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed)); } + + //////////////////////////////////////////////////////////////////////////// + // appendInitialize, again + + // These will detach + vi.resize(10); + vs.resize(10); + vo.resize(10); + + QCOMPARE(vi.size(), size_t(10)); + QCOMPARE(vs.size(), size_t(10)); + QCOMPARE(vo.size(), size_t(10)); + + QCOMPARE(CountedObject::liveCount, size_t(10)); + for (size_t i = 0; i < 5; ++i) { + QCOMPARE(vi[i], 0); + QVERIFY(vs[i].isNull()); + + QCOMPARE(vo[i].id, i); + QCOMPARE(int(vo[i].flags), CountedObject::DefaultConstructed + | CountedObject::CopyConstructed); + } + + for (size_t i = 5; i < 10; ++i) { + QCOMPARE(vi[i], 0); + QVERIFY(vs[i].isNull()); + + QCOMPARE(vo[i].id, i + 5); + QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed)); + } + + //////////////////////////////////////////////////////////////////////////// + // truncate + QVERIFY(!vi.isShared()); + QVERIFY(!vs.isShared()); + QVERIFY(!vo.isShared()); + + // These shouldn't detach + vi.resize(7); + vs.resize(7); + vo.resize(7); + + QCOMPARE(vi.size(), size_t(7)); + QCOMPARE(vs.size(), size_t(7)); + QCOMPARE(vo.size(), size_t(7)); + + QCOMPARE(CountedObject::liveCount, size_t(7)); + for (size_t i = 0; i < 5; ++i) { + QCOMPARE(vi[i], 0); + QVERIFY(vs[i].isNull()); + + QCOMPARE(vo[i].id, i); + QCOMPARE(int(vo[i].flags), CountedObject::DefaultConstructed + | CountedObject::CopyConstructed); + } + + for (size_t i = 5; i < 7; ++i) { + QCOMPARE(vi[i], 0); + QVERIFY(vs[i].isNull()); + + QCOMPARE(vo[i].id, i + 5); + QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed)); + } } Q_DECLARE_METATYPE(QArrayDataPointer) -- cgit v1.2.3 From 5e82bb9e6fe71fda6befecf6019e8248846a3fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Feb 2012 23:28:30 +0100 Subject: Introduce QArrayDataPointer::needsDetach While QArrayDataPointer offers generic detach() functionality, this is only useful for operations that may modify data, but don't otherwise affect the container itself, such as non-const iteration, front() and back(). For other modifying operations, users of the API typically need to decide whether a detach is needed based on QArrayData's requirements (is data mutable? is it currently shared?) and its own (do we have spare capacity for growth?). Now that data may be shared, static or otherwise immutable (e.g., fromRawData) it no longer suffices to check the ref-count for isShared(). This commit adds needsDetach() which, from the point-of-view of QArrayData(Pointer), answers the question: 'Can contained data and associated metadata be changed?'. This fixes QArrayDataPointer::setSharable for static data (e.g., Q_ARRAY_LITERAL), previously it only catered to shared_null. SimpleVector is also fixed since it wasn't checking Mutability and it needs to because it supports fromRawData(). Change-Id: I3c7f9c85c83dfd02333762852fa456208e96d5ad Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qarraydata/simplevector.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 641516e0d0..7e679704c8 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -175,7 +175,7 @@ public: if (size() == newSize) return; - if (d->ref.isShared() || newSize > capacity()) { + if (d.needsDetach() || newSize > capacity()) { SimpleVector detached(Data::allocate( d->detachCapacity(newSize), d->detachFlags())); if (newSize) { @@ -211,7 +211,7 @@ public: return; T *const begin = d->begin(); - if (d->ref.isShared() + if (d.needsDetach() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( d->detachCapacity(size() + (last - first)), @@ -232,7 +232,7 @@ public: if (first == last) return; - if (d->ref.isShared() + if (d.needsDetach() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( d->detachCapacity(size() + (last - first)), @@ -272,7 +272,7 @@ public: T *const begin = d->begin(); T *const where = begin + position; const T *const end = begin + d->size; - if (d->ref.isShared() + if (d.needsDetach() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( d->detachCapacity(size() + (last - first)), -- cgit v1.2.3 From 8b56b8ed32cf6351047b21c80359f5f2b895a314 Mon Sep 17 00:00:00 2001 From: Laszlo Papp Date: Thu, 23 Feb 2012 07:41:30 +0200 Subject: Add a remainingTime() method to the public interface of the QTimer class It is an extension coming from the use case when you, for instance, need to implement a countdown timer in client codes, and manually maintain a dedicated variable for counting down with the help of yet another Timer. There might be other use cases as well. The returned value is meant to be in milliseconds, as the method documentation says, since it is reasonable, and consistent with the rest (ie. the interval accessor). The elapsed time is already being tracked inside the event dispatcher, thus the effort is only exposing that for all platforms supported according to the desired timer identifier, and propagating up to the QTimer public API. It is done by using the QTimerInfoList class in the glib and unix dispatchers, and the WinTimeInfo struct for the windows dispatcher. It might be a good idea to to establish a QWinTimerInfo (qtimerinfo_win{_p.h,cpp}) in the future for resembling the interface for windows with the glib/unix management so that it would be consistent. That would mean abstracting out a base class (~interface) for the timer info classes. Something like that QAbstractTimerInfo. Test: Build test only on (Arch)Linux, Windows and Mac. I have also run the unit tests and they passed as well. Change-Id: Ie37b3aff909313ebc92e511e27d029abb070f110 Reviewed-by: Thiago Macieira Reviewed-by: Bradley T. Hughes --- .../kernel/qcoreapplication/tst_qcoreapplication.cpp | 1 + tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp | 17 +++++++++++++++++ tests/auto/corelib/thread/qthread/tst_qthread.cpp | 1 + .../benchlibeventcounter/tst_benchlibeventcounter.cpp | 1 + .../selftests/benchliboptions/tst_benchliboptions.cpp | 1 + 5 files changed, 21 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 84d723ca61..29fa98b8bb 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -616,6 +616,7 @@ public: bool unregisterTimer(int ) { return false; } bool unregisterTimers(QObject *) { return false; } QList registeredTimers(QObject *) const { return QList(); } + int remainingTime(int) { return 0; } void wakeUp() {} void interrupt() {} void flush() {} diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp index e8dade9387..e4ecfb6f2d 100644 --- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp +++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp @@ -55,6 +55,7 @@ private slots: void zeroTimer(); void singleShotTimeout(); void timeout(); + void remainingTime(); void livelock_data(); void livelock(); void timerInfiniteRecursion_data(); @@ -143,6 +144,22 @@ void tst_QTimer::timeout() QVERIFY(helper.count > oldCount); } +void tst_QTimer::remainingTime() +{ + TimerHelper helper; + QTimer timer; + + connect(&timer, SIGNAL(timeout()), &helper, SLOT(timeout())); + timer.start(200); + + QCOMPARE(helper.count, 0); + + QTest::qWait(50); + QCOMPARE(helper.count, 0); + + int remainingTime = timer.remainingTime(); + QVERIFY2(qAbs(remainingTime - 150) < 50, qPrintable(QString::number(remainingTime))); +} void tst_QTimer::livelock_data() { diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index 8eccd17376..41cfc52354 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -1234,6 +1234,7 @@ public: bool unregisterTimer(int ) { return false; } bool unregisterTimers(QObject *) { return false; } QList registeredTimers(QObject *) const { return QList(); } + int remainingTime(int) { return 0; } void wakeUp() {} void interrupt() {} void flush() {} diff --git a/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp b/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp index bcd703b5d1..82de653586 100644 --- a/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp +++ b/tests/auto/testlib/selftests/benchlibeventcounter/tst_benchlibeventcounter.cpp @@ -62,6 +62,7 @@ public: void unregisterSocketNotifier(QSocketNotifier*) {} bool unregisterTimer(int) { return false; } bool unregisterTimers(QObject*) { return false; } + int remainingTime(int) { return 0; } void wakeUp() {} }; diff --git a/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp b/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp index cb1f7feead..d3be93b715 100644 --- a/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp +++ b/tests/auto/testlib/selftests/benchliboptions/tst_benchliboptions.cpp @@ -62,6 +62,7 @@ public: void unregisterSocketNotifier(QSocketNotifier*) {} bool unregisterTimer(int) { return false; } bool unregisterTimers(QObject*) { return false; } + int remainingTime(int) { return 0; } void wakeUp() {} }; -- cgit v1.2.3 From fb20f9c2da369b07fc50857a90b596ae63f943da Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 1 Apr 2012 18:53:55 +0100 Subject: Stop relying on QHash ordering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tst_rcc and tst_qdom rely on specific QHash orderings inside rcc and QDom respectively (see QTBUG-25078 and QTBUG-25071). A workaround is added to make them succeed: QDom checks for all possible orderings, and rcc initializes the hash seed to 0 if the QT_RCC_TEST environment variable is set. Change-Id: I5ed6b50602fceba731c797aec8dffc9cc1d6a1ce Reviewed-by: João Abecasis Reviewed-by: Robin Burchell --- tests/auto/tools/rcc/tst_rcc.cpp | 10 ++++++++++ tests/auto/xml/dom/qdom/tst_qdom.cpp | 16 ++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/tools/rcc/tst_rcc.cpp b/tests/auto/tools/rcc/tst_rcc.cpp index dbf5cebd9d..8af85a6d09 100644 --- a/tests/auto/tools/rcc/tst_rcc.cpp +++ b/tests/auto/tools/rcc/tst_rcc.cpp @@ -52,6 +52,7 @@ #include #include #include +#include typedef QMap QStringMap; Q_DECLARE_METATYPE(QStringMap) @@ -61,6 +62,8 @@ class tst_rcc : public QObject Q_OBJECT private slots: + void initTestCase(); + void rcc_data(); void rcc(); void binary_data(); @@ -69,6 +72,13 @@ private slots: void cleanupTestCase(); }; +void tst_rcc::initTestCase() +{ + // rcc uses a QHash to store files in the resource system. + // we must force a certain hash order when testing or tst_rcc will fail, see QTBUG-25078 + QVERIFY(qputenv("QT_RCC_TEST", "1")); +} + QString findExpectedFile(const QString &base) { QString expectedrccfile = base; diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp index 1533e6a139..1155cd0547 100644 --- a/tests/auto/xml/dom/qdom/tst_qdom.cpp +++ b/tests/auto/xml/dom/qdom/tst_qdom.cpp @@ -1792,8 +1792,15 @@ void tst_QDom::doubleNamespaceDeclarations() const QXmlInputSource source(&file); QVERIFY(doc.setContent(&source, &reader)); - QVERIFY(doc.toString(0) == QString::fromLatin1("\n\n\n") || - doc.toString(0) == QString::fromLatin1("\n\n\n")); + // tst_QDom relies on a specific QHash ordering, see QTBUG-25071 + QString docAsString = doc.toString(0); + QVERIFY(docAsString == QString::fromLatin1("\n\n\n") || + docAsString == QString::fromLatin1("\n\n\n") || + docAsString == QString::fromLatin1("\n\n\n") || + docAsString == QString::fromLatin1("\n\n\n") || + docAsString == QString::fromLatin1("\n\n\n") || + docAsString == QString::fromLatin1("\n\n\n") + ); } void tst_QDom::setContentQXmlReaderOverload() const @@ -1922,7 +1929,7 @@ void tst_QDom::cloneDTD_QTBUG8398() const QVERIFY(domDocument.setContent(dtd)); QDomDocument domDocument2 = domDocument.cloneNode(true).toDocument(); - // for some reason, our DOM implementation reverts the order of entities + // this string is relying on a specific QHash ordering, QTBUG-25071 QString expected("\n" "\n" @@ -1932,7 +1939,8 @@ void tst_QDom::cloneDTD_QTBUG8398() const QString output; QTextStream stream(&output); domDocument2.save(stream, 0); - QCOMPARE(output, expected); + // check against the original string and the expected one, QTBUG-25071 + QVERIFY(output == dtd || output == expected); } void tst_QDom::DTDNotationDecl() -- cgit v1.2.3 From 9a77171ccc2838c2fd7b666ed9ee9c7ba8ebd488 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sat, 24 Mar 2012 08:50:02 +0000 Subject: QHash security fix (1.5/2): qHash two arguments overload support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Algorithmic complexity attacks against hash tables have been known since 2003 (cf. [1, 2]), and they have been left unpatched for years until the 2011 attacks [3] against many libraries / (reference) implementations of programming languages. This patch adds a qHash overload taking two arguments: the value to be hashed, and a uint to be used as a seed for the hash function itself (support the global QHash seed was added in a previous patch). The seed itself is not used just yet; instead, 0 is passed. Compatibility with the one-argument qHash(T) implementation is kept through a catch-all template. [1] http://www.cs.rice.edu/~scrosby/hash/CrosbyWallach_UsenixSec2003.pdf [2] http://perldoc.perl.org/perlsec.html#Algorithmic-Complexity-Attacks [3] http://www.ocert.org/advisories/ocert-2011-003.html Task-number: QTBUG-23529 Change-Id: I1d0a84899476d134db455418c8043a349a7e5317 Reviewed-by: João Abecasis --- tests/auto/corelib/tools/qhash/tst_qhash.cpp | 97 ++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 3b5d15dbfc..9d18c7a34e 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -73,6 +73,7 @@ private slots: void noNeedlessRehashes(); void const_shared_null(); + void twoArguments_qHash(); }; struct Foo { @@ -1203,5 +1204,101 @@ void tst_QHash::const_shared_null() QVERIFY(!hash2.isDetached()); } +// This gets set to != 0 in wrong qHash overloads +static int wrongqHashOverload = 0; + +struct OneArgumentQHashStruct1 {}; +bool operator==(const OneArgumentQHashStruct1 &, const OneArgumentQHashStruct1 &) { return false; } +uint qHash(OneArgumentQHashStruct1) { return 0; } + +struct OneArgumentQHashStruct2 {}; +bool operator==(const OneArgumentQHashStruct2 &, const OneArgumentQHashStruct2 &) { return false; } +uint qHash(const OneArgumentQHashStruct2 &) { return 0; } + +struct OneArgumentQHashStruct3 {}; +bool operator==(const OneArgumentQHashStruct3 &, const OneArgumentQHashStruct3 &) { return false; } +uint qHash(OneArgumentQHashStruct3) { return 0; } +uint qHash(OneArgumentQHashStruct3 &, uint) { wrongqHashOverload = 1; return 0; } + +struct OneArgumentQHashStruct4 {}; +bool operator==(const OneArgumentQHashStruct4 &, const OneArgumentQHashStruct4 &) { return false; } +uint qHash(const OneArgumentQHashStruct4 &) { return 0; } +uint qHash(OneArgumentQHashStruct4 &, uint) { wrongqHashOverload = 1; return 0; } + + +struct TwoArgumentsQHashStruct1 {}; +bool operator==(const TwoArgumentsQHashStruct1 &, const TwoArgumentsQHashStruct1 &) { return false; } +uint qHash(const TwoArgumentsQHashStruct1 &) { wrongqHashOverload = 1; return 0; } +uint qHash(const TwoArgumentsQHashStruct1 &, uint) { return 0; } + +struct TwoArgumentsQHashStruct2 {}; +bool operator==(const TwoArgumentsQHashStruct2 &, const TwoArgumentsQHashStruct2 &) { return false; } +uint qHash(TwoArgumentsQHashStruct2) { wrongqHashOverload = 1; return 0; } +uint qHash(const TwoArgumentsQHashStruct2 &, uint) { return 0; } + +struct TwoArgumentsQHashStruct3 {}; +bool operator==(const TwoArgumentsQHashStruct3 &, const TwoArgumentsQHashStruct3 &) { return false; } +uint qHash(const TwoArgumentsQHashStruct3 &) { wrongqHashOverload = 1; return 0; } +uint qHash(TwoArgumentsQHashStruct3, uint) { return 0; } + +struct TwoArgumentsQHashStruct4 {}; +bool operator==(const TwoArgumentsQHashStruct4 &, const TwoArgumentsQHashStruct4 &) { return false; } +uint qHash(TwoArgumentsQHashStruct4) { wrongqHashOverload = 1; return 0; } +uint qHash(TwoArgumentsQHashStruct4, uint) { return 0; } + +/*! + \internal + + Check that QHash picks up the right overload. + The best one, for a type T, is the two-args version of qHash: + either uint qHash(T, uint) or uint qHash(const T &, uint). + + If neither of these exists, then one between + uint qHash(T) or uint qHash(const T &) must exist + (and it gets selected instead). +*/ +void tst_QHash::twoArguments_qHash() +{ + QHash oneArgHash1; + OneArgumentQHashStruct1 oneArgObject1; + oneArgHash1[oneArgObject1] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash oneArgHash2; + OneArgumentQHashStruct2 oneArgObject2; + oneArgHash2[oneArgObject2] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash oneArgHash3; + OneArgumentQHashStruct3 oneArgObject3; + oneArgHash3[oneArgObject3] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash oneArgHash4; + OneArgumentQHashStruct4 oneArgObject4; + oneArgHash4[oneArgObject4] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash twoArgsHash1; + TwoArgumentsQHashStruct1 twoArgsObject1; + twoArgsHash1[twoArgsObject1] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash twoArgsHash2; + TwoArgumentsQHashStruct2 twoArgsObject2; + twoArgsHash2[twoArgsObject2] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash twoArgsHash3; + TwoArgumentsQHashStruct3 twoArgsObject3; + twoArgsHash3[twoArgsObject3] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash twoArgsHash4; + TwoArgumentsQHashStruct4 twoArgsObject4; + twoArgsHash4[twoArgsObject4] = 1; + QCOMPARE(wrongqHashOverload, 0); +} + QTEST_APPLESS_MAIN(tst_QHash) #include "tst_qhash.moc" -- cgit v1.2.3 From a959f34d716f42925b22d42838e7a4b97e415c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sun, 1 Apr 2012 01:05:47 +0200 Subject: Clean up constructors for "statics" in QString and QByteArray There were two constuctors offering essentially the same functionality. One taking the QStatic*Data struct, the other what essentially amounts to a pointer wrapper of that struct. The former was dropped and the latter untemplatized and kept, as that is the most generic and widely applicable. The template parameter in the wrapper was not very useful as it essentially duplicated information that already maintained in the struct, and there were no consistency checks to ensure they were in sync. In this case, using a wrapper is preferred over the use of naked pointers both as a way to make explicit the transfer of ownership as well as to avoid unintended conversions. By using the reference count (even if only by calling deref() in the destructor), QByteArray and QString must own their Data pointers. Const qualification was dropped from the member variable in these wrappers as it causes some compilers to emit warnings on the lack of constructors, and because it isn't needed there. To otherwise reduce noise, QStatic*Data gained a member function to directly access the const_cast'ed naked pointer. This plays nicely with the above constructor. Its use also allows us to do further changes in the QStatic*Data structs with fewer changes in remaining code. The function has an assert on isStatic(), to ensure it is not inadvertently used with data that requires ref-count operations. With this change, the need for the private constructor taking a naked Q*Data pointer is obviated and that was dropped too. In updating QStringBuilder's QConcatenable specializations I noticed they were broken (using data, instead of data()), so a test was added to avoid this happening again in the future. An unnecessary ref-count increment in QByteArray::clear was also dropped. Change-Id: I9b92fbaae726ab9807837e83d0d19812bf7db5ab Reviewed-by: Thiago Macieira --- .../corelib/tools/qbytearray/tst_qbytearray.cpp | 10 ++++---- .../qstringbuilder1/stringbuilder.cpp | 30 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index fe9b5f67c4..72493d3956 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -181,7 +181,7 @@ private slots: } while (false) \ /**/ -struct StaticByteArrays { +static const struct StaticByteArrays { struct Standard { QByteArrayData data; const char string[8]; @@ -207,10 +207,10 @@ struct StaticByteArrays { ,{{ Q_REFCOUNT_INITIALIZE_STATIC, /* length = */ 4, 0, 0, sizeof(QByteArrayData) + sizeof(char) }, 0, "dataBAD"} }; -static const QStaticByteArrayData<1> &staticStandard = reinterpret_cast &>(statics.standard); -static const QStaticByteArrayData<1> &staticNotNullTerminated = reinterpret_cast &>(statics.notNullTerminated); -static const QStaticByteArrayData<1> &staticShifted = reinterpret_cast &>(statics.shifted); -static const QStaticByteArrayData<1> &staticShiftedNotNullTerminated = reinterpret_cast &>(statics.shiftedNotNullTerminated); +static const QByteArrayDataPtr staticStandard = { const_cast(&statics.standard.data) }; +static const QByteArrayDataPtr staticNotNullTerminated = { const_cast(&statics.notNullTerminated.data) }; +static const QByteArrayDataPtr staticShifted = { const_cast(&statics.shifted.data) }; +static const QByteArrayDataPtr staticShiftedNotNullTerminated = { const_cast(&statics.shiftedNotNullTerminated.data) }; tst_QByteArray::tst_QByteArray() { diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp index 556b9ac16a..429652d92d 100644 --- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp @@ -107,6 +107,21 @@ void runScenario() QCOMPARE(r, r3); #endif + { + static const QStaticStringData<12> literalData = { + { Q_REFCOUNT_INITIALIZE_STATIC, 12, 0, 0, sizeof(QStringData) }, + { 's', 'o', 'm', 'e', ' ', 'l', 'i', 't', 'e', 'r', 'a', 'l' } + }; + static QStringDataPtr literal = { literalData.data_ptr() }; + + r = literal; + QCOMPARE(r, string); + r = r Q literal; + QCOMPARE(r, r2); + r = literal Q literal; + QCOMPARE(r, r2); + } + #ifndef QT_NO_CAST_FROM_ASCII r = string P LITERAL; QCOMPARE(r, r2); @@ -211,6 +226,21 @@ void runScenario() QCOMPARE(r, ba); } + { + static const QStaticByteArrayData<12> literalData = { + { Q_REFCOUNT_INITIALIZE_STATIC, 12, 0, 0, sizeof(QByteArrayData) }, + { 's', 'o', 'm', 'e', ' ', 'l', 'i', 't', 'e', 'r', 'a', 'l' } + }; + static QByteArrayDataPtr literal = { literalData.data_ptr() }; + + QByteArray ba = literal; + QCOMPARE(ba, QByteArray(LITERAL)); + ba = ba Q literal; + QCOMPARE(ba, QByteArray(LITERAL LITERAL)); + ba = literal Q literal; + QCOMPARE(ba, QByteArray(LITERAL LITERAL)); + } + //operator QString += { QString str = QString::fromUtf8(UTF8_LITERAL); -- cgit v1.2.3 From 4c892e14c6929e174c8bccc9ec5693a63a8ce69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 3 Apr 2012 13:23:55 +0200 Subject: Introduce initializer macros for QString- and QByteArrayData This enables easier updating of those structs, by reducing the amount of code that needs to be fixed. The common (and known) use cases are covered by the two macros being introduced in each case. Change-Id: I44981ca9b9b034f99238a11797b30bb85471cfb7 Reviewed-by: Thiago Macieira --- .../corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp index 429652d92d..862789cc73 100644 --- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp @@ -109,7 +109,7 @@ void runScenario() { static const QStaticStringData<12> literalData = { - { Q_REFCOUNT_INITIALIZE_STATIC, 12, 0, 0, sizeof(QStringData) }, + Q_STATIC_STRING_DATA_HEADER_INITIALIZER(12), { 's', 'o', 'm', 'e', ' ', 'l', 'i', 't', 'e', 'r', 'a', 'l' } }; static QStringDataPtr literal = { literalData.data_ptr() }; @@ -228,7 +228,7 @@ void runScenario() { static const QStaticByteArrayData<12> literalData = { - { Q_REFCOUNT_INITIALIZE_STATIC, 12, 0, 0, sizeof(QByteArrayData) }, + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(12), { 's', 'o', 'm', 'e', ' ', 'l', 'i', 't', 'e', 'r', 'a', 'l' } }; static QByteArrayDataPtr literal = { literalData.data_ptr() }; -- cgit v1.2.3 From e1626bf038d8ca8d968e7862bd8bced5c6cc2677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 4 Apr 2012 01:29:26 +0200 Subject: Revert "Add tests to verify QByteArray's zero termination" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The approach used to verify for zero-termination is too intrusive and requires additional maintenance work to ensure new zero-termination tests are added with new functionality. Zero-termination testing will be re-established in a subsequent commit. This reverts commit 4ef5a6269c1465662ea3872596ba284a13cce25e. Change-Id: I862434a072f447f7f0c4bbf8f757ba216212db3c Reviewed-by: Jędrzej Nowacki --- .../corelib/tools/qbytearray/tst_qbytearray.cpp | 128 +-------------------- 1 file changed, 5 insertions(+), 123 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 72493d3956..ea6f745795 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -147,40 +147,8 @@ private slots: void movablity_data(); void movablity(); void literals(); - - void zeroTermination_data(); - void zeroTermination(); }; -// Except for QByteArrays initialized with fromRawData(), QByteArray ensures -// that data() is null-terminated. VERIFY_ZERO_TERMINATION checks that -// invariant and goes further by testing that the null-character is in writable -// memory allocated by QByteArray. If the invariant is broken, tools like -// valgrind should be able to detect this. -#define VERIFY_ZERO_TERMINATION(ba) \ - do { \ - /* Statics could be anything, as can fromRawData() strings */ \ - QByteArray::DataPtr baDataPtr = ba.data_ptr(); \ - if (!baDataPtr->ref.isStatic() \ - && baDataPtr->offset == QByteArray().data_ptr()->offset) { \ - int baSize = ba.size(); \ - QCOMPARE(ba.constData()[baSize], '\0'); \ - \ - QByteArray baCopy(ba.constData(), baSize); \ - if (!baDataPtr->ref.isShared()) { \ - /* Don't detach, assumes no setSharable support */ \ - char *baData = ba.data(); \ - baData[baSize] = 'x'; \ - \ - QCOMPARE(ba.constData()[baSize], 'x'); \ - QCOMPARE(ba, baCopy); \ - \ - baData[baSize] = '\0'; /* Sanity restored */ \ - } \ - } \ - } while (false) \ - /**/ - static const struct StaticByteArrays { struct Standard { QByteArrayData data; @@ -256,13 +224,8 @@ void tst_QByteArray::qCompress_data() void tst_QByteArray::qCompress() { QFETCH( QByteArray, ba ); - QByteArray compressed = ::qCompress( ba ); - QByteArray uncompressed = ::qUncompress(compressed); - - QCOMPARE(uncompressed, ba); - VERIFY_ZERO_TERMINATION(compressed); - VERIFY_ZERO_TERMINATION(uncompressed); + QTEST( ::qUncompress( compressed ), "ba" ); } void tst_QByteArray::qUncompressCorruptedData_data() @@ -294,11 +257,9 @@ void tst_QByteArray::qUncompressCorruptedData() QByteArray res; res = ::qUncompress(in); QCOMPARE(res, QByteArray()); - VERIFY_ZERO_TERMINATION(res); res = ::qUncompress(in + "blah"); QCOMPARE(res, QByteArray()); - VERIFY_ZERO_TERMINATION(res); #else QSKIP("This test freezes on this platform"); #endif @@ -308,7 +269,7 @@ void tst_QByteArray::qCompressionZeroTermination() { QString s = "Hello, I'm a string."; QByteArray ba = ::qUncompress(::qCompress(s.toLocal8Bit())); - VERIFY_ZERO_TERMINATION(ba); + QVERIFY((int) *(ba.data() + ba.size()) == 0); } #endif @@ -328,7 +289,6 @@ void tst_QByteArray::constByteArray() QVERIFY(cba.constData()[1] == 'b'); QVERIFY(cba.constData()[2] == 'c'); QVERIFY(cba.constData()[3] == '\0'); - VERIFY_ZERO_TERMINATION(cba); } void tst_QByteArray::leftJustified() @@ -546,11 +506,9 @@ void tst_QByteArray::base64() QByteArray arr = QByteArray::fromBase64(base64); QCOMPARE(arr, rawdata); - VERIFY_ZERO_TERMINATION(arr); QByteArray arr64 = rawdata.toBase64(); QCOMPARE(arr64, base64); - VERIFY_ZERO_TERMINATION(arr64); } //different from the previous test as the input are invalid @@ -775,24 +733,17 @@ void tst_QByteArray::chop() src.chop(choplength); QCOMPARE(src, expected); - VERIFY_ZERO_TERMINATION(src); } void tst_QByteArray::prepend() { QByteArray ba("foo"); QCOMPARE(ba.prepend((char*)0), QByteArray("foo")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend(QByteArray()), QByteArray("foo")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend("1"), QByteArray("1foo")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend(QByteArray("2")), QByteArray("21foo")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend('3'), QByteArray("321foo")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.prepend("\0 ", 2), QByteArray::fromRawData("\0 321foo", 8)); - VERIFY_ZERO_TERMINATION(ba); } void tst_QByteArray::prependExtended_data() @@ -816,17 +767,11 @@ void tst_QByteArray::prependExtended() QCOMPARE(QByteArray("").prepend(array), QByteArray("data")); QCOMPARE(array.prepend((char*)0), QByteArray("data")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend(QByteArray()), QByteArray("data")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend("1"), QByteArray("1data")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend(QByteArray("2")), QByteArray("21data")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend('3'), QByteArray("321data")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.prepend("\0 ", 2), QByteArray::fromRawData("\0 321data", 9)); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.size(), 9); } @@ -834,19 +779,12 @@ void tst_QByteArray::append() { QByteArray ba("foo"); QCOMPARE(ba.append((char*)0), QByteArray("foo")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append(QByteArray()), QByteArray("foo")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append("1"), QByteArray("foo1")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append(QByteArray("2")), QByteArray("foo12")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append('3'), QByteArray("foo123")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append("\0"), QByteArray("foo123")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.append("\0", 1), QByteArray::fromRawData("foo123\0", 7)); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.size(), 7); } @@ -863,19 +801,12 @@ void tst_QByteArray::appendExtended() QCOMPARE(QByteArray("").append(array), QByteArray("data")); QCOMPARE(array.append((char*)0), QByteArray("data")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append(QByteArray()), QByteArray("data")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append("1"), QByteArray("data1")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append(QByteArray("2")), QByteArray("data12")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append('3'), QByteArray("data123")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append("\0"), QByteArray("data123")); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.append("\0", 1), QByteArray::fromRawData("data123\0", 8)); - VERIFY_ZERO_TERMINATION(array); QCOMPARE(array.size(), 8); } @@ -883,28 +814,22 @@ void tst_QByteArray::insert() { QByteArray ba("Meal"); QCOMPARE(ba.insert(1, QByteArray("ontr")), QByteArray("Montreal")); - VERIFY_ZERO_TERMINATION(ba); QCOMPARE(ba.insert(ba.size(), "foo"), QByteArray("Montrealfoo")); - VERIFY_ZERO_TERMINATION(ba); ba = QByteArray("13"); QCOMPARE(ba.insert(1, QByteArray("2")), QByteArray("123")); - VERIFY_ZERO_TERMINATION(ba); ba = "ac"; QCOMPARE(ba.insert(1, 'b'), QByteArray("abc")); QCOMPARE(ba.size(), 3); - VERIFY_ZERO_TERMINATION(ba); ba = "ikl"; QCOMPARE(ba.insert(1, "j"), QByteArray("ijkl")); QCOMPARE(ba.size(), 4); - VERIFY_ZERO_TERMINATION(ba); ba = "ab"; QCOMPARE(ba.insert(1, "\0X\0", 3), QByteArray::fromRawData("a\0X\0b", 5)); QCOMPARE(ba.size(), 5); - VERIFY_ZERO_TERMINATION(ba); } void tst_QByteArray::insertExtended_data() @@ -917,7 +842,6 @@ void tst_QByteArray::insertExtended() QFETCH(QByteArray, array); QCOMPARE(array.insert(1, "i"), QByteArray("diata")); QCOMPARE(array.size(), 5); - VERIFY_ZERO_TERMINATION(array); } void tst_QByteArray::remove_data() @@ -948,7 +872,6 @@ void tst_QByteArray::remove() QFETCH(int, length); QFETCH(QByteArray, expected); QCOMPARE(src.remove(position, length), expected); - VERIFY_ZERO_TERMINATION(src); } void tst_QByteArray::replace_data() @@ -990,8 +913,6 @@ void tst_QByteArray::replace() QCOMPARE(str1.replace(pos, len, after).constData(), expected.constData()); QCOMPARE(str2.replace(pos, len, after.data()), expected); - VERIFY_ZERO_TERMINATION(str1); - VERIFY_ZERO_TERMINATION(str2); } void tst_QByteArray::replaceWithSpecifiedLength() @@ -1004,7 +925,6 @@ void tst_QByteArray::replaceWithSpecifiedLength() const char _expected[] = "zxc\0vbcdefghjk"; QByteArray expected(_expected,sizeof(_expected)-1); QCOMPARE(ba,expected); - VERIFY_ZERO_TERMINATION(ba); } void tst_QByteArray::indexOf_data() @@ -1307,7 +1227,6 @@ void tst_QByteArray::appendAfterFromRawData() data[0] = 'Y'; } QVERIFY(arr.at(0) == 'X'); - VERIFY_ZERO_TERMINATION(arr); } void tst_QByteArray::toFromHex_data() @@ -1379,17 +1298,15 @@ void tst_QByteArray::toFromHex() QFETCH(QByteArray, hex_alt1); { - QByteArray th = str.toHex(); + const QByteArray th = str.toHex(); QCOMPARE(th.size(), hex.size()); QCOMPARE(th, hex); - VERIFY_ZERO_TERMINATION(th); } { - QByteArray fh = QByteArray::fromHex(hex); + const QByteArray fh = QByteArray::fromHex(hex); QCOMPARE(fh.size(), str.size()); QCOMPARE(fh, str); - VERIFY_ZERO_TERMINATION(fh); } QCOMPARE(QByteArray::fromHex(hex_alt1), str); @@ -1402,17 +1319,14 @@ void tst_QByteArray::toFromPercentEncoding() QByteArray data = arr.toPercentEncoding(); QCOMPARE(QString(data), QString("Qt%20is%20great%21")); QCOMPARE(QByteArray::fromPercentEncoding(data), arr); - VERIFY_ZERO_TERMINATION(data); data = arr.toPercentEncoding("! ", "Qt"); QCOMPARE(QString(data), QString("%51%74 is grea%74!")); QCOMPARE(QByteArray::fromPercentEncoding(data), arr); - VERIFY_ZERO_TERMINATION(data); data = arr.toPercentEncoding(QByteArray(), "abcdefghijklmnopqrstuvwxyz", 'Q'); QCOMPARE(QString(data), QString("Q51Q74Q20Q69Q73Q20Q67Q72Q65Q61Q74Q21")); QCOMPARE(QByteArray::fromPercentEncoding(data, 'Q'), arr); - VERIFY_ZERO_TERMINATION(data); // verify that to/from percent encoding preserves nullity arr = ""; @@ -1422,7 +1336,6 @@ void tst_QByteArray::toFromPercentEncoding() QVERIFY(!arr.toPercentEncoding().isNull()); QVERIFY(QByteArray::fromPercentEncoding("").isEmpty()); QVERIFY(!QByteArray::fromPercentEncoding("").isNull()); - VERIFY_ZERO_TERMINATION(arr); arr = QByteArray(); QVERIFY(arr.isEmpty()); @@ -1431,7 +1344,6 @@ void tst_QByteArray::toFromPercentEncoding() QVERIFY(arr.toPercentEncoding().isNull()); QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isEmpty()); QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isNull()); - VERIFY_ZERO_TERMINATION(arr); } void tst_QByteArray::fromPercentEncoding_data() @@ -1673,9 +1585,6 @@ void tst_QByteArray::repeated() const QFETCH(int, count); QCOMPARE(string.repeated(count), expected); - - QByteArray repeats = string.repeated(count); - VERIFY_ZERO_TERMINATION(repeats); } void tst_QByteArray::repeated_data() const @@ -1767,7 +1676,6 @@ void tst_QByteArray::byteRefDetaching() const copy[0] = 'S'; QCOMPARE(str, QByteArray("str")); - VERIFY_ZERO_TERMINATION(copy); } { @@ -1776,7 +1684,6 @@ void tst_QByteArray::byteRefDetaching() const str[0] = 'S'; QCOMPARE(buf[0], char('s')); - VERIFY_ZERO_TERMINATION(str); } { @@ -1787,7 +1694,6 @@ void tst_QByteArray::byteRefDetaching() const str[0] = 'S'; QCOMPARE(buf[0], char('s')); - VERIFY_ZERO_TERMINATION(str); } } @@ -1797,25 +1703,19 @@ void tst_QByteArray::reserve() QByteArray qba; qba.reserve(capacity); QVERIFY(qba.capacity() == capacity); - VERIFY_ZERO_TERMINATION(qba); - char *data = qba.data(); + for (int i = 0; i < capacity; i++) { qba.resize(i); QVERIFY(capacity == qba.capacity()); QVERIFY(data == qba.data()); - VERIFY_ZERO_TERMINATION(qba); } QByteArray nil1, nil2; nil1.reserve(0); - VERIFY_ZERO_TERMINATION(nil1); nil2.squeeze(); - VERIFY_ZERO_TERMINATION(nil2); nil1.squeeze(); - VERIFY_ZERO_TERMINATION(nil1); nil2.reserve(0); - VERIFY_ZERO_TERMINATION(nil2); } void tst_QByteArray::reserveExtended_data() @@ -1826,16 +1726,12 @@ void tst_QByteArray::reserveExtended_data() void tst_QByteArray::reserveExtended() { QFETCH(QByteArray, array); - array.reserve(1024); QVERIFY(array.capacity() == 1024); QCOMPARE(array, QByteArray("data")); - VERIFY_ZERO_TERMINATION(array); - array.squeeze(); QCOMPARE(array, QByteArray("data")); QCOMPARE(array.capacity(), array.size()); - VERIFY_ZERO_TERMINATION(array); } void tst_QByteArray::movablity_data() @@ -1928,7 +1824,6 @@ void tst_QByteArray::literals() QVERIFY(str == "abcd"); QVERIFY(str.data_ptr()->ref.isStatic()); QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData)); - VERIFY_ZERO_TERMINATION(str); const char *s = str.constData(); QByteArray str2 = str; @@ -1936,27 +1831,14 @@ void tst_QByteArray::literals() // detach on non const access QVERIFY(str.data() != s); - VERIFY_ZERO_TERMINATION(str); QVERIFY(str2.constData() == s); QVERIFY(str2.data() != s); - VERIFY_ZERO_TERMINATION(str2); #else QSKIP("Only tested on c++0x compliant compiler or gcc"); #endif } -void tst_QByteArray::zeroTermination_data() -{ - movablity_data(); -} - -void tst_QByteArray::zeroTermination() -{ - QFETCH(QByteArray, array); - VERIFY_ZERO_TERMINATION(array); -} - const char globalChar = '1'; QTEST_APPLESS_MAIN(tst_QByteArray) -- cgit v1.2.3 From b143a65728fefd8d8f748e1cf984b38e0ca5b9bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 4 Apr 2012 01:26:44 +0200 Subject: Add zero-termination checks to QString and QByteArray tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This uses an alternative approach to the testing formerly introduced in 4ef5a626. Zero-termination tests are injected into all QCOMPARE/QTEST invocations. This makes such testing more thorough and widespread, and gets seamlessly extended by future tests. It also fixes an issue uncovered by the test where using a past-the-end position with QString::insert(pos, char), could move uninitialized data and clobber the null-terminator. Change-Id: I7392580245b419ee65c3ae6f261b6e851d66dd4f Reviewed-by: Jędrzej Nowacki --- .../corelib/tools/qbytearray/tst_qbytearray.cpp | 59 ++++++++++++++++++++++ tests/auto/corelib/tools/qstring/tst_qstring.cpp | 59 ++++++++++++++++++++++ 2 files changed, 118 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index ea6f745795..a30ecb7ab1 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -180,6 +180,65 @@ static const QByteArrayDataPtr staticNotNullTerminated = { const_cast(&statics.shifted.data) }; static const QByteArrayDataPtr staticShiftedNotNullTerminated = { const_cast(&statics.shiftedNotNullTerminated.data) }; +template const T &verifyZeroTermination(const T &t) { return t; } + +QByteArray verifyZeroTermination(const QByteArray &ba) +{ + // This test does some evil stuff, it's all supposed to work. + + QByteArray::DataPtr baDataPtr = const_cast(ba).data_ptr(); + + // Skip if isStatic() or fromRawData(), as those offer no guarantees + if (baDataPtr->ref.isStatic() + || baDataPtr->offset != QByteArray().data_ptr()->offset) + return ba; + + int baSize = ba.size(); + char baTerminator = ba.constData()[baSize]; + if ('\0' != baTerminator) + return QString::fromAscii( + "*** Result ('%1') not null-terminated: 0x%2 ***").arg(QString::fromAscii(ba)) + .arg(baTerminator, 2, 16, QChar('0')).toAscii(); + + // Skip mutating checks on shared strings + if (baDataPtr->ref.isShared()) + return ba; + + const char *baData = ba.constData(); + const QByteArray baCopy(baData, baSize); // Deep copy + + const_cast(baData)[baSize] = 'x'; + if ('x' != ba.constData()[baSize]) { + return QString::fromAscii("*** Failed to replace null-terminator in " + "result ('%1') ***").arg(QString::fromAscii(ba)).toAscii(); + } + if (ba != baCopy) { + return QString::fromAscii( "*** Result ('%1') differs from its copy " + "after null-terminator was replaced ***").arg(QString::fromAscii(ba)).toAscii(); + } + const_cast(baData)[baSize] = '\0'; // Restore sanity + + return ba; +} + +// Overriding QTest's QCOMPARE, to check QByteArray for null termination +#undef QCOMPARE +#define QCOMPARE(actual, expected) \ + do { \ + if (!QTest::qCompare(verifyZeroTermination(actual), expected, \ + #actual, #expected, __FILE__, __LINE__)) \ + return; \ + } while (0) \ + /**/ +#undef QTEST +#define QTEST(actual, testElement) \ + do { \ + if (!QTest::qTest(verifyZeroTermination(actual), testElement, \ + #actual, #testElement, __FILE__, __LINE__)) \ + return; \ + } while (0) \ + /**/ + tst_QByteArray::tst_QByteArray() { qRegisterMetaType("qulonglong"); diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 7d4a9b5aba..97394482b0 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -229,6 +229,65 @@ private slots: void assignQLatin1String(); }; +template const T &verifyZeroTermination(const T &t) { return t; } + +QString verifyZeroTermination(const QString &str) +{ + // This test does some evil stuff, it's all supposed to work. + + QString::DataPtr strDataPtr = const_cast(str).data_ptr(); + + // Skip if isStatic() or fromRawData(), as those offer no guarantees + if (strDataPtr->ref.isStatic() + || strDataPtr->offset != QString().data_ptr()->offset) + return str; + + int strSize = str.size(); + QChar strTerminator = str.constData()[strSize]; + if (QChar('\0') != strTerminator) + return QString::fromAscii( + "*** Result ('%1') not null-terminated: 0x%2 ***").arg(str) + .arg(strTerminator.unicode(), 4, 16, QChar('0')); + + // Skip mutating checks on shared strings + if (strDataPtr->ref.isShared()) + return str; + + const QChar *strData = str.constData(); + const QString strCopy(strData, strSize); // Deep copy + + const_cast(strData)[strSize] = QChar('x'); + if (QChar('x') != str.constData()[strSize]) { + return QString::fromAscii("*** Failed to replace null-terminator in " + "result ('%1') ***").arg(str); + } + if (str != strCopy) { + return QString::fromAscii( "*** Result ('%1') differs from its copy " + "after null-terminator was replaced ***").arg(str); + } + const_cast(strData)[strSize] = QChar('\0'); // Restore sanity + + return str; +} + +// Overriding QTest's QCOMPARE, to check QString for null termination +#undef QCOMPARE +#define QCOMPARE(actual, expected) \ + do { \ + if (!QTest::qCompare(verifyZeroTermination(actual), expected, \ + #actual, #expected, __FILE__, __LINE__)) \ + return; \ + } while (0) \ + /**/ +#undef QTEST +#define QTEST(actual, testElement) \ + do { \ + if (!QTest::qTest(verifyZeroTermination(actual), testElement, \ + #actual, #testElement, __FILE__, __LINE__)) \ + return; \ + } while (0) \ + /**/ + typedef QList IntList; Q_DECLARE_METATYPE(QList) -- cgit v1.2.3 From 4a11611c8a5084acaa68e6adc4c32eda9ca672ec Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 4 Apr 2012 21:43:53 +0200 Subject: Fix unittest for QStandardPaths::enableTestMode It was confusing DataLocation and GenericDataLocation, and the same for CacheLocation and GenericCacheLocation. The test was passing in the api_changes branch because these were giving the same result (empty app name), but the QCoreApplication::applicationName fix in master makes these different, so the bug in the test showed up after merging. Change-Id: I80ef6883c96cfd02b8c277d9d686717028d396bb Reviewed-by: Thiago Macieira --- tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index a389efa5ca..ed396d3344 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -173,14 +173,14 @@ void tst_qstandardpaths::enableTestMode() // GenericDataLocation const QString dataDir = qttestDir + QLatin1String("/share"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), dataDir); - const QStringList gdDirs = QStandardPaths::standardLocations(QStandardPaths::DataLocation); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), dataDir); + const QStringList gdDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); QCOMPARE(gdDirs, QStringList() << dataDir << m_globalAppDir); - // CacheLocation + // GenericCacheLocation const QString cacheDir = qttestDir + QLatin1String("/cache"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::CacheLocation), cacheDir); - const QStringList cacheDirs = QStandardPaths::standardLocations(QStandardPaths::CacheLocation); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation), cacheDir); + const QStringList cacheDirs = QStandardPaths::standardLocations(QStandardPaths::GenericCacheLocation); QCOMPARE(cacheDirs, QStringList() << cacheDir); #endif -- cgit v1.2.3 From 10747da77d8df4894eaa7ee256b5bfb68faac635 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 4 Apr 2012 20:44:33 +0100 Subject: Add test for qHash(QString) / qHash(QStringRef) Two equal strings / stringrefs must return the same hash. Change-Id: I2af9a11ab721ca25f4039048a7e5f260e6ff0148 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 97394482b0..dda4c52347 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -51,6 +51,7 @@ #include #include +#include Q_DECLARE_METATYPE(qlonglong) @@ -4929,6 +4930,13 @@ void tst_QString::compare() QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseSensitive)), csr); QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseInsensitive)), cir); + if (csr == 0) { + QVERIFY(qHash(s1) == qHash(s2)); + QVERIFY(qHash(s1) == qHash(r2)); + QVERIFY(qHash(r1) == qHash(s2)); + QVERIFY(qHash(r1) == qHash(r2)); + } + if (!cir) { QCOMPARE(s1.toCaseFolded(), s2.toCaseFolded()); } -- cgit v1.2.3 From 9ddb822a8672af8495ee6e3e30449800c96589e4 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 4 Apr 2012 21:00:11 +0100 Subject: Add test for qHash(QByteArray) Two equal QByteArrays must return the same hash. Change-Id: Iddd45b0c420213ca2b82bbcb164367acb6104ec8 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index a30ecb7ab1..b7793051b1 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -43,6 +43,7 @@ #include #include +#include #include #include #if defined(Q_OS_WINCE) @@ -1557,6 +1558,9 @@ void tst_QByteArray::compare() QCOMPARE(str2 <= str1, isGreater || isEqual); QCOMPARE(str2 >= str1, isLess || isEqual); QCOMPARE(str2 != str1, !isEqual); + + if (isEqual) + QVERIFY(qHash(str1) == qHash(str2)); } void tst_QByteArray::compareCharStar_data() -- cgit v1.2.3 From 6f51fee995cf6f4a746077209f4dbb729c463769 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 26 Mar 2012 15:28:40 -0300 Subject: Remove references to QT_NO_STL from QtCore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QT_NO_STL is now no longer defined, so remove the conditionals and select the STL side. Change-Id: Ieedd248ae16e5a128b4ac287f850b3ebc8fb6181 Reviewed-by: João Abecasis --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 8 -------- tests/auto/other/collections/tst_collections.cpp | 21 +++------------------ tests/benchmarks/corelib/tools/qstringlist/main.cpp | 4 ---- tests/benchmarks/corelib/tools/qvector/qrawvector.h | 4 ---- 4 files changed, 3 insertions(+), 34 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index dda4c52347..7afd435e52 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -876,7 +876,6 @@ void tst_QString::constructorQByteArray() void tst_QString::STL() { -#ifndef QT_NO_STL #ifndef QT_NO_CAST_TO_ASCII QString qt( "QString" ); @@ -920,9 +919,6 @@ void tst_QString::STL() QCOMPARE(s, QString::fromLatin1("hello")); QCOMPARE(stlStr, s.toStdWString()); -#else - QSKIP( "Not tested without STL support"); -#endif } void tst_QString::truncate() @@ -3360,7 +3356,6 @@ void tst_QString::fromStdString() #ifdef Q_CC_HPACC QSKIP("This test crashes on HP-UX with aCC"); #endif -#if !defined(QT_NO_STL) std::string stroustrup = "foo"; QString eng = QString::fromStdString( stroustrup ); QCOMPARE( eng, QString("foo") ); @@ -3368,7 +3363,6 @@ void tst_QString::fromStdString() std::string stdnull( cnull, sizeof(cnull)-1 ); QString qtnull = QString::fromStdString( stdnull ); QCOMPARE( qtnull.size(), int(stdnull.size()) ); -#endif } void tst_QString::toStdString() @@ -3376,7 +3370,6 @@ void tst_QString::toStdString() #ifdef Q_CC_HPACC QSKIP("This test crashes on HP-UX with aCC"); #endif -#if !defined(QT_NO_STL) QString nord = "foo"; std::string stroustrup1 = nord.toStdString(); QVERIFY( qstrcmp(stroustrup1.c_str(), "foo") == 0 ); @@ -3390,7 +3383,6 @@ void tst_QString::toStdString() QString qtnull( qcnull, sizeof(qcnull)/sizeof(QChar) ); std::string stdnull = qtnull.toStdString(); QCOMPARE( int(stdnull.size()), qtnull.size() ); -#endif } void tst_QString::utf8() diff --git a/tests/auto/other/collections/tst_collections.cpp b/tests/auto/other/collections/tst_collections.cpp index a9cef635c7..2d5d6a6553 100644 --- a/tests/auto/other/collections/tst_collections.cpp +++ b/tests/auto/other/collections/tst_collections.cpp @@ -78,9 +78,7 @@ void foo() #include -#ifndef QT_NO_STL -# include -#endif +#include #include "qalgorithms.h" #include "qbitarray.h" @@ -136,14 +134,12 @@ private slots: void conversions(); void javaStyleIterators(); void constAndNonConstStlIterators(); -#ifndef QT_NO_STL void vector_stl_data(); void vector_stl(); void list_stl_data(); void list_stl(); void linkedlist_stl_data(); void linkedlist_stl(); -#endif void q_init(); void pointersize(); void containerInstantiation(); @@ -228,7 +224,7 @@ void tst_Collections::list() QVERIFY(list.size() == 6); QVERIFY(list.end() - list.begin() == list.size()); -#if !defined(QT_NO_STL) && !defined(Q_CC_MSVC) && !defined(Q_CC_SUN) +#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 @@ -1038,10 +1034,8 @@ void tst_Collections::vector() v.prepend(1); v << 3 << 4 << 5 << 6; -#if !defined(QT_NO_STL) QVERIFY(std::binary_search(v.begin(), v.end(), 2) == true); QVERIFY(std::binary_search(v.begin(), v.end(), 9) == false); -#endif 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); @@ -2870,7 +2864,6 @@ void tst_Collections::constAndNonConstStlIterators() testMapLikeStlIterators >(); } -#ifndef QT_NO_STL void tst_Collections::vector_stl_data() { QTest::addColumn("elements"); @@ -2953,7 +2946,6 @@ void tst_Collections::list_stl() QCOMPARE(QList::fromStdList(stdList), list); } -#endif template T qtInit(T * = 0) @@ -3014,7 +3006,6 @@ void instantiateContainer() ContainerType container; const ContainerType constContainer(container); -#ifndef QT_NO_STL typename ContainerType::const_iterator constIt; constIt = constContainer.begin(); constIt = container.cbegin(); @@ -3024,7 +3015,7 @@ void instantiateContainer() constIt = constContainer.cend(); container.constEnd(); Q_UNUSED(constIt) -#endif + container.clear(); container.contains(value); container.count(); @@ -3043,12 +3034,10 @@ void instantiateMutableIterationContainer() instantiateContainer(); ContainerType container; -#ifndef QT_NO_STL typename ContainerType::iterator it; it = container.begin(); it = container.end(); Q_UNUSED(it) -#endif // QSet lacks count(T). const ValueType value = ValueType(); @@ -3622,10 +3611,8 @@ struct IntOrString IntOrString(const QString &v) : val(v.toInt()) { } operator int() { return val; } operator QString() { return QString::number(val); } -#ifndef QT_NO_STL operator std::string() { return QString::number(val).toStdString(); } IntOrString(const std::string &v) : val(QString::fromStdString(v).toInt()) { } -#endif }; template void insert_remove_loop_impl() @@ -3742,14 +3729,12 @@ void tst_Collections::insert_remove_loop() insert_remove_loop_impl >(); insert_remove_loop_impl >(); -#ifndef QT_NO_STL insert_remove_loop_impl >(); insert_remove_loop_impl >(); insert_remove_loop_impl >(); insert_remove_loop_impl >(); insert_remove_loop_impl >(); insert_remove_loop_impl >(); -#endif } diff --git a/tests/benchmarks/corelib/tools/qstringlist/main.cpp b/tests/benchmarks/corelib/tools/qstringlist/main.cpp index 48bf7f1fc5..b4c1be29d9 100644 --- a/tests/benchmarks/corelib/tools/qstringlist/main.cpp +++ b/tests/benchmarks/corelib/tools/qstringlist/main.cpp @@ -163,7 +163,6 @@ void tst_QStringList::split_qlist_qstring() const void tst_QStringList::split_stdvector_stdstring() const { -#ifndef QT_NO_STL QFETCH(QString, input); const char split_char = ':'; std::string stdinput = input.toStdString(); @@ -176,12 +175,10 @@ void tst_QStringList::split_stdvector_stdstring() const token.push_back(each)) ; } -#endif } void tst_QStringList::split_stdvector_stdwstring() const { -#ifndef QT_NO_STL QFETCH(QString, input); const wchar_t split_char = ':'; std::wstring stdinput = input.toStdWString(); @@ -194,7 +191,6 @@ void tst_QStringList::split_stdvector_stdwstring() const token.push_back(each)) ; } -#endif } void tst_QStringList::split_stdlist_stdstring() const diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index 0fdfa86f1d..8c2d014a41 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -48,10 +48,8 @@ #include #include -#ifndef QT_NO_STL #include #include -#endif #include #include #include @@ -253,12 +251,10 @@ public: //static QRawVector fromList(const QList &list); -#ifndef QT_NO_STL static inline QRawVector fromStdVector(const std::vector &vector) { QRawVector tmp; qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; } inline std::vector toStdVector() const { std::vector tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; } -#endif private: T *allocate(int alloc); -- cgit v1.2.3 From 9dde45722b9ab760e8c14722904cfa4eca5663e9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 26 Mar 2012 15:29:34 -0300 Subject: Remove references to QT_NO_STL from QtConcurrent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same as with QtCore, remove the #ifdef and #ifndef and select the side with STL. Change-Id: If1440080328c7c51afe35f5944a19dafc4761ee5 Reviewed-by: Stephen Kelly Reviewed-by: Morten Johan Sørvig --- .../concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp | 4 ---- .../tst_qtconcurrentiteratekernel.cpp | 10 ---------- tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp | 4 ---- 3 files changed, 18 deletions(-) (limited to 'tests') diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp index eb1faab94f..c8d4c211a9 100644 --- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp +++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp @@ -57,9 +57,7 @@ private slots: void resultAt(); void incrementalResults(); void noDetach(); -#ifndef QT_NO_STL void stlContainers(); -#endif }; void tst_QtConcurrentFilter::filter() @@ -1496,7 +1494,6 @@ void tst_QtConcurrentFilter::noDetach() } } -#ifndef QT_NO_STL void tst_QtConcurrentFilter::stlContainers() { std::vector vector; @@ -1523,7 +1520,6 @@ void tst_QtConcurrentFilter::stlContainers() QCOMPARE(list2.size(), (std::list::size_type)(1)); QCOMPARE(*list2.begin(), 1); } -#endif QTEST_MAIN(tst_QtConcurrentFilter) #include "tst_qtconcurrentfilter.moc" diff --git a/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp index 46562b5eb0..538a821535 100644 --- a/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp +++ b/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp @@ -65,7 +65,6 @@ struct TestIterator }; #include -#ifndef QT_NO_STL namespace std { template <> struct iterator_traits @@ -79,7 +78,6 @@ int distance(TestIterator &a, TestIterator &b) } } -#endif #include #include @@ -96,10 +94,8 @@ private slots: void stresstest(); void noIterations(); void throttling(); -#ifndef QT_NO_STL void blockSize(); void multipleResults(); -#endif }; QAtomicInt iterations; @@ -268,8 +264,6 @@ public: } }; -// Missing stl iterators prevent correct block size calculation. -#ifndef QT_NO_STL void tst_QtConcurrentIterateKernel::blockSize() { const int expectedMinimumBlockSize = 1024 / QThread::idealThreadCount(); @@ -278,7 +272,6 @@ void tst_QtConcurrentIterateKernel::blockSize() qDebug() << "block size" << peakBlockSize; QVERIFY(peakBlockSize >= expectedMinimumBlockSize); } -#endif class MultipleResultsFor : public IterateKernel { @@ -292,8 +285,6 @@ public: } }; -// Missing stl iterators prevent correct summation. -#ifndef QT_NO_STL void tst_QtConcurrentIterateKernel::multipleResults() { QFuture f = startThreadEngine(new MultipleResultsFor(0, 10)).startAsynchronously(); @@ -303,7 +294,6 @@ void tst_QtConcurrentIterateKernel::multipleResults() QCOMPARE(f.resultAt(9), 9); f.waitForFinished(); } -#endif QTEST_MAIN(tst_QtConcurrentIterateKernel) diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp index d0609d00ef..220f28a542 100644 --- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -72,9 +72,7 @@ private slots: #endif void incrementalResults(); void noDetach(); -#ifndef QT_NO_STL void stlContainers(); -#endif void qFutureAssignmentLeak(); void stressTest(); public slots: @@ -2301,7 +2299,6 @@ void tst_QtConcurrentMap::noDetach() } -#ifndef QT_NO_STL void tst_QtConcurrentMap::stlContainers() { std::vector vector; @@ -2322,7 +2319,6 @@ void tst_QtConcurrentMap::stlContainers() QtConcurrent::blockingMap(list, multiplyBy2Immutable); } -#endif InstanceCounter ic_fn(const InstanceCounter & ic) { -- cgit v1.2.3 From e6e4456de0506aa9896b687dc858eb9ae03d8917 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 1 Apr 2012 18:47:56 +0100 Subject: QFileSystemModel: fix sorting When sorting a model recursively, the children of a QFileSystemNode are extracted from their parent in a QHash order; then filtered, then sorted (using a stable sort) depending on the sorting column. This means that the order of the children comparing to equal for the chosen sort are shown in the order they were picked from the iteration on the QHash, which isn't reliable at all. Moreover, the criteria used in QFileSystemModelSorter for sorting are too loose: when sorting by any column but the name, if the result is "equality", then the file names should be used to determine the sort order. This patch removes the stable sort in favour of a full sort, and fixes the criteria of soring inside QFileSystemModelSorter. Change-Id: Idd9aece22f2ebbe77ec40d372b43cde4c200ff38 Reviewed-by: Stephen Kelly --- tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 1a3d083864..5eaf8b1b2c 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -863,7 +863,7 @@ void tst_QFileSystemModel::sort() QTest::qWait(500); QModelIndex parent = myModel->index(dirPath, 0); QList expectedOrder; - expectedOrder << tempFile2.fileName() << tempFile.fileName() << dirPath + QChar('/') + "." << dirPath + QChar('/') + ".."; + expectedOrder << tempFile2.fileName() << tempFile.fileName() << dirPath + QChar('/') + ".." << dirPath + QChar('/') + "."; //File dialog Mode means sub trees are not sorted, only the current root if (fileDialogMode) { // FIXME: we were only able to disableRecursiveSort in developer builds, so we can only -- cgit v1.2.3 From ea17c21fd8b93a94027fad7d3827904ae96e2a3b Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 4 Apr 2012 20:37:04 +0100 Subject: QHostAddress: improve qHash implementation Avoid the conversion to a temporary QString -- just hash the address as a byte array. Change-Id: Ic35cdbbc3ee66c32a28d911bd27de0092395979f Done-with: Shane Kearns Reviewed-by: Thiago Macieira Reviewed-by: Shane Kearns --- tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index a0403e5550..d1027c81e0 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -323,6 +323,8 @@ void tst_QHostAddress::compare() QFETCH(bool, result); QCOMPARE(first == second, result); + if (result == true) + QVERIFY(qHash(first) == qHash(second)); } void tst_QHostAddress::assignment() -- cgit v1.2.3 From 4893a5422e2978f4b9a0e7785af1696e3438ac22 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 27 Mar 2012 18:40:06 +0100 Subject: New qHash algorithm for uchar/ushort arrays (QString, QByteArray, etc.) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port of Robin's work from I0a53aa4581e25b351b9cb5033415b5163d05fe71 on top of the new qHash patches (the original commit just introduced lots of conflicts, so I redid it from scratch). This is based on the work done in the QHash benchmark over the past few months experimenting with the performance of the string hashing algorithm used by Java. The Java algorithm, in turn, appears to have been based off a variant of djb's work at http://cr.yp.to/cdb/cdb.txt. This commit provides a performance boost of ~12-33% on the QHash benchmark. Unfortunately, the rcc test depends on QHash ordering. Randomizing QHash or changing qHash will cause the test to fail (see QTBUG-25078), so for now the testdata is changed as well. Done-with: Robin Burchell Change-Id: Ie05d8e21588d1b2d4bd555ef254e1eb101864b75 Reviewed-by: João Abecasis Reviewed-by: Robin Burchell --- tests/auto/tools/rcc/data/images/images.expected | 48 ++++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'tests') diff --git a/tests/auto/tools/rcc/data/images/images.expected b/tests/auto/tools/rcc/data/images/images.expected index 71be819310..4ebf066568 100644 --- a/tests/auto/tools/rcc/data/images/images.expected +++ b/tests/auto/tools/rcc/data/images/images.expected @@ -1,8 +1,8 @@ /**************************************************************************** ** Resource object code ** -IGNORE: ** Created: Tue Jul 15 11:17:15 2008 -IGNORE: ** by: The Resource Compiler for Qt version 4.4.2 +IGNORE: ** Created: Sun Apr 1 21:20:28 2012 +IGNORE: ** by: The Resource Compiler for Qt version 5.0.0 ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ @@ -10,16 +10,7 @@ IGNORE: ** by: The Resource Compiler for Qt version 4.4.2 #include static const unsigned char qt_resource_data[] = { -IGNORE: // /data5/dev/qt/tests/auto/rcc/data/images/square.png - 0x0,0x0,0x0,0x5e, - 0x89, - 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, - 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x1,0x3,0x0,0x0,0x0,0x49,0xb4,0xe8,0xb7, - 0x0,0x0,0x0,0x6,0x50,0x4c,0x54,0x45,0x0,0x0,0x0,0x58,0xa8,0xff,0x8c,0x14, - 0x1f,0xab,0x0,0x0,0x0,0x13,0x49,0x44,0x41,0x54,0x8,0xd7,0x63,0x60,0x0,0x81, - 0xfa,0xff,0xff,0xff,0xd,0x3e,0x2,0x4,0x0,0x8d,0x4d,0x68,0x6b,0xcf,0xb8,0x8e, - 0x86,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, -IGNORE: // /data5/dev/qt/tests/auto/rcc/data/images/circle.png +IGNORE: // /dev/qt5/qtbase/tests/auto/tools/rcc/data/images/images/circle.png 0x0,0x0,0x0,0xa5, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, @@ -33,7 +24,16 @@ IGNORE: // /data5/dev/qt/tests/auto/rcc/data/images/circle.png 0x4c,0x48,0x31,0x15,0x53,0xec,0x5,0x14,0x9b,0x11,0xc5,0x6e,0x8,0xdd,0x8e,0x1b, 0x14,0x54,0x19,0xf3,0xa1,0x23,0xdb,0xd5,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44, 0xae,0x42,0x60,0x82, -IGNORE: // /data5/dev/qt/tests/auto/rcc/data/images/subdir/triangle.png +IGNORE: // /dev/qt5/qtbase/tests/auto/tools/rcc/data/images/images/square.png + 0x0,0x0,0x0,0x5e, + 0x89, + 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, + 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x1,0x3,0x0,0x0,0x0,0x49,0xb4,0xe8,0xb7, + 0x0,0x0,0x0,0x6,0x50,0x4c,0x54,0x45,0x0,0x0,0x0,0x58,0xa8,0xff,0x8c,0x14, + 0x1f,0xab,0x0,0x0,0x0,0x13,0x49,0x44,0x41,0x54,0x8,0xd7,0x63,0x60,0x0,0x81, + 0xfa,0xff,0xff,0xff,0xd,0x3e,0x2,0x4,0x0,0x8d,0x4d,0x68,0x6b,0xcf,0xb8,0x8e, + 0x86,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, +IGNORE: // /dev/qt5/qtbase/tests/auto/tools/rcc/data/images/images/subdir/triangle.png 0x0,0x0,0x0,0xaa, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, @@ -56,21 +56,21 @@ static const unsigned char qt_resource_name[] = { 0x7,0x3,0x7d,0xc3, 0x0,0x69, 0x0,0x6d,0x0,0x61,0x0,0x67,0x0,0x65,0x0,0x73, - // square.png - 0x0,0xa, - 0x8,0x8b,0x6,0x27, + // subdir + 0x0,0x6, + 0x7,0xab,0x8b,0x2, 0x0,0x73, - 0x0,0x71,0x0,0x75,0x0,0x61,0x0,0x72,0x0,0x65,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, + 0x0,0x75,0x0,0x62,0x0,0x64,0x0,0x69,0x0,0x72, // circle.png 0x0,0xa, 0xa,0x2d,0x16,0x47, 0x0,0x63, 0x0,0x69,0x0,0x72,0x0,0x63,0x0,0x6c,0x0,0x65,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, - // subdir - 0x0,0x6, - 0x7,0xab,0x8b,0x2, + // square.png + 0x0,0xa, + 0x8,0x8b,0x6,0x27, 0x0,0x73, - 0x0,0x75,0x0,0x62,0x0,0x64,0x0,0x69,0x0,0x72, + 0x0,0x71,0x0,0x75,0x0,0x61,0x0,0x72,0x0,0x65,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // triangle.png 0x0,0xc, 0x5,0x59,0xa7,0xc7, @@ -85,11 +85,11 @@ static const unsigned char qt_resource_struct[] = { // :/images 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x2, // :/images/subdir - 0x0,0x0,0x0,0x46,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x5, + 0x0,0x0,0x0,0x12,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x5, // :/images/square.png - 0x0,0x0,0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x3e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0xa9, // :/images/circle.png - 0x0,0x0,0x0,0x2c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x62, + 0x0,0x0,0x0,0x24,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0, // :/images/subdir/triangle.png 0x0,0x0,0x0,0x58,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x1,0xb, -- cgit v1.2.3 From d4f3052a1b210c09976883afbe0fac087171be4f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 3 Apr 2012 13:58:39 -0300 Subject: Adjust a double leading slash in the path for FTP to /%2F Some FTP implementations (currently not including QNAM) strip the first slash off the path in an FTP URL so that the path in the URL is relative to the login path (the user's home directory). To reach the root directory, another slash is necessary, hence the double slash. In anticipation of future URL normalisation, which Qt 4 could do, "//" could be rendered to "/", so this extra slash should be "%2F". This operation is done only in QUrl::fromUserInput. Change-Id: If9619ef6b546a3f4026cb26b74a7a5a865123609 Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 852eb0ab97..a5c11469ad 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2429,6 +2429,10 @@ void tst_QUrl::fromUserInput_data() // FYI: The scheme in the resulting url user QUrl authUrl("user:pass@domain.com"); QTest::newRow("misc-1") << "user:pass@domain.com" << authUrl; + + // FTP with double slashes in path + QTest::newRow("ftp-double-slash-1") << "ftp.example.com//path" << QUrl("ftp://ftp.example.com/%2Fpath"); + QTest::newRow("ftp-double-slash-1") << "ftp://ftp.example.com//path" << QUrl("ftp://ftp.example.com/%2Fpath"); } void tst_QUrl::fromUserInput() -- cgit v1.2.3 From 7be255156feb7636a5cca5c4fe78f42879ffe69b Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Fri, 6 Apr 2012 16:34:19 +0200 Subject: Deprecate qMemCopy/qMemSet in favour of their stdlib equivilents. Just like qMalloc/qRealloc/qFree, there is absolutely no reason to wrap these functions just to avoid an include, except to pay for it with worse runtime performance. On OS X, on byte sizes from 50 up to 1000, calling memset directly is 28-15% faster(!) than adding an additional call to qMemSet. The advantage on sizes above that is unmeasurable. For qMemCopy, the benefits are a little more modest: 16-7%. Change-Id: I98aa92bb765aea0448e3f20af42a039b369af0b3 Reviewed-by: Giuseppe D'Angelo Reviewed-by: John Brooks Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- .../corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp | 2 +- tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp | 8 ++++---- tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp | 4 ++-- .../widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp | 2 +- tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp | 2 +- tests/baselineserver/shared/baselineprotocol.cpp | 2 +- tests/benchmarks/corelib/tools/qvector/qrawvector.h | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp index c6ccc9308a..0cafc1d5ad 100644 --- a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp +++ b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp @@ -402,7 +402,7 @@ public: if (readSize < 0) return -1; - qMemCopy(data, openFile_->content.constData() + position_, readSize); + memcpy(data, openFile_->content.constData() + position_, readSize); position_ += readSize; return readSize; diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index b7793051b1..037893a13e 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -622,7 +622,7 @@ void tst_QByteArray::fromBase64() void tst_QByteArray::qvsnprintf() { char buf[20]; - qMemSet(buf, 42, sizeof(buf)); + memset(buf, 42, sizeof(buf)); QCOMPARE(::qsnprintf(buf, 10, "%s", "bubu"), 4); QCOMPARE(static_cast(buf), "bubu"); @@ -631,12 +631,12 @@ void tst_QByteArray::qvsnprintf() QCOMPARE(buf[5], char(42)); #endif - qMemSet(buf, 42, sizeof(buf)); + memset(buf, 42, sizeof(buf)); QCOMPARE(::qsnprintf(buf, 5, "%s", "bubu"), 4); QCOMPARE(static_cast(buf), "bubu"); QCOMPARE(buf[5], char(42)); - qMemSet(buf, 42, sizeof(buf)); + memset(buf, 42, sizeof(buf)); #ifdef Q_OS_WIN // VS 2005 uses the Qt implementation of vsnprintf. # if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_OS_WINCE) @@ -661,7 +661,7 @@ void tst_QByteArray::qvsnprintf() QCOMPARE(buf[4], char(42)); #ifndef Q_OS_WIN - qMemSet(buf, 42, sizeof(buf)); + memset(buf, 42, sizeof(buf)); QCOMPARE(::qsnprintf(buf, 10, ""), 0); #endif } diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index 932d652b69..827fa3606c 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -112,7 +112,7 @@ static void initializePadding(QImage *image) if (paddingBytes == 0) return; for (int y = 0; y < image->height(); ++y) { - qMemSet(image->scanLine(y) + effectiveBytesPerLine, 0, paddingBytes); + memset(image->scanLine(y) + effectiveBytesPerLine, 0, paddingBytes); } } @@ -454,7 +454,7 @@ void tst_QImageWriter::saveWithNoFormat() SKIP_IF_UNSUPPORTED(format); QImage niceImage(64, 64, QImage::Format_ARGB32); - qMemSet(niceImage.bits(), 0, niceImage.byteCount()); + memset(niceImage.bits(), 0, niceImage.byteCount()); QImageWriter writer(fileName /* , 0 - no format! */); if (error != 0) { diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 5eaf8b1b2c..47c40032c3 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -400,7 +400,7 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi if (initial_files.at(i)[0] == '.') { QString hiddenFile = QDir::toNativeSeparators(file.fileName()); wchar_t nativeHiddenFile[MAX_PATH]; - qMemSet(nativeHiddenFile, 0, sizeof(nativeHiddenFile)); + memset(nativeHiddenFile, 0, sizeof(nativeHiddenFile)); hiddenFile.toWCharArray(nativeHiddenFile); DWORD currentAttributes = ::GetFileAttributes(nativeHiddenFile); if (currentAttributes == 0xFFFFFFFF) { diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index 2ee166c4a2..f9610fab16 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -885,7 +885,7 @@ void tst_QItemDelegate::decoration() } case QVariant::Image: { QImage img(size, QImage::Format_Mono); - qMemSet(img.bits(), 0, img.byteCount()); + memset(img.bits(), 0, img.byteCount()); value = img; break; } diff --git a/tests/baselineserver/shared/baselineprotocol.cpp b/tests/baselineserver/shared/baselineprotocol.cpp index 9fcd99546c..a687c8d61b 100644 --- a/tests/baselineserver/shared/baselineprotocol.cpp +++ b/tests/baselineserver/shared/baselineprotocol.cpp @@ -232,7 +232,7 @@ quint64 ImageItem::computeChecksum(const QImage &image) uchar *p = img.bits() + bpl - padBytes; const int h = img.height(); for (int y = 0; y < h; ++y) { - qMemSet(p, 0, padBytes); + memset(p, 0, padBytes); p += bpl; } } diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index 8c2d014a41..18d9847c95 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -379,7 +379,7 @@ QRawVector::QRawVector(int asize) while (i != b) new (--i) T; } else { - qMemSet(m_begin, 0, asize * sizeof(T)); + memset(m_begin, 0, asize * sizeof(T)); } } @@ -474,7 +474,7 @@ void QRawVector::realloc(int asize, int aalloc, bool ref) } else if (asize > xsize) { // initialize newly allocated memory to 0 - qMemSet(xbegin + xsize, 0, (asize - xsize) * sizeof(T)); + memset(xbegin + xsize, 0, (asize - xsize) * sizeof(T)); } xsize = asize; -- cgit v1.2.3 From 680f35ec1ee7cad8881a5fd9edadc6594cb2fe71 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 10 Apr 2012 13:15:29 +0100 Subject: Add unit test for usagePolicies Change-Id: I749268d81521d84ffc709014963a0f34fbf6d74c Reviewed-by: Lars Knoll --- .../network/bearer/qnetworksession/test/test.pro | 2 +- .../qnetworksession/test/tst_qnetworksession.cpp | 31 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/network/bearer/qnetworksession/test/test.pro b/tests/auto/network/bearer/qnetworksession/test/test.pro index 2f1a9ba6ea..c87e8e9bda 100644 --- a/tests/auto/network/bearer/qnetworksession/test/test.pro +++ b/tests/auto/network/bearer/qnetworksession/test/test.pro @@ -2,7 +2,7 @@ CONFIG += testcase SOURCES += tst_qnetworksession.cpp HEADERS += ../../qbearertestcommon.h -QT = core network testlib +QT = core network testlib network-private TARGET = tst_qnetworksession CONFIG(debug_and_release) { diff --git a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp index 27e1e7f013..5980e5fbdc 100644 --- a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp +++ b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp @@ -48,6 +48,7 @@ #ifndef QT_NO_BEARERMANAGEMENT #include #include +#include #endif QT_USE_NAMESPACE @@ -93,6 +94,8 @@ private slots: void sessionAutoClose_data(); void sessionAutoClose(); + void usagePolicies(); + private: QNetworkConfigurationManager manager; int inProcessSessionManagementCount; @@ -1261,6 +1264,34 @@ void tst_QNetworkSession::sessionAutoClose() QCOMPARE(autoCloseSession.toInt(), -1); } + +void tst_QNetworkSession::usagePolicies() +{ + QNetworkSession session(manager.defaultConfiguration()); + QNetworkSession::UsagePolicies initial; + initial = session.usagePolicies(); + if (initial != 0) + QNetworkSessionPrivate::setUsagePolicies(session, 0); + QSignalSpy spy(&session, SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies))); + QNetworkSessionPrivate::setUsagePolicies(session, QNetworkSession::NoBackgroundTrafficPolicy); + QCOMPARE(spy.count(), 1); + QNetworkSession::UsagePolicies policies = qvariant_cast(spy.at(0).at(0)); + QCOMPARE(policies, QNetworkSession::NoBackgroundTrafficPolicy); + QCOMPARE(session.usagePolicies(), QNetworkSession::NoBackgroundTrafficPolicy); + QNetworkSessionPrivate::setUsagePolicies(session, initial); + spy.clear(); + + session.open(); + QVERIFY(session.waitForOpened()); + + //policies may be changed when session is opened, if so, signal should have been emitted + if (session.usagePolicies() != initial) + QCOMPARE(spy.count(), 1); + else + QCOMPARE(spy.count(), 0); +} + + #endif QTEST_MAIN(tst_QNetworkSession) -- cgit v1.2.3 From 8d3cb11261fe9d6ec2e071c959b836f7bfadc33d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Mar 2012 22:11:33 -0300 Subject: Make QUrl handle ambiguous delimiters correctly Refactor the way that QUrl stores and returns the components of the URL so that ambiguous delimiters (gen-delims that could change the meaning of the parsing) are interpreted correctly. Previously, QUrl called "unambiguous" the form found in a full URL, even though each item in isolation could have more characters decoded. Now, instead, store only the fully decoded form. To recreate the compound forms (the full URL, as well as the user info and the authority), we need to do more processing. This commit applies to the user name, password, path and fragment only. The scheme, host and port do not need this work because they are special; the query is handled separately. Change-Id: I5907ba9b8fe048fff23c128be95668c22820663a Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index a5c11469ad..c9f977e11f 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -225,7 +225,7 @@ void tst_QUrl::hashInPath() { QUrl withHashInPath; withHashInPath.setPath(QString::fromLatin1("hi#mum.txt")); - QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi%23mum.txt")); + QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi#mum.txt")); QCOMPARE(withHashInPath.path(QUrl::MostDecoded), QString::fromLatin1("hi#mum.txt")); QCOMPARE(withHashInPath.toString(QUrl::FullyEncoded), QString("hi%23mum.txt")); QCOMPARE(withHashInPath.toDisplayString(QUrl::PreferLocalFile), QString("hi%23mum.txt")); @@ -236,10 +236,9 @@ void tst_QUrl::hashInPath() const QUrl localWithHash = QUrl::fromLocalFile("/hi#mum.txt"); QCOMPARE(localWithHash.toEncoded(), QByteArray("file:///hi%23mum.txt")); QCOMPARE(localWithHash.toString(), QString("file:///hi%23mum.txt")); - QEXPECT_FAIL("", "Regression in the new QUrl, will fix soon", Abort); QCOMPARE(localWithHash.path(), QString::fromLatin1("/hi#mum.txt")); - QCOMPARE(localWithHash.toString(QUrl::PreferLocalFile), QString("/hi#mum.txt")); - QCOMPARE(localWithHash.toDisplayString(QUrl::PreferLocalFile), QString("/hi#mum.txt")); + QCOMPARE(localWithHash.toString(QUrl::PreferLocalFile | QUrl::PrettyDecoded), QString("/hi#mum.txt")); + QCOMPARE(localWithHash.toDisplayString(QUrl::PreferLocalFile | QUrl::PrettyDecoded), QString("/hi#mum.txt")); } void tst_QUrl::unc() @@ -567,7 +566,7 @@ void tst_QUrl::setUrl() { QUrl carsten; carsten.setPath("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18"); - QCOMPARE(carsten.path(), QString::fromLatin1("/home/gis/src/kde/kdelibs/kfile/.%23kfiledetailview.cpp.1.18")); + QCOMPARE(carsten.path(), QString::fromLatin1("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18")); QUrl charles; charles.setPath("/home/charles/foo%20moo"); -- cgit v1.2.3 From ef288340da61a72ac6d7ecb48e5bce5fef8cf11b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Mar 2012 22:59:56 -0300 Subject: Fix the handling of ambiguous delimiters in the query part of a URL This is the same fix as the previous commit did for the other components of the URL. But we're also changing how we handle the "[]" characters in a query: previously the handling was like for other sub-delims; now, they're always decoded, assuming that the RFC had a mistake and they were meant to be decoded. Change-Id: If4b1c3df8f341cb114f2cc4860de22f8bf0be743 Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index c9f977e11f..8bd3e94166 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -1866,7 +1866,7 @@ void tst_QUrl::tolerantParser() QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D")); url.setUrl("//[::56:56:56:56:56:56:56]?[]"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?%5B%5D")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?[]")); url.setUrl("%hello.com/f%"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%25hello.com/f%25")); @@ -1891,7 +1891,7 @@ void tst_QUrl::tolerantParser() QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D")); url.setEncodedUrl("//[::56:56:56:56:56:56:56]?[]"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?%5B%5D")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?[]")); url.setEncodedUrl("data:text/css,div%20{%20border-right:%20solid;%20}"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("data:text/css,div%20%7B%20border-right:%20solid;%20%7D")); -- cgit v1.2.3 From 9af551f7ab55d86ae0cca645bb7a86933b00d75c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 3 Apr 2012 12:42:03 -0300 Subject: Add a big test for QUrl encoding principles This tests how QUrl encodes and decodes certain characters and leaves some other ones alone. It also tests that the output of toString() (in whichever encoding was being tested) is also parsed again to be exactly the same as the previously decoded form. Change-Id: Ie358d001f8b903409db61db48bde1ea679241a60 Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 233 ++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 8bd3e94166..8b94a8ef66 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -160,6 +160,8 @@ private slots: void emptyAuthorityRemovesExistingAuthority(); void acceptEmptyAuthoritySegments(); void lowercasesScheme(); + void componentEncodings_data(); + void componentEncodings(); }; // Testing get/set functions @@ -2576,5 +2578,236 @@ void tst_QUrl::lowercasesScheme() QCOMPARE(url.scheme(), QString("hello")); } +void tst_QUrl::componentEncodings_data() +{ + QTest::addColumn("url"); + QTest::addColumn("encoding"); + QTest::addColumn("userName"); + QTest::addColumn("password"); + QTest::addColumn("userInfo"); + QTest::addColumn("host"); + QTest::addColumn("authority"); + QTest::addColumn("path"); + QTest::addColumn("query"); + QTest::addColumn("fragment"); + QTest::addColumn("toString"); + + QTest::newRow("empty") << QUrl() << int(QUrl::FullyEncoded) + << QString() << QString() << QString() + << QString() << QString() + << QString() << QString() << QString() << QString(); + + // hostname cannot contain spaces + QTest::newRow("encoded-space") << QUrl("x://user name:pass word@host/path name?query value#fragment value") + << int(QUrl::FullyEncoded) + << "user%20name" << "pass%20word" << "user%20name:pass%20word" + << "host" << "user%20name:pass%20word@host" + << "/path%20name" << "query%20value" << "fragment%20value" + << "x://user%20name:pass%20word@host/path%20name?query%20value#fragment%20value"; + + QTest::newRow("decoded-space") << QUrl("x://user%20name:pass%20word@host/path%20name?query%20value#fragment%20value") + << int(QUrl::DecodeSpaces) + << "user name" << "pass word" << "user name:pass word" + << "host" << "user name:pass word@host" + << "/path name" << "query value" << "fragment value" + << "x://user name:pass word@host/path name?query value#fragment value"; + + // binary data is always encoded + // this is also testing non-UTF8 data + QTest::newRow("binary") << QUrl("x://%c0%00:%c1%01@host/%c2%02?%c3%03#%d4%04") + << int(QUrl::MostDecoded) + << "%C0%00" << "%C1%01" << "%C0%00:%C1%01" + << "host" << "%C0%00:%C1%01@host" + << "/%C2%02" << "%C3%03" << "%D4%04" + << "x://%C0%00:%C1%01@host/%C2%02?%C3%03#%D4%04"; + + // unicode tests + // hostnames can participate in this test, but we need a top-level domain that accepts Unicode + QTest::newRow("encoded-unicode") << QUrl(QString::fromUtf8("x://\xc2\x80:\xc3\x90@smørbrød.example.no/\xe0\xa0\x80?\xf0\x90\x80\x80#é")) + << int(QUrl::FullyEncoded) + << "%C2%80" << "%C3%90" << "%C2%80:%C3%90" + << "xn--smrbrd-cyad.example.no" << "%C2%80:%C3%90@xn--smrbrd-cyad.example.no" + << "/%E0%A0%80" << "%F0%90%80%80" << "%C3%A9" + << "x://%C2%80:%C3%90@xn--smrbrd-cyad.example.no/%E0%A0%80?%F0%90%80%80#%C3%A9"; + QTest::newRow("decoded-unicode") << QUrl("x://%C2%80:%C3%90@XN--SMRBRD-cyad.example.NO/%E0%A0%80?%F0%90%80%80#%C3%A9") + << int(QUrl::DecodeUnicode) + << QString::fromUtf8("\xc2\x80") << QString::fromUtf8("\xc3\x90") + << QString::fromUtf8("\xc2\x80:\xc3\x90") + << QString::fromUtf8("smørbrød.example.no") + << QString::fromUtf8("\xc2\x80:\xc3\x90@smørbrød.example.no") + << QString::fromUtf8("/\xe0\xa0\x80") + << QString::fromUtf8("\xf0\x90\x80\x80") << QString::fromUtf8("é") + << QString::fromUtf8("x://\xc2\x80:\xc3\x90@smørbrød.example.no/\xe0\xa0\x80?\xf0\x90\x80\x80#é"); + + // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + // these are always decoded + QTest::newRow("decoded-unreserved") << QUrl("x://%61:%71@%41%30%2eexample%2ecom/%7e?%5f#%51") + << int(QUrl::FullyEncoded) + << "a" << "q" << "a:q" + << "a0.example.com" << "a:q@a0.example.com" + << "/~" << "_" << "Q" + << "x://a:q@a0.example.com/~?_#Q"; + + // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + // / "*" / "+" / "," / ";" / "=" + // like the unreserved, these are decoded everywhere + // don't test in query because they might remain encoded + QTest::newRow("decoded-subdelims") << QUrl("x://%21%24%26:%27%28%29@host/%2a%2b%2c#%3b%3d") + << int(QUrl::FullyEncoded) + << "!$&" << "'()" << "!$&:'()" + << "host" << "!$&:'()@host" + << "/*+," << "" << ";=" + << "x://!$&:'()@host/*+,#;="; + + // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + // these are the separators between fields + // they must appear encoded in proper URLs everywhere + // 1) test the delimiters that, if they were decoded, would change the URL parsing + QTest::newRow("encoded-gendelims-changing") << QUrl("x://%5b%3a%2f%3f%23%40%5d:%5b%2f%3f%23%40%5d@host/%2f%3f%23?%23") + << int(QUrl::MostDecoded) + << "[:/?#@]" << "[/?#@]" << "[%3A/?#@]:[/?#@]" + << "host" << "%5B%3A/?#%40%5D:%5B/?#%40%5D@host" + << "/%2F?#" << "#" << "" + << "x://%5B%3A%2F%3F%23%40%5D:%5B%2F%3F%23%40%5D@host/%2F%3F%23?%23"; + + // 2) test the delimiters that may appear decoded and would not change the meaning + // and test that %2f is *not* decoded to a slash in the path + // don't test the query because in this mode it doesn't transform anything + QTest::newRow("decoded-gendelims-unchanging") << QUrl("x://:%3a@host/%2f%3a%40#%23%3a%2f%3f%40") + << int(QUrl::DecodeUnambiguousDelimiters) + << "" << ":" << "::" + << "host" << "::@host" + << "/%2F:@" << "" << "#:/?@" + << "x://::@host/%2F:@##:/?@"; + + // 3) test "[" and "]". Even though they are not ambiguous in the path, query or fragment + // the RFC does not allow them to appear there decoded. QUrl adheres strictly in FullyEncoded mode + QTest::newRow("encoded-square-brackets") << QUrl("x:/[]#[]") + << int(QUrl::FullyEncoded) + << "" << "" << "" + << "" << "" + << "/%5B%5D" << "" << "%5B%5D" + << "x:/%5B%5D#%5B%5D"; + + // 4) like above, but now decode them, which is allowed + QTest::newRow("decoded-square-brackets") << QUrl("x:/%5B%5D#%5B%5D") + << int(QUrl::MostDecoded) + << "" << "" << "" + << "" << "" + << "/[]" << "" << "[]" + << "x:/[]#[]"; + + // test the query + // since QUrl doesn't know what chars the user wants to use for the pair and value delimiters, + // it keeps the delimiters alone except for "#", which must always be encoded. + QTest::newRow("unencoded-delims-query") << QUrl("?!$()*+,;=:/?[]@") + << int(QUrl::FullyEncoded) + << QString() << QString() << QString() + << QString() << QString() + << QString() << "!$()*+,;=:/?[]@" << QString() + << "?!$()*+,;=:/?[]@"; + QTest::newRow("undecoded-delims-query") << QUrl("?%21%24%26%27%28%29%2a%2b%2c%2f%3a%3b%3d%3f%40%5b%5d") + << int(QUrl::DecodeUnambiguousDelimiters) + << QString() << QString() << QString() + << QString() << QString() + << QString() << "%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D" << QString() + << "?%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D"; + + // other characters: '"' / "<" / ">" / "^" / "\" / "{" / "|" "}" + // the RFC does not allow them undecoded anywhere, but we do + QTest::newRow("encoded-others") << QUrl("x://\"<>^\\{|}:\"<>^\\{|}@host/\"<>^\\{|}?\"<>^\\{|}#\"<>^\\{|}") + << int(QUrl::FullyEncoded) + << "%22%3C%3E%5E%5C%7B%7C%7D" << "%22%3C%3E%5E%5C%7B%7C%7D" + << "%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D" + << "host" << "%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host" + << "/%22%3C%3E%5E%5C%7B%7C%7D" << "%22%3C%3E%5E%5C%7B%7C%7D" + << "%22%3C%3E%5E%5C%7B%7C%7D" + << "x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host/%22%3C%3E%5E%5C%7B%7C%7D" + "?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D"; + QTest::newRow("decoded-others") << QUrl("x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host" + "/%22%3C%3E%5E%5C%7B%7C%7D?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D") + << int(QUrl::DecodeAllDelimiters) + << "\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}:\"<>^\\{|}" + << "host" << "\"<>^\\{|}:\"<>^\\{|}@host" + << "/\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}" + << "x://\"<>^\\{|}:\"<>^\\{|}@host/\"<>^\\{|}?\"<>^\\{|}#\"<>^\\{|}"; + + + // Beauty is in the eye of the beholder + // Test PrettyDecoder against our expectations + + // spaces and unicode are considered pretty and are decoded + // this includes hostnames + QTest::newRow("pretty-spaces-unicode") << QUrl("x://%20%c3%a9:%c3%a9%20@XN--SMRBRD-cyad.example.NO/%c3%a9%20?%20%c3%a9#%c3%a9%20") + << int(QUrl::PrettyDecoded) + << QString::fromUtf8(" é") << QString::fromUtf8("é ") + << QString::fromUtf8(" é:é ") + << QString::fromUtf8("smørbrød.example.no") + << QString::fromUtf8(" é:é @smørbrød.example.no") + << QString::fromUtf8("/é ") << QString::fromUtf8(" é") + << QString::fromUtf8("é ") + << QString::fromUtf8("x:// é:é @smørbrød.example.no/é ? é#é "); + + // the pretty form re-encodes the subdelims (except in the query, where they are left alone) + QTest::newRow("pretty-subdelims") << QUrl("x://%21%24%26:%27%28%29@host/%2a%2b%2c?%26=%26&%3d=%3d#%3b%3d") + << int(QUrl::PrettyDecoded) + << "!$&" << "'()" << "!$&:'()" + << "host" << "!$&:'()@host" + << "/*+," << "%26=%26&%3D=%3D" << ";=" + << "x://!$&:'()@host/*+,?%26=%26&%3D=%3D#;="; + + // the pretty form decodes all unambiguous gen-delims + // (except in query, where they are left alone) + QTest::newRow("pretty-gendelims") << QUrl("x://%5b%3a%40%2f%5d:%5b%3a%40%2f%5d@host" + "/%3a%40%5b%3f%23%5d?[?%3f%23]%5b:%3a@%40%5d#%23") + << int(QUrl::PrettyDecoded) + << "[:@/]" << "[:@/]" << "[%3A@/]:[:@/]" + << "host" << "%5B%3A%40/%5D:%5B:%40/%5D@host" + << "/:@[?#]" << "[?%3F#]%5B:%3A@%40%5D" << "#" + << "x://%5B%3A%40%2F%5D:%5B:%40%2F%5D@host/:@[%3F%23]?[?%3F%23]%5B:%3A@%40%5D##"; +} + +void tst_QUrl::componentEncodings() +{ + QFETCH(QUrl, url); + QFETCH(int, encoding); + QFETCH(QString, userName); + QFETCH(QString, password); + QFETCH(QString, userInfo); + QFETCH(QString, host); + QFETCH(QString, authority); + QFETCH(QString, path); + QFETCH(QString, query); + QFETCH(QString, fragment); + QFETCH(QString, toString); + + QUrl::ComponentFormattingOptions formatting(encoding); + QCOMPARE(url.userName(formatting), userName); + QCOMPARE(url.password(formatting), password); + QCOMPARE(url.userInfo(formatting), userInfo); + QCOMPARE(url.host(formatting), host); + QCOMPARE(url.authority(formatting), authority); + QCOMPARE(url.path(formatting), path); + QCOMPARE(url.query(formatting), query); + QCOMPARE(url.fragment(formatting), fragment); + QCOMPARE(url.toString(formatting), + (((QString(toString ))))); // the weird () and space is to align the output + + // repeat with the URL we got from toString + QUrl url2(toString); + QCOMPARE(url2.userName(formatting), userName); + QCOMPARE(url2.password(formatting), password); + QCOMPARE(url2.userInfo(formatting), userInfo); + QCOMPARE(url2.host(formatting), host); + QCOMPARE(url2.authority(formatting), authority); + QCOMPARE(url2.path(formatting), path); + QCOMPARE(url2.query(formatting), query); + QCOMPARE(url2.fragment(formatting), fragment); + QCOMPARE(url2.toString(formatting), toString); + + // and use the comparison operator + QCOMPARE(url2, url); +} + QTEST_MAIN(tst_QUrl) #include "tst_qurl.moc" -- cgit v1.2.3 From 0441b2d4c332e0ae6e5ca52878985b826e8f68ca Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 30 Mar 2012 10:31:37 -0300 Subject: Merge QUrl::DecodeAllDelimiters and QUrl::DecodeUnambiguousDelimiters There's little value in having the DecodeUnambiguousDelimiters option since neither QUrl nor QUrlQuery can return values that are ambiguous in that particular context, ever. This option could be used to encode a character if, when placed in a URL, it would need to be encoded. Such cases are hash (#) or question marks (?) in the path component, or slashes (/) and at signs (@) in the userinfo. However, we don't need two enums for that, since there are no other characters that can appear in either form. Still, leave two bits for this enum. In the future, if we want to split the gen-delims from the sub-delims, we are able to. Change-Id: If5416b524680eb67dd4abbe7d072ca0ef7218506 Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 6 +++--- tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 8b94a8ef66..aae970eac6 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2674,7 +2674,7 @@ void tst_QUrl::componentEncodings_data() // and test that %2f is *not* decoded to a slash in the path // don't test the query because in this mode it doesn't transform anything QTest::newRow("decoded-gendelims-unchanging") << QUrl("x://:%3a@host/%2f%3a%40#%23%3a%2f%3f%40") - << int(QUrl::DecodeUnambiguousDelimiters) + << int(QUrl::DecodeDelimiters) << "" << ":" << "::" << "host" << "::@host" << "/%2F:@" << "" << "#:/?@" @@ -2707,7 +2707,7 @@ void tst_QUrl::componentEncodings_data() << QString() << "!$()*+,;=:/?[]@" << QString() << "?!$()*+,;=:/?[]@"; QTest::newRow("undecoded-delims-query") << QUrl("?%21%24%26%27%28%29%2a%2b%2c%2f%3a%3b%3d%3f%40%5b%5d") - << int(QUrl::DecodeUnambiguousDelimiters) + << int(QUrl::DecodeDelimiters) << QString() << QString() << QString() << QString() << QString() << QString() << "%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D" << QString() @@ -2726,7 +2726,7 @@ void tst_QUrl::componentEncodings_data() "?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D"; QTest::newRow("decoded-others") << QUrl("x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host" "/%22%3C%3E%5E%5C%7B%7C%7D?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D") - << int(QUrl::DecodeAllDelimiters) + << int(QUrl::DecodeDelimiters) << "\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}:\"<>^\\{|}" << "host" << "\"<>^\\{|}:\"<>^\\{|}@host" << "/\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}" diff --git a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp index ec9170bd7d..24b651a8a3 100644 --- a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp +++ b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp @@ -605,8 +605,8 @@ void tst_QUrlQuery::encodedSetQueryItems_data() QTest::newRow("ampersand") << "%26=%26" << "%26" << "%26" << F(QUrl::PrettyDecoded) << "%26=%26" << "&" << "&"; QTest::newRow("hash") << "#=#" << "%23" << "%23" << F(QUrl::PrettyDecoded) - << "%23=%23" << "#" << "#"; - QTest::newRow("decode-hash") << "%23=%23" << "%23" << "%23" << F(QUrl::DecodeAllDelimiters) + << "#=#" << "#" << "#"; + QTest::newRow("decode-hash") << "%23=%23" << "%23" << "%23" << F(QUrl::DecodeDelimiters) << "#=#" << "#" << "#"; QTest::newRow("percent") << "%25=%25" << "%25" << "%25" << F(QUrl::PrettyDecoded) @@ -623,7 +623,7 @@ void tst_QUrlQuery::encodedSetQueryItems_data() // plus signs must not be touched QTest::newRow("encode-plus") << "+=+" << "+" << "+" << F(QUrl::FullyEncoded) << "+=+" << "+" << "+"; - QTest::newRow("decode-2b") << "%2b=%2b" << "%2b" << "%2b" << F(QUrl::DecodeAllDelimiters) + QTest::newRow("decode-2b") << "%2b=%2b" << "%2b" << "%2b" << F(QUrl::DecodeDelimiters) << "%2B=%2B" << "%2B" << "%2B"; @@ -680,7 +680,7 @@ void tst_QUrlQuery::differentDelimiters() expected << qItem("foo", "bar") << qItem("hello", "world"); COMPARE_ITEMS(query.queryItems(), expected); COMPARE_ITEMS(query.queryItems(QUrl::FullyEncoded), expected); - COMPARE_ITEMS(query.queryItems(QUrl::DecodeAllDelimiters), expected); + COMPARE_ITEMS(query.queryItems(QUrl::DecodeDelimiters), expected); } { -- cgit v1.2.3 From a01c662d3737fd9f26a7e4455d7bcb03628155d7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 30 Mar 2012 13:32:19 -0300 Subject: Introduce QUrl::DecodeReserved and reorder the enums DecodeReserved applies to all characters between 0x21 and 0x7E that aren't unreserved, a delimiter, or the percent sign itself. Change-Id: Ie64bddb6b814dfa3bb8380e3aa24de1bb3645a65 Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index aae970eac6..7deb0fc381 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2713,9 +2713,9 @@ void tst_QUrl::componentEncodings_data() << QString() << "%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D" << QString() << "?%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D"; - // other characters: '"' / "<" / ">" / "^" / "\" / "{" / "|" "}" + // reserved characters: '"' / "<" / ">" / "^" / "\" / "{" / "|" "}" // the RFC does not allow them undecoded anywhere, but we do - QTest::newRow("encoded-others") << QUrl("x://\"<>^\\{|}:\"<>^\\{|}@host/\"<>^\\{|}?\"<>^\\{|}#\"<>^\\{|}") + QTest::newRow("encoded-reserved") << QUrl("x://\"<>^\\{|}:\"<>^\\{|}@host/\"<>^\\{|}?\"<>^\\{|}#\"<>^\\{|}") << int(QUrl::FullyEncoded) << "%22%3C%3E%5E%5C%7B%7C%7D" << "%22%3C%3E%5E%5C%7B%7C%7D" << "%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D" @@ -2724,9 +2724,9 @@ void tst_QUrl::componentEncodings_data() << "%22%3C%3E%5E%5C%7B%7C%7D" << "x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host/%22%3C%3E%5E%5C%7B%7C%7D" "?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D"; - QTest::newRow("decoded-others") << QUrl("x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host" + QTest::newRow("decoded-reserved") << QUrl("x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host" "/%22%3C%3E%5E%5C%7B%7C%7D?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D") - << int(QUrl::DecodeDelimiters) + << int(QUrl::DecodeReserved) << "\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}:\"<>^\\{|}" << "host" << "\"<>^\\{|}:\"<>^\\{|}@host" << "/\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}" -- cgit v1.2.3 From 997ac954abe8e4f7d9323f13a79989f277de8301 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 30 Mar 2012 16:21:45 -0300 Subject: Allow {} to remain decoded in URLs in the path and query This allows things like http://example.com/{1234-5678}?id={abcd-ef01}. But do not allow it in other parts of the URL. I could allow it in the fragment, but in the username and password it would be too ugly. In order to do that, make DecodeReserved use two bits and have PrettyDecoded set only one of them. That way, toString(PrettyDecoded) can be distinguished from toString(PrettyDecoded | DecodeReserved), just as path(PrettyDecoded) can be distinguished from path(PrettyDecoded & ~DecodeDelimiters). Also, take the opportunity to avoid decoding the reserved characters in the query. Keep them encoded as they should be. Change-Id: I1604a0c8015c6b03dc2fbf49ea9d1dbed96fc186 Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 7deb0fc381..f8a0edf0dc 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2765,6 +2765,16 @@ void tst_QUrl::componentEncodings_data() << "host" << "%5B%3A%40/%5D:%5B:%40/%5D@host" << "/:@[?#]" << "[?%3F#]%5B:%3A@%40%5D" << "#" << "x://%5B%3A%40%2F%5D:%5B:%40%2F%5D@host/:@[%3F%23]?[?%3F%23]%5B:%3A@%40%5D##"; + + // the pretty form keeps the other characters decoded everywhere + // except when rebuilding the full URL, when we only allow "{}" to remain decoded + QTest::newRow("pretty-reserved") << QUrl("x://\"<>^\\{|}:\"<>^\\{|}@host/\"<>^\\{|}?\"<>^\\{|}#\"<>^\\{|}") + << int(QUrl::PrettyDecoded) + << "\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}:\"<>^\\{|}" + << "host" << "\"<>^\\{|}:\"<>^\\{|}@host" + << "/\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}" + << "x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host/%22%3C%3E%5E%5C{%7C}" + "?%22%3C%3E%5E%5C{%7C}#%22%3C%3E%5E%5C%7B%7C%7D"; } void tst_QUrl::componentEncodings() -- cgit v1.2.3 From 1b7e9dba75f18342911bc6954be3e754322f091f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 30 Mar 2012 17:48:42 -0300 Subject: Change the component formatting enum values so the default is zero By having the default value equal to zero, we follow the principle of least surprise. For example, if we had url.path() and we refactored to url.path(QUrl::DecodeSpaces) Then instead of ensuring spaces are decoded, we make spaces the only thing encoded (unicode, delimiters and reserved characters are encoded). Besides, modifying the default can only be used to encode something that wasn't encoded previously, so having the enums as Encode makes more sense. As a side-effect, toEncoded() does not support any extra encoding options. Change-Id: I2624ec446e65c2d979e9ca2f81bd3db22b00bb13 Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 18 +++++++------ .../corelib/io/qurlinternal/tst_qurlinternal.cpp | 30 +++++++++++----------- tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp | 13 ++++++---- 3 files changed, 33 insertions(+), 28 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index f8a0edf0dc..5611f5b2f4 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2599,14 +2599,14 @@ void tst_QUrl::componentEncodings_data() // hostname cannot contain spaces QTest::newRow("encoded-space") << QUrl("x://user name:pass word@host/path name?query value#fragment value") - << int(QUrl::FullyEncoded) + << int(QUrl::EncodeSpaces) << "user%20name" << "pass%20word" << "user%20name:pass%20word" << "host" << "user%20name:pass%20word@host" << "/path%20name" << "query%20value" << "fragment%20value" << "x://user%20name:pass%20word@host/path%20name?query%20value#fragment%20value"; QTest::newRow("decoded-space") << QUrl("x://user%20name:pass%20word@host/path%20name?query%20value#fragment%20value") - << int(QUrl::DecodeSpaces) + << int(QUrl::MostDecoded) << "user name" << "pass word" << "user name:pass word" << "host" << "user name:pass word@host" << "/path name" << "query value" << "fragment value" @@ -2624,13 +2624,13 @@ void tst_QUrl::componentEncodings_data() // unicode tests // hostnames can participate in this test, but we need a top-level domain that accepts Unicode QTest::newRow("encoded-unicode") << QUrl(QString::fromUtf8("x://\xc2\x80:\xc3\x90@smørbrød.example.no/\xe0\xa0\x80?\xf0\x90\x80\x80#é")) - << int(QUrl::FullyEncoded) + << int(QUrl::EncodeUnicode) << "%C2%80" << "%C3%90" << "%C2%80:%C3%90" << "xn--smrbrd-cyad.example.no" << "%C2%80:%C3%90@xn--smrbrd-cyad.example.no" << "/%E0%A0%80" << "%F0%90%80%80" << "%C3%A9" << "x://%C2%80:%C3%90@xn--smrbrd-cyad.example.no/%E0%A0%80?%F0%90%80%80#%C3%A9"; QTest::newRow("decoded-unicode") << QUrl("x://%C2%80:%C3%90@XN--SMRBRD-cyad.example.NO/%E0%A0%80?%F0%90%80%80#%C3%A9") - << int(QUrl::DecodeUnicode) + << int(QUrl::MostDecoded) << QString::fromUtf8("\xc2\x80") << QString::fromUtf8("\xc3\x90") << QString::fromUtf8("\xc2\x80:\xc3\x90") << QString::fromUtf8("smørbrød.example.no") @@ -2661,8 +2661,10 @@ void tst_QUrl::componentEncodings_data() // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" // these are the separators between fields - // they must appear encoded in proper URLs everywhere - // 1) test the delimiters that, if they were decoded, would change the URL parsing + // they must appear encoded in certain positions, no exceptions + // in other positions, they can appear decoded, so they always do + // 1) test the delimiters that must appear encoded + // (if they were decoded, they'd would change the URL parsing) QTest::newRow("encoded-gendelims-changing") << QUrl("x://%5b%3a%2f%3f%23%40%5d:%5b%2f%3f%23%40%5d@host/%2f%3f%23?%23") << int(QUrl::MostDecoded) << "[:/?#@]" << "[/?#@]" << "[%3A/?#@]:[/?#@]" @@ -2674,7 +2676,7 @@ void tst_QUrl::componentEncodings_data() // and test that %2f is *not* decoded to a slash in the path // don't test the query because in this mode it doesn't transform anything QTest::newRow("decoded-gendelims-unchanging") << QUrl("x://:%3a@host/%2f%3a%40#%23%3a%2f%3f%40") - << int(QUrl::DecodeDelimiters) + << int(QUrl::FullyEncoded) << "" << ":" << "::" << "host" << "::@host" << "/%2F:@" << "" << "#:/?@" @@ -2707,7 +2709,7 @@ void tst_QUrl::componentEncodings_data() << QString() << "!$()*+,;=:/?[]@" << QString() << "?!$()*+,;=:/?[]@"; QTest::newRow("undecoded-delims-query") << QUrl("?%21%24%26%27%28%29%2a%2b%2c%2f%3a%3b%3d%3f%40%5b%5d") - << int(QUrl::DecodeDelimiters) + << int(QUrl::MostDecoded) << QString() << QString() << QString() << QString() << QString() << QString() << "%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D" << QString() diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index f853bab9e5..3ac2b46964 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -812,7 +812,7 @@ void tst_QUrlInternal::correctEncodedMistakes() QString output = QTest::currentDataTag(); expected.prepend(output); - if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::DecodeUnicode)) + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), 0)) output += input; QCOMPARE(output, expected); } @@ -822,7 +822,7 @@ static void addUtf8Data(const char *name, const char *data) QString encoded = QByteArray(data).toPercentEncoding(); QString decoded = QString::fromUtf8(data); - QTest::newRow(QByteArray("decode-") + name) << encoded << QUrl::ComponentFormattingOptions(QUrl::DecodeUnicode) << decoded; + QTest::newRow(QByteArray("decode-") + name) << encoded << QUrl::ComponentFormattingOptions(QUrl::MostDecoded) << decoded; QTest::newRow(QByteArray("encode-") + name) << decoded << QUrl::ComponentFormattingOptions(QUrl::FullyEncoded) << encoded; } @@ -877,17 +877,17 @@ void tst_QUrlInternal::encodingRecode_data() QTest::newRow("encode-nul") << QString::fromLatin1("abc\0def", 7) << F(QUrl::MostDecoded) << "abc%00def"; // space - QTest::newRow("space-leave-decoded") << "Hello World " << F(QUrl::DecodeSpaces) << "Hello World "; + QTest::newRow("space-leave-decoded") << "Hello World " << F(QUrl::MostDecoded) << "Hello World "; QTest::newRow("space-leave-encoded") << "Hello%20World%20" << F(QUrl::FullyEncoded) << "Hello%20World%20"; QTest::newRow("space-encode") << "Hello World " << F(QUrl::FullyEncoded) << "Hello%20World%20"; - QTest::newRow("space-decode") << "Hello%20World%20" << F(QUrl::DecodeSpaces) << "Hello World "; + QTest::newRow("space-decode") << "Hello%20World%20" << F(QUrl::MostDecoded) << "Hello World "; // decode unreserved QTest::newRow("unreserved-decode") << "%66%6f%6f%42a%72" << F(QUrl::FullyEncoded) << "fooBar"; // mix encoding with decoding - QTest::newRow("encode-control-decode-space") << "\1\2%200" << F(QUrl::DecodeSpaces) << "%01%02 0"; - QTest::newRow("decode-space-encode-control") << "%20\1\2" << F(QUrl::DecodeSpaces) << " %01%02"; + QTest::newRow("encode-control-decode-space") << "\1\2%200" << F(QUrl::MostDecoded) << "%01%02 0"; + QTest::newRow("decode-space-encode-control") << "%20\1\2" << F(QUrl::MostDecoded) << " %01%02"; // decode and encode valid UTF-8 data // invalid is tested in encodingRecodeInvalidUtf8 @@ -922,11 +922,11 @@ void tst_QUrlInternal::encodingRecode_data() QTest::newRow("ff") << "%ff" << F(QUrl::FullyEncoded) << "%FF"; // decode UTF-8 mixed with non-UTF-8 and unreserved - QTest::newRow("utf8-mix-1") << "%80%C2%80" << F(QUrl::DecodeUnicode) << QString::fromUtf8("%80\xC2\x80"); - QTest::newRow("utf8-mix-2") << "%C2%C2%80" << F(QUrl::DecodeUnicode) << QString::fromUtf8("%C2\xC2\x80"); - QTest::newRow("utf8-mix-3") << "%E0%C2%80" << F(QUrl::DecodeUnicode) << QString::fromUtf8("%E0\xC2\x80"); - QTest::newRow("utf8-mix-3") << "A%C2%80" << F(QUrl::DecodeUnicode) << QString::fromUtf8("A\xC2\x80"); - QTest::newRow("utf8-mix-3") << "%C2%80A" << F(QUrl::DecodeUnicode) << QString::fromUtf8("\xC2\x80""A"); + QTest::newRow("utf8-mix-1") << "%80%C2%80" << F(QUrl::MostDecoded) << QString::fromUtf8("%80\xC2\x80"); + QTest::newRow("utf8-mix-2") << "%C2%C2%80" << F(QUrl::MostDecoded) << QString::fromUtf8("%C2\xC2\x80"); + QTest::newRow("utf8-mix-3") << "%E0%C2%80" << F(QUrl::MostDecoded) << QString::fromUtf8("%E0\xC2\x80"); + QTest::newRow("utf8-mix-3") << "A%C2%80" << F(QUrl::MostDecoded) << QString::fromUtf8("A\xC2\x80"); + QTest::newRow("utf8-mix-3") << "%C2%80A" << F(QUrl::MostDecoded) << QString::fromUtf8("\xC2\x80""A"); } void tst_QUrlInternal::encodingRecode() @@ -955,9 +955,9 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8_data() extern void loadNonCharactersRows(); loadNonCharactersRows(); - QTest::newRow("utf8-mix-4") << QByteArray("\xE0!A2\x80"); - QTest::newRow("utf8-mix-5") << QByteArray("\xE0\xA2!80"); - QTest::newRow("utf8-mix-5") << QByteArray("\xE0\xA2\x33"); + QTest::newRow("utf8-mix-4") << QByteArray("\xE0.A2\x80"); + QTest::newRow("utf8-mix-5") << QByteArray("\xE0\xA2.80"); + QTest::newRow("utf8-mix-6") << QByteArray("\xE0\xA2\x33"); } void tst_QUrlInternal::encodingRecodeInvalidUtf8() @@ -968,7 +968,7 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8() // prepend some data to be sure that it remains there QString output = QTest::currentDataTag(); - if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::DecodeUnicode)) + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::MostDecoded)) output += input; QCOMPARE(output, QTest::currentDataTag() + input); diff --git a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp index 24b651a8a3..7148a71153 100644 --- a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp +++ b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp @@ -593,10 +593,13 @@ void tst_QUrlQuery::encodedSetQueryItems_data() QTest::newRow("encode-space") << " = " << " " << " " << F(QUrl::FullyEncoded) << "%20=%20" << "%20" << "%20"; - QTest::newRow("non-delimiters") << "%3C%5C%3E=%7B%7C%7D%5E%60" << "%3C%5C%3E" << "%7B%7C%7D%5E%60" << F(QUrl::PrettyDecoded) + // tri-state + QTest::newRow("decode-non-delimiters") << "%3C%5C%3E=%7B%7C%7D%5E%60" << "%3C%5C%3E" << "%7B%7C%7D%5E%60" << F(QUrl::DecodeReserved) << "<\\>={|}^`" << "<\\>" << "{|}^`"; - QTest::newRow("encode-non-delimiters") << "<\\>={|}^`" << "<\\>" << "{|}^`" << F(QUrl::FullyEncoded) + QTest::newRow("encode-non-delimiters") << "<\\>={|}^`" << "<\\>" << "{|}^`" << F(QUrl::EncodeReserved) << "%3C%5C%3E=%7B%7C%7D%5E%60" << "%3C%5C%3E" << "%7B%7C%7D%5E%60"; + QTest::newRow("pretty-non-delimiters") << "<\\>={|}^`" << "<\\>" << "{|}^`" << F(QUrl::PrettyDecoded) + << "%3C%5C%3E=%7B%7C%7D%5E%60" << "<\\>" << "{|}^`"; QTest::newRow("equals") << "%3D=%3D" << "%3D" << "%3D" << F(QUrl::PrettyDecoded) << "%3D=%3D" << "=" << "="; @@ -606,7 +609,7 @@ void tst_QUrlQuery::encodedSetQueryItems_data() << "%26=%26" << "&" << "&"; QTest::newRow("hash") << "#=#" << "%23" << "%23" << F(QUrl::PrettyDecoded) << "#=#" << "#" << "#"; - QTest::newRow("decode-hash") << "%23=%23" << "%23" << "%23" << F(QUrl::DecodeDelimiters) + QTest::newRow("decode-hash") << "%23=%23" << "%23" << "%23" << F(QUrl::PrettyDecoded) << "#=#" << "#" << "#"; QTest::newRow("percent") << "%25=%25" << "%25" << "%25" << F(QUrl::PrettyDecoded) @@ -623,7 +626,7 @@ void tst_QUrlQuery::encodedSetQueryItems_data() // plus signs must not be touched QTest::newRow("encode-plus") << "+=+" << "+" << "+" << F(QUrl::FullyEncoded) << "+=+" << "+" << "+"; - QTest::newRow("decode-2b") << "%2b=%2b" << "%2b" << "%2b" << F(QUrl::DecodeDelimiters) + QTest::newRow("decode-2b") << "%2b=%2b" << "%2b" << "%2b" << F(QUrl::MostDecoded) << "%2B=%2B" << "%2B" << "%2B"; @@ -680,7 +683,7 @@ void tst_QUrlQuery::differentDelimiters() expected << qItem("foo", "bar") << qItem("hello", "world"); COMPARE_ITEMS(query.queryItems(), expected); COMPARE_ITEMS(query.queryItems(QUrl::FullyEncoded), expected); - COMPARE_ITEMS(query.queryItems(QUrl::DecodeDelimiters), expected); + COMPARE_ITEMS(query.queryItems(QUrl::MostDecoded), expected); } { -- cgit v1.2.3 From bb03f8e812ac7151ae98812fd899d0391326f21c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 2 Apr 2012 19:55:57 -0300 Subject: Readd a bunch of tests that had got removed in the QUrl porting Most of the tests were removed while QUrl::toEncoded or fromEncoded were deprecated in the development process. Since they aren't deprecated in the end, bring them back. Change-Id: Ibdb6cd3c4b83869150724a8e327a03a2cd22580d Reviewed-by: Robin Burchell Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 46 ++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 5611f5b2f4..e069ee791a 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -228,19 +228,20 @@ void tst_QUrl::hashInPath() QUrl withHashInPath; withHashInPath.setPath(QString::fromLatin1("hi#mum.txt")); QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi#mum.txt")); - QCOMPARE(withHashInPath.path(QUrl::MostDecoded), QString::fromLatin1("hi#mum.txt")); - QCOMPARE(withHashInPath.toString(QUrl::FullyEncoded), QString("hi%23mum.txt")); + QCOMPARE(withHashInPath.toEncoded(), QByteArray("hi%23mum.txt")); + QCOMPARE(withHashInPath.toString(), QString("hi%23mum.txt")); QCOMPARE(withHashInPath.toDisplayString(QUrl::PreferLocalFile), QString("hi%23mum.txt")); QUrl fromHashInPath = QUrl::fromEncoded(withHashInPath.toEncoded()); QVERIFY(withHashInPath == fromHashInPath); const QUrl localWithHash = QUrl::fromLocalFile("/hi#mum.txt"); + QCOMPARE(localWithHash.path(), QString::fromLatin1("/hi#mum.txt")); QCOMPARE(localWithHash.toEncoded(), QByteArray("file:///hi%23mum.txt")); QCOMPARE(localWithHash.toString(), QString("file:///hi%23mum.txt")); QCOMPARE(localWithHash.path(), QString::fromLatin1("/hi#mum.txt")); - QCOMPARE(localWithHash.toString(QUrl::PreferLocalFile | QUrl::PrettyDecoded), QString("/hi#mum.txt")); - QCOMPARE(localWithHash.toDisplayString(QUrl::PreferLocalFile | QUrl::PrettyDecoded), QString("/hi#mum.txt")); + QCOMPARE(localWithHash.toString(QUrl::PreferLocalFile), QString("/hi#mum.txt")); + QCOMPARE(localWithHash.toDisplayString(QUrl::PreferLocalFile), QString("/hi#mum.txt")); } void tst_QUrl::unc() @@ -278,7 +279,7 @@ void tst_QUrl::comparison() // 6.2.2 Syntax-based Normalization QUrl url3 = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D"); QUrl url4 = QUrl::fromEncoded("eXAMPLE://a/./b/../b/%63/%7bfoo%7d"); - QEXPECT_FAIL("", "Broken, FIXME", Continue); + QEXPECT_FAIL("", "Normalization not implemented, will probably not be implemented like this", Continue); QCOMPARE(url3, url4); // 6.2.2.1 Make sure hexdecimal characters in percent encoding are @@ -375,7 +376,7 @@ void tst_QUrl::setUrl() } { - QUrl url("http://www.foo.bar:80"); + QUrl url("hTTp://www.foo.bar:80"); QVERIFY(url.isValid()); QCOMPARE(url.scheme(), QString::fromLatin1("http")); QCOMPARE(url.path(), QString()); @@ -562,6 +563,7 @@ void tst_QUrl::setUrl() QUrl url15582("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.html"); QCOMPARE(url15582.toString(), QString::fromLatin1("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html")); + QCOMPARE(url15582.toEncoded(), QByteArray("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html")); QCOMPARE(url15582.toString(QUrl::FullyEncoded), QString("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html")); } @@ -582,10 +584,13 @@ void tst_QUrl::setUrl() { QUrl udir; + QCOMPARE(udir.toEncoded(), QByteArray()); QCOMPARE(udir.toString(QUrl::FullyEncoded), QString()); + QVERIFY(!udir.isValid()); udir = QUrl::fromLocalFile("/home/dfaure/file.txt"); QCOMPARE(udir.path(), QString::fromLatin1("/home/dfaure/file.txt")); + QCOMPARE(udir.toEncoded(), QByteArray("file:///home/dfaure/file.txt")); QCOMPARE(udir.toString(QUrl::FullyEncoded), QString("file:///home/dfaure/file.txt")); } @@ -1819,6 +1824,7 @@ void tst_QUrl::tolerantParser() QUrl url("http://www.example.com/path%20with spaces.html"); QVERIFY(url.isValid()); QCOMPARE(url.path(), QString("/path with spaces.html")); + QCOMPARE(url.toEncoded(), QByteArray("http://www.example.com/path%20with%20spaces.html")); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%20with%20spaces.html")); url.setUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode); QVERIFY(!url.isValid()); @@ -1854,24 +1860,39 @@ void tst_QUrl::tolerantParser() url.setUrl("http://foo.bar/[image][1].jpg"); QVERIFY(url.isValid()); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toString(), QString("http://foo.bar/[image][1].jpg")); url.setUrl("[].jpg"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%5B%5D.jpg")); + QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg")); + QCOMPARE(url.toString(), QString("[].jpg")); url.setUrl("/some/[path]/[]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("/some/%5Bpath%5D/%5B%5D")); + QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D")); + QCOMPARE(url.toString(), QString("/some/[path]/[]")); url.setUrl("//[::56:56:56:56:56:56:56]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]")); + QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]")); + QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]")); url.setUrl("//[::56:56:56:56:56:56:56]#[]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D")); + QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]#%5B%5D")); + QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]#[]")); url.setUrl("//[::56:56:56:56:56:56:56]?[]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?[]")); + QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]?[]")); + QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]?[]")); + // invoke the tolerant parser's error correction url.setUrl("%hello.com/f%"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%25hello.com/f%25")); + QCOMPARE(url.toEncoded(), QByteArray("%25hello.com/f%25")); + QCOMPARE(url.toString(), QString("%25hello.com/f%25")); url.setEncodedUrl("http://www.host.com/foo.php?P0=[2006-3-8]"); QVERIFY(url.isValid()); @@ -1879,24 +1900,37 @@ void tst_QUrl::tolerantParser() url.setEncodedUrl("http://foo.bar/[image][1].jpg"); QVERIFY(url.isValid()); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toString(), QString("http://foo.bar/[image][1].jpg")); url.setEncodedUrl("[].jpg"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%5B%5D.jpg")); + QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg")); + QCOMPARE(url.toString(), QString("[].jpg")); url.setEncodedUrl("/some/[path]/[]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("/some/%5Bpath%5D/%5B%5D")); + QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D")); + QCOMPARE(url.toString(), QString("/some/[path]/[]")); url.setEncodedUrl("//[::56:56:56:56:56:56:56]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]")); + QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]")); url.setEncodedUrl("//[::56:56:56:56:56:56:56]#[]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D")); + QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]#%5B%5D")); + QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]#[]")); url.setEncodedUrl("//[::56:56:56:56:56:56:56]?[]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?[]")); + QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]?[]")); + QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]?[]")); url.setEncodedUrl("data:text/css,div%20{%20border-right:%20solid;%20}"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("data:text/css,div%20%7B%20border-right:%20solid;%20%7D")); + QCOMPARE(url.toEncoded(), QByteArray("data:text/css,div%20%7B%20border-right:%20solid;%20%7D")); + QCOMPARE(url.toString(), QString("data:text/css,div { border-right: solid; }")); } { -- cgit v1.2.3 From a0a1595185a07fb2e5b9f95cd6075b65c2bd03a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 6 Apr 2012 09:35:24 +0200 Subject: Prefer QCOMPARE to QVERIFY, as it gives better output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Done-by: Jędrzej Nowacki Change-Id: Ic1c8fd5b8acede52b45e5ea16b14fb5bae78f171 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 037893a13e..267aa71085 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -1286,7 +1286,7 @@ void tst_QByteArray::appendAfterFromRawData() arr += QByteArray::fromRawData(data, sizeof(data)); data[0] = 'Y'; } - QVERIFY(arr.at(0) == 'X'); + QCOMPARE(arr.at(0), 'X'); } void tst_QByteArray::toFromHex_data() -- cgit v1.2.3 From 1035c93245ef299c2f29be5b119b736430e81dc3 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 11 Apr 2012 18:06:11 +0300 Subject: make QStringList::sort() to take a Qt::CaseSensitivity param Task-number: QTBUG-12892 Change-Id: I402e6fb12ff24ac26c5a8103bf81547946f9cc58 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- .../corelib/tools/qstringlist/tst_qstringlist.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp index d02e649bdf..16a329f1dd 100644 --- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp +++ b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp @@ -44,10 +44,13 @@ #include #include +#include + class tst_QStringList : public QObject { Q_OBJECT private slots: + void sort(); void filter(); void replaceInStrings(); void removeDuplicates(); @@ -199,6 +202,23 @@ void tst_QStringList::filter() QCOMPARE( list5, list6 ); } +void tst_QStringList::sort() +{ + QStringList list1, list2; + list1 << "alpha" << "beta" << "BETA" << "gamma" << "Gamma" << "gAmma" << "epsilon"; + list1.sort(); + list2 << "BETA" << "Gamma" << "alpha" << "beta" << "epsilon" << "gAmma" << "gamma"; + QCOMPARE( list1, list2 ); + + char *current_locale = setlocale(LC_ALL, "C"); + QStringList list3, list4; + list3 << "alpha" << "beta" << "BETA" << "gamma" << "Gamma" << "gAmma" << "epsilon"; + list3.sort(Qt::CaseInsensitive); + list4 << "alpha" << "beta" << "BETA" << "epsilon" << "Gamma" << "gAmma" << "gamma"; + QCOMPARE( list3, list4 ); + setlocale(LC_ALL, current_locale); +} + void tst_QStringList::replaceInStrings() { QStringList list1, list2; -- cgit v1.2.3 From 4d79312f1c3ba04130129d7047aade56cee6c70f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 11 Apr 2012 17:55:18 -0300 Subject: Ensure proper handling of empty-but-present URL components The new QUrl is able to distinguish a URL component that is empty from one that is absent. The previous one already had that capability for the port, fragment and query, and the new one extends that to the username, password and path. The path did not need this handling because its delimiter from the authority it part of the path. For example, a URL with no username is one where it's set to QString() (null). A URL like "http://:kde@kde.org" is understood as an empty-but-present username, for which toString(RemovePassword) will return "http://@kde.org", keeping the empty-but-present username. Change-Id: I2d97a7656f3f1099e3cf400b199e68e4c480d924 Reviewed-by: Shane Kearns --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 34 ++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index e069ee791a..f9fbb8cba8 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -808,10 +808,21 @@ void tst_QUrl::toString_data() << uint(QUrl::RemovePassword) << QString::fromLatin1("http://ole@www.troll.no:9090/index.html?ole=semann&gud=hei#top"); + // show that QUrl keeps the empty-but-present username if you remove the password + // see data3-bis for another case + QTest::newRow("data2-bis") << QString::fromLatin1("http://:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top") + << uint(QUrl::RemovePassword) + << QString::fromLatin1("http://@www.troll.no:9090/index.html?ole=semann&gud=hei#top"); + QTest::newRow("data3") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top") << uint(QUrl::RemoveUserInfo) << QString::fromLatin1("http://www.troll.no:9090/index.html?ole=semann&gud=hei#top"); + // show that QUrl keeps the empty-but-preset hostname if you remove the userinfo + QTest::newRow("data3-bis") << QString::fromLatin1("http://ole:password@/index.html?ole=semann&gud=hei#top") + << uint(QUrl::RemoveUserInfo) + << QString::fromLatin1("http:///index.html?ole=semann&gud=hei#top"); + QTest::newRow("data4") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top") << uint(QUrl::RemovePort) << QString::fromLatin1("http://ole:password@www.troll.no/index.html?ole=semann&gud=hei#top"); @@ -926,20 +937,26 @@ void tst_QUrl::toString_constructed_data() QTest::addColumn("fragment"); QTest::addColumn("asString"); QTest::addColumn("asEncoded"); + QTest::addColumn("options"); QString n(""); QTest::newRow("data1") << n << n << n << QString::fromLatin1("qt.nokia.com") << -1 << QString::fromLatin1("index.html") << QByteArray() << n << QString::fromLatin1("//qt.nokia.com/index.html") - << QByteArray("//qt.nokia.com/index.html"); + << QByteArray("//qt.nokia.com/index.html") << 0u; QTest::newRow("data2") << QString::fromLatin1("file") << n << n << n << -1 << QString::fromLatin1("/root") << QByteArray() - << n << QString::fromLatin1("file:///root") << QByteArray("file:///root"); + << n << QString::fromLatin1("file:///root") << QByteArray("file:///root") << 0u; QTest::newRow("userAndPass") << QString::fromLatin1("http") << QString::fromLatin1("dfaure") << QString::fromLatin1("kde") << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n - << QString::fromLatin1("http://dfaure:kde@kde.org:443/") << QByteArray("http://dfaure:kde@kde.org:443/"); + << QString::fromLatin1("http://dfaure:kde@kde.org:443/") << QByteArray("http://dfaure:kde@kde.org:443/") + << 0u; QTest::newRow("PassWithoutUser") << QString::fromLatin1("http") << n << QString::fromLatin1("kde") << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n - << QString::fromLatin1("http://:kde@kde.org:443/") << QByteArray("http://:kde@kde.org:443/"); + << QString::fromLatin1("http://:kde@kde.org:443/") << QByteArray("http://:kde@kde.org:443/") << 0u; + QTest::newRow("PassWithoutUser-RemovePassword") << QString::fromLatin1("http") << n << QString::fromLatin1("kde") + << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n + << QString::fromLatin1("http://kde.org:443/") << QByteArray("http://kde.org:443/") + << uint(QUrl::RemovePassword); } void tst_QUrl::toString_constructed() @@ -954,6 +971,7 @@ void tst_QUrl::toString_constructed() QFETCH(QString, fragment); QFETCH(QString, asString); QFETCH(QByteArray, asEncoded); + QFETCH(uint, options); QUrl url; if (!scheme.isEmpty()) @@ -974,9 +992,11 @@ void tst_QUrl::toString_constructed() url.setFragment(fragment); QVERIFY(url.isValid()); - QCOMPARE(url.toString(), asString); - QCOMPARE(QString::fromLatin1(url.toEncoded()), QString::fromLatin1(asEncoded)); // readable in case of differences - QCOMPARE(url.toEncoded(), asEncoded); + + QUrl::FormattingOptions formattingOptions(options); + QCOMPARE(url.toString(formattingOptions), asString); + QCOMPARE(QString::fromLatin1(url.toEncoded(formattingOptions)), QString::fromLatin1(asEncoded)); // readable in case of differences + QCOMPARE(url.toEncoded(formattingOptions), asEncoded); } -- cgit v1.2.3 From 03dbba9a62ea6391639c54ccc89ea75d4a872597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Fri, 16 Mar 2012 07:00:45 +0100 Subject: QLayoutItem - make controlTypes a virtual function. Just implementing the ### Qt5 suggestion about making controlTypes a virtual function. Change-Id: Ic1db47fe488f089de965438e456e9b48e0b96f32 Reviewed-by: Girish Ramakrishnan Reviewed-by: Lars Knoll --- tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp index 764d777cea..647376412f 100644 --- a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp +++ b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,7 @@ private slots: void layoutItemRect(); void warnIfWrongParent(); void controlTypes(); + void controlTypes2(); void adjustSizeShouldMakeSureLayoutIsActivated(); }; @@ -310,7 +312,16 @@ void tst_QLayout::controlTypes() QCOMPARE(layout.controlTypes(), QSizePolicy::DefaultType); QSizePolicy p; QCOMPARE(p.controlType(),QSizePolicy::DefaultType); +} +void tst_QLayout::controlTypes2() +{ + QWidget main; + QVBoxLayout *const layout = new QVBoxLayout(&main); + layout->setMargin(0); + QComboBox *combo = new QComboBox(&main); + layout->addWidget(combo); + QCOMPARE(layout->controlTypes(), QSizePolicy::ComboBox); } void tst_QLayout::adjustSizeShouldMakeSureLayoutIsActivated() -- cgit v1.2.3 From 1424702918720576792da713cd3b8fee485775cf Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 10 Apr 2012 13:14:51 +0100 Subject: Add unit test for BackgroundRequestAttribute Change-Id: I807953cac3d23825461f9ae860badbd148835330 Reviewed-by: Martin Petersson --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 48 +++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 185c3eedd8..2d784fcbbc 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -75,6 +75,7 @@ #include #include #include +#include #endif #ifdef QT_BUILD_INTERNAL #include @@ -402,6 +403,9 @@ private Q_SLOTS: void ftpAuthentication_data(); void ftpAuthentication(); + void backgroundRequest_data(); + void backgroundRequest(); + // NOTE: This test must be last! void parentingRepliesToTheApp(); private: @@ -6778,7 +6782,6 @@ void tst_QNetworkReply::closeDuringDownload() QTest::qWait(1000); //cancelling ftp takes some time, this avoids a warning caused by test's cleanup() destroying the connection cache before the abort is finished } - void tst_QNetworkReply::ftpAuthentication_data() { QTest::addColumn("referenceName"); @@ -6806,6 +6809,49 @@ void tst_QNetworkReply::ftpAuthentication() QCOMPARE(reply->error(), QNetworkReply::NetworkError(error)); } +void tst_QNetworkReply::backgroundRequest_data() +{ + QTest::addColumn("background"); + QTest::addColumn("policy"); + QTest::addColumn("error"); + + QTest::newRow("fg, normal") << false << 0 << QNetworkReply::NoError; + QTest::newRow("bg, normal") << true << 0 << QNetworkReply::NoError; + QTest::newRow("fg, nobg") << false << (int)QNetworkSession::NoBackgroundTrafficPolicy << QNetworkReply::NoError; + QTest::newRow("bg, nobg") << true << (int)QNetworkSession::NoBackgroundTrafficPolicy << QNetworkReply::BackgroundRequestNotAllowedError; + +} + +void tst_QNetworkReply::backgroundRequest() +{ +#ifdef QT_BUILD_INTERNAL + QFETCH(bool, background); + QFETCH(int, policy); + QFETCH(QNetworkReply::NetworkError, error); + + QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName())); + + if (background) + request.setAttribute(QNetworkRequest::BackgroundRequestAttribute, QVariant::fromValue(true)); + + //this preconstructs the session so we can change policies in advance + manager.setConfiguration(networkConfiguration); + + const QWeakPointer session = QNetworkAccessManagerPrivate::getNetworkSession(&manager); + QVERIFY(session); + QNetworkSession::UsagePolicies original = session.data()->usagePolicies(); + QNetworkSessionPrivate::setUsagePolicies(*const_cast(session.data()), QNetworkSession::UsagePolicies(policy)); + + QNetworkReplyPtr reply(manager.get(request)); + + QVERIFY(waitForFinish(reply) != Timeout); + if (session) + QNetworkSessionPrivate::setUsagePolicies(*const_cast(session.data()), original); + + QVERIFY(reply->isFinished()); + QCOMPARE(reply->error(), error); +#endif +} // NOTE: This test must be last testcase in tst_qnetworkreply! void tst_QNetworkReply::parentingRepliesToTheApp() -- cgit v1.2.3 From 8427ff09ab7ce15b7b9ecc60514aec8dd2b6a24f Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Mon, 9 Apr 2012 19:14:31 +0100 Subject: QSharedPointer: hash autotest fix The hash autotest is wrong: it assumed that the iterator on the hash would reach the end after iterating on two elements with identical key. But three elements were added to that hash, and the third one can appear after the other two. That code path is left for the map test only. Change-Id: I51de7987e2b132b6caff7bb4bac6a57fb7fcb530 Reviewed-by: Robin Burchell Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index f8b9abb359..bb9be1d65f 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -1623,7 +1623,8 @@ void hashAndMapTest() QVERIFY(it != c.end()); QCOMPARE(it.key(), k1); ++it; - QVERIFY(it == c.end()); + if (Ordered) + QVERIFY(it == c.end()); } void tst_QSharedPointer::map() -- cgit v1.2.3 From 5e24d22af075ce790b471fb9aca59a80037f34df Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 13 Apr 2012 19:41:47 +0100 Subject: QHash: fix key() test The key returned by QHash::key is an arbitrary one that maps to the given value. The test instead relied on it being a specific one. Change-Id: I090351797e8b52036d78160fd810518a11e8107d Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qhash/tst_qhash.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 9d18c7a34e..5bd13b23a3 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -526,14 +526,14 @@ void tst_QHash::key() hash2.insert(3, "two"); QCOMPARE(hash2.key("one"), 1); QCOMPARE(hash2.key("one", def), 1); - QCOMPARE(hash2.key("two"), 2); - QCOMPARE(hash2.key("two", def), 2); + QVERIFY(hash2.key("two") == 2 || hash2.key("two") == 3); + QVERIFY(hash2.key("two", def) == 2 || hash2.key("two", def) == 3); QCOMPARE(hash2.key("three"), 0); QCOMPARE(hash2.key("three", def), def); hash2.insert(-1, "two"); - QCOMPARE(hash2.key("two"), -1); - QCOMPARE(hash2.key("two", def), -1); + QVERIFY(hash2.key("two") == 2 || hash2.key("two") == 3 || hash2.key("two") == -1); + QVERIFY(hash2.key("two", def) == 2 || hash2.key("two", def) == 3 || hash2.key("two", def) == -1); hash2.insert(0, "zero"); QCOMPARE(hash2.key("zero"), 0); -- cgit v1.2.3 From 51fecf80b7643035159bf79970231ee2f4017af5 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 15 Apr 2012 19:05:10 +0100 Subject: Mark tst_qabstractitemmodel as insignificant after QHash randomization The testChildrenLayoutsChanged fails randomly. This happens rarely, f.i. wasn't spotted by CI when QHash randomization itself was merged; but is indeed reproducible by running the test a few times in a row. This is now blocking api_merges integration, and I have no idea how to fix it. This patch marks the test as insignificant for now (the bug tracking this test failure is QTBUG-25325), and switches the failing tests from QVERIFY(a == b) to a proper QCOMPARE (so that the expected values do show up in the build logs). Change-Id: I16f0e28bcbb06dbac2e7169f4676a19ccf626a92 Reviewed-by: Stephen Kelly --- .../auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro | 1 + .../corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro b/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro index 9e59251379..8bfe6628da 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro @@ -6,3 +6,4 @@ mtdir = ../../../other/modeltest INCLUDEPATH += $$PWD/$${mtdir} SOURCES = tst_qabstractitemmodel.cpp $${mtdir}/dynamictreemodel.cpp $${mtdir}/modeltest.cpp HEADERS = $${mtdir}/dynamictreemodel.h $${mtdir}/modeltest.h +CONFIG += insignificant_test # QTBUG-25325 diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp index 8d451dbff9..28babdbacb 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -2135,8 +2135,8 @@ void tst_QAbstractItemModel::testChildrenLayoutsChanged() QVERIFY(p1FirstPersistent.row() == 1); QVERIFY(p1LastPersistent.row() == 0); - QVERIFY(p2FirstPersistent.row() == 9); - QVERIFY(p2LastPersistent.row() == 8); + QCOMPARE(p2FirstPersistent.row(), 9); + QCOMPARE(p2LastPersistent.row(), 8); } } -- cgit v1.2.3 From 65e75acd05b16fea11d85f3a6a330d50c8ce7c5d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Mar 2012 09:53:06 -0300 Subject: Update the error codes in QtDBus Change the old com.trolltech ones to org.qtproject and introduce Use the alternate domain name for the Qt Project because the dash character is not valid in interface and error names. Task-number: QTBUG-23274 Change-Id: Iac1699e70525d67f983c10560932acff6b2ecde6 Reviewed-by: Lars Knoll Reviewed-by: Jason McDonald --- .../qdbusabstractinterface/tst_qdbusabstractinterface.cpp | 14 +++++++------- tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index b696294005..7ac5cd3c6c 100644 --- a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -1034,9 +1034,9 @@ void tst_QDBusAbstractInterface::createErrors_data() QTest::addColumn("path"); QTest::addColumn("errorName"); - QTest::newRow("invalid-service") << "this isn't valid" << "/" << "com.trolltech.QtDBus.Error.InvalidService"; + QTest::newRow("invalid-service") << "this isn't valid" << "/" << "org.qtproject.QtDBus.Error.InvalidService"; QTest::newRow("invalid-path") << QDBusConnection::sessionBus().baseService() << "this isn't valid" - << "com.trolltech.QtDBus.Error.InvalidObjectPath"; + << "org.qtproject.QtDBus.Error.InvalidObjectPath"; } void tst_QDBusAbstractInterface::createErrors() @@ -1055,7 +1055,7 @@ void tst_QDBusAbstractInterface::createErrorsPeer_data() QTest::addColumn("path"); QTest::addColumn("errorName"); - QTest::newRow("invalid-path") << "this isn't valid" << "com.trolltech.QtDBus.Error.InvalidObjectPath"; + QTest::newRow("invalid-path") << "this isn't valid" << "org.qtproject.QtDBus.Error.InvalidObjectPath"; } void tst_QDBusAbstractInterface::createErrorsPeer() @@ -1071,10 +1071,10 @@ void tst_QDBusAbstractInterface::createErrorsPeer() void tst_QDBusAbstractInterface::callErrors_data() { createErrors_data(); - QTest::newRow("service-wildcard") << QString() << "/" << "com.trolltech.QtDBus.Error.InvalidService"; + QTest::newRow("service-wildcard") << QString() << "/" << "org.qtproject.QtDBus.Error.InvalidService"; QTest::newRow("path-wildcard") << QDBusConnection::sessionBus().baseService() << QString() - << "com.trolltech.QtDBus.Error.InvalidObjectPath"; - QTest::newRow("full-wildcard") << QString() << QString() << "com.trolltech.QtDBus.Error.InvalidService"; + << "org.qtproject.QtDBus.Error.InvalidObjectPath"; + QTest::newRow("full-wildcard") << QString() << QString() << "org.qtproject.QtDBus.Error.InvalidService"; } void tst_QDBusAbstractInterface::callErrors() @@ -1113,7 +1113,7 @@ void tst_QDBusAbstractInterface::asyncCallErrors() void tst_QDBusAbstractInterface::callErrorsPeer_data() { createErrorsPeer_data(); - QTest::newRow("path-wildcard") << QString() << "com.trolltech.QtDBus.Error.InvalidObjectPath"; + QTest::newRow("path-wildcard") << QString() << "org.qtproject.QtDBus.Error.InvalidObjectPath"; } void tst_QDBusAbstractInterface::callErrorsPeer() diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index 13f3bd2060..57d7f82c1f 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -928,26 +928,26 @@ void tst_QDBusMarshall::sendCallErrors_data() << "Method \"ping\" with signature \"\" on interface \"com.trolltech.autotests.qpong\" doesn't exist\n" << (const char*)0; QTest::newRow("invalid-service") << "this isn't valid" << objectPath << interfaceName << "ping" << QVariantList() - << "com.trolltech.QtDBus.Error.InvalidService" + << "org.qtproject.QtDBus.Error.InvalidService" << "Invalid service name: this isn't valid" << ""; QTest::newRow("empty-path") << serviceName << "" << interfaceName << "ping" << QVariantList() - << "com.trolltech.QtDBus.Error.InvalidObjectPath" + << "org.qtproject.QtDBus.Error.InvalidObjectPath" << "Object path cannot be empty" << ""; QTest::newRow("invalid-path") << serviceName << "//" << interfaceName << "ping" << QVariantList() - << "com.trolltech.QtDBus.Error.InvalidObjectPath" + << "org.qtproject.QtDBus.Error.InvalidObjectPath" << "Invalid object path: //" << ""; // empty interfaces are valid QTest::newRow("invalid-interface") << serviceName << objectPath << "this isn't valid" << "ping" << QVariantList() - << "com.trolltech.QtDBus.Error.InvalidInterface" + << "org.qtproject.QtDBus.Error.InvalidInterface" << "Invalid interface class: this isn't valid" << ""; QTest::newRow("empty-method") << serviceName << objectPath << interfaceName << "" << QVariantList() - << "com.trolltech.QtDBus.Error.InvalidMember" + << "org.qtproject.QtDBus.Error.InvalidMember" << "method name cannot be empty" << ""; QTest::newRow("invalid-method") << serviceName << objectPath << interfaceName << "this isn't valid" << QVariantList() - << "com.trolltech.QtDBus.Error.InvalidMember" + << "org.qtproject.QtDBus.Error.InvalidMember" << "Invalid method name: this isn't valid" << ""; QTest::newRow("invalid-variant1") << serviceName << objectPath << interfaceName << "ping" -- cgit v1.2.3 From e02a144a3c8e7858d879ac2d0038bc7d00906ae6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Mar 2012 11:11:03 -0300 Subject: Finish cleaning up com.trolltech -> org.qtproject in QtDBus Lots of uses of the annotations and error names, plus a bunch of local unit test names (including one file that had to be renamed). The meta object generator is updated to support both the old and new names. That means some references to com.trolltech *must* remain in the source code. Task-number: QTBUG-23274 Change-Id: Icc38ae040232f07c437e7546ee744a4703f41726 Reviewed-by: Jason McDonald Reviewed-by: Lorn Potter --- .../qdbusabstractadaptor/qmyserver/qmyserver.cpp | 6 ++-- .../tst_qdbusabstractadaptor.cpp | 6 ++-- .../com.trolltech.QtDBus.Pinger.xml | 34 ---------------------- tests/auto/dbus/qdbusabstractinterface/interface.h | 2 +- .../org.qtproject.QtDBus.Pinger.xml | 34 ++++++++++++++++++++++ tests/auto/dbus/qdbusabstractinterface/pinger.cpp | 2 +- tests/auto/dbus/qdbusabstractinterface/pinger.h | 6 ++-- .../qdbusabstractinterface.pro | 2 +- .../qdbusabstractinterface/qpinger/qpinger.cpp | 6 ++-- .../tst_qdbusabstractinterface.cpp | 12 ++++---- .../dbus/qdbusconnection/tst_qdbusconnection.cpp | 8 ++--- tests/auto/dbus/qdbuscontext/tst_qdbuscontext.cpp | 4 +-- tests/auto/dbus/qdbusinterface/myobject.h | 14 ++++----- .../dbus/qdbusinterface/qmyserver/qmyserver.cpp | 6 ++-- .../dbus/qdbusinterface/tst_qdbusinterface.cpp | 16 +++++----- tests/auto/dbus/qdbusmarshall/qpong/qpong.cpp | 6 ++-- .../auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp | 6 ++-- .../dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp | 15 ++++++---- .../dbus/qdbuspendingcall/tst_qdbuspendingcall.cpp | 4 +-- .../qdbuspendingreply/tst_qdbuspendingreply.cpp | 4 +-- tests/auto/dbus/qdbusreply/tst_qdbusreply.cpp | 4 +-- 21 files changed, 101 insertions(+), 96 deletions(-) delete mode 100644 tests/auto/dbus/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml create mode 100644 tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml (limited to 'tests') diff --git a/tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver.cpp b/tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver.cpp index d5d5f2c431..39e6633bfc 100644 --- a/tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver.cpp +++ b/tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver.cpp @@ -43,8 +43,8 @@ #include "../myobject.h" -static const char serviceName[] = "com.trolltech.autotests.qmyserver"; -static const char objectPath[] = "/com/trolltech/qmyserver"; +static const char serviceName[] = "org.qtproject.autotests.qmyserver"; +static const char objectPath[] = "/org/qtproject/qmyserver"; //static const char *interfaceName = serviceName; const char *slotSpy; @@ -55,7 +55,7 @@ Q_DECLARE_METATYPE(QDBusConnection::RegisterOptions) class MyServer : public QDBusServer { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.qmyserver") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.autotests.qmyserver") public: MyServer(QString addr = "unix:tmpdir=/tmp", QObject* parent = 0) diff --git a/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp b/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp index c14d77eec3..30571fadd6 100644 --- a/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp +++ b/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp @@ -48,8 +48,8 @@ #include "../qdbusmarshall/common.h" #include "myobject.h" -static const char serviceName[] = "com.trolltech.autotests.qmyserver"; -static const char objectPath[] = "/com/trolltech/qmyserver"; +static const char serviceName[] = "org.qtproject.autotests.qmyserver"; +static const char objectPath[] = "/org/qtproject/qmyserver"; static const char *interfaceName = serviceName; const char *slotSpy; @@ -644,7 +644,7 @@ void tst_QDBusAbstractAdaptor::signalEmissions() QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); - con.registerService("com.trolltech.tst_QDBusAbstractAdaptor"); + con.registerService("org.qtproject.tst_QDBusAbstractAdaptor"); MyObject obj(3); con.registerObject("/", &obj, QDBusConnection::ExportAdaptors diff --git a/tests/auto/dbus/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml b/tests/auto/dbus/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml deleted file mode 100644 index d945ec9b43..0000000000 --- a/tests/auto/dbus/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/auto/dbus/qdbusabstractinterface/interface.h b/tests/auto/dbus/qdbusabstractinterface/interface.h index 2bd99fa11a..94addb7355 100644 --- a/tests/auto/dbus/qdbusabstractinterface/interface.h +++ b/tests/auto/dbus/qdbusabstractinterface/interface.h @@ -78,7 +78,7 @@ Q_DECLARE_METATYPE(UnregisteredType) class Interface: public QObject { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.Pinger") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.QtDBus.Pinger") Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp SCRIPTABLE true) Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp SCRIPTABLE true) Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp SCRIPTABLE true) diff --git a/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml b/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml new file mode 100644 index 0000000000..845e7be5b4 --- /dev/null +++ b/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/dbus/qdbusabstractinterface/pinger.cpp b/tests/auto/dbus/qdbusabstractinterface/pinger.cpp index 93d4732f74..a931f41d6f 100644 --- a/tests/auto/dbus/qdbusabstractinterface/pinger.cpp +++ b/tests/auto/dbus/qdbusabstractinterface/pinger.cpp @@ -41,7 +41,7 @@ /* * This file was generated by qdbusxml2cpp version 0.7 - * Command line was: qdbusxml2cpp -i interface.h -p pinger com.trolltech.QtDBus.Pinger.xml + * Command line was: qdbusxml2cpp -i interface.h -p pinger org.qtproject.QtDBus.Pinger.xml * * qdbusxml2cpp is Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). * diff --git a/tests/auto/dbus/qdbusabstractinterface/pinger.h b/tests/auto/dbus/qdbusabstractinterface/pinger.h index eb05d7535a..7fc6e640fe 100644 --- a/tests/auto/dbus/qdbusabstractinterface/pinger.h +++ b/tests/auto/dbus/qdbusabstractinterface/pinger.h @@ -41,7 +41,7 @@ /* * This file was generated by qdbusxml2cpp version 0.7 - * Command line was: qdbusxml2cpp -i interface.h -p pinger com.trolltech.QtDBus.Pinger.xml + * Command line was: qdbusxml2cpp -i interface.h -p pinger org.qtproject.QtDBus.Pinger.xml * * qdbusxml2cpp is Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). * @@ -63,14 +63,14 @@ #include "interface.h" /* - * Proxy class for interface com.trolltech.QtDBus.Pinger + * Proxy class for interface org.qtproject.QtDBus.Pinger */ class ComTrolltechQtDBusPingerInterface: public QDBusAbstractInterface { Q_OBJECT public: static inline const char *staticInterfaceName() - { return "com.trolltech.QtDBus.Pinger"; } + { return "org.qtproject.QtDBus.Pinger"; } public: ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); diff --git a/tests/auto/dbus/qdbusabstractinterface/qdbusabstractinterface.pro b/tests/auto/dbus/qdbusabstractinterface/qdbusabstractinterface.pro index 9d8d542b88..623b07fcbd 100644 --- a/tests/auto/dbus/qdbusabstractinterface/qdbusabstractinterface.pro +++ b/tests/auto/dbus/qdbusabstractinterface/qdbusabstractinterface.pro @@ -3,4 +3,4 @@ TARGET = tst_qdbusabstractinterface TEMPLATE = subdirs CONFIG += ordered SUBDIRS = qpinger test -OTHER_FILES += com.trolltech.QtDBus.Pinger.xml +OTHER_FILES += org.qtproject.QtDBus.Pinger.xml diff --git a/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.cpp b/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.cpp index 87c6bad7fc..3ecc839a34 100644 --- a/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.cpp +++ b/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.cpp @@ -42,14 +42,14 @@ #include #include "../interface.h" -static const char serviceName[] = "com.trolltech.autotests.qpinger"; -static const char objectPath[] = "/com/trolltech/qpinger"; +static const char serviceName[] = "org.qtproject.autotests.qpinger"; +static const char objectPath[] = "/org/qtproject/qpinger"; //static const char *interfaceName = serviceName; class PingerServer : public QDBusServer { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.qpinger") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.autotests.qpinger") public: PingerServer(QString addr = "unix:tmpdir=/tmp", QObject* parent = 0) : QDBusServer(addr, parent), diff --git a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index 7ac5cd3c6c..59ec2955e4 100644 --- a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -49,8 +49,8 @@ #include "interface.h" #include "pinger.h" -static const char serviceName[] = "com.trolltech.autotests.qpinger"; -static const char objectPath[] = "/com/trolltech/qpinger"; +static const char serviceName[] = "org.qtproject.autotests.qpinger"; +static const char objectPath[] = "/org/qtproject/qpinger"; static const char *interfaceName = serviceName; typedef QSharedPointer Pinger; @@ -452,9 +452,9 @@ void tst_QDBusAbstractInterface::makeAsyncMultiOutCallPeer() QCoreApplication::instance()->processEvents(); } -static const char server_serviceName[] = "com.trolltech.autotests.dbusserver"; -static const char server_objectPath[] = "/com/trolltech/server"; -static const char server_interfaceName[] = "com.trolltech.QtDBus.Pinger"; +static const char server_serviceName[] = "org.qtproject.autotests.dbusserver"; +static const char server_objectPath[] = "/org/qtproject/server"; +static const char server_interfaceName[] = "org.qtproject.QtDBus.Pinger"; class DBusServerThread : public QThread { @@ -975,7 +975,7 @@ void tst_QDBusAbstractInterface::getComplexSignalPeer() void tst_QDBusAbstractInterface::followSignal() { - const QString serviceToFollow = "com.trolltech.tst_qdbusabstractinterface.FollowMe"; + const QString serviceToFollow = "org.qtproject.tst_qdbusabstractinterface.FollowMe"; Pinger p = getPinger(serviceToFollow); QVERIFY2(p, "Not connected to D-Bus"); diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp index 65b68b7f34..f99220ea1a 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp @@ -118,7 +118,7 @@ private slots: void callVirtualObjectLocal(); public: - QString serviceName() const { return "com.trolltech.Qt.Autotests.QDBusConnection"; } + QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; } bool callMethod(const QDBusConnection &conn, const QString &path); bool callMethodPeer(const QDBusConnection &conn, const QString &path); }; @@ -970,7 +970,7 @@ void tst_QDBusConnection::slotsWithLessParameters() { QDBusConnection con = QDBusConnection::sessionBus(); - QDBusMessage signal = QDBusMessage::createSignal("/", "com.trolltech.TestCase", + QDBusMessage signal = QDBusMessage::createSignal("/", "org.qtproject.TestCase", "oneSignal"); signal << "one parameter"; @@ -1051,7 +1051,7 @@ void tst_QDBusConnection::serviceRegistrationRaceCondition() // connect to the signal: RaceConditionSignalWaiter recv; - session.connect(serviceName, "/", "com.trolltech.TestCase", "oneSignal", &recv, SLOT(countUp())); + session.connect(serviceName, "/", "org.qtproject.TestCase", "oneSignal", &recv, SLOT(countUp())); // create a secondary connection and register a name QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, connectionName); @@ -1060,7 +1060,7 @@ void tst_QDBusConnection::serviceRegistrationRaceCondition() QVERIFY(connection.registerService(serviceName)); // send a signal - QDBusMessage msg = QDBusMessage::createSignal("/", "com.trolltech.TestCase", "oneSignal"); + QDBusMessage msg = QDBusMessage::createSignal("/", "org.qtproject.TestCase", "oneSignal"); connection.send(msg); // make a blocking call just to be sure that the buffer was flushed diff --git a/tests/auto/dbus/qdbuscontext/tst_qdbuscontext.cpp b/tests/auto/dbus/qdbuscontext/tst_qdbuscontext.cpp index bc06f8e377..3ec9e636a8 100644 --- a/tests/auto/dbus/qdbuscontext/tst_qdbuscontext.cpp +++ b/tests/auto/dbus/qdbuscontext/tst_qdbuscontext.cpp @@ -41,13 +41,13 @@ #include #include -const char errorName[] = "com.trolltech.tst_QDBusContext.Error"; +const char errorName[] = "org.qtproject.tst_QDBusContext.Error"; const char errorMsg[] = "A generic error"; class TestObject: public QObject, protected QDBusContext { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.tst_QDBusContext.TestObject") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.tst_QDBusContext.TestObject") public: inline TestObject(QObject *parent) : QObject(parent) { } public Q_SLOTS: diff --git a/tests/auto/dbus/qdbusinterface/myobject.h b/tests/auto/dbus/qdbusinterface/myobject.h index 94e7b3d4c5..12c8da6ef6 100644 --- a/tests/auto/dbus/qdbusinterface/myobject.h +++ b/tests/auto/dbus/qdbusinterface/myobject.h @@ -50,12 +50,12 @@ Q_DECLARE_METATYPE(QVariantList) class MyObject: public QObject { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.MyObject") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.QtDBus.MyObject") Q_CLASSINFO("D-Bus Introspection", "" -" \n" +" \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" @@ -83,14 +83,14 @@ class MyObject: public QObject " \n" " \n" " \n" -" \n" -" \n" +" \n" +" \n" " \n" " \n" " \n" " \n" -" \n" -" \n" +" \n" +" \n" " \n" " \n" "") diff --git a/tests/auto/dbus/qdbusinterface/qmyserver/qmyserver.cpp b/tests/auto/dbus/qdbusinterface/qmyserver/qmyserver.cpp index 1815a6ef79..cb3cd1b27e 100644 --- a/tests/auto/dbus/qdbusinterface/qmyserver/qmyserver.cpp +++ b/tests/auto/dbus/qdbusinterface/qmyserver/qmyserver.cpp @@ -43,8 +43,8 @@ #include "../myobject.h" -static const char serviceName[] = "com.trolltech.autotests.qmyserver"; -static const char objectPath[] = "/com/trolltech/qmyserver"; +static const char serviceName[] = "org.qtproject.autotests.qmyserver"; +static const char objectPath[] = "/org/qtproject/qmyserver"; //static const char *interfaceName = serviceName; int MyObject::callCount = 0; @@ -53,7 +53,7 @@ QVariantList MyObject::callArgs; class MyServer : public QDBusServer { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.qmyserver") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.autotests.qmyserver") public: MyServer(QString addr = "unix:tmpdir=/tmp", QObject* parent = 0) diff --git a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp index c866c9d155..af2355aa5d 100644 --- a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp @@ -50,11 +50,11 @@ #include "../qdbusmarshall/common.h" #include "myobject.h" -#define TEST_INTERFACE_NAME "com.trolltech.QtDBus.MyObject" +#define TEST_INTERFACE_NAME "org.qtproject.QtDBus.MyObject" #define TEST_SIGNAL_NAME "somethingHappened" -static const char serviceName[] = "com.trolltech.autotests.qmyserver"; -static const char objectPath[] = "/com/trolltech/qmyserver"; +static const char serviceName[] = "org.qtproject.autotests.qmyserver"; +static const char objectPath[] = "/org/qtproject/qmyserver"; static const char *interfaceName = serviceName; int MyObject::callCount = 0; @@ -63,9 +63,9 @@ QVariantList MyObject::callArgs; class MyObjectUnknownType: public QObject { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.MyObject") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.QtDBus.MyObject") Q_CLASSINFO("D-Bus Introspection", "" -" \n" +" \n" " \n" " \n" " \n" @@ -381,7 +381,7 @@ void tst_QDBusInterface::introspectUnknownTypes() MyObjectUnknownType obj; con.registerObject("/unknownTypes", &obj, QDBusConnection::ExportAllContents); QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/unknownTypes"), - "com.trolltech.QtDBus.MyObjectUnknownTypes"); + "org.qtproject.QtDBus.MyObjectUnknownTypes"); const QMetaObject *mo = iface.metaObject(); QVERIFY(mo->indexOfMethod("regularMethod()") != -1); // this is the control @@ -414,7 +414,7 @@ public: if (path == "/some/path/superNode") return "zitroneneis"; if (path == "/some/path/superNode/foo") - return " \n" + return " \n" " \n" " \n" ; return QString(); @@ -460,7 +460,7 @@ void tst_QDBusInterface::introspectVirtualObject() QDBusMessage message2 = QDBusMessage::createMethodCall(con.baseService(), path + "/foo", "org.freedesktop.DBus.Introspectable", "Introspect"); QDBusMessage reply2 = con.call(message2, QDBus::Block, 5000); QVERIFY(reply2.arguments().at(0).toString().contains( - QRegExp(".*" + QRegExp(".*" ".*\n" ".*.* -static const char serviceName[] = "com.trolltech.autotests.qpong"; -static const char objectPath[] = "/com/trolltech/qpong"; +static const char serviceName[] = "org.qtproject.autotests.qpong"; +static const char objectPath[] = "/org/qtproject/qpong"; static const char *interfaceName = serviceName; class tst_QDBusMarshall: public QObject @@ -925,7 +925,7 @@ void tst_QDBusMarshall::sendCallErrors_data() // this error comes from the bus server QTest::newRow("empty-service") << "" << objectPath << interfaceName << "ping" << QVariantList() << "org.freedesktop.DBus.Error.UnknownMethod" - << "Method \"ping\" with signature \"\" on interface \"com.trolltech.autotests.qpong\" doesn't exist\n" << (const char*)0; + << "Method \"ping\" with signature \"\" on interface \"org.qtproject.autotests.qpong\" doesn't exist\n" << (const char*)0; QTest::newRow("invalid-service") << "this isn't valid" << objectPath << interfaceName << "ping" << QVariantList() << "org.qtproject.QtDBus.Error.InvalidService" diff --git a/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp b/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp index a523a66bdd..b459fdc1b1 100644 --- a/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp +++ b/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp @@ -297,7 +297,7 @@ signals: }; const char TypesTest16_xml[] = "" - ""; + ""; class TypesTest17: public QObject { @@ -308,7 +308,7 @@ signals: }; const char TypesTest17_xml[] = "" - ""; + ""; class TypesTest18: public QObject { @@ -319,7 +319,7 @@ signals: }; const char TypesTest18_xml[] = "" - ""; + ""; class TypesTest19: public QObject { @@ -330,7 +330,7 @@ signals: }; const char TypesTest19_xml[] = "" - ""; + ""; class TypesTest20: public QObject { @@ -340,9 +340,13 @@ signals: void signal(QVariantMap); }; const char TypesTest20_xml[] = + "" + ""; +const char TypesTest20_oldxml[] = "" ""; + void tst_QDBusMetaObject::types_data() { QTest::addColumn("metaobject"); @@ -368,6 +372,7 @@ void tst_QDBusMetaObject::types_data() QTest::newRow("Struct4") << &TypesTest18::staticMetaObject << QString(TypesTest18_xml); QTest::newRow("QVariantList") << &TypesTest19::staticMetaObject << QString(TypesTest19_xml); QTest::newRow("QVariantMap") << &TypesTest20::staticMetaObject << QString(TypesTest20_xml); + QTest::newRow("QVariantMap-oldannotation") << &TypesTest20::staticMetaObject << QString(TypesTest20_oldxml); } void tst_QDBusMetaObject::types() @@ -671,7 +676,7 @@ public: }; const char PropertyTest4_xml[] = "" - "" + "" ""; class PropertyTest_b: public QObject diff --git a/tests/auto/dbus/qdbuspendingcall/tst_qdbuspendingcall.cpp b/tests/auto/dbus/qdbuspendingcall/tst_qdbuspendingcall.cpp index 60a8061ae4..eca352456f 100644 --- a/tests/auto/dbus/qdbuspendingcall/tst_qdbuspendingcall.cpp +++ b/tests/auto/dbus/qdbuspendingcall/tst_qdbuspendingcall.cpp @@ -46,12 +46,12 @@ #include #include -#define TEST_INTERFACE_NAME "com.trolltech.QtDBus.MyObject" +#define TEST_INTERFACE_NAME "org.qtproject.QtDBus.MyObject" class MyObject : public QDBusAbstractAdaptor { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.MyObject") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.QtDBus.MyObject") public: MyObject(QObject* parent =0) diff --git a/tests/auto/dbus/qdbuspendingreply/tst_qdbuspendingreply.cpp b/tests/auto/dbus/qdbuspendingreply/tst_qdbuspendingreply.cpp index 865c9a86ff..6d5bdf7ba6 100644 --- a/tests/auto/dbus/qdbuspendingreply/tst_qdbuspendingreply.cpp +++ b/tests/auto/dbus/qdbuspendingreply/tst_qdbuspendingreply.cpp @@ -106,7 +106,7 @@ private slots: class TypesInterface: public QDBusAbstractAdaptor { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.Qt.Autotests.TypesInterface") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.Qt.Autotests.TypesInterface") public: TypesInterface(QObject *parent) : QDBusAbstractAdaptor(parent) @@ -241,7 +241,7 @@ tst_QDBusPendingReply::tst_QDBusPendingReply() QDBusConnection::sessionBus().registerObject("/", this); iface = new QDBusInterface(QDBusConnection::sessionBus().baseService(), "/", - "com.trolltech.Qt.Autotests.TypesInterface", + "org.qtproject.Qt.Autotests.TypesInterface", QDBusConnection::sessionBus(), this); } diff --git a/tests/auto/dbus/qdbusreply/tst_qdbusreply.cpp b/tests/auto/dbus/qdbusreply/tst_qdbusreply.cpp index b6026f215b..a5ccd24735 100644 --- a/tests/auto/dbus/qdbusreply/tst_qdbusreply.cpp +++ b/tests/auto/dbus/qdbusreply/tst_qdbusreply.cpp @@ -102,7 +102,7 @@ private slots: class TypesInterface: public QDBusAbstractAdaptor { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.Qt.Autotests.TypesInterface") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.Qt.Autotests.TypesInterface") public: TypesInterface(QObject *parent) : QDBusAbstractAdaptor(parent) @@ -226,7 +226,7 @@ tst_QDBusReply::tst_QDBusReply() QDBusConnection::sessionBus().registerObject("/", this); iface = new QDBusInterface(QDBusConnection::sessionBus().baseService(), "/", - "com.trolltech.Qt.Autotests.TypesInterface", + "org.qtproject.Qt.Autotests.TypesInterface", QDBusConnection::sessionBus(), this); } -- cgit v1.2.3 From 77fd8fd9977b987c99acba6417ac369a9975d989 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 16 Apr 2012 01:17:00 +0200 Subject: Show the type and address of QObjects in debug output. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I9f44ab80a6fb763adc9cbaf47de8e1b97212332d Reviewed-by: Jędrzej Nowacki --- tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 1e382dde3a..6a6460d17b 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -3666,6 +3666,11 @@ protected: // Chars insert '\0' into the qdebug stream, it is not possible to find a real string length return; } + if (QMetaType::typeFlags(currentId) & QMetaType::PointerToQObject) { + QByteArray currentName = QMetaType::typeName(currentId); + currentName.chop(1); + ok &= (msg.contains(", " + currentName) || msg.contains(", 0x0")); + } ok &= msg.endsWith(") "); QVERIFY2(ok, (QString::fromLatin1("Message is not correctly finished: '") + msg + '\'').toLatin1().constData()); @@ -3694,6 +3699,7 @@ void tst_QVariant::debugStream_data() QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId(), 0) << qMetaTypeId(); QTest::newRow("MyClass") << QVariant(qMetaTypeId(), 0) << qMetaTypeId(); QTest::newRow("InvalidVariant") << QVariant() << int(QMetaType::UnknownType); + QTest::newRow("CustomQObject") << QVariant::fromValue(this) << qMetaTypeId(); } void tst_QVariant::debugStream() -- cgit v1.2.3 From da7880b0f032e67e3a2b24ec9bb47259ffd671da Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 15 Apr 2012 23:03:40 +0200 Subject: Update parent indexes first with changePersistentIndex. Otherwise, the order of updating of the indexes will cause inconsistent results because it will rely on ordering within a QHash (which is indeterminate). Task-number: QTBUG-25325 Change-Id: I7d99578c8ee2954b8562dc5aff7dc32e74d41fb5 Reviewed-by: Lars Knoll --- .../itemmodels/qabstractitemmodel/qabstractitemmodel.pro | 1 - tests/auto/other/modeltest/dynamictreemodel.cpp | 12 +++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro b/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro index 8bfe6628da..9e59251379 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro @@ -6,4 +6,3 @@ mtdir = ../../../other/modeltest INCLUDEPATH += $$PWD/$${mtdir} SOURCES = tst_qabstractitemmodel.cpp $${mtdir}/dynamictreemodel.cpp $${mtdir}/modeltest.cpp HEADERS = $${mtdir}/dynamictreemodel.h $${mtdir}/modeltest.h -CONFIG += insignificant_test # QTBUG-25325 diff --git a/tests/auto/other/modeltest/dynamictreemodel.cpp b/tests/auto/other/modeltest/dynamictreemodel.cpp index 325fc19db2..ab783d0ba2 100644 --- a/tests/auto/other/modeltest/dynamictreemodel.cpp +++ b/tests/auto/other/modeltest/dynamictreemodel.cpp @@ -372,7 +372,17 @@ void ModelChangeChildrenLayoutsCommand::doCommand() } } - foreach (const QModelIndex &idx, m_model->persistentIndexList()) { + // If we're changing one of the parent indexes, we need to ensure that we do that before + // changing any children of that parent. The reason is that we're keeping parent1 and parent2 + // around as QPersistentModelIndex instances, and we query idx.parent() in the loop. + QModelIndexList persistent = m_model->persistentIndexList(); + foreach (const QModelIndex &parent, parents) { + int idx = persistent.indexOf(parent); + if (idx != -1) + persistent.move(idx, 0); + } + + foreach (const QModelIndex &idx, persistent) { if (idx.parent() == parent1) { if (idx.row() == rowSize1 - 1) { m_model->changePersistentIndex(idx, m_model->createIndex(0, idx.column(), idx.internalPointer())); -- cgit v1.2.3 From 9b06be8646b48efedd90568d7481bebfd7ba90a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 16 Apr 2012 16:01:50 +0200 Subject: Fix tst_qtracebench benchmark. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Default QDataStream version was changed in Qt5, but the test tried to load an old dumped file. Change-Id: I49c06c232ec8a27f33c9da345bae4e03cd0c56fb Reviewed-by: Samuel Rødal --- tests/benchmarks/gui/painting/qtracebench/tst_qtracebench.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/benchmarks/gui/painting/qtracebench/tst_qtracebench.cpp b/tests/benchmarks/gui/painting/qtracebench/tst_qtracebench.cpp index 72e2248850..a040a540ed 100644 --- a/tests/benchmarks/gui/painting/qtracebench/tst_qtracebench.cpp +++ b/tests/benchmarks/gui/painting/qtracebench/tst_qtracebench.cpp @@ -179,6 +179,7 @@ ReplayWidget::ReplayWidget(const QString &filename_) } QDataStream in(&file); + in.setVersion(QDataStream::Qt_4_7); char *data; uint size; -- cgit v1.2.3 From 7e0beba891cb963a1d535bd45b0be78b43b8d07f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 16 Apr 2012 10:30:47 +0200 Subject: Skip tests toolbar-dialog/widget_window. To enable merging the api_changes branch. Task-number: QTBUG-25331 Change-Id: I90d32ca0bd96eed62bae5f01316d6360a3b435c8 Reviewed-by: Sergio Ahumada --- tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp | 4 ++++ tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp | 3 +++ 2 files changed, 7 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index e46d905022..0e19e88793 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -387,6 +387,9 @@ void tst_QDialog::toolDialogPosition() { #if defined(Q_OS_WINCE) QSKIP("No real support for Qt::Tool on WinCE"); +#endif +#ifdef Q_OS_WIN + QSKIP("QTBUG-25331 - positioning failure"); #endif QDialog dialog(0, Qt::Tool); dialog.move(QPoint(100,100)); @@ -394,6 +397,7 @@ void tst_QDialog::toolDialogPosition() dialog.show(); const QPoint afterShowPosition = dialog.pos(); QCOMPARE(afterShowPosition, beforeShowPosition); + } class Dialog : public QDialog diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index 78d9d36bc9..be33381620 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -91,6 +91,9 @@ void tst_QWidget_window::cleanupTestCase() void tst_QWidget_window::tst_move_show() { +#ifdef Q_OS_WIN + QSKIP("QTBUG-25331"); +#endif QWidget w; w.move(100, 100); w.show(); -- cgit v1.2.3