diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2012-04-17 12:58:41 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@nokia.com> | 2012-04-17 12:58:52 +0200 |
commit | 64255ef6502b1144f7b0aa4b2bf62803e0d4788b (patch) | |
tree | 29bf116bfda2ccf61057115690d14f85cc9b085b /tests | |
parent | 4a9fb41a7947d0bb7a47a9625603a436df288b24 (diff) | |
parent | 7e0beba891cb963a1d535bd45b0be78b43b8d07f (diff) |
Merge remote-tracking branch 'origin/api_changes'
Change-Id: I964b0a6f5c38351fdfafb8a2a128a349ff8c89d1
Diffstat (limited to 'tests')
135 files changed, 8863 insertions, 2879 deletions
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<int> vector; @@ -1523,7 +1520,6 @@ void tst_QtConcurrentFilter::stlContainers() QCOMPARE(list2.size(), (std::list<int>::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 <qiterator.h> -#ifndef QT_NO_STL namespace std { template <> struct iterator_traits<TestIterator> @@ -79,7 +78,6 @@ int distance(TestIterator &a, TestIterator &b) } } -#endif #include <qtconcurrentiteratekernel.h> #include <QtTest/QtTest> @@ -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<TestIterator, int> { @@ -292,8 +285,6 @@ public: } }; -// Missing stl iterators prevent correct summation. -#ifndef QT_NO_STL void tst_QtConcurrentIterateKernel::multipleResults() { QFuture<int> 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<int> vector; @@ -2322,7 +2319,6 @@ void tst_QtConcurrentMap::stlContainers() QtConcurrent::blockingMap(list, multiplyBy2Immutable); } -#endif InstanceCounter ic_fn(const InstanceCounter & ic) { diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp index c0ed152c32..e513b2cea2 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<QByteArray>("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() @@ -344,6 +264,9 @@ void tst_Utf8::nonCharacters_data() 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 <QtTest/QtTest> + +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)); +} 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/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 <class T> 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<type>, alignment); \ + \ + /* Some internal sanity validation, just for fun */ \ + TEST_AlignOf_impl(AlignmentInStruct<type [5]>, alignment); \ + TEST_AlignOf_impl(AlignmentInStruct<type &>, Q_ALIGNOF(void *)); \ + TEST_AlignOf_impl(AlignmentInStruct<type (&) [5]>, \ + Q_ALIGNOF(void *)); \ + TEST_AlignOf_RValueRef(AlignmentInStruct<type &&>, \ + 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<qint64>, 4); +#else + TEST_AlignOf_impl(AlignmentInStruct<qint64>, 8); +#endif + + TEST_AlignOf_impl(AlignmentInStruct<quint64>, Q_ALIGNOF(AlignmentInStruct<qint64>)); + TEST_AlignOf_impl(AlignmentInStruct<double>, Q_ALIGNOF(AlignmentInStruct<qint64>)); + + // 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<qint64>)); +#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/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 <QtTest/QtTest> +#include <QtCore/qendian.h> + + +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<type ## size>( \ + 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" 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/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/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..bad18fabef --- /dev/null +++ b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp @@ -0,0 +1,503 @@ +/**************************************************************************** +** +** 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 <QtCore/QString> +#include <QtTest/QtTest> +#include <QtCore/private/qipaddress_p.h> + +#ifdef __GLIBC__ +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#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 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() +{ + QTest::addColumn<QString>("data"); + QTest::addColumn<QIPAddressUtils::IPv4Address>("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<QString>("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<QIPAddressUtils::IPv4Address>("ip"); + QTest::addColumn<QString>("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); +} + +void tst_QIpAddress::parseIp6_data() +{ + qRegisterMetaType<Ip6>(); + QTest::addColumn<QString>("address"); + QTest::addColumn<Ip6>("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<QString>("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<Ip6>(); + QTest::addColumn<Ip6>("ip"); + QTest::addColumn<QString>("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" diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index b15d5fca2c..29f6fe9da4 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::GenericDataLocation), dataDir); + const QStringList gdDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); + QCOMPARE(gdDirs, QStringList() << dataDir << m_globalAppDir); + + // GenericCacheLocation + const QString cacheDir = qttestDir + QLatin1String("/cache"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation), cacheDir); + const QStringList cacheDirs = QStandardPaths::standardLocations(QStandardPaths::GenericCacheLocation); + 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<QStandardPaths::StandardLocation, QString> 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 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 a74d817b8a..f9fbb8cba8 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. @@ -39,37 +40,18 @@ ** ****************************************************************************/ +#define QT_DEPRECATED +#define QT_DISABLE_DEPRECATED_BEFORE 0 +#include <qurl.h> #include <QtTest/QtTest> #include <QtCore/QDebug> #include <qcoreapplication.h> #include <qfileinfo.h> -#include <qurl.h> #include <qtextcodec.h> #include <qmap.h> -#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 @@ -85,12 +67,12 @@ private slots: void unc(); void assignment(); void comparison(); + void comparison2_data(); + void comparison2(); void copying(); void setUrl(); void i18n_data(); void i18n(); - void punycode_data(); - void punycode(); void resolving_data(); void resolving(); void toString_data(); @@ -136,34 +118,20 @@ private slots: void toPercentEncoding(); 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(); void schemeValidator(); void invalidSchemeValidator(); + void strictParser_data(); + void strictParser(); void tolerantParser(); void correctEncodedMistakes_data(); 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(); @@ -180,7 +148,6 @@ private slots: void toEncoded(); void setAuthority_data(); void setAuthority(); - void errorString(); void clear(); void resolvedWithAbsoluteSchemes() const; void resolvedWithAbsoluteSchemes_data() const; @@ -192,8 +159,9 @@ private slots: void toEncodedNotUsingUninitializedPath(); void emptyAuthorityRemovesExistingAuthority(); void acceptEmptyAuthoritySegments(); - void removeAllEncodedQueryItems_data(); - void removeAllEncodedQueryItems(); + void lowercasesScheme(); + void componentEncodings_data(); + void componentEncodings(); }; // Testing get/set functions @@ -262,9 +230,18 @@ 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.path(), QString::fromLatin1("/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() @@ -302,7 +279,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("", "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 // treated case-insensitively @@ -311,13 +289,55 @@ void tst_QUrl::comparison() QUrl url6; url6.setEncodedQuery("a=%2A"); QVERIFY(url5 == url6); +} + +void tst_QUrl::comparison2_data() +{ + QTest::addColumn<QUrl>("url1"); + QTest::addColumn<QUrl>("url2"); + QTest::addColumn<int>("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); - // 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); + // 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() @@ -352,6 +372,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 +388,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")); @@ -380,11 +402,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")); } { @@ -451,15 +473,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")); } @@ -550,6 +564,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")); } { @@ -559,20 +574,24 @@ void tst_QUrl::setUrl() 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()); + 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")); } { @@ -630,7 +649,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 @@ -789,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"); @@ -907,20 +937,26 @@ void tst_QUrl::toString_constructed_data() QTest::addColumn<QString>("fragment"); QTest::addColumn<QString>("asString"); QTest::addColumn<QByteArray>("asEncoded"); + QTest::addColumn<uint>("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() @@ -935,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()) @@ -955,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); } @@ -1001,6 +1040,7 @@ void tst_QUrl::toLocalFile() QUrl url(theUrl); QCOMPARE(url.toLocalFile(), theFile); + QCOMPARE(url.isLocalFile(), !theFile.isEmpty()); } void tst_QUrl::fromLocalFile_data() @@ -1201,7 +1241,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() @@ -1449,8 +1489,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"); @@ -1481,40 +1519,58 @@ void tst_QUrl::ipv6_data() { QTest::addColumn<QString>("ipv6Auth"); QTest::addColumn<bool>("isValid"); + QTest::addColumn<QString>("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() { @@ -1547,26 +1603,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<QString>("original"); - QTest::addColumn<QByteArray>("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<QString>("url"); @@ -1580,7 +1616,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 } @@ -1593,93 +1629,6 @@ void tst_QUrl::isRelative() QCOMPARE(QUrl(url).isRelative(), trueFalse); } -void tst_QUrl::setQueryItems() -{ - QUrl url; - - QList<QPair<QString, QString> > 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::queryItems() -{ - QUrl url; - QVERIFY(!url.hasQuery()); - - QList<QPair<QString, QString> > 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<QPair<QString, QString> > 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<QString>("url"); @@ -1709,27 +1658,6 @@ void tst_QUrl::hasQuery() QCOMPARE(qurl.encodedQuery().isNull(), !trueFalse); } -void tst_QUrl::hasQueryItem_data() -{ - QTest::addColumn<QString>("url"); - QTest::addColumn<QString>("item"); - QTest::addColumn<bool>("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/")); @@ -1754,6 +1682,7 @@ void tst_QUrl::isValid() QUrl url = QUrl::fromEncoded("http://strange<username>@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"); @@ -1765,7 +1694,7 @@ void tst_QUrl::isValid() QVERIFY(url.isValid()); url.setAuthority("strange;hostname"); QVERIFY(!url.isValid()); - QVERIFY(url.errorString().contains("invalid hostname")); + QVERIFY(url.errorString().contains("Hostname contains invalid characters")); } { @@ -1778,7 +1707,8 @@ void tst_QUrl::isValid() QVERIFY(url.isValid()); url.setHost("stuff;1"); QVERIFY(!url.isValid()); - QVERIFY(url.errorString().contains("invalid hostname")); + QVERIFY2(url.errorString().contains("Hostname contains invalid characters"), + qPrintable(url.errorString())); } } @@ -1822,6 +1752,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); } @@ -1829,27 +1761,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()); } { @@ -1858,6 +1789,55 @@ void tst_QUrl::invalidSchemeValidator() } } +void tst_QUrl::strictParser_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<QString>("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<user_name>@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>" << "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() { { @@ -1865,6 +1845,7 @@ void tst_QUrl::tolerantParser() 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()); } @@ -1886,58 +1867,90 @@ 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.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.toEncoded(), QByteArray("//[::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.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")); + 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.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]?[]")); + 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()); 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.toEncoded(), QByteArray("//[::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.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")); + 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.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]?[]")); + 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; }")); } { @@ -1962,16 +1975,15 @@ void tst_QUrl::correctEncodedMistakes_data() QTest::addColumn<QByteArray>("encodedUrl"); QTest::addColumn<bool>("result"); QTest::addColumn<QString>("toDecoded"); - QTest::addColumn<QByteArray>("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() @@ -1979,14 +1991,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); } } @@ -1995,16 +2004,14 @@ void tst_QUrl::correctDecodedMistakes_data() QTest::addColumn<QString>("decodedUrl"); QTest::addColumn<bool>("result"); QTest::addColumn<QString>("toDecoded"); - QTest::addColumn<QByteArray>("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() @@ -2012,671 +2019,14 @@ 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); - } -} - -void tst_QUrl::idna_testsuite_data() -{ - QTest::addColumn<int>("numchars"); - QTest::addColumn<ushortarray>("unicode"); - QTest::addColumn<QByteArray>("punycode"); - QTest::addColumn<int>("allowunassigned"); - QTest::addColumn<int>("usestd3asciirules"); - QTest::addColumn<int>("toasciirc"); - QTest::addColumn<int>("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<QString>("in"); - QTest::addColumn<QString>("out"); - QTest::addColumn<QString>("profile"); - QTest::addColumn<int>("flags"); - QTest::addColumn<int>("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 -extern void qt_nameprep(QString *source, int from); -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<QString>("in"); - QTest::addColumn<QString>("out"); - QTest::addColumn<QString>("profile"); - QTest::addColumn<int>("flags"); - QTest::addColumn<int>("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; + QCOMPARE(url.toString(), toDecoded); } } -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<QString>("in"); - QTest::addColumn<QString>("toace"); - QTest::addColumn<QString>("fromace"); - QTest::addColumn<QString>("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<QString>("source"); - QTest::addColumn<bool>("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<QString>("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<QString>("tld"); @@ -2784,13 +2134,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"))); @@ -2862,8 +2212,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"); @@ -2903,10 +2253,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"); @@ -2920,12 +2270,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"); @@ -2948,16 +2304,19 @@ 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); QCOMPARE(url.port(), -1); + QVERIFY(url.errorString().contains("out of range")); } } @@ -3003,19 +2362,6 @@ void tst_QUrl::setAuthority() QCOMPARE(u.toString(), url); } -void tst_QUrl::errorString() -{ - QUrl u = QUrl::fromEncoded("http://strange<username>@bad_hostname/", QUrl::StrictMode); - QVERIFY(!u.isValid()); - QString errorString = "Invalid URL \"http://strange<username>@bad_hostname/\": " - "error at position 14: expected end of URL, but found '<'"; - QCOMPARE(u.errorString(), errorString); - - QUrl v; - errorString = "Invalid URL \"\": "; - QCOMPARE(v.errorString(), errorString); -} - void tst_QUrl::clear() { QUrl url("a"); @@ -3044,7 +2390,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"; @@ -3119,7 +2465,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; @@ -3138,6 +2484,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() @@ -3275,27 +2625,254 @@ void tst_QUrl::effectiveTLDs() QCOMPARE(domain.topLevelDomain(), TLD); } -void tst_QUrl::removeAllEncodedQueryItems_data() +void tst_QUrl::lowercasesScheme() { - QTest::addColumn<QUrl>("url"); - QTest::addColumn<QByteArray>("key"); - QTest::addColumn<QUrl>("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"); + QUrl url; + url.setScheme("HELLO"); + QCOMPARE(url.scheme(), QString("hello")); } -void tst_QUrl::removeAllEncodedQueryItems() +void tst_QUrl::componentEncodings_data() +{ + QTest::addColumn<QUrl>("url"); + QTest::addColumn<int>("encoding"); + QTest::addColumn<QString>("userName"); + QTest::addColumn<QString>("password"); + QTest::addColumn<QString>("userInfo"); + QTest::addColumn<QString>("host"); + QTest::addColumn<QString>("authority"); + QTest::addColumn<QString>("path"); + QTest::addColumn<QString>("query"); + QTest::addColumn<QString>("fragment"); + QTest::addColumn<QString>("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::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::MostDecoded) + << "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::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::MostDecoded) + << 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 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/?#@]:[/?#@]" + << "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::FullyEncoded) + << "" << ":" << "::" + << "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::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() + << "?%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D"; + + // reserved characters: '"' / "<" / ">" / "^" / "\" / "{" / "|" "}" + // the RFC does not allow them undecoded anywhere, but we do + 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" + << "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-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::DecodeReserved) + << "\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}:\"<>^\\{|}" + << "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##"; + + // 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() { QFETCH(QUrl, url); - QFETCH(QByteArray, key); - QFETCH(QUrl, result); - url.removeAllEncodedQueryItems(key); - QCOMPARE(url, result); + 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) 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..3ac2b46964 --- /dev/null +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -0,0 +1,982 @@ +/**************************************************************************** +** +** 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. +** +** $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 <QtCore/QUrl> +#include <QtTest/QtTest> + +#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); +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 +#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) +Q_DECLARE_METATYPE(QUrl::ComponentFormattingOptions) + +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(); + + // percent-encoding internals + void correctEncodedMistakes_data(); + void correctEncodedMistakes(); + void encodingRecode_data(); + void encodingRecode(); + void encodingRecodeInvalidUtf8_data(); + void encodingRecodeInvalidUtf8(); +}; +#include "tst_qurlinternal.moc" + +void tst_QUrlInternal::idna_testsuite_data() +{ + QTest::addColumn<int>("numchars"); + QTest::addColumn<ushortarray>("unicode"); + QTest::addColumn<QByteArray>("punycode"); + QTest::addColumn<int>("allowunassigned"); + QTest::addColumn<int>("usestd3asciirules"); + QTest::addColumn<int>("toasciirc"); + QTest::addColumn<int>("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<QString>("in"); + QTest::addColumn<QString>("out"); + QTest::addColumn<QString>("profile"); + QTest::addColumn<int>("flags"); + QTest::addColumn<int>("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<QString>("in"); + QTest::addColumn<QString>("out"); + QTest::addColumn<QString>("profile"); + QTest::addColumn<int>("flags"); + QTest::addColumn<int>("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<QString>("in"); + QTest::addColumn<QString>("toace"); + QTest::addColumn<QString>("fromace"); + QTest::addColumn<QString>("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<QString>("source"); + QTest::addColumn<bool>("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<QString>("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()); +} + +void tst_QUrlInternal::correctEncodedMistakes_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<QString>("expected"); + + 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"; + + // 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() +{ + QFETCH(QString, input); + QFETCH(QString, expected); + + // 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(), 0)) + output += input; + QCOMPARE(output, expected); +} + +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::MostDecoded) << decoded; + QTest::newRow(QByteArray("encode-") + name) << decoded << QUrl::ComponentFormattingOptions(QUrl::FullyEncoded) << encoded; +} + +void tst_QUrlInternal::encodingRecode_data() +{ + typedef QUrl::ComponentFormattingOptions F; + QTest::addColumn<QString>("input"); + QTest::addColumn<F>("encodingMode"); + QTest::addColumn<QString>("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::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::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::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 + 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-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 + 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::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() +{ + QFETCH(QString, input); + QFETCH(QString, expected); + QFETCH(QUrl::ComponentFormattingOptions, 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); +} + +void tst_QUrlInternal::encodingRecodeInvalidUtf8_data() +{ + QTest::addColumn<QByteArray>("utf8"); + QTest::addColumn<QString>("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-6") << QByteArray("\xE0\xA2\x33"); +} + +void tst_QUrlInternal::encodingRecodeInvalidUtf8() +{ + QFETCH(QByteArray, utf8); + QString input = utf8.toPercentEncoding(); + + // 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::MostDecoded)) + output += input; + QCOMPARE(output, QTest::currentDataTag() + input); + + // this is just control + 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) 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..7148a71153 --- /dev/null +++ b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp @@ -0,0 +1,818 @@ +/**************************************************************************** +** +** 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 <QtCore/QUrlQuery> +#include <QtTest/QtTest> + +typedef QList<QPair<QString, QString> > QueryItems; +Q_DECLARE_METATYPE(QueryItems) +Q_DECLARE_METATYPE(QUrl::ComponentFormattingOptions) + +class tst_QUrlQuery : public QObject +{ + Q_OBJECT + +public: + tst_QUrlQuery() + { + qRegisterMetaType<QueryItems>(); + } + +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(); + + // 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) +{ + QString result; + if (key.isNull()) + result += "null -> "; + else + result += '"' % key % "\" -> "; + if (value.isNull()) + result += "null"; + else + result += '"' % value % '"'; + return result; +} + +static QString prettyPair(QList<QPair<QString, QString> >::const_iterator it) +{ + return prettyElement(it->first, it->second); +} + +template <typename T> +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<QPair<QString, QString> > &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<QString, QString> &pair) +{ + // items is already a copy + items.append(pair); + return items; +} + +inline QueryItems operator+(const QPair<QString, QString> &pair, QueryItems items) +{ + // items is already a copy + items.prepend(pair); + return items; +} + +inline QPair<QString, QString> qItem(const QString &first, const QString &second) +{ + return qMakePair(first, second); +} + +inline QPair<QString, QString> qItem(const char *first, const QString &second) +{ + return qMakePair(QString::fromUtf8(first), second); +} + +inline QPair<QString, QString> qItem(const char *first, const char *second) +{ + return qMakePair(QString::fromUtf8(first), QString::fromUtf8(second)); +} + +inline QPair<QString, QString> 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(')'))); + + QList<QPair<QString, QString> > 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() +{ + 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<QPair<QString, QString> > 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<QPair<QString, QString> > 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<QPair<QString, QString> > 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<QPair<QString, QString> > 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<QueryItems>("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<QString>("queryString"); + QTest::addColumn<QueryItems>("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<QString, QString> 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<QString, QString> 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<QString>("queryString"); + QTest::addColumn<QueryItems>("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<QString>("queryString"); + QTest::addColumn<QString>("key"); + QTest::addColumn<QString>("value"); + QTest::addColumn<QUrl::ComponentFormattingOptions>("encoding"); + QTest::addColumn<QString>("expectedQuery"); + QTest::addColumn<QString>("expectedKey"); + QTest::addColumn<QString>("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"; + + // 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::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" << "=" << "="; + 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) + << "#=#" << "#" << "#"; + QTest::newRow("decode-hash") << "%23=%23" << "%23" << "%23" << F(QUrl::PrettyDecoded) + << "#=#" << "#" << "#"; + + 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::MostDecoded) + << "%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::MostDecoded), 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)")); + } +} + +void tst_QUrlQuery::old_queryItems() +{ + // test imported from old tst_qurl.cpp + QUrlQuery url; + + QList<QPair<QString, QString> > 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<QPair<QString, QString> > 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<QString>("url"); + QTest::addColumn<QString>("item"); + QTest::addColumn<bool>("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<QUrl>("url"); + QTest::addColumn<QByteArray>("key"); + QTest::addColumn<QUrl>("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" 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); } } diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index f4aefb2726..e8f6c29a94 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -617,6 +617,7 @@ public: bool unregisterTimer(int ) { return false; } bool unregisterTimers(QObject *) { return false; } QList<TimerInfo> registeredTimers(QObject *) const { return QList<TimerInfo>(); } + int remainingTime(int) { return 0; } void wakeUp() {} void interrupt() {} void flush() {} diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 1651d00738..55997a3ca0 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); @@ -196,7 +197,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignal") << QByteArray("voidSignal()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>()) << (QList<QByteArray>()) << (QList<QByteArray>()) @@ -205,7 +206,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokable") << QByteArray("voidInvokable()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>()) << (QList<QByteArray>()) << (QList<QByteArray>()) @@ -214,7 +215,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlot") << QByteArray("voidSlot()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>()) << (QList<QByteArray>()) << (QList<QByteArray>()) @@ -223,16 +224,25 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject()") << QByteArray("MethodTestObject()") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList<int>()) << (QList<QByteArray>()) << (QList<QByteArray>()) << QMetaMethod::Public << QMetaMethod::Constructor; + QTest::newRow("voidSignalVoid") + << QByteArray("voidSignalVoid()") + << int(QMetaType::Void) << QByteArray("void") + << QList<int>() + << QList<QByteArray>() + << QList<QByteArray>() + << QMetaMethod::Protected + << QMetaMethod::Signal; + QTest::newRow("voidSignalInt") << QByteArray("voidSignalInt(int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << int(QMetaType::Int)) << (QList<QByteArray>() << QByteArray("int")) << (QList<QByteArray>() << QByteArray("voidSignalIntArg")) @@ -241,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>() << int(QMetaType::Int)) << (QList<QByteArray>() << QByteArray("int")) << (QList<QByteArray>() << QByteArray("voidInvokableIntArg")) @@ -250,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>() << int(QMetaType::Int)) << (QList<QByteArray>() << QByteArray("int")) << (QList<QByteArray>() << QByteArray("voidSlotIntArg")) @@ -259,7 +269,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(int)") << QByteArray("MethodTestObject(int)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList<int>() << int(QMetaType::Int)) << (QList<QByteArray>() << QByteArray("int")) << (QList<QByteArray>() << QByteArray("constructorIntArg")) @@ -268,7 +278,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalQReal") << QByteArray("voidSignalQReal(qreal)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << qMetaTypeId<qreal>()) << (QList<QByteArray>() << QByteArray("qreal")) << (QList<QByteArray>() << QByteArray("voidSignalQRealArg")) @@ -277,7 +287,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokableQReal") << QByteArray("voidInvokableQReal(qreal)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << qMetaTypeId<qreal>()) << (QList<QByteArray>() << QByteArray("qreal")) << (QList<QByteArray>() << QByteArray("voidInvokableQRealArg")) @@ -286,7 +296,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlotQReal") << QByteArray("voidSlotQReal(qreal)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << qMetaTypeId<qreal>()) << (QList<QByteArray>() << QByteArray("qreal")) << (QList<QByteArray>() << QByteArray("voidSlotQRealArg")) @@ -295,7 +305,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(qreal)") << QByteArray("MethodTestObject(qreal)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList<int>() << qMetaTypeId<qreal>()) << (QList<QByteArray>() << QByteArray("qreal")) << (QList<QByteArray>() << QByteArray("constructorQRealArg")) @@ -304,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>() << int(QMetaType::QString)) << (QList<QByteArray>() << QByteArray("QString")) << (QList<QByteArray>() << QByteArray("voidSignalQStringArg")) @@ -313,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>() << int(QMetaType::QString)) << (QList<QByteArray>() << QByteArray("QString")) << (QList<QByteArray>() << QByteArray("voidInvokableQStringArg")) @@ -322,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>() << int(QMetaType::QString)) << (QList<QByteArray>() << QByteArray("QString")) << (QList<QByteArray>() << QByteArray("voidSlotQStringArg")) @@ -331,7 +341,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(QString)") << QByteArray("MethodTestObject(QString)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList<int>() << int(QMetaType::QString)) << (QList<QByteArray>() << QByteArray("QString")) << (QList<QByteArray>() << QByteArray("constructorQStringArg")) @@ -340,7 +350,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalCustomType") << QByteArray("voidSignalCustomType(CustomType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << qMetaTypeId<CustomType>()) << (QList<QByteArray>() << QByteArray("CustomType")) << (QList<QByteArray>() << QByteArray("voidSignalCustomTypeArg")) @@ -349,7 +359,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokableCustomType") << QByteArray("voidInvokableCustomType(CustomType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << qMetaTypeId<CustomType>()) << (QList<QByteArray>() << QByteArray("CustomType")) << (QList<QByteArray>() << QByteArray("voidInvokableCustomTypeArg")) @@ -358,7 +368,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlotCustomType") << QByteArray("voidSlotCustomType(CustomType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << qMetaTypeId<CustomType>()) << (QList<QByteArray>() << QByteArray("CustomType")) << (QList<QByteArray>() << QByteArray("voidSlotCustomTypeArg")) @@ -367,7 +377,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(CustomType)") << QByteArray("MethodTestObject(CustomType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList<int>() << qMetaTypeId<CustomType>()) << (QList<QByteArray>() << QByteArray("CustomType")) << (QList<QByteArray>() << QByteArray("constructorCustomTypeArg")) @@ -376,7 +386,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSignalCustomUnregisteredType") << QByteArray("voidSignalCustomUnregisteredType(CustomUnregisteredType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << 0) << (QList<QByteArray>() << QByteArray("CustomUnregisteredType")) << (QList<QByteArray>() << QByteArray("voidSignalCustomUnregisteredTypeArg")) @@ -385,7 +395,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidInvokableCustomUnregisteredType") << QByteArray("voidInvokableCustomUnregisteredType(CustomUnregisteredType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << 0) << (QList<QByteArray>() << QByteArray("CustomUnregisteredType")) << (QList<QByteArray>() << QByteArray("voidInvokableCustomUnregisteredTypeArg")) @@ -394,7 +404,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("voidSlotCustomUnregisteredType") << QByteArray("voidSlotCustomUnregisteredType(CustomUnregisteredType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::Void) << QByteArray("void") << (QList<int>() << 0) << (QList<QByteArray>() << QByteArray("CustomUnregisteredType")) << (QList<QByteArray>() << QByteArray("voidSlotCustomUnregisteredTypeArg")) @@ -403,7 +413,7 @@ void tst_QMetaMethod::method_data() QTest::newRow("MethodTestObject(CustomUnregisteredType)") << QByteArray("MethodTestObject(CustomUnregisteredType)") - << int(QMetaType::Void) << QByteArray("") + << int(QMetaType::UnknownType) << QByteArray("") << (QList<int>() << 0) << (QList<QByteArray>() << QByteArray("CustomUnregisteredType")) << (QList<QByteArray>() << QByteArray("constructorCustomUnregisteredTypeArg")) @@ -536,7 +546,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; @@ -544,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>() << int(QMetaType::Bool) << int(QMetaType::Int)) << (QList<QByteArray>() << QByteArray("bool") << QByteArray("int")) << (QList<QByteArray>() << QByteArray("") << QByteArray("")) @@ -553,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>() << int(QMetaType::Bool) << int(QMetaType::Int)) << (QList<QByteArray>() << QByteArray("bool") << QByteArray("int")) << (QList<QByteArray>() << QByteArray("") << QByteArray("")) @@ -562,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>() << int(QMetaType::Bool) << int(QMetaType::Int)) << (QList<QByteArray>() << QByteArray("bool") << QByteArray("int")) << (QList<QByteArray>() << QByteArray("") << QByteArray("")) @@ -571,7 +581,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>() << int(QMetaType::Bool) << int(QMetaType::Int)) << (QList<QByteArray>() << QByteArray("bool") << QByteArray("int")) << (QList<QByteArray>() << QByteArray("") << QByteArray("")) @@ -603,15 +613,51 @@ void tst_QMetaMethod::method() QCOMPARE(method.methodType(), methodType); QCOMPARE(method.access(), access); - QCOMPARE(method.signature(), signature.constData()); + 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); + } - QCOMPARE(method.tag(), ""); + QByteArray computedName = signature.left(signature.indexOf('(')); + QCOMPARE(method.name(), computedName); - QCOMPARE(method.typeName(), returnTypeName.constData()); - QCOMPARE(QMetaType::type(method.typeName()), returnType); + 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)); + } - QCOMPARE(method.parameterTypes(), parameterTypeNames); + if (method.parameterTypes() != parameterTypeNames) { + // QMetaMethod should always produce semantically equivalent typenames + QList<QByteArray> 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<int> 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() diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 09fd0a7adb..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<a, a>, QList<b>) " << "void foo(QMap<a,a>,QList<b>)"; + QTest::newRow("void template args") << " void foo( Foo<void>, Bar<void> ) " + << "void foo(Foo<void>,Bar<void>)"; + QTest::newRow("void* template args") << " void foo( Foo<void*>, Bar<void *> ) " + << "void foo(Foo<void*>,Bar<void*>)"; QTest::newRow("rettype") << "QList<int, int> foo()" << "QList<int,int>foo()"; + QTest::newRow("rettype void template") << "Foo<void> foo()" << "Foo<void>foo()"; 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() @@ -978,25 +992,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 +1128,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..4b0a64ab54 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); @@ -228,7 +229,8 @@ 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<QByteArray>() << "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<QByteArray>() << "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<QByteArray>() << "QString" << "int"); QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "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<QByteArray>() << "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<QByteArray>() << "QString" << "int"); QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "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<QByteArray>() << "QString"); QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "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<QByteArray>() << "QString"); QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c"); QCOMPARE(method2.tag(), QByteArray("Q_FOO")); QVERIFY(method2.access() == QMetaMethod::Protected); @@ -346,7 +354,8 @@ 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<QByteArray>() << "QString" << "int"); QVERIFY(method1.parameterNames().isEmpty()); QVERIFY(method1.tag().isEmpty()); QVERIFY(method1.access() == QMetaMethod::Public); @@ -358,7 +367,8 @@ 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<QByteArray>() << "QString"); QVERIFY(method2.parameterNames().isEmpty()); QVERIFY(method2.tag().isEmpty()); QVERIFY(method2.access() == QMetaMethod::Public); @@ -383,7 +393,8 @@ 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<QByteArray>() << "QString" << "int"); QVERIFY(method1.parameterNames().isEmpty()); QVERIFY(method1.tag().isEmpty()); QVERIFY(method1.access() == QMetaMethod::Protected); @@ -395,7 +406,8 @@ 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<QByteArray>() << "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<QByteArray>() << "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<QByteArray>() << "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<QByteArray>() << "QString" << "int"); QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "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<QByteArray>() << "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<QByteArray>() << "QString" << "int"); QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "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<QByteArray>() << "QString"); QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "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<QByteArray>() << "QString"); QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "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); @@ -754,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() @@ -1161,12 +1181,15 @@ 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())) return false; + if (method1.parameterTypes() != method2.parameterTypes()) + return false; + if (method1.parameterNames() != method2.parameterNames()) return false; @@ -1391,7 +1414,7 @@ TestObject::TestObject(QObject *parent) TestObject::~TestObject() { - qFree(m_metaObject); + free(m_metaObject); } QMetaObject *TestObject::buildMetaObject() @@ -1466,7 +1489,7 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, if (_a[0]) *reinterpret_cast<QObject**>(_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 +1501,7 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, case 2: *reinterpret_cast<QVariantList(*)>(_a[0]) = _t->listInvokableQRealQString(*reinterpret_cast<qreal(*)>(_a[1]), *reinterpret_cast<QString(*)>(_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/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 09bd9fe445..4eb26928ac 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -97,16 +97,36 @@ private slots: void isEnum(); void registerStreamBuiltin(); void automaticTemplateRegistration(); + void saveAndLoadBuiltin_data(); + void saveAndLoadBuiltin(); + void saveAndLoadCustom(); }; 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<QString>::Defined), 1); QCOMPARE(int(QMetaTypeId2<Foo>::Defined), 0); QCOMPARE(int(QMetaTypeId2<void*>::Defined), 1); QCOMPARE(int(QMetaTypeId2<int*>::Defined), 0); + QVERIFY(QMetaTypeId2<CustomQObject*>::Defined); + QVERIFY(!QMetaTypeId2<CustomQObject>::Defined); + QVERIFY(!QMetaTypeId2<CustomNonQObject>::Defined); + QVERIFY(!QMetaTypeId2<CustomNonQObject*>::Defined); } struct Bar @@ -312,6 +332,7 @@ void tst_QMetaType::typeName_data() QTest::addColumn<QString>("aTypeName"); QT_FOR_EACH_STATIC_TYPE(TYPENAME_DATA) + QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << static_cast<const char*>(0); QTest::newRow("Whity<double>") << static_cast<QMetaType::Type>(::qMetaTypeId<Whity<double> >()) << QString::fromLatin1("Whity<double>"); QTest::newRow("Whity<int>") << static_cast<QMetaType::Type>(::qMetaTypeId<Whity<int> >()) << QString::fromLatin1("Whity<int>"); @@ -510,6 +531,46 @@ template<> struct TestValueFactory<QMetaType::QRegExp> { #endif } }; +template<> struct TestValueFactory<QMetaType::QRegularExpression> { + static QRegularExpression *create() + { +#ifndef QT_NO_REGEXP + return new QRegularExpression("abc.*def"); +#else + return 0; +#endif + } +}; +template<> struct TestValueFactory<QMetaType::QJsonValue> { + static QJsonValue *create() { return new QJsonValue(123.); } +}; +template<> struct TestValueFactory<QMetaType::QJsonObject> { + 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<QMetaType::QJsonArray> { + 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<QMetaType::QJsonDocument> { + static QJsonDocument *create() { + return new QJsonDocument( + QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }") + ); + } +}; template<> struct TestValueFactory<QMetaType::QVariant> { static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); } }; @@ -630,6 +691,8 @@ void tst_QMetaType::sizeOf_data() { QTest::addColumn<QMetaType::Type>("type"); QTest::addColumn<size_t>("size"); + + QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << size_t(0); #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ QTest::newRow(#RealType) << QMetaType::MetaTypeName << size_t(QTypeInfo<RealType>::sizeOf); FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW) @@ -805,41 +868,15 @@ void tst_QMetaType::construct_data() create_data(); } -#ifndef Q_ALIGNOF -template<uint N> -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<class T> -struct TypeAlignment -{ -#ifdef Q_ALIGNOF - enum { Value = Q_ALIGNOF(T) }; -#else - enum { Value = RoundToNextHighestPowerOfTwo<sizeof(T)>::Value }; -#endif -}; - template<int ID> static void testConstructHelper() { typedef typename MetaEnumToType<ID>::Type Type; QMetaType info(ID); int size = info.sizeOf(); - void *storage1 = qMallocAligned(size, TypeAlignment<Type>::Value); + void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type)); void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0); - void *storage2 = qMallocAligned(size, TypeAlignment<Type>::Value); + void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type)); void *actual2 = info.construct(storage2, /*copy=*/0); QCOMPARE(actual1, storage1); QCOMPARE(actual2, storage2); @@ -908,9 +945,9 @@ static void testConstructCopyHelper() QMetaType info(ID); int size = QMetaType::sizeOf(ID); QCOMPARE(info.sizeOf(), size); - void *storage1 = qMallocAligned(size, TypeAlignment<Type>::Value); + void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type)); void *actual1 = QMetaType::construct(ID, storage1, expected); - void *storage2 = qMallocAligned(size, TypeAlignment<Type>::Value); + void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type)); void *actual2 = info.construct(storage2, expected); QCOMPARE(actual1, storage1); QCOMPARE(actual2, storage2); @@ -1052,6 +1089,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() @@ -1291,6 +1329,133 @@ void tst_QMetaType::automaticTemplateRegistration() } } +template <typename T> +struct StreamingTraits +{ + enum { isStreamable = 1 }; // Streamable by default +}; + +// Non-streamable types + +#define DECLARE_NONSTREAMABLE(Type) \ + template<> struct StreamingTraits<Type> { enum { isStreamable = 0 }; }; + +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*) + +#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<int>("type"); + QTest::addColumn<bool>("isStreamable"); + +#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ + QTest::newRow(#RealType) << MetaTypeId << bool(StreamingTraits<RealType>::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<CustomStreamableType>(); + 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>("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; 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 2d180b88ea..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<Class&>&)\0" - "constTypeRefSignal(Template<const Class&>)\0" - "typeConstRefSignal(Template<const Class&>const&)\0" - "typeRefSlot(Template<Class&>&)\0" - "constTypeRefSlot(Template<const Class&>)\0" - "typeConstRefSlot(Template<const Class&>const&)\0" -}; - -const QMetaObject OldNormalizeObject::staticMetaObject = { - { &QObject::staticMetaObject, 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<void*>(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<Class&>(*)>(_a[1]))); break; - case 1: constTypeRefSignal((*reinterpret_cast< const Template<const Class&>(*)>(_a[1]))); break; - case 2: typeConstRefSignal((*reinterpret_cast< Template<const Class&>const(*)>(_a[1]))); break; - case 3: typeRefSlot((*reinterpret_cast< Template<Class&>(*)>(_a[1]))); break; - case 4: constTypeRefSlot((*reinterpret_cast< const Template<const Class&>(*)>(_a[1]))); break; - case 5: typeConstRefSlot((*reinterpret_cast< Template<const Class&>const(*)>(_a[1]))); break; - default: ; - } - _id -= 6; - } - return _id; -} - -// SIGNAL 0 -void OldNormalizeObject::typeRefSignal(Template<Class&> & _t1) -{ - void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) }; - QMetaObject::activate(this, &staticMetaObject, 0, _a); -} - -// SIGNAL 1 -void OldNormalizeObject::constTypeRefSignal(const Template<const Class&> & _t1) -{ - void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) }; - QMetaObject::activate(this, &staticMetaObject, 1, _a); -} - -// SIGNAL 2 -void OldNormalizeObject::typeConstRefSignal(Template<Class const&> const & _t1) -{ - void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) }; - QMetaObject::activate(this, &staticMetaObject, 2, _a); -} -QT_END_MOC_NAMESPACE diff --git a/tests/auto/corelib/kernel/qobject/test/test.pro b/tests/auto/corelib/kernel/qobject/test/test.pro index c08f910f8f..824223db15 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 f7f13e65ea..f429af7ce2 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -45,6 +45,7 @@ #include <qpointer.h> #include <qtimer.h> #include <qregexp.h> +#include <qregularexpression.h> #include <qmetaobject.h> #include <qvariant.h> #include <QTcpServer> @@ -164,6 +165,7 @@ signals: void signal3(); void signal4(); QT_MOC_COMPAT void signal5(); + void signal6(void); public slots: void aPublicSlot() { aPublicSlotCalled++; } @@ -656,6 +658,26 @@ void tst_QObject::findChildren() l = qFindChildren<QObject*>(&o, QRegExp("harry")); QCOMPARE(l.size(), 0); + l = o.findChildren<QObject*>(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<QObject*>(QRegularExpression("t.*")); + QCOMPARE(l.size(), 2); + QVERIFY(l.contains(&t1)); + QVERIFY(l.contains(&t121)); + tl = o.findChildren<QTimer*>(QRegularExpression(".*")); + QCOMPARE(tl.size(), 3); + QVERIFY(tl.contains(&t1)); + QVERIFY(tl.contains(&t121)); + tl = o.findChildren<QTimer*>(QRegularExpression("o.*")); + QCOMPARE(tl.size(), 0); + l = o.findChildren<QObject*>(QRegularExpression("harry")); + QCOMPARE(l.size(), 0); + // empty and null string check op = qFindChild<QObject*>(&o); QCOMPARE(op, &o1); @@ -803,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() @@ -1793,56 +1817,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)); @@ -2291,8 +2315,6 @@ public slots: void constTemplateSlot3(const Template< const int >) {} }; -#include "oldnormalizeobject.h" - void tst_QObject::normalize() { NormalizeObject object; @@ -2603,82 +2625,6 @@ void tst_QObject::normalize() SIGNAL(typeConstRefSignal(Template<Class const &> const &)), SLOT(typeConstRefSlot(Template<Class const &> 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<const Class &> &)), - SLOT(constTypeRefSlot(const Template<const Class &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<Class const &> &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template<const Class &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template<Class const &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - - // these fail in older Qt versions, but pass now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<const Class &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<Class const &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template<const Class &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(constTypeRefSignal(Template<Class const &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - - // these also fail in older Qt versions, but pass now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<const Class &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(const Template<Class const &> &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template<const Class &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template<Class const &> const &)), - SLOT(constTypeRefSlot(Template<Class const &> const &)))); - - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<const Class &> &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(const Template<Class const &> &)))); - // this fails in older versions, but passes now due to proper normalizing - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(const Template<const Class &> &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template<const Class &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(oldobject.connect(&oldobject, - SIGNAL(typeConstRefSignal(Template<Class const &> const &)), - SLOT(typeConstRefSlot(Template<Class const &> const &)))); - QVERIFY(object.connect(&object, SIGNAL(typePointerConstRefSignal(Class*const&)), SLOT(typePointerConstRefSlot(Class*const&)))); 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/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 <QtTest/QtTest> -#include <QWidget> #include <qtranslator.h> #include <qfile.h> -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() diff --git a/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin b/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin Binary files differnew file mode 100644 index 0000000000..eaa50f7310 --- /dev/null +++ b/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregularexpression.bin diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 655c714322..6a6460d17b 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -58,6 +58,7 @@ #include <qmatrix4x4.h> #include <qpen.h> #include <qpolygon.h> +#include <qpalette.h> #include <qtransform.h> #include <qvector2d.h> #include <qvector3d.h> @@ -192,6 +193,7 @@ private slots: void toLocale(); void toRegExp(); + void toRegularExpression(); void matrix(); @@ -274,6 +276,8 @@ private slots: void forwardDeclare(); void debugStream_data(); void debugStream(); + void debugStreamType_data(); + void debugStreamType(); void loadQt4Stream_data(); void loadQt4Stream(); @@ -283,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); @@ -1319,6 +1326,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<QRegularExpression>(); + QCOMPARE(re, QRegularExpression("[ab]\\w+")); +} + void tst_QVariant::matrix() { QVariant variant; @@ -1519,6 +1541,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; @@ -1625,8 +1649,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; @@ -1944,6 +1968,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() @@ -2547,9 +2572,24 @@ 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<CustomQObjectDerivedNoMetaType*>()); + QCOMPARE(data.value<QObject *>(), object); + QCOMPARE(data.value<CustomQObjectDerivedNoMetaType *>(), object); + QCOMPARE(data.value<CustomQObject *>(), object); + QVERIFY(data.value<CustomQWidget*>() == 0); + } + { CustomQObjectDerived *object = new CustomQObjectDerived(this); QVariant data = QVariant::fromValue(object); @@ -2787,7 +2827,7 @@ Q_DECLARE_METATYPE( MyClass ) void tst_QVariant::loadUnknownUserType() { qRegisterMetaType<MyClass>("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); @@ -3548,6 +3588,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<QVariant::Type>(id)); QCOMPARE(constructedVariant.userType(), id); @@ -3567,6 +3611,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); @@ -3588,8 +3636,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; } @@ -3603,13 +3651,29 @@ 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; + } + 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()); + } QtMsgHandler oldMsgHandler; @@ -3627,11 +3691,15 @@ void tst_QVariant::debugStream_data() const char *tagName = QMetaType::typeName(id); if (!tagName) continue; - QTest::newRow(tagName) << QVariant(static_cast<QVariant::Type>(id)) << id; + if (id != QMetaType::Void) { + QTest::newRow(tagName) << QVariant(static_cast<QVariant::Type>(id)) << id; + } } QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId<QBitArray>(); QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>(); QTest::newRow("MyClass") << QVariant(qMetaTypeId<MyClass>(), 0) << qMetaTypeId<MyClass>(); + QTest::newRow("InvalidVariant") << QVariant() << int(QMetaType::UnknownType); + QTest::newRow("CustomQObject") << QVariant::fromValue(this) << qMetaTypeId<tst_QVariant*>(); } void tst_QVariant::debugStream() @@ -3644,5 +3712,62 @@ 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()); +} + +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" 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 <int I> +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 <typename T> class QBasicAtomicInteger; // even if it this class isn't supported +QT_END_NAMESPACE - int expectedValue = 0; - int newValue = 0; - int valueToAdd = 0; +template <typename T, typename Atomic> +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<int, QBasicAtomicInt>(); + +#ifdef Q_ATOMIC_INT32_IS_SUPPORTED + warningFreeHelperTemplate<int, QBasicAtomicInteger<int> >(); + warningFreeHelperTemplate<unsigned int, QBasicAtomicInteger<unsigned int> >(); +#endif + +#ifdef Q_ATOMIC_INT16_IS_SUPPORTED + warningFreeHelperTemplate<qint16, QBasicAtomicInteger<qint16> >(); + warningFreeHelperTemplate<quint16, QBasicAtomicInteger<quint16> >(); +#endif + +#ifdef Q_ATOMIC_INT8_IS_SUPPORTED + warningFreeHelperTemplate<char, QBasicAtomicInteger<char> >(); + warningFreeHelperTemplate<signed char, QBasicAtomicInteger<signed char> >(); + warningFreeHelperTemplate<unsigned char, QBasicAtomicInteger<unsigned char> >(); +#endif + +#ifdef Q_ATOMIC_INT64_IS_SUPPORTED +#if !defined(__i386__) || (defined(Q_CC_GNU) && defined(__OPTIMIZE__)) + warningFreeHelperTemplate<qlonglong, QBasicAtomicInteger<qlonglong> >(); + warningFreeHelperTemplate<qulonglong, QBasicAtomicInteger<qulonglong> >(); +#endif +#endif } void tst_QAtomicInt::warningFree() @@ -130,6 +199,35 @@ void tst_QAtomicInt::warningFree() (void)foo; } +template <typename T> 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<int>) ? 1 : -1]; + char dummy2[Q_ALIGNOF(QAtomicInt) == Q_ALIGNOF(TypeInStruct<int>) ? 1 : -1]; + (void)dummy1; (void)dummy2; + +#ifdef Q_ATOMIC_INT32_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<int>), Q_ALIGNOF(TypeInStruct<int>)); +#endif + +#ifdef Q_ATOMIC_INT16_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<short>), Q_ALIGNOF(TypeInStruct<short>)); +#endif + +#ifdef Q_ATOMIC_INT8_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<char>), Q_ALIGNOF(TypeInStruct<char>)); +#endif + +#ifdef Q_ATOMIC_INT64_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<qlonglong>), Q_ALIGNOF(TypeInStruct<qlonglong>)); +#endif + +#endif +} + void tst_QAtomicInt::constructor_data() { QTest::addColumn<int>("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<void>) == Q_ALIGNOF(void*) ? 1 : -1]; + (void)dummy; +#endif +} + void tst_QAtomicPointer::constructor() { void *one = this; 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<TimerInfo> registeredTimers(QObject *) const { return QList<TimerInfo>(); } + int remainingTime(int) { return 0; } void wakeUp() {} void interrupt() {} void flush() {} diff --git a/tests/auto/corelib/tools/qarraydata/qarraydata.pro b/tests/auto/corelib/tools/qarraydata/qarraydata.pro new file mode 100644 index 0000000000..8e368117fa --- /dev/null +++ b/tests/auto/corelib/tools/qarraydata/qarraydata.pro @@ -0,0 +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..7e679704c8 --- /dev/null +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -0,0 +1,378 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + + +#ifndef QARRAY_TEST_SIMPLE_VECTOR_H +#define QARRAY_TEST_SIMPLE_VECTOR_H + +#include <QtCore/qarraydata.h> +#include <QtCore/qarraydatapointer.h> + +#include <algorithm> + +template <class T> +struct SimpleVector +{ +private: + typedef QTypedArrayData<T> Data; + +public: + typedef T value_type; + typedef typename Data::iterator iterator; + typedef typename Data::const_iterator const_iterator; + + SimpleVector() + { + } + + 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)) + { + if (n) + d->copyAppend(n, t); + } + + SimpleVector(const T *begin, const T *end) + : d(Data::allocate(end - begin)) + { + if (end - begin) + d->copyAppend(begin, end); + } + + SimpleVector(QArrayDataPointerRef<T> ptr) + : d(ptr) + { + } + + explicit SimpleVector(Data *ptr) + : d(ptr) + { + } + + bool empty() const { return d->size == 0; } + 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; } + 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; } + + 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()); + return *begin(); + } + + const T &back() const + { + Q_ASSERT(!isEmpty()); + return *(end() - 1); + } + + void reserve(size_t n) + { + if (n == 0) + return; + + if (n <= capacity()) { + if (d->capacityReserved) + return; + if (!d->ref.isShared()) { + d->capacityReserved = 1; + return; + } + } + + SimpleVector detached(Data::allocate(qMax(n, size()), + d->detachFlags() | Data::CapacityReserved)); + if (size()) + detached.d->copyAppend(constBegin(), constEnd()); + detached.swap(*this); + } + + void resize(size_t newSize) + { + if (size() == newSize) + return; + + if (d.needsDetach() || 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) { + append(first, last); + return; + } + + if (first == last) + return; + + T *const begin = d->begin(); + if (d.needsDetach() + || capacity() - size() < size_t(last - first)) { + SimpleVector detached(Data::allocate( + d->detachCapacity(size() + (last - first)), + d->detachFlags() | Data::Grow)); + + detached.d->copyAppend(first, last); + detached.d->copyAppend(begin, begin + d->size); + detached.swap(*this); + + return; + } + + d->insert(begin, first, last); + } + + void append(const_iterator first, const_iterator last) + { + if (first == last) + return; + + if (d.needsDetach() + || capacity() - size() < size_t(last - first)) { + SimpleVector detached(Data::allocate( + d->detachCapacity(size() + (last - first)), + d->detachFlags() | Data::Grow)); + + if (d->size) { + const T *const begin = constBegin(); + detached.d->copyAppend(begin, begin + d->size); + } + detached.d->copyAppend(first, last); + detached.swap(*this); + + return; + } + + 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.needsDetach() + || capacity() - size() < size_t(last - first)) { + SimpleVector detached(Data::allocate( + d->detachCapacity(size() + (last - first)), + d->detachFlags() | Data::Grow)); + + if (position) + detached.d->copyAppend(begin, where); + detached.d->copyAppend(first, last); + detached.d->copyAppend(where, end); + detached.swap(*this); + + return; + } + + if ((first >= where && first < end) + || (last > where && last <= end)) { + // 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; + } + + d->insert(where, first, last); + } + + void swap(SimpleVector &other) + { + qSwap(d, other.d); + } + + void clear() + { + d.clear(); + } + + void detach() + { + d.detach(); + } + + static SimpleVector fromRawData(const T *data, size_t size, + QArrayData::AllocationOptions options = Data::Default) + { + return SimpleVector(Data::fromRawData(data, size, options)); + } + +private: + QArrayDataPointer<T> d; +}; + +template <class T> +bool operator==(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs) +{ + if (lhs.isSharedWith(rhs)) + return true; + if (lhs.size() != rhs.size()) + return false; + return std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +template <class T> +bool operator!=(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs) +{ + return !(lhs == rhs); +} + +template <class T> +bool operator<(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs) +{ + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +} + +template <class T> +bool operator>(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs) +{ + return rhs < lhs; +} + +template <class T> +bool operator<=(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs) +{ + return !(rhs < lhs); +} + +template <class T> +bool operator>=(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs) +{ + return !(lhs < rhs); +} + +namespace std { + template <class T> + void swap(SimpleVector<T> &v1, SimpleVector<T> &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 new file mode 100644 index 0000000000..53217b2222 --- /dev/null +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -0,0 +1,1605 @@ +/**************************************************************************** +** +** 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 <QtTest/QtTest> +#include <QtCore/QString> +#include <QtCore/qarraydata.h> + +#include "simplevector.h" + +struct SharedNullVerifier +{ + SharedNullVerifier() + { + Q_ASSERT(QArrayData::shared_null[0].ref.isStatic()); + Q_ASSERT(QArrayData::shared_null[0].ref.isShared()); + Q_ASSERT(QArrayData::shared_null[0].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 + +private slots: + void referenceCounting(); + void sharedNullEmpty(); + void staticData(); + void simpleVector(); + void simpleVectorReserve_data(); + void simpleVectorReserve(); + void allocate_data(); + void allocate(); + void alignment_data(); + void alignment(); + void typedData(); + void gccBug43247(); + void arrayOps(); + void arrayOps2(); + void setSharable_data(); + void setSharable(); + void fromRawData(); + void literals(); + void variadicLiterals(); + void rValueReferences(); + void grow(); +}; + +template <class T> const T &const_(const T &t) { return t; } + +void tst_QArrayData::referenceCounting() +{ + { + // Reference counting initialized to 1 (owned) + QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(1) }, 0, 0, 0, 0 }; + + QCOMPARE(array.ref.atomic.load(), 1); + + QVERIFY(!array.ref.isStatic()); + QVERIFY(array.ref.isSharable()); + + QVERIFY(array.ref.ref()); + QCOMPARE(array.ref.atomic.load(), 2); + + QVERIFY(array.ref.deref()); + QCOMPARE(array.ref.atomic.load(), 1); + + QVERIFY(array.ref.ref()); + QCOMPARE(array.ref.atomic.load(), 2); + + QVERIFY(array.ref.deref()); + QCOMPARE(array.ref.atomic.load(), 1); + + QVERIFY(!array.ref.deref()); + QCOMPARE(array.ref.atomic.load(), 0); + + // 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(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(array.ref.atomic.load(), 0); + + QVERIFY(!array.ref.deref()); + QCOMPARE(array.ref.atomic.load(), 0); + + // Free/release data + } + + { + // Reference counting initialized to -1 (static read-only data) + QArrayData array = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 }; + + QCOMPARE(array.ref.atomic.load(), -1); + + QVERIFY(array.ref.isStatic()); + QVERIFY(array.ref.isSharable()); + + QVERIFY(array.ref.ref()); + QCOMPARE(array.ref.atomic.load(), -1); + + QVERIFY(array.ref.deref()); + QCOMPARE(array.ref.atomic.load(), -1); + } +} + +void tst_QArrayData::sharedNullEmpty() +{ + QArrayData *null = const_cast<QArrayData *>(QArrayData::shared_null); + QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0); + + 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(null->ref.atomic.load(), -1); + QCOMPARE(empty->ref.atomic.load(), -1); + + QVERIFY(null->ref.ref()); + QVERIFY(empty->ref.ref()); + + QCOMPARE(null->ref.atomic.load(), -1); + QCOMPARE(empty->ref.atomic.load(), -1); + + QVERIFY(null->ref.deref()); + QVERIFY(empty->ref.deref()); + + QCOMPARE(null->ref.atomic.load(), -1); + QCOMPARE(empty->ref.atomic.load(), -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<char, 10> charArray = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(char, 10), + { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } + }; + QStaticArrayData<int, 10> intArray = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10), + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } + }; + QStaticArrayData<double, 10> 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<void *>(&charArray.data)); + QCOMPARE(intArray.header.data(), reinterpret_cast<void *>(&intArray.data)); + QCOMPARE(doubleArray.header.data(), reinterpret_cast<void *>(&doubleArray.data)); +} + +void tst_QArrayData::simpleVector() +{ + QArrayData data0 = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 }; + QStaticArrayData<int, 7> data1 = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 7), + { 0, 1, 2, 3, 4, 5, 6 } + }; + + int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + SimpleVector<int> v1; + SimpleVector<int> v2(v1); + SimpleVector<int> v3(static_cast<QTypedArrayData<int> *>(&data0)); + SimpleVector<int> v4(static_cast<QTypedArrayData<int> *>(&data1.header)); + SimpleVector<int> v5(static_cast<QTypedArrayData<int> *>(&data0)); + SimpleVector<int> v6(static_cast<QTypedArrayData<int> *>(&data1.header)); + SimpleVector<int> v7(10, 5); + SimpleVector<int> v8(array, array + sizeof(array)/sizeof(*array)); + + 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(!v7.isNull()); + QVERIFY(!v8.isNull()); + + QVERIFY(v1.isEmpty()); + QVERIFY(v2.isEmpty()); + QVERIFY(v3.isEmpty()); + QVERIFY(v4.isEmpty()); + QVERIFY(v5.isEmpty()); + QVERIFY(!v6.isEmpty()); + QVERIFY(!v7.isEmpty()); + QVERIFY(!v8.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(v7.size(), size_t(10)); + QCOMPARE(v8.size(), size_t(10)); + + 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(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<int>(v7), v7.isShared())); + 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)); + QVERIFY(!v1.isSharedWith(v5)); + QVERIFY(!v1.isSharedWith(v6)); + + 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); + 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)); + + { + SimpleVector<int> 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)); + } + + // A single detach should do + QCOMPARE(temp.begin(), tempBegin); + } + + { + int count = 0; + Q_FOREACH (int value, v7) { + QCOMPARE(value, 5); + ++count; + } + + 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)); + + v1.swap(v6); + QVERIFY(v6.isNull()); + QVERIFY(v1.isSharedWith(v5)); + + { + using std::swap; + swap(v1, v6); + 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]); + + { + v7.setSharable(true); + QVERIFY(v7.isSharable()); + + SimpleVector<int> 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<int> 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<int> copy2(v7); + QVERIFY(copy2.isSharedWith(v7)); + } + + { + SimpleVector<int> null; + SimpleVector<int> 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()); + } +} + +Q_DECLARE_METATYPE(SimpleVector<int>) + +void tst_QArrayData::simpleVectorReserve_data() +{ + QTest::addColumn<SimpleVector<int> >("vector"); + QTest::addColumn<size_t>("capacity"); + QTest::addColumn<size_t>("size"); + + QTest::newRow("null") << SimpleVector<int>() << size_t(0) << size_t(0); + QTest::newRow("empty") << SimpleVector<int>(0, 42) << size_t(0) << size_t(0); + QTest::newRow("non-empty") << SimpleVector<int>(5, 42) << size_t(5) << size_t(5); + + static const QStaticArrayData<int, 15> 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<int> p = { + static_cast<QTypedArrayData<int> *>( + const_cast<QArrayData *>(&array.header)) }; + + QTest::newRow("static") << SimpleVector<int>(p) << size_t(0) << size_t(15); + QTest::newRow("raw-data") << SimpleVector<int>::fromRawData(array.data, 15) << size_t(0) << size_t(15); +} + +void tst_QArrayData::simpleVectorReserve() +{ + QFETCH(SimpleVector<int>, vector); + QFETCH(size_t, capacity); + QFETCH(size_t, size); + + QVERIFY(!capacity || capacity >= size); + + QCOMPARE(vector.capacity(), capacity); + QCOMPARE(vector.size(), size); + + const SimpleVector<int> 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) + : objectSize(objectSize) + , alignment(alignment) + { + } + + ~Deallocator() + { + Q_FOREACH (QArrayData *data, headers) + QArrayData::deallocate(data, objectSize, alignment); + } + + size_t objectSize; + size_t alignment; + QVector<QArrayData *> headers; +}; + +Q_DECLARE_METATYPE(const QArrayData *) +Q_DECLARE_METATYPE(QArrayData::AllocationOptions) + +void tst_QArrayData::allocate_data() +{ + QTest::addColumn<size_t>("objectSize"); + QTest::addColumn<size_t>("alignment"); + QTest::addColumn<QArrayData::AllocationOptions>("allocateOptions"); + QTest::addColumn<bool>("isCapacityReserved"); + QTest::addColumn<bool>("isSharable"); + QTest::addColumn<const QArrayData *>("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 *) } + }; + + 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::AllocationOptions allocateOptions; + bool isCapacityReserved; + bool isSharable; + const QArrayData *commonEmpty; + } options[] = { + { "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 }, + { "Grow", QArrayData::Grow, false, true, 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].allocateOptions << options[j].isCapacityReserved + << options[j].isSharable << options[j].commonEmpty; +} + +void tst_QArrayData::allocate() +{ + QFETCH(size_t, objectSize); + QFETCH(size_t, alignment); + QFETCH(QArrayData::AllocationOptions, allocateOptions); + QFETCH(bool, isCapacityReserved); + QFETCH(bool, isSharable); + 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, + 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::AllocationOptions(allocateOptions)); + keeper.headers.append(data); + + QCOMPARE(data->size, 0); + 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); + + // 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<size_t>("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, QArrayData::Default); + 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); + } +} + +void tst_QArrayData::typedData() +{ + QStaticArrayData<int, 10> 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<int> *array = + static_cast<QTypedArrayData<int> *>(&data.header); + QCOMPARE(array->data(), data.data); + + int j = 0; + for (QTypedArrayData<int>::iterator iter = array->begin(); + iter != array->end(); ++iter, ++j) + QCOMPARE(iter, data.data + j); + QCOMPARE(j, 10); + } + + { + const QTypedArrayData<int> *array = + static_cast<const QTypedArrayData<int> *>(&data.header); + + QCOMPARE(array->data(), data.data); + + int j = 0; + for (QTypedArrayData<int>::const_iterator iter = array->begin(); + iter != array->end(); ++iter, ++j) + QCOMPARE(iter, data.data + j); + QCOMPARE(j, 10); + } + + { + QTypedArrayData<int> *null = QTypedArrayData<int>::sharedNull(); + QTypedArrayData<int> *empty = QTypedArrayData<int>::allocate(0); + + 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<char>::AlignmentDummy)); + QArrayData *array = QTypedArrayData<char>::allocate(10); + 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<short>::deallocate(array); + + QVERIFY(true); + } + + { + Deallocator keeper(sizeof(short), + Q_ALIGNOF(QTypedArrayData<short>::AlignmentDummy)); + QArrayData *array = QTypedArrayData<short>::allocate(10); + 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<short>::deallocate(array); + + QVERIFY(true); + } + + { + Deallocator keeper(sizeof(double), + Q_ALIGNOF(QTypedArrayData<double>::AlignmentDummy)); + QArrayData *array = QTypedArrayData<double>::allocate(10); + 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<double>::deallocate(array); + + QVERIFY(true); + } +} + +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<int> array(10, 0); + // QVector<int> 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); + } +} + +struct CountedObject +{ + CountedObject() + : id(liveCount++) + , flags(DefaultConstructed) + { + } + + CountedObject(const CountedObject &other) + : id(other.id) + , flags(other.flags == DefaultConstructed + ? ObjectFlags(CopyConstructed | DefaultConstructed) + : CopyConstructed) + { + ++liveCount; + } + + ~CountedObject() + { + --liveCount; + } + + CountedObject &operator=(const CountedObject &other) + { + flags = ObjectFlags(other.flags | CopyAssigned); + id = other.id; + return *this; + } + + struct LeakChecker + { + LeakChecker() + : previousLiveCount(liveCount) + { + } + + ~LeakChecker() + { + QCOMPARE(liveCount, previousLiveCount); + } + + private: + const size_t previousLiveCount; + }; + + enum ObjectFlags { + DefaultConstructed = 1, + CopyConstructed = 2, + CopyAssigned = 4 + }; + + size_t id; // not unique + ObjectFlags flags; + + 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<int>::isComplex && !QTypeInfo<int>::isStatic); + QVERIFY(QTypeInfo<QString>::isComplex && !QTypeInfo<QString>::isStatic); + QVERIFY(QTypeInfo<CountedObject>::isComplex && QTypeInfo<CountedObject>::isStatic); + + QCOMPARE(CountedObject::liveCount, size_t(5)); + for (size_t i = 0; i < 5; ++i) + QCOMPARE(objArray[i].id, i); + + //////////////////////////////////////////////////////////////////////////// + // copyAppend (I) + SimpleVector<int> vi(intArray, intArray + 5); + SimpleVector<QString> vs(stringArray, stringArray + 5); + SimpleVector<CountedObject> 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); + QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed + | CountedObject::DefaultConstructed); + } + + //////////////////////////////////////////////////////////////////////////// + // 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<int>(5, referenceInt); + vs = SimpleVector<QString>(5, referenceString); + vo = SimpleVector<CountedObject>(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); + QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed + | CountedObject::DefaultConstructed); + } + + //////////////////////////////////////////////////////////////////////////// + // 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 < 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::arrayOps2() +{ + CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker) + + //////////////////////////////////////////////////////////////////////////// + // appendInitialize + SimpleVector<int> vi(5); + SimpleVector<QString> vs(5); + SimpleVector<CountedObject> 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)); + } + + //////////////////////////////////////////////////////////////////////////// + // 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<int>) + +static inline bool arrayIsFilledWith(const QArrayDataPointer<int> &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<QArrayDataPointer<int> >("array"); + QTest::addColumn<size_t>("size"); + QTest::addColumn<size_t>("capacity"); + QTest::addColumn<bool>("isCapacityReserved"); + QTest::addColumn<int>("fillValue"); + + QArrayDataPointer<int> null; + QArrayDataPointer<int> empty; empty.clear(); + + static QStaticArrayData<int, 10> staticArrayData = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10), + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } + }; + + QArrayDataPointer<int> emptyReserved(QTypedArrayData<int>::allocate(5, + QArrayData::CapacityReserved)); + QArrayDataPointer<int> nonEmpty(QTypedArrayData<int>::allocate(5, + QArrayData::Default)); + QArrayDataPointer<int> nonEmptyExtraCapacity( + QTypedArrayData<int>::allocate(10, QArrayData::Default)); + QArrayDataPointer<int> nonEmptyReserved(QTypedArrayData<int>::allocate(15, + QArrayData::CapacityReserved)); + QArrayDataPointer<int> staticArray( + static_cast<QTypedArrayData<int> *>(&staticArrayData.header)); + QArrayDataPointer<int> rawData( + QTypedArrayData<int>::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(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; +} + +void tst_QArrayData::setSharable() +{ + QFETCH(QArrayDataPointer<int>, 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<int> 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, as is additional capacity + // if capacityReserved flag is not set. + if ((capacity == 0 && size != 0) + || (!isCapacityReserved && capacity > size)) + 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<int> 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<int> copy(array); + QVERIFY(array->ref.isShared()); + QCOMPARE(copy.data(), array.data()); + } + + QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved)); + 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<int> raw = SimpleVector<int>::fromRawData(array, + sizeof(array)/sizeof(array[0]), QArrayData::Default); + + QCOMPARE(raw.size(), size_t(11)); + QCOMPARE(raw.constBegin(), array); + QCOMPARE((void *)raw.constEnd(), (void *)(array + sizeof(array)/sizeof(array[0]))); + + QVERIFY(!raw.isShared()); + QVERIFY(SimpleVector<int>(raw).isSharedWith(raw)); + QVERIFY(!raw.isShared()); + + // Detach + QCOMPARE(raw.back(), 11); + QVERIFY(raw.constBegin() != array); + } + + { + // Immutable, unsharable + SimpleVector<int> raw = SimpleVector<int>::fromRawData(array, + sizeof(array)/sizeof(array[0]), QArrayData::Unsharable); + + QCOMPARE(raw.size(), size_t(11)); + QCOMPARE(raw.constBegin(), array); + QCOMPARE((void *)raw.constEnd(), (void *)(array + sizeof(array)/sizeof(array[0]))); + + SimpleVector<int> 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((void *)raw.constEnd(), (void *)(array + sizeof(array)/sizeof(array[0]))); + + // Detach + QCOMPARE(raw.back(), 11); + QVERIFY(raw.constBegin() != array); + } +} + +void tst_QArrayData::literals() +{ + { + QArrayDataPointer<char> 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<wchar_t> 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<char> 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()); + QCOMPARE((void *)(v.constBegin() + v.size()), (void *)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<int> 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<char> 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<const char *> 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<int> 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()); + QCOMPARE((void *)(v.constBegin() + v.size()), (void *)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) +} + +#ifdef Q_COMPILER_RVALUE_REFS +// std::remove_reference is in C++11, but requires library support +template <class T> struct RemoveReference { typedef T Type; }; +template <class T> struct RemoveReference<T &> { typedef T Type; }; + +// single-argument std::move is in C++11, but requires library support +template <class T> +typename RemoveReference<T>::Type &&cxx11Move(T &&t) +{ + return static_cast<typename RemoveReference<T>::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<int> v1(1, 42); + SimpleVector<int> v2; + + const SimpleVector<int>::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<int> 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 +} + +void tst_QArrayData::grow() +{ + SimpleVector<int> 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] = { int(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" diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 5e53683abd..267aa71085 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -43,6 +43,7 @@ #include <qbytearray.h> #include <qfile.h> +#include <qhash.h> #include <limits.h> #include <private/qtools_p.h> #if defined(Q_OS_WINCE) @@ -91,8 +92,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(); @@ -117,6 +124,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(); @@ -130,11 +143,103 @@ private slots: void byteRefDetaching() const; void reserve(); + void reserveExtended_data(); + void reserveExtended(); void movablity_data(); void movablity(); void literals(); }; +static const 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 QByteArrayDataPtr staticStandard = { const_cast<QByteArrayData *>(&statics.standard.data) }; +static const QByteArrayDataPtr staticNotNullTerminated = { const_cast<QByteArrayData *>(&statics.notNullTerminated.data) }; +static const QByteArrayDataPtr staticShifted = { const_cast<QByteArrayData *>(&statics.shifted.data) }; +static const QByteArrayDataPtr staticShiftedNotNullTerminated = { const_cast<QByteArrayData *>(&statics.shiftedNotNullTerminated.data) }; + +template <class T> 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<QByteArray &>(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<char *>(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<char *>(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>("qulonglong"); @@ -517,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<const char *>(buf), "bubu"); @@ -526,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<const char *>(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) @@ -556,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 } @@ -701,6 +806,35 @@ void tst_QByteArray::prepend() QCOMPARE(ba.prepend("\0 ", 2), QByteArray::fromRawData("\0 321foo", 8)); } +void tst_QByteArray::prependExtended_data() +{ + QTest::addColumn<QByteArray>("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 +848,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 +892,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<QByteArray>("src"); @@ -1078,18 +1246,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); } } @@ -1111,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() @@ -1231,6 +1406,91 @@ void tst_QByteArray::toFromPercentEncoding() QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isNull()); } +void tst_QByteArray::fromPercentEncoding_data() +{ + QTest::addColumn<QByteArray>("encodedString"); + QTest::addColumn<QByteArray>("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<QByteArray>("decodedString"); + QTest::addColumn<QByteArray>("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<QByteArray>("original"); + QTest::addColumn<QByteArray>("encoded"); + QTest::addColumn<QByteArray>("excludeInEncoding"); + QTest::addColumn<QByteArray>("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<QByteArray>("str1"); @@ -1298,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() @@ -1449,6 +1712,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 @@ -1501,6 +1781,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<QByteArray>("array"); @@ -1511,6 +1807,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() @@ -1587,8 +1885,8 @@ void tst_QByteArray::literals() QVERIFY(str.length() == 4); QVERIFY(str == "abcd"); - QVERIFY(str.data_ptr()->ref == -1); - QVERIFY(str.data_ptr()->offset == 0); + QVERIFY(str.data_ptr()->ref.isStatic()); + QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData)); const char *s = str.constData(); QByteArray str2 = str; diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 3b5d15dbfc..5bd13b23a3 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 { @@ -525,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); @@ -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<OneArgumentQHashStruct1, int> oneArgHash1; + OneArgumentQHashStruct1 oneArgObject1; + oneArgHash1[oneArgObject1] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash<OneArgumentQHashStruct2, int> oneArgHash2; + OneArgumentQHashStruct2 oneArgObject2; + oneArgHash2[oneArgObject2] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash<OneArgumentQHashStruct3, int> oneArgHash3; + OneArgumentQHashStruct3 oneArgObject3; + oneArgHash3[oneArgObject3] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash<OneArgumentQHashStruct4, int> oneArgHash4; + OneArgumentQHashStruct4 oneArgObject4; + oneArgHash4[oneArgObject4] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash<TwoArgumentsQHashStruct1, int> twoArgsHash1; + TwoArgumentsQHashStruct1 twoArgsObject1; + twoArgsHash1[twoArgsObject1] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash<TwoArgumentsQHashStruct2, int> twoArgsHash2; + TwoArgumentsQHashStruct2 twoArgsObject2; + twoArgsHash2[twoArgsObject2] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash<TwoArgumentsQHashStruct3, int> twoArgsHash3; + TwoArgumentsQHashStruct3 twoArgsObject3; + twoArgsHash3[twoArgsObject3] = 1; + QCOMPARE(wrongqHashOverload, 0); + + QHash<TwoArgumentsQHashStruct4, int> twoArgsHash4; + TwoArgumentsQHashStruct4 twoArgsObject4; + twoArgsHash4[twoArgsObject4] = 1; + QCOMPARE(wrongqHashOverload, 0); +} + QTEST_APPLESS_MAIN(tst_QHash) #include "tst_qhash.moc" diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index 934130d3ee..c883c1c5f6 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -48,6 +48,9 @@ class tst_QList : public QObject Q_OBJECT private slots: + void init(); + void cleanup(); + void length() const; void lengthSignature() const; void append() const; @@ -84,8 +87,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<Complex::Guard *>(&dummyForGuard)->~Guard(); + QCOMPARE(Complex::errors(), 0); +} + void tst_QList::length() const { /* Empty list. */ @@ -690,5 +785,82 @@ void tst_QList::const_shared_null() const QVERIFY(!list2.isDetached()); } +Q_DECLARE_METATYPE(QList<int>); +Q_DECLARE_METATYPE(QList<Complex>); + +template <class T> +void generateSetSharableData() +{ + QTest::addColumn<QList<T> >("list"); + QTest::addColumn<int>("size"); + + QTest::newRow("null") << QList<T>() << 0; + QTest::newRow("non-empty") << (QList<T>() << T(0) << T(1) << T(2) << T(3) << T(4)) << 5; +} + +template <class T> +void runSetSharableTest() +{ + QFETCH(QList<T>, list); + QFETCH(int, size); + + QVERIFY(!list.isDetached()); // Shared with QTest + + list.setSharable(true); + + QCOMPARE(list.size(), size); + + { + QList<T> copy(list); + QVERIFY(!copy.isDetached()); + QVERIFY(copy.isSharedWith(list)); + } + + list.setSharable(false); + QVERIFY(list.isDetached() || list.isSharedWith(QList<T>())); + + { + QList<T> copy(list); + + QVERIFY(copy.isDetached() || copy.isSharedWith(QList<T>())); + QCOMPARE(copy.size(), size); + QCOMPARE(copy, list); + } + + list.setSharable(true); + + { + QList<T> 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<int>(); +} + +void tst_QList::setSharable2_data() const +{ + generateSetSharableData<Complex>(); +} + +void tst_QList::setSharable1() const +{ + runSetSharableTest<int>(); +} + +void tst_QList::setSharable2() const +{ + runSetSharableTest<Complex>(); +} + QTEST_APPLESS_MAIN(tst_QList) #include "tst_qlist.moc" diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index f9de2f0c05..7e12e42107 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -1751,7 +1751,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; } diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index 7d0ef7d7e4..a28ea94aa5 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 <qmap.h> #include <QtTest/QtTest> #include <QDebug> -#include <qmap.h> 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<QString, QString> StringMap; @@ -105,6 +110,11 @@ int MyClass::count = 0; typedef QMap<QString, MyClass> 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<int, QString>::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() @@ -655,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 @@ -675,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 @@ -846,10 +887,129 @@ void tst_QMap::const_shared_null() QMap<int, QString> map2; map2.setSharable(true); QVERIFY(!map2.isDetached()); +} + +void tst_QMap::equal_range() +{ + QMap<int, QString> map; + + QPair<QMap<int, QString>::iterator, QMap<int, QString>::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<int, QString> 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 <class T> +const T &const_(const T &t) +{ + return t; +} + +void tst_QMap::setSharable() +{ + QMap<int, QString> 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<int, QString> 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<int, QString> 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<int, QString> copy(map); + + QVERIFY(!map.isDetached()); + QVERIFY(copy.isSharedWith(map)); + } +} + +void tst_QMap::insert() +{ + QMap<QString, float> map; + map.insert("cs/key1", 1); + map.insert("cs/key2", 2); + map.insert("cs/key1", 3); + QCOMPARE(map.count(), 2); + + QMap<int, int> 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/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 5b697a3509..bb9be1d65f 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 <typename Base> -class RefCountHack: public Base +template<typename T> static inline +QtSharedPointer::ExternalRefCountData *refCountData(const QtSharedPointer::ExternalRefCount<T> &b) { -public: - using Base::d; -}; -template<typename Base> static inline -QtSharedPointer::ExternalRefCountData *refCountData(const Base &b) -{ return static_cast<const RefCountHack<Base> *>(&b)->d; } + // access d-pointer: + struct Dummy { + void* value; + QtSharedPointer::ExternalRefCountData* data; + }; + // sanity checks: + Q_STATIC_ASSERT(sizeof(QtSharedPointer::ExternalRefCount<T>) == sizeof(Dummy)); + Q_ASSERT(static_cast<const Dummy*>(static_cast<const void*>(&b))->value == b.data()); + return static_cast<const Dummy*>(static_cast<const void*>(&b))->data; +} class Data { @@ -1619,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() diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 4eabd61025..1905c9c049 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -41,6 +41,7 @@ #include <QtTest/QtTest> #include <qregexp.h> +#include <qregularexpression.h> #include <qtextcodec.h> #include <qtextstream.h> #include <qstringlist.h> @@ -50,6 +51,7 @@ #include <qlocale.h> #include <locale.h> +#include <qhash.h> Q_DECLARE_METATYPE(qlonglong) @@ -194,6 +196,7 @@ private slots: void localeAwareCompare(); void split_data(); void split(); + void split_regexp_data(); void split_regexp(); void fromUtf16_data(); void fromUtf16(); @@ -227,6 +230,65 @@ private slots: void assignQLatin1String(); }; +template <class T> 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<QString &>(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<QChar *>(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<QChar *>(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<int> IntList; Q_DECLARE_METATYPE(QList<QVariant>) @@ -823,7 +885,6 @@ void tst_QString::constructorQByteArray() void tst_QString::STL() { -#ifndef QT_NO_STL #ifndef QT_NO_CAST_TO_ASCII QString qt( "QString" ); @@ -867,9 +928,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() @@ -1089,6 +1147,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 ); @@ -1276,6 +1345,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) { @@ -1311,6 +1389,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); @@ -1336,6 +1417,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)); @@ -1430,16 +1513,69 @@ void tst_QString::mid() QVERIFY(a.mid(9999).isNull()); QVERIFY(a.mid(9999,1).isNull()); + 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); + 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_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()); + 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), 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); + 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() @@ -1456,16 +1592,69 @@ void tst_QString::midRef() QVERIFY(a.midRef(9999).toString().isEmpty()); QVERIFY(a.midRef(9999,1).toString().isEmpty()); + 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); + 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_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()); + 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), 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); + 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() @@ -2075,6 +2264,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() @@ -2139,8 +2331,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 } @@ -3168,7 +3365,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") ); @@ -3176,7 +3372,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() @@ -3184,7 +3379,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 ); @@ -3198,7 +3392,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() @@ -3881,8 +4074,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 ); + } } @@ -4403,6 +4600,7 @@ void tst_QString::split() QFETCH(QStringList, result); QRegExp rx = QRegExp(QRegExp::escape(sep)); + QRegularExpression re(QRegularExpression::escape(sep)); QStringList list; @@ -4410,6 +4608,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); @@ -4419,6 +4619,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); @@ -4429,39 +4631,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<QString>("string"); + QTest::addColumn<QString>("pattern"); + QTest::addColumn<QStringList>("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() @@ -4717,6 +4931,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()); } @@ -5065,8 +5286,8 @@ void tst_QString::literals() QVERIFY(str.length() == 4); QVERIFY(str == QLatin1String("abcd")); - QVERIFY(str.data_ptr()->ref == -1); - QVERIFY(str.data_ptr()->offset == 0); + QVERIFY(str.data_ptr()->ref.isStatic()); + QVERIFY(str.data_ptr()->offset == sizeof(QStringData)); const QChar *s = str.constData(); QString str2 = str; diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp index 556b9ac16a..862789cc73 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_STATIC_STRING_DATA_HEADER_INITIALIZER(12), + { '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_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(12), + { '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); diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp index 6066f7c8e0..16a329f1dd 100644 --- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp +++ b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp @@ -41,12 +41,16 @@ #include <QtTest/QtTest> #include <qregexp.h> +#include <qregularexpression.h> #include <qstringlist.h> +#include <locale.h> + class tst_QStringList : public QObject { Q_OBJECT private slots: + void sort(); void filter(); void replaceInStrings(); void removeDuplicates(); @@ -72,18 +76,37 @@ void tst_QStringList::indexOf_regExp() { QStringList list; list << "harald" << "trond" << "vohi" << "harald"; + { + QRegExp re(".*o.*"); + + 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); - QRegExp re(".*o.*"); + QCOMPARE(list.indexOf(QRegExp("[aeiou]")), -1); + } - QCOMPARE(list.indexOf(re), 1); - QCOMPARE(list.indexOf(re, 2), 2); - QCOMPARE(list.indexOf(re, 3), -1); + { + QRegularExpression re(".*o.*"); - 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(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 +114,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 +194,29 @@ 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::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() @@ -170,6 +238,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() diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index c79aee4187..67ca547736 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<int>); + +void tst_QVector::setSharable_data() +{ + QTest::addColumn<QVector<int> >("vector"); + QTest::addColumn<int>("size"); + QTest::addColumn<int>("capacity"); + QTest::addColumn<bool>("isCapacityReserved"); + + QVector<int> null; + QVector<int> empty(0, 5); + QVector<int> emptyReserved; + QVector<int> nonEmpty; + QVector<int> 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<int>, 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<int> copy(vector); + + QVERIFY(!copy.isDetached()); + QVERIFY(copy.isSharedWith(vector)); + } + + vector.setSharable(false); + QVERIFY(vector.isDetached() || vector.isSharedWith(QVector<int>())); + + { + QVector<int> copy(vector); + + QVERIFY(copy.isDetached() || copy.isSharedWith(QVector<int>())); + 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<int> 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" diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro index d8961559e5..38225e12f7 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 \ 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/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/com.trolltech.QtDBus.Pinger.xml b/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml index d945ec9b43..845e7be5b4 100644 --- a/tests/auto/dbus/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml +++ b/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml @@ -1,10 +1,10 @@ <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node> - <interface name="com.trolltech.QtDBus.Pinger"> + <interface name="org.qtproject.QtDBus.Pinger"> <property name="stringProp" type="s" access="readwrite"/> <property name="variantProp" type="v" access="readwrite"/> <property name="complexProp" type="(s)" access="readwrite"> - <annotation name="com.trolltech.QtDBus.QtTypeName" value="RegisteredType"/> + <annotation name="org.qtproject.QtDBus.QtTypeName" value="RegisteredType"/> </property> <signal name="voidSignal"/> <signal name="stringSignal"> @@ -12,7 +12,7 @@ </signal> <signal name="complexSignal"> <arg name="" type="(s)"/> - <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="RegisteredType"/> + <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="RegisteredType"/> </signal> <method name="voidMethod" /> <method name="sleepMethod"> @@ -24,7 +24,7 @@ </method> <method name="complexMethod"> <arg type="(s)" direction="out"/> - <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="RegisteredType"/> + <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="RegisteredType"/> </method> <method name="multiOutMethod"> <arg type="s" direction="out"/> 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 <QtDBus/QtDBus> #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 b696294005..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<com::trolltech::QtDBus::Pinger> 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"); @@ -1034,9 +1034,9 @@ void tst_QDBusAbstractInterface::createErrors_data() QTest::addColumn<QString>("path"); QTest::addColumn<QString>("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<QString>("path"); QTest::addColumn<QString>("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/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 <QtDBus> #include <QtTest> -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", "" -" <interface name=\"com.trolltech.QtDBus.MyObject\" >\n" +" <interface name=\"org.qtproject.QtDBus.MyObject\" >\n" " <property access=\"readwrite\" type=\"i\" name=\"prop1\" />\n" " <property name=\"complexProp\" type=\"ai\" access=\"readwrite\">\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName\" value=\"QList<int>\"/>\n" +" <annotation name=\"org.qtproject.QtDBus.QtTypeName\" value=\"QList<int>\"/>\n" " </property>\n" " <signal name=\"somethingHappened\" >\n" " <arg direction=\"out\" type=\"s\" />\n" @@ -83,14 +83,14 @@ class MyObject: public QObject " <method name=\"ping\" >\n" " <arg direction=\"in\" type=\"ai\" name=\"ping\" />\n" " <arg direction=\"out\" type=\"ai\" name=\"ping\" />\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.In0\" value=\"QList<int>\"/>\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList<int>\"/>\n" +" <annotation name=\"org.qtproject.QtDBus.QtTypeName.In0\" value=\"QList<int>\"/>\n" +" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QList<int>\"/>\n" " </method>\n" " <method name=\"ping_invokable\" >\n" " <arg direction=\"in\" type=\"ai\" name=\"ping_invokable\" />\n" " <arg direction=\"out\" type=\"ai\" name=\"ping_invokable\" />\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.In0\" value=\"QList<int>\"/>\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList<int>\"/>\n" +" <annotation name=\"org.qtproject.QtDBus.QtTypeName.In0\" value=\"QList<int>\"/>\n" +" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QList<int>\"/>\n" " </method>\n" " </interface>\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", "" -" <interface name=\"com.trolltech.QtDBus.MyObjectUnknownTypes\" >\n" +" <interface name=\"org.qtproject.QtDBus.MyObjectUnknownTypes\" >\n" " <property access=\"readwrite\" type=\"~\" name=\"prop1\" />\n" " <signal name=\"somethingHappened\" >\n" " <arg direction=\"out\" type=\"~\" />\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 " <interface name=\"com.trolltech.QtDBus.VirtualObject\">\n" + return " <interface name=\"org.qtproject.QtDBus.VirtualObject\">\n" " <method name=\"klingeling\" />\n" " </interface>\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("<node>.*<interface name=\"com.trolltech.QtDBus.VirtualObject\">" + QRegExp("<node>.*<interface name=\"org.qtproject.QtDBus.VirtualObject\">" ".*<method name=\"klingeling\" />\n" ".*</interface>.*<interface name=") )); } diff --git a/tests/auto/dbus/qdbusmarshall/common.h b/tests/auto/dbus/qdbusmarshall/common.h index f4c10c467d..ed5c03ea64 100644 --- a/tests/auto/dbus/qdbusmarshall/common.h +++ b/tests/auto/dbus/qdbusmarshall/common.h @@ -85,8 +85,8 @@ Q_DECLARE_METATYPE(QList<QList<QDBusSignature> >) typedef QMap<int, QString> IntStringMap; typedef QMap<QString, QString> StringStringMap; typedef QMap<QDBusObjectPath, QString> ObjectPathStringMap; -typedef QHash<qlonglong, QDateTime> LLDateTimeMap; -typedef QHash<QDBusSignature, QString> SignatureStringMap; +typedef QMap<qlonglong, QDateTime> LLDateTimeMap; +typedef QMap<QDBusSignature, QString> SignatureStringMap; Q_DECLARE_METATYPE(IntStringMap) Q_DECLARE_METATYPE(StringStringMap) Q_DECLARE_METATYPE(ObjectPathStringMap) @@ -209,8 +209,8 @@ void commonInit() qDBusRegisterMetaType<QMap<int, QString> >(); qDBusRegisterMetaType<QMap<QString, QString> >(); qDBusRegisterMetaType<QMap<QDBusObjectPath, QString> >(); - qDBusRegisterMetaType<QHash<qlonglong, QDateTime> >(); - qDBusRegisterMetaType<QHash<QDBusSignature, QString> >(); + qDBusRegisterMetaType<QMap<qlonglong, QDateTime> >(); + qDBusRegisterMetaType<QMap<QDBusSignature, QString> >(); qDBusRegisterMetaType<MyStruct>(); qDBusRegisterMetaType<MyVariantMapStruct>(); @@ -418,23 +418,6 @@ bool compare(const QMap<Key, T> &m1, const QMap<Key, T> &m2) return true; } -template<typename Key, typename T> -bool compare(const QHash<Key, T> &m1, const QHash<Key, T> &m2) -{ - if (m1.count() != m2.size()) - return false; - typename QHash<Key, T>::ConstIterator i1 = m1.constBegin(); - typename QHash<Key, T>::ConstIterator end = m1.constEnd(); - for ( ; i1 != end; ++i1) { - typename QHash<Key, T>::ConstIterator i2 = m2.find(i1.key()); - if (i2 == m2.constEnd()) - return false; - if (!compare(*i1, *i2)) - return false; - } - return true; -} - template<typename T> inline bool compare(const QDBusArgument &arg, const QVariant &v2, T * = 0) { @@ -536,10 +519,10 @@ bool compareToArgument(const QDBusArgument &arg, const QVariant &v2) return compare<QMap<QString, QString> >(arg, v2); else if (id == qMetaTypeId<QMap<QDBusObjectPath, QString> >()) return compare<QMap<QDBusObjectPath, QString> >(arg, v2); - else if (id == qMetaTypeId<QHash<qlonglong, QDateTime> >()) - return compare<QHash<qlonglong, QDateTime> >(arg, v2); - else if (id == qMetaTypeId<QHash<QDBusSignature, QString> >()) - return compare<QHash<QDBusSignature, QString> >(arg, v2); + else if (id == qMetaTypeId<QMap<qlonglong, QDateTime> >()) + return compare<QMap<qlonglong, QDateTime> >(arg, v2); + else if (id == qMetaTypeId<QMap<QDBusSignature, QString> >()) + return compare<QMap<QDBusSignature, QString> >(arg, v2); else if (id == qMetaTypeId<QList<QByteArray> >()) return compare<QList<QByteArray> >(arg, v2); @@ -701,11 +684,11 @@ template<> bool compare(const QVariant &v1, const QVariant &v2) else if (id == qMetaTypeId<QMap<QDBusObjectPath, QString> >()) return compare(qvariant_cast<QMap<QDBusObjectPath, QString> >(v1), qvariant_cast<QMap<QDBusObjectPath, QString> >(v2)); - else if (id == qMetaTypeId<QHash<qlonglong, QDateTime> >()) // lldtmap - return compare(qvariant_cast<QHash<qint64, QDateTime> >(v1), qvariant_cast<QHash<qint64, QDateTime> >(v2)); + else if (id == qMetaTypeId<QMap<qlonglong, QDateTime> >()) // lldtmap + return compare(qvariant_cast<QMap<qint64, QDateTime> >(v1), qvariant_cast<QMap<qint64, QDateTime> >(v2)); - else if (id == qMetaTypeId<QHash<QDBusSignature, QString> >()) - return compare(qvariant_cast<QHash<QDBusSignature, QString> >(v1), qvariant_cast<QHash<QDBusSignature, QString> >(v2)); + else if (id == qMetaTypeId<QMap<QDBusSignature, QString> >()) + return compare(qvariant_cast<QMap<QDBusSignature, QString> >(v1), qvariant_cast<QMap<QDBusSignature, QString> >(v2)); else if (id == qMetaTypeId<MyStruct>()) // (is) return qvariant_cast<MyStruct>(v1) == qvariant_cast<MyStruct>(v2); diff --git a/tests/auto/dbus/qdbusmarshall/qpong/qpong.cpp b/tests/auto/dbus/qdbusmarshall/qpong/qpong.cpp index 39779c1fd9..564b82af35 100644 --- a/tests/auto/dbus/qdbusmarshall/qpong/qpong.cpp +++ b/tests/auto/dbus/qdbusmarshall/qpong/qpong.cpp @@ -41,14 +41,14 @@ #include <QtCore/QtCore> #include <QtDBus/QtDBus> -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 Pong: public QObject { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.qpong") + Q_CLASSINFO("D-Bus Interface", "org.qtproject.autotests.qpong") public slots: void ping(QDBusMessage msg) diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index e8f5b255ab..8412fb85be 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -49,8 +49,8 @@ #include <dbus/dbus.h> -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 @@ -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<QDBusSignature, QString> gsmap; + QMap<QDBusSignature, QString> 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<qlonglong, QDateTime> lldtmap; + QMap<qlonglong, QDateTime> 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<QDBusSignature, QString> gsmap; + QMap<QDBusSignature, QString> gsmap; gsmap[QDBusSignature("i")] = "int32"; gsmap[QDBusSignature("s")] = "string"; gsmap[QDBusSignature("a{gs}")] = "array of dict_entry of (signature, string)"; @@ -925,29 +925,29 @@ 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() - << "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" diff --git a/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp b/tests/auto/dbus/qdbusmetaobject/tst_qdbusmetaobject.cpp index ed4ed4c6a2..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[] = "<signal name=\"signal\"><arg type=\"(ss)\"/>" - "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"StringPair\"></signal>"; + "<annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"StringPair\"></signal>"; class TypesTest17: public QObject { @@ -308,7 +308,7 @@ signals: }; const char TypesTest17_xml[] = "<signal name=\"signal\"><arg type=\"(s)\"/>" - "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"Struct1\"></signal>"; + "<annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"Struct1\"></signal>"; class TypesTest18: public QObject { @@ -319,7 +319,7 @@ signals: }; const char TypesTest18_xml[] = "<signal name=\"signal\"><arg type=\"(ssa(ss)sayasx)\"/>" - "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"Struct4\"></signal>"; + "<annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"Struct4\"></signal>"; class TypesTest19: public QObject { @@ -330,7 +330,7 @@ signals: }; const char TypesTest19_xml[] = "<signal name=\"signal\"><arg type=\"av\"/>" - "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QVariantList\"></signal>"; + "<annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QVariantList\"></signal>"; class TypesTest20: public QObject { @@ -341,8 +341,12 @@ signals: }; const char TypesTest20_xml[] = "<signal name=\"signal\"><arg type=\"a{sv}\"/>" + "<annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QVariantMap\"></signal>"; +const char TypesTest20_oldxml[] = + "<signal name=\"signal\"><arg type=\"a{sv}\"/>" "<annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QVariantMap\"></signal>"; + void tst_QDBusMetaObject::types_data() { QTest::addColumn<const QMetaObject *>("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() @@ -397,16 +402,21 @@ 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); 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 +437,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()); } } @@ -664,9 +676,207 @@ public: }; const char PropertyTest4_xml[] = "<property name=\"property\" type=\"(s)\" access=\"write\">" - "<annotation name=\"com.trolltech.QtDBus.QtTypeName\" value=\"Struct1\"/>" + "<annotation name=\"org.qtproject.QtDBus.QtTypeName\" value=\"Struct1\"/>" "</property>"; +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[] = + "<property name=\"property\" type=\"b\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"y\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"n\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"q\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"u\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"x\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"t\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"d\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"s\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"v\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"o\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"g\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"h\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"ay\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"as\" access=\"readwrite\"/>"; + +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[] = + "<property name=\"property\" type=\"av\" access=\"readwrite\"/>"; + +class PropertyTest_ao: public QObject +{ + Q_OBJECT + Q_PROPERTY(QList<QDBusObjectPath> property READ property WRITE setProperty) +public: + QList<QDBusObjectPath> property() { return QList<QDBusObjectPath>(); } + void setProperty(QList<QDBusObjectPath>) { } +}; +const char PropertyTest_ao_xml[] = + "<property name=\"property\" type=\"ao\" access=\"readwrite\"/>"; + +class PropertyTest_ag: public QObject +{ + Q_OBJECT + Q_PROPERTY(QList<QDBusSignature> property READ property WRITE setProperty) +public: + QList<QDBusSignature> property() { return QList<QDBusSignature>(); } + void setProperty(QList<QDBusSignature>) { } +}; +const char PropertyTest_ag_xml[] = + "<property name=\"property\" type=\"ag\" access=\"readwrite\"/>"; + void tst_QDBusMetaObject::properties_data() { QTest::addColumn<const QMetaObject *>("metaobject"); @@ -676,6 +886,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<QDBusObjectPath>") << &PropertyTest_ao::staticMetaObject << QString(PropertyTest_ao_xml); + QTest::newRow("QList<QDBusSignature>") << &PropertyTest_ag::staticMetaObject << QString(PropertyTest_ag_xml); } void tst_QDBusMetaObject::properties() 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 <QtTest/QtTest> #include <QtDBus> -#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 5836945484..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); } @@ -474,77 +474,77 @@ void tst_QDBusPendingReply::multipleTypes() void tst_QDBusPendingReply::synchronousSimpleTypes() { - QDBusPendingReply<bool> rbool = iface->call("retrieveBool"); + QDBusPendingReply<bool> rbool(iface->call("retrieveBool")); rbool.waitForFinished(); QVERIFY(rbool.isFinished()); QCOMPARE(rbool.argumentAt<0>(), adaptor->retrieveBool()); - QDBusPendingReply<uchar> ruchar = iface->call("retrieveUChar"); + QDBusPendingReply<uchar> ruchar(iface->call("retrieveUChar")); ruchar.waitForFinished(); QVERIFY(ruchar.isFinished()); QCOMPARE(ruchar.argumentAt<0>(), adaptor->retrieveUChar()); - QDBusPendingReply<short> rshort = iface->call("retrieveShort"); + QDBusPendingReply<short> rshort(iface->call("retrieveShort")); rshort.waitForFinished(); QVERIFY(rshort.isFinished()); QCOMPARE(rshort.argumentAt<0>(), adaptor->retrieveShort()); - QDBusPendingReply<ushort> rushort = iface->call("retrieveUShort"); + QDBusPendingReply<ushort> rushort(iface->call("retrieveUShort")); rushort.waitForFinished(); QVERIFY(rushort.isFinished()); QCOMPARE(rushort.argumentAt<0>(), adaptor->retrieveUShort()); - QDBusPendingReply<int> rint = iface->call("retrieveInt"); + QDBusPendingReply<int> rint(iface->call("retrieveInt")); rint.waitForFinished(); QVERIFY(rint.isFinished()); QCOMPARE(rint.argumentAt<0>(), adaptor->retrieveInt()); - QDBusPendingReply<uint> ruint = iface->call("retrieveUInt"); + QDBusPendingReply<uint> ruint(iface->call("retrieveUInt")); ruint.waitForFinished(); QVERIFY(ruint.isFinished()); QCOMPARE(ruint.argumentAt<0>(), adaptor->retrieveUInt()); - QDBusPendingReply<qlonglong> rqlonglong = iface->call("retrieveLongLong"); + QDBusPendingReply<qlonglong> rqlonglong(iface->call("retrieveLongLong")); rqlonglong.waitForFinished(); QVERIFY(rqlonglong.isFinished()); QCOMPARE(rqlonglong.argumentAt<0>(), adaptor->retrieveLongLong()); - QDBusPendingReply<qulonglong> rqulonglong = iface->call("retrieveULongLong"); + QDBusPendingReply<qulonglong> rqulonglong(iface->call("retrieveULongLong")); rqulonglong.waitForFinished(); QVERIFY(rqulonglong.isFinished()); QCOMPARE(rqulonglong.argumentAt<0>(), adaptor->retrieveULongLong()); - QDBusPendingReply<double> rdouble = iface->call("retrieveDouble"); + QDBusPendingReply<double> rdouble(iface->call("retrieveDouble")); rdouble.waitForFinished(); QVERIFY(rdouble.isFinished()); QCOMPARE(rdouble.argumentAt<0>(), adaptor->retrieveDouble()); - QDBusPendingReply<QString> rstring = iface->call("retrieveString"); + QDBusPendingReply<QString> rstring(iface->call("retrieveString")); rstring.waitForFinished(); QVERIFY(rstring.isFinished()); QCOMPARE(rstring.argumentAt<0>(), adaptor->retrieveString()); - QDBusPendingReply<QDBusObjectPath> robjectpath = iface->call("retrieveObjectPath"); + QDBusPendingReply<QDBusObjectPath> robjectpath(iface->call("retrieveObjectPath")); robjectpath.waitForFinished(); QVERIFY(robjectpath.isFinished()); QCOMPARE(robjectpath.argumentAt<0>().path(), adaptor->retrieveObjectPath().path()); - QDBusPendingReply<QDBusSignature> rsignature = iface->call("retrieveSignature"); + QDBusPendingReply<QDBusSignature> rsignature(iface->call("retrieveSignature")); rsignature.waitForFinished(); QVERIFY(rsignature.isFinished()); QCOMPARE(rsignature.argumentAt<0>().signature(), adaptor->retrieveSignature().signature()); - QDBusPendingReply<QDBusVariant> rdbusvariant = iface->call("retrieveVariant"); + QDBusPendingReply<QDBusVariant> rdbusvariant(iface->call("retrieveVariant")); rdbusvariant.waitForFinished(); QVERIFY(rdbusvariant.isFinished()); QCOMPARE(rdbusvariant.argumentAt<0>().variant(), adaptor->retrieveVariant().variant()); - QDBusPendingReply<QByteArray> rbytearray = iface->call("retrieveByteArray"); + QDBusPendingReply<QByteArray> rbytearray(iface->call("retrieveByteArray")); rbytearray.waitForFinished(); QVERIFY(rbytearray.isFinished()); QCOMPARE(rbytearray.argumentAt<0>(), adaptor->retrieveByteArray()); - QDBusPendingReply<QStringList> rstringlist = iface->call("retrieveStringList"); + QDBusPendingReply<QStringList> 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<int> rint = iface->asyncCall("sendError"); + QDBusPendingReply<int> rint(iface->asyncCall("sendError")); rint.waitForFinished(); QVERIFY(rint.isFinished()); QVERIFY(rint.isError()); error = rint.error(); VERIFY_ERROR(error); - QDBusPendingReply<int,int> rintint = iface->asyncCall("sendError"); + QDBusPendingReply<int,int> rintint(iface->asyncCall("sendError")); rintint.waitForFinished(); QVERIFY(rintint.isFinished()); QVERIFY(rintint.isError()); error = rintint.error(); VERIFY_ERROR(error); - QDBusPendingReply<QString> rstring = iface->asyncCall("sendError"); + QDBusPendingReply<QString> rstring(iface->asyncCall("sendError")); rstring.waitForFinished(); QVERIFY(rstring.isFinished()); QVERIFY(rstring.isError()); 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); } 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/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 <qwindow.h> +#include <qbackingstore.h> +#include <qpainter.h> + +#include <QtTest/QtTest> + +#include <QEvent> + +// 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 <tst_qbackingstore.moc> +QTEST_MAIN(tst_QBackingStore); 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<QPointF> rawPosList; + QVector<QPointF> rawPosList; rawPosList << QPointF(12, 34) << QPointF(56, 78); rawTouchPoint.setRawScreenPositions(rawPosList); const ulong timestamp = 1234; diff --git a/tests/auto/gui/kernel/qwindow/qwindow.pro b/tests/auto/gui/kernel/qwindow/qwindow.pro index e419a10440..fb8132afab 100644 --- a/tests/auto/gui/kernel/qwindow/qwindow.pro +++ b/tests/auto/gui/kernel/qwindow/qwindow.pro @@ -4,3 +4,7 @@ TARGET = tst_qwindow 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 7bbcb8db7d..3dc2886b80 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -54,8 +54,10 @@ class tst_QWindow: public QObject Q_OBJECT private slots: + void eventOrderOnShow(); void mapGlobal(); void positioning(); + void isExposed(); void isActive(); void testInputEvents(); void touchToMouseTranslation(); @@ -117,6 +119,7 @@ public: bool event(QEvent *event) { m_received[event->type()]++; + m_order << event->type(); return QWindow::event(event); } @@ -126,10 +129,32 @@ public: return m_received.value(type, 0); } + int eventIndex(QEvent::Type type) + { + return m_order.indexOf(type); + } + private: QHash<QEvent::Type, int> m_received; + QVector<QEvent::Type> 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); @@ -139,11 +164,8 @@ void tst_QWindow::positioning() QCOMPARE(window.geometry(), geometry); window.show(); -#ifdef Q_OS_MAC - QEXPECT_FAIL("", "This test fails on Mac OS X, see QTBUG-23059", Abort); -#endif 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(); @@ -154,6 +176,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); @@ -185,16 +210,35 @@ void tst_QWindow::positioning() } } -void tst_QWindow::isActive() +void tst_QWindow::isExposed() { + QRect geometry(80, 80, 40, 40); + Window window; - window.setGeometry(80, 80, 40, 40); + window.setGeometry(geometry); + QCOMPARE(window.geometry(), geometry); window.show(); + QTRY_VERIFY(window.received(QEvent::Expose) > 0); + QTRY_VERIFY(window.isExposed()); + + window.hide(); + #ifdef Q_OS_MAC QEXPECT_FAIL("", "This test fails on Mac OS X, see QTBUG-23059", Abort); #endif - QTRY_COMPARE(window.received(QEvent::Map), 1); + 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_VERIFY(window.isExposed()); QTRY_COMPARE(window.received(QEvent::Resize), 1); QTRY_VERIFY(QGuiApplication::focusWindow() == &window); QVERIFY(window.isActive()); @@ -204,15 +248,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); @@ -228,7 +271,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/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index e93b226b04..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 <QtNetwork/qnetworkconfigmanager.h> #include <QtNetwork/qnetworkconfiguration.h> #include <QtNetwork/qnetworksession.h> +#include <QtNetwork/private/qnetworksession_p.h> #endif #ifdef QT_BUILD_INTERNAL #include <QtNetwork/private/qnetworkaccessmanager_p.h> @@ -102,15 +103,7 @@ Q_DECLARE_METATYPE(QList<QFile*>) // for multiparts Q_DECLARE_METATYPE(QSslConfiguration) #endif -class QNetworkReplyPtr: public QSharedPointer<QNetworkReply> -{ -public: - inline QNetworkReplyPtr(QNetworkReply *ptr = 0) - : QSharedPointer<QNetworkReply>(ptr) - { } - - inline operator QNetworkReply *() const { return data(); } -}; +typedef QSharedPointer<QNetworkReply> QNetworkReplyPtr; class MyCookieJar; class tst_QNetworkReply: public QObject @@ -158,6 +151,12 @@ class tst_QNetworkReply: public QObject QScopedPointer<QNetworkSession> 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(); @@ -404,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: @@ -745,6 +747,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())); @@ -1181,15 +1185,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; @@ -1214,23 +1218,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: @@ -1252,7 +1256,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(); @@ -1280,7 +1284,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())); @@ -1309,7 +1313,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()) { @@ -1404,7 +1408,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()); @@ -1571,7 +1575,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()); @@ -1809,7 +1813,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()) @@ -2503,7 +2507,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; @@ -2584,7 +2588,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()), @@ -2616,7 +2620,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())); @@ -2648,7 +2652,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); @@ -2682,7 +2686,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); @@ -2707,11 +2711,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); @@ -2737,7 +2741,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); @@ -2758,11 +2762,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); @@ -2791,7 +2795,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); @@ -2809,7 +2813,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); @@ -2857,11 +2861,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*)), @@ -2884,7 +2888,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*))); @@ -2910,7 +2914,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 @@ -2936,7 +2940,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 @@ -2965,7 +2969,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); @@ -2984,13 +2988,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*)), @@ -3015,7 +3019,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()); @@ -3042,7 +3046,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); @@ -3068,7 +3072,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); @@ -3088,7 +3092,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()); @@ -3111,7 +3115,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()); @@ -3142,7 +3146,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<QSslError>))); @@ -3174,7 +3178,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); @@ -3199,7 +3203,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); @@ -3261,8 +3265,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); @@ -3292,7 +3296,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); @@ -3315,7 +3319,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); @@ -3485,7 +3489,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); @@ -3709,7 +3713,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*))); @@ -3777,7 +3781,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); @@ -3812,7 +3816,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); @@ -3856,8 +3860,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()) @@ -3909,7 +3913,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); @@ -3943,7 +3947,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); @@ -3992,7 +3996,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); @@ -4007,7 +4011,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); @@ -4033,7 +4037,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); @@ -4106,7 +4110,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*)), @@ -4183,7 +4187,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(); @@ -4209,7 +4213,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*))); @@ -4238,7 +4242,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*))); @@ -4266,7 +4270,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*))); @@ -4298,7 +4302,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*)), @@ -4376,11 +4380,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<QSslError>&)), reply, SLOT(ignoreSslErrors())); + connect(reply, SIGNAL(sslErrors(const QList<QSslError>&)), reply.data(), SLOT(ignoreSslErrors())); // get the request started and the incoming socket connected QTestEventLoop::instance().enterLoop(10); @@ -4464,11 +4468,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(); @@ -4523,8 +4527,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 @@ -4583,8 +4587,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())); @@ -4623,7 +4627,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); @@ -4637,7 +4641,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); @@ -4651,7 +4655,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); @@ -4690,11 +4694,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; @@ -4742,8 +4746,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()); @@ -4808,9 +4812,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()); @@ -4851,12 +4855,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); @@ -5087,10 +5091,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); @@ -5130,7 +5134,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. @@ -5217,7 +5221,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()); @@ -5242,11 +5246,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); @@ -5270,7 +5274,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); @@ -5300,12 +5304,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); @@ -5552,7 +5556,7 @@ void tst_QNetworkReply::ignoreSslErrorsList() { QFETCH(QString, url); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QFETCH(QList<QSslError>, expectedSslErrors); reply->ignoreSslErrors(expectedSslErrors); @@ -5579,7 +5583,7 @@ void tst_QNetworkReply::ignoreSslErrorsListWithSlot() { QFETCH(QString, url); QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.get(request); + QNetworkReplyPtr reply(manager.get(request)); QFETCH(QList<QSslError>, expectedSslErrors); // store the errors to ignore them later in the slot connected below @@ -5614,7 +5618,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); @@ -5889,9 +5893,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); @@ -5909,7 +5913,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); @@ -5933,7 +5937,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); @@ -5952,7 +5956,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); @@ -5981,7 +5985,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); @@ -6004,7 +6008,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); @@ -6017,7 +6021,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); @@ -6031,11 +6035,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); @@ -6124,7 +6128,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()); @@ -6137,7 +6141,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()); @@ -6165,7 +6169,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()); @@ -6181,7 +6185,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()); @@ -6199,7 +6203,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()); @@ -6214,7 +6218,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()); @@ -6323,7 +6327,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); @@ -6334,7 +6338,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); @@ -6346,9 +6350,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); @@ -6370,7 +6374,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); @@ -6389,7 +6393,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); @@ -6410,7 +6414,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); @@ -6573,16 +6577,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); @@ -6590,7 +6593,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); @@ -6621,7 +6624,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); @@ -6638,7 +6641,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); @@ -6691,7 +6694,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); } @@ -6702,7 +6705,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"); @@ -6714,7 +6717,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"); @@ -6728,7 +6731,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); @@ -6746,7 +6749,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"); @@ -6779,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<QString>("referenceName"); @@ -6807,6 +6809,49 @@ void tst_QNetworkReply::ftpAuthentication() QCOMPARE(reply->error(), QNetworkReply::NetworkError(error)); } +void tst_QNetworkReply::backgroundRequest_data() +{ + QTest::addColumn<bool>("background"); + QTest::addColumn<int>("policy"); + QTest::addColumn<QNetworkReply::NetworkError>("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<const QNetworkSession> session = QNetworkAccessManagerPrivate::getNetworkSession(&manager); + QVERIFY(session); + QNetworkSession::UsagePolicies original = session.data()->usagePolicies(); + QNetworkSessionPrivate::setUsagePolicies(*const_cast<QNetworkSession *>(session.data()), QNetworkSession::UsagePolicies(policy)); + + QNetworkReplyPtr reply(manager.get(request)); + + QVERIFY(waitForFinish(reply) != Timeout); + if (session) + QNetworkSessionPrivate::setUsagePolicies(*const_cast<QNetworkSession *>(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() 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 <QtNetwork/qnetworkconfigmanager.h> #include <QtNetwork/qnetworksession.h> +#include <private/qnetworksession_p.h> #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<QNetworkSession::UsagePolicies>(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) diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index d74e1b1e89..d1027c81e0 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 <qcoreapplication.h> #include <QtTest/QtTest> #include <qhostaddress.h> @@ -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; @@ -321,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() 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<QSslSocket> -{ -public: - inline QSslSocketPtr(QSslSocket *ptr = 0) - : QSharedPointer<QSslSocket>(ptr) - { } - - inline operator QSslSocket *() const { return data(); } -}; +typedef QSharedPointer<QSslSocket> 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<QSslError>)), + connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(untrustedWorkaroundSlot(QList<QSslError>))); #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<QSslError>)), + connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(untrustedWorkaroundSlot(QList<QSslError>))); #endif @@ -662,8 +654,8 @@ void tst_QSslSocket::sessionCipher() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; - connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); + this->socket = socket.data(); + connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), 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<QSslCertificate> 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<QSslError>)), + connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(untrustedWorkaroundSlot(QList<QSslError>))); #endif @@ -806,7 +798,7 @@ void tst_QSslSocket::protocol() return; QSslSocketPtr socket = newSocket(); - this->socket = socket; + this->socket = socket.data(); QList<QSslCertificate> 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<QSslError> &)), 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<QSslError> &)), 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<QSslError> &)), this, SLOT(ignoreErrorSlot())); + connect(this->socket, SIGNAL(sslErrors(const QList<QSslError> &)), 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<QSslError> &)), this, SLOT(ignoreErrorSlot())); + connect(this->socket, SIGNAL(sslErrors(const QList<QSslError> &)), 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<QSslError> &)), this, SLOT(ignoreErrorSlot())); + connect(this->socket, SIGNAL(sslErrors(const QList<QSslError> &)), 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<QSslError>)), this, SLOT(untrustedWorkaroundSlot(QList<QSslError>))); @@ -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<QSslError>))); - QSignalSpy peerVerifyErrorSpy(socket, SIGNAL(peerVerifyError(QSslError))); + QSignalSpy sslErrorsSpy(socket.data(), SIGNAL(sslErrors(QList<QSslError>))); + 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<QSslError> &)), this, SLOT(ignoreErrorSlot())); + connect(this->socket, SIGNAL(sslErrors(const QList<QSslError> &)), 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<QSslError> &)), this, SLOT(ignoreErrorSlot())); + connect(socket.data(), SIGNAL(sslErrors(const QList<QSslError> &)), 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<QSslSocket> -{ -public: - inline QSslSocketPtr(QSslSocket *ptr = 0) - : QSharedPointer<QSslSocket>(ptr) - { } - - inline operator QSslSocket *() const { return data(); } -}; +typedef QSharedPointer<QSslSocket> 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<QSslCertificate>()); 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<QSslCertificate>()); 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<QSslSocket> -{ -public: - inline QSslSocketPtr(QSslSocket *ptr = 0) - : QSharedPointer<QSslSocket>(ptr) - { } - - inline operator QSslSocket *() const { return data(); } -}; +typedef QSharedPointer<QSslSocket> 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<QSslCertificate>()); 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<QSslCertificate>()); 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. diff --git a/tests/auto/other/collections/tst_collections.cpp b/tests/auto/other/collections/tst_collections.cpp index 973938594f..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 <QtTest/QtTest> -#ifndef QT_NO_STL -# include <algorithm> -#endif +#include <algorithm> #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<QMultiHash<QString, QString> >(); } -#ifndef QT_NO_STL void tst_Collections::vector_stl_data() { QTest::addColumn<QStringList>("elements"); @@ -2953,7 +2946,6 @@ void tst_Collections::list_stl() QCOMPARE(QList<QString>::fromStdList(stdList), list); } -#endif template <typename T> 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(); @@ -3032,8 +3023,8 @@ void instantiateContainer() container.isEmpty(); container.size(); - container != constContainer; - container == constContainer; + Q_UNUSED((container != constContainer)); + Q_UNUSED((container == constContainer)); container = constContainer; } @@ -3043,12 +3034,10 @@ void instantiateMutableIterationContainer() instantiateContainer<ContainerType, ValueType>(); 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(); @@ -3097,8 +3086,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; @@ -3318,30 +3307,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<typename C> void testVectorAlignment() @@ -3349,13 +3336,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<typename C> @@ -3364,13 +3351,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<typename C> @@ -3382,8 +3369,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 +3378,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)); } } @@ -3624,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<class Container> void insert_remove_loop_impl() @@ -3744,14 +3729,12 @@ void tst_Collections::insert_remove_loop() insert_remove_loop_impl<QVarLengthArray<int, 15> >(); insert_remove_loop_impl<QVarLengthArray<QString, 15> >(); -#ifndef QT_NO_STL insert_remove_loop_impl<ExtList<std::string> >(); insert_remove_loop_impl<QVector<std::string> >(); insert_remove_loop_impl<QVarLengthArray<std::string> >(); insert_remove_loop_impl<QVarLengthArray<std::string, 10> >(); insert_remove_loop_impl<QVarLengthArray<std::string, 3> >(); insert_remove_loop_impl<QVarLengthArray<std::string, 15> >(); -#endif } 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/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())); diff --git a/tests/auto/other/networkselftest/tst_networkselftest.cpp b/tests/auto/other/networkselftest/tst_networkselftest.cpp index 3c0c4406fe..1935ef0c23 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 << 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/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 8384c9a295..977013ab8c 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -265,7 +265,6 @@ private slots: void mdiSubWindowTest(); void lineEditTest(); void groupBoxTest(); - void workspaceTest(); void dialogButtonBoxTest(); void dialTest(); void rubberBandTest(); @@ -601,7 +600,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; } @@ -2056,32 +2055,6 @@ void tst_QAccessibility::groupBoxTest() } } -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/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<tst_BadXmlSub *>(this)->mo = builder.toMetaObject(); 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() {} }; 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<void> &) {} inline TestTemplate<void> mySlot() { return TestTemplate<void>(); } signals: void mySignal(const TestTemplate<void> &); void myVoidSignal(); + void myVoidSignal2(void); }; diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index ecd9dc599e..78e18f9229 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -755,7 +755,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() @@ -881,6 +881,8 @@ void tst_Moc::slotsWithVoidTemplate() &test, SLOT(dummySlot(void)))); QVERIFY(QObject::connect(&test, SIGNAL(mySignal(const TestTemplate<void> &)), &test, SLOT(anotherSlot(const TestTemplate<void> &)))); + QVERIFY(QObject::connect(&test, SIGNAL(myVoidSignal2()), + &test, SLOT(dummySlot2()))); } void tst_Moc::structQObject() @@ -1100,14 +1102,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()")); } } @@ -1116,22 +1118,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()")); } } @@ -1238,7 +1240,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<QByteArray> paramNames = mm.parameterNames(); QCOMPARE(paramNames.size(), 1); @@ -1251,7 +1253,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); @@ -1260,7 +1262,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<QByteArray> paramNames = mm.parameterNames(); QCOMPARE(paramNames.size(), 1); 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 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/tst_qdbuscpp2xml/"> + <file>test1.h</file> +</qresource> +</RCC> 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 <stephen.kelly@kdab.com> +** 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 <QObject> + +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<bool> &a1, const QList<short> &a2, const QList<ushort> &a3, const QList<int> &a4, const QList<uint> &a5); + void signal_container_args2(const QList<qlonglong> &a1, const QList<qulonglong> &a2, const QList<double> &a3, const QList<QDBusObjectPath> &a4, const QList<QDBusSignature> &a5, const QList<QDBusUnixFileDescriptor> &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<bool> &a1, const QList<short> &a2, const QList<ushort> &a3, const QList<int> &a4, const QList<uint> &a5); + Q_SCRIPTABLE void signal_container_args2_scriptable(const QList<qlonglong> &a1, const QList<qulonglong> &a2, const QList<double> &a3, const QList<QDBusObjectPath> &a4, const QList<QDBusSignature> &a5, const QList<QDBusUnixFileDescriptor> &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 <stephen.kelly@kdab.com> +** 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 <QtTest/QtTest> + +#include "test1.h" + +#include <QtDBus/QDBusConnection> + +// 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 + "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n<node>" + + (input.isEmpty() ? QString() : QString("\n " + input.trimmed())) + + "\n</node>\n"; +} + +class tst_qdbuscpp2xml : public QObject +{ + Q_OBJECT + +private slots: + void qdbuscpp2xml_data(); + void qdbuscpp2xml(); + + void initTestCase(); + void cleanupTestCase(); + +private: + QHash<QString, QObject*> 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<QString>("inputfile"); + QTest::addColumn<int>("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/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 <QtCore/qglobal.h> 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, 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 <QtCore/QList> #include <QtCore/QResource> #include <QtCore/QLocale> +#include <QtCore/QtGlobal> typedef QMap<QString, QString> 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/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 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 @@ -388,12 +388,16 @@ 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)); const QPoint beforeShowPosition = dialog.pos(); dialog.show(); const QPoint afterShowPosition = dialog.pos(); QCOMPARE(afterShowPosition, beforeShowPosition); + } class Dialog : public QDialog diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 1a3d083864..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) { @@ -863,7 +863,7 @@ void tst_QFileSystemModel::sort() QTest::qWait(500); QModelIndex parent = myModel->index(dirPath, 0); QList<QString> 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 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 8772fb1e7e..df529c6095 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); 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/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index 2b52f5f234..f9610fab16 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -58,6 +58,7 @@ #include <qtreewidget.h> #include <QItemDelegate> +#include <QComboBox> #include <QAbstractItemDelegate> #include <QTextEdit> #include <QPlainTextEdit> @@ -228,6 +229,7 @@ private slots: void editorEvent(); void enterKey_data(); void enterKey(); + void comboBox(); void task257859_finalizeEdit(); void QTBUG4435_keepSelectionOnCheck(); @@ -780,6 +782,9 @@ void tst_QItemDelegate::dateTimeEditor() QTimeEdit *timeEditor = qFindChild<QTimeEdit *>(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 +796,7 @@ void tst_QItemDelegate::dateTimeEditor() QDateEdit *dateEditor = qFindChild<QDateEdit *>(widget.viewport()); QVERIFY(dateEditor); QCOMPARE(dateEditor->date(), date); + dateEditor->setDate(date.addDays(60)); widget.clearFocus(); widget.setFocus(); @@ -806,6 +812,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() @@ -873,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; } @@ -1195,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<QComboBox*>(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: 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 <QtWidgets/QFrame> #include <QtWidgets/QWindowsStyle> #include <QtWidgets/QSizePolicy> +#include <QtWidgets/QComboBox> #include <QPushButton> #include <QRadioButton> #include <private/qlayoutengine_p.h> @@ -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() 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 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(); 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 ); } diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index 82632a018c..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<QMacStyle *>(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; @@ -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()); } } @@ -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 eb433786f2..bc5100f118 100644 --- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp +++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp @@ -1823,7 +1823,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 <QtTest/QtTest> -#include <qapplication.h> -#include <qmainwindow.h> -#include <qmenubar.h> -#include <qworkspace.h> - -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<int>("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 -= \ diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp index 3633975896..bfd6ff0810 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("<a>\n<b p:c=\"\" xmlns:p=\"NS\" p:d=\"\"/>\n</a>\n") || - doc.toString(0) == QString::fromLatin1("<a>\n<b p:c=\"\" p:d=\"\" xmlns:p=\"NS\"/>\n</a>\n")); + // tst_QDom relies on a specific QHash ordering, see QTBUG-25071 + QString docAsString = doc.toString(0); + QVERIFY(docAsString == QString::fromLatin1("<a>\n<b p:c=\"\" xmlns:p=\"NS\" p:d=\"\"/>\n</a>\n") || + docAsString == QString::fromLatin1("<a>\n<b p:c=\"\" p:d=\"\" xmlns:p=\"NS\"/>\n</a>\n") || + docAsString == QString::fromLatin1("<a>\n<b p:d=\"\" p:c=\"\" xmlns:p=\"NS\"/>\n</a>\n") || + docAsString == QString::fromLatin1("<a>\n<b p:d=\"\" xmlns:p=\"NS\" p:c=\"\"/>\n</a>\n") || + docAsString == QString::fromLatin1("<a>\n<b xmlns:p=\"NS\" p:c=\"\" p:d=\"\"/>\n</a>\n") || + docAsString == QString::fromLatin1("<a>\n<b xmlns:p=\"NS\" p:d=\"\" p:c=\"\"/>\n</a>\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("<?xml version='1.0' encoding='UTF-8'?>\n" "<!DOCTYPE first [\n" "<!ENTITY thirdFile SYSTEM 'third.xml'>\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() 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/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(); 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; } } 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 <QFile> +#include <QMap> +#include <QString> +#include <QTest> +#include <qdebug.h> + + +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<int, int> map; + QBENCHMARK { + for (int i = 0; i < 100000; ++i) + map.insert(i, i); + } +} + +void tst_QMap::insertion_int_string() +{ + QMap<int, QString> map; + QString str("Hello World"); + QBENCHMARK { + for (int i = 0; i < 100000; ++i) + map.insert(i, str); + } +} + +void tst_QMap::insertion_string_int() +{ + QMap<QString, int> 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<int, int> 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<int, QString> 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<QString, int> 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<int, int> map; + for (int i = 0; i < 100000; ++i) + map.insert(i, i); + + int j = 0; + QBENCHMARK { + for (int i = 0; i < 100; ++i) { + QMap<int, int>::const_iterator it = map.constBegin(); + QMap<int, int>::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/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 7e570d93ff..18d9847c95 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -48,10 +48,8 @@ #include <QtCore/qalgorithms.h> #include <QtCore/qlist.h> -#ifndef QT_NO_STL #include <iterator> #include <vector> -#endif #include <stddef.h> #include <stdlib.h> #include <string.h> @@ -66,24 +64,18 @@ QT_BEGIN_NAMESPACE template <typename T> class QRawVector { - struct Data : QVectorData { T array[1]; }; + typedef QVectorTypedData<T> Data; T *m_begin; int m_size; 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); @@ -259,28 +251,29 @@ public: //static QRawVector<T> fromList(const QList<T> &list); -#ifndef QT_NO_STL static inline QRawVector<T> fromStdVector(const std::vector<T> &vector) { QRawVector<T> tmp; qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; } inline std::vector<T> toStdVector() const { std::vector<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; } -#endif 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<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this); + + class AlignmentDummy { QVectorData header; T array[1]; }; + + static Q_DECL_CONSTEXPR int offsetOfTypedData() + { + // (non-POD)-safe offsetof(AlignmentDummy, array) + return (sizeof(QVectorData) + (alignOfTypedData() - 1)) & ~(alignOfTypedData() - 1); } - static inline int alignOfTypedData() + static Q_DECL_CONSTEXPR int alignOfTypedData() { #ifdef Q_ALIGNOF - return qMax<int>(sizeof(void*), Q_ALIGNOF(Data)); + return Q_ALIGNOF(AlignmentDummy); #else - return 0; + return sizeof(void *); #endif } @@ -288,11 +281,11 @@ public: QVector<T> mutateToVector() { Data *d = toBase(m_begin); - d->ref = 1; + d->ref.initializeOwned(); d->alloc = m_alloc; d->size = m_size; - d->sharable = 0; - d->capacity = 0; + d->capacityReserved = 0; + d->offset = offsetOfTypedData(); QVector<T> v; *reinterpret_cast<QVectorData **>(&v) = d; @@ -309,7 +302,7 @@ void QRawVector<T>::reserve(int asize) template <typename T> void QRawVector<T>::resize(int asize) { realloc(asize, (asize > m_alloc || (asize < m_size && asize < (m_alloc >> 1))) - ? QVectorData::grow(sizeOfTypedData(), asize, sizeof(T), QTypeInfo<T>::isStatic) + ? QVectorData::grow(offsetOfTypedData(), asize, sizeof(T)) : m_alloc, false); } template <typename T> inline void QRawVector<T>::clear() @@ -370,7 +363,7 @@ QRawVector<T> &QRawVector<T>::operator=(const QRawVector<T> &v) template <typename T> inline T *QRawVector<T>::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); } @@ -386,7 +379,7 @@ QRawVector<T>::QRawVector(int asize) while (i != b) new (--i) T; } else { - qMemSet(m_begin, 0, asize * sizeof(T)); + memset(m_begin, 0, asize * sizeof(T)); } } @@ -446,10 +439,9 @@ void QRawVector<T>::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; @@ -482,7 +474,7 @@ void QRawVector<T>::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; @@ -511,8 +503,7 @@ void QRawVector<T>::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<T>::isStatic), false); + realloc(m_size, QVectorData::grow(offsetOfTypedData(), m_size + 1, sizeof(T)), false); if (QTypeInfo<T>::isComplex) new (m_begin + m_size) T(copy); else @@ -533,8 +524,7 @@ typename QRawVector<T>::iterator QRawVector<T>::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<T>::isStatic), false); + realloc(m_size, QVectorData::grow(offsetOfTypedData(), m_size + n, sizeof(T)), false); if (QTypeInfo<T>::isStatic) { T *b = m_begin + m_size; T *i = m_begin + m_size + n; 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 \ 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; 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<QNetworkReply> -{ -public: - inline QNetworkReplyPtr(QNetworkReply *ptr = 0) - : QSharedPointer<QNetworkReply>(ptr) - { } - - inline operator QNetworkReply *() const { return data(); } -}; - +typedef QSharedPointer<QNetworkReply> 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); diff --git a/tests/manual/cmake/CMakeLists.txt b/tests/manual/cmake/CMakeLists.txt index f79d078baa..f7b16946c1 100644 --- a/tests/manual/cmake/CMakeLists.txt +++ b/tests/manual/cmake/CMakeLists.txt @@ -90,3 +90,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 <stephen.kelly@kdab.com> +** 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/auto/corelib/kernel/qobject/oldnormalizeobject.h b/tests/manual/cmake/pass9/mydbusobject.h index f73027707a..dd9a023ffe 100644 --- a/tests/auto/corelib/kernel/qobject/oldnormalizeobject.h +++ b/tests/manual/cmake/pass9/mydbusobject.h @@ -1,9 +1,9 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> ** Contact: http://www.qt-project.org/ ** -** This file is part of the QtTest module of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,31 +39,20 @@ ** ****************************************************************************/ -#ifndef OLDNORMALIZEOBJECT_H -#define OLDNORMALIZEOBJECT_H +#ifndef MYDBUSOBJECT_H +#define MYDBUSOBJECT_H #include <QObject> -struct Struct; -class Class; -template <typename T> class Template; - -// An object with old moc output that incorrectly normalizes 'T<C> const &' in the function -// signatures -class OldNormalizeObject : public QObject +class MyDBusObject : public QObject { - /* tmake ignore Q_OBJECT */ Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.qtProject.Tests.MyDBusObject") +public: + MyDBusObject(QObject *parent = 0); signals: - void typeRefSignal(Template<Class &> &ref); - void constTypeRefSignal(const Template<const Class &> &ref); - void typeConstRefSignal(Template<Class const &> const &ref); - -public slots: - void typeRefSlot(Template<Class &> &) {} - void constTypeRefSlot(const Template<const Class &> &) {} - void typeConstRefSlot(Template<Class const &> const &) {} + void someSignal(); }; -#endif // OLDNORMALIZEOBJECT_H +#endif |