diff options
Diffstat (limited to 'tests/auto/corelib/tools')
20 files changed, 759 insertions, 302 deletions
diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp index 1dfe01663f..78d3e9e2b8 100644 --- a/tests/auto/corelib/tools/collections/tst_collections.cpp +++ b/tests/auto/corelib/tools/collections/tst_collections.cpp @@ -3129,7 +3129,7 @@ void tst_Collections::qtimerList() QFAIL("QList preallocates too much memory"); } -#define QVERIFY_TYPE(Type) QVERIFY(sizeof(Type)) +#define QVERIFY_TYPE(Type) QVERIFY(sizeof(Type) > 0) template <typename Container> void testContainerTypedefs(Container container) diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 5730c4df35..a7c08fddb3 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -789,7 +789,7 @@ void tst_QArrayData::alignment() + minAlignment - Q_ALIGNOF(QArrayData))); // Data is aligned - QCOMPARE(quintptr(data->data()) % alignment, quintptr(0u)); + QCOMPARE(quintptr(quintptr(data->data()) % alignment), quintptr(0u)); // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 18739cb4e1..d010ff807d 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -2000,6 +2000,9 @@ void tst_QByteArray::toUpperLower_data() QTest::addColumn<QByteArray>("lower"); QTest::newRow("empty") << QByteArray() << QByteArray() << QByteArray(); + QTest::newRow("literal") << QByteArrayLiteral("Hello World") + << QByteArrayLiteral("HELLO WORLD") + << QByteArrayLiteral("hello world"); QTest::newRow("ascii") << QByteArray("Hello World, this is a STRING") << QByteArray("HELLO WORLD, THIS IS A STRING") << QByteArray("hello world, this is a string"); @@ -2014,8 +2017,34 @@ void tst_QByteArray::toUpperLower() QFETCH(QByteArray, input); QFETCH(QByteArray, upper); QFETCH(QByteArray, lower); + QCOMPARE(lower.toLower(), lower); + QCOMPARE(upper.toUpper(), upper); QCOMPARE(input.toUpper(), upper); QCOMPARE(input.toLower(), lower); + + QByteArray copy = input; + QCOMPARE(qMove(copy).toUpper(), upper); + copy = input; + copy.detach(); + QCOMPARE(qMove(copy).toUpper(), upper); + + copy = input; + QCOMPARE(qMove(copy).toLower(), lower); + copy = input; + copy.detach(); + QCOMPARE(qMove(copy).toLower(), lower); + + copy = lower; + QCOMPARE(qMove(copy).toLower(), lower); + copy = lower; + copy.detach(); + QCOMPARE(qMove(copy).toLower(), lower); + + copy = upper; + QCOMPARE(qMove(copy).toUpper(), upper); + copy = upper; + copy.detach(); + QCOMPARE(qMove(copy).toUpper(), upper); } void tst_QByteArray::macTypes() diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/tools/qchar/tst_qchar.cpp index a4350ea2fe..55c911a5fc 100644 --- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp +++ b/tests/auto/corelib/tools/qchar/tst_qchar.cpp @@ -47,6 +47,8 @@ public slots: void init(); void cleanup(); private slots: + void operators_data(); + void operators(); void toUpper(); void toLower(); void toTitle(); @@ -99,6 +101,33 @@ void tst_QChar::cleanup() #endif } +void tst_QChar::operators_data() +{ + QTest::addColumn<QChar>("lhs"); + QTest::addColumn<QChar>("rhs"); + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) + QTest::newRow(qPrintable(QString().sprintf("'\\%d' (op) '\\%d'", i, j))) + << QChar(ushort(i)) << QChar(ushort(j)); + } +} + +void tst_QChar::operators() +{ + QFETCH(QChar, lhs); + QFETCH(QChar, rhs); + +#define CHECK(op) QCOMPARE((lhs op rhs), (lhs.unicode() op rhs.unicode())) + CHECK(==); + CHECK(!=); + CHECK(< ); + CHECK(> ); + CHECK(<=); + CHECK(>=); +#undef CHECK +} + void tst_QChar::toUpper() { QVERIFY(QChar('a').toUpper() == 'A'); diff --git a/tests/auto/corelib/tools/qdatetime/qdatetime.pro b/tests/auto/corelib/tools/qdatetime/qdatetime.pro index 0a89fe7645..25d11443e4 100644 --- a/tests/auto/corelib/tools/qdatetime/qdatetime.pro +++ b/tests/auto/corelib/tools/qdatetime/qdatetime.pro @@ -11,3 +11,8 @@ win32-msvc|win32-msvc9x { QMAKE_CXXFLAGS_RELEASE -= -O1 } DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +mac { + OBJECTIVE_SOURCES += tst_qdatetime_mac.mm + LIBS += -framework Foundation +} diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index ae812bef0e..e992c41bc1 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -145,6 +145,8 @@ private slots: void invalid() const; + void macTypes(); + private: enum { LocalTimeIsUtc = 0, LocalTimeAheadOfUtc = 1, LocalTimeBehindUtc = -1} localTimeType; bool europeanTimeZone; @@ -2989,5 +2991,15 @@ void tst_QDateTime::invalid() const QCOMPARE(tzDate.timeSpec(), Qt::TimeZone); } +void tst_QDateTime::macTypes() +{ +#ifndef Q_OS_MAC + QSKIP("This is a Apple-only test"); +#else + extern void tst_QDateTime_macTypes(); // in qdatetime_mac.mm + tst_QDateTime_macTypes(); +#endif +} + QTEST_APPLESS_MAIN(tst_QDateTime) #include "tst_qdatetime.moc" diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm b/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm new file mode 100644 index 0000000000..d03ae3faeb --- /dev/null +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Petroules Corporation. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QDateTime> +#include <QtTest/QtTest> + +#include <CoreFoundation/CoreFoundation.h> +#include <Foundation/Foundation.h> + +void tst_QDateTime_macTypes() +{ + // QDateTime <-> CFDate + { + QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); + const CFDateRef cfDate = qtDateTime.toCFDate(); + QCOMPARE(QDateTime::fromCFDate(cfDate), qtDateTime); + CFRelease(cfDate); + } + { + QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); + const CFDateRef cfDate = qtDateTime.toCFDate(); + QDateTime qtDateTimeCopy(qtDateTime); + qtDateTime.setTime_t(10000); // modify + QCOMPARE(QDateTime::fromCFDate(cfDate), qtDateTimeCopy); + } + // QDateTime <-> NSDate + { + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); + const NSDate *nsDate = qtDateTime.toNSDate(); + QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTime); + [autoreleasepool release]; + } + { + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); + const NSDate *nsDate = qtDateTime.toNSDate(); + QDateTime qtDateTimeCopy(qtDateTime); + qtDateTime.setTime_t(10000); // modify + QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTimeCopy); + [autoreleasepool release]; + } +} diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp index d1152419c0..c1d6184072 100644 --- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp @@ -51,6 +51,7 @@ private slots: void operators(); void properties(); void metaTypes(); + void propertyOrderIsNotImportant(); void bezierSpline_data(); void bezierSpline(); void tcbSpline_data(); @@ -552,6 +553,25 @@ void tst_QEasingCurve::metaTypes() QVERIFY(qMetaTypeId<QEasingCurve>() == QMetaType::QEasingCurve); } +/* + Test to ensure that regardless of what order properties are set, they should produce the same + behavior. + */ +void tst_QEasingCurve::propertyOrderIsNotImportant() +{ + + QEasingCurve c1; + c1.setPeriod(1); + c1.setType(QEasingCurve::OutSine); + QVERIFY(c1.valueForProgress(0.75) > 0.9); + + QEasingCurve c2; + c2.setType(QEasingCurve::OutSine); + c2.setPeriod(1); + + QCOMPARE(c1.valueForProgress(0.75), c2.valueForProgress(0.75)); +} + void tst_QEasingCurve::bezierSpline_data() { QTest::addColumn<QString>("definition"); diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index a1fc50fb38..39aaee102b 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -57,8 +57,6 @@ private slots: void operator_eq(); // copied from tst_QMap void rehash_isnt_quadratic(); void dont_need_default_constructor(); - void qhash(); - void fp_qhash_of_zero_is_zero(); void qmultihash_specific(); void compare(); @@ -70,9 +68,6 @@ private slots: void const_shared_null(); void twoArguments_qHash(); void initializerList(); - - void qthash_data(); - void qthash(); void eraseValidIteratorOnSharedHash(); }; @@ -1009,83 +1004,6 @@ void tst_QHash::dont_need_default_constructor() } } -void tst_QHash::qhash() -{ - { - QBitArray a1; - QBitArray a2; - QVERIFY(qHash(a1) == 0); - - a1.resize(1); - a1.setBit(0, true); - - a2.resize(1); - a2.setBit(0, false); - - uint h1 = qHash(a1); - uint h2 = qHash(a2); - - QVERIFY(h1 != h2); - - a2.setBit(0, true); - QVERIFY(h1 == qHash(a2)); - - a1.fill(true, 8); - a1.resize(7); - - h1 = qHash(a1); - - a2.fill(true, 7); - h2 = qHash(a2); - - QVERIFY(h1 == h2); - - a2.setBit(0, false); - uint h3 = qHash(a2); - QVERIFY(h2 != h3); - - a2.setBit(0, true); - QVERIFY(h2 == qHash(a2)); - - a2.setBit(6, false); - uint h4 = qHash(a2); - QVERIFY(h2 != h4); - - a2.setBit(6, true); - QVERIFY(h2 == qHash(a2)); - - QVERIFY(h3 != h4); - } - - { - QPair<int, int> p12(1, 2); - QPair<int, int> p21(2, 1); - - QVERIFY(qHash(p12) == qHash(p12)); - QVERIFY(qHash(p21) == qHash(p21)); - QVERIFY(qHash(p12) != qHash(p21)); - - QPair<int, int> pA(0x12345678, 0x12345678); - QPair<int, int> pB(0x12345675, 0x12345675); - - QVERIFY(qHash(pA) != qHash(pB)); - } -} - -void tst_QHash::fp_qhash_of_zero_is_zero() -{ - QCOMPARE(qHash(-0.0f), 0U); - QCOMPARE(qHash( 0.0f), 0U); - - QCOMPARE(qHash(-0.0 ), 0U); - QCOMPARE(qHash( 0.0 ), 0U); - -#ifndef Q_OS_DARWIN - QCOMPARE(qHash(-0.0L), 0U); - QCOMPARE(qHash( 0.0L), 0U); -#endif -} - void tst_QHash::qmultihash_specific() { QMultiHash<int, int> hash1; @@ -1384,25 +1302,6 @@ void tst_QHash::initializerList() #endif } -void tst_QHash::qthash_data() -{ - QTest::addColumn<QString>("key"); - QTest::addColumn<uint>("hash"); - - QTest::newRow("null") << QString() << 0u; - QTest::newRow("empty") << QStringLiteral("") << 0u; - QTest::newRow("abcdef") << QStringLiteral("abcdef") << 108567222u; - QTest::newRow("tqbfjotld") << QStringLiteral("The quick brown fox jumps over the lazy dog") << 140865879u; - QTest::newRow("42") << QStringLiteral("42") << 882u; -} - -void tst_QHash::qthash() -{ - QFETCH(QString, key); - const uint result = qt_hash(key); - QTEST(result, "hash"); -} - void tst_QHash::eraseValidIteratorOnSharedHash() { QHash<int, int> a, b; diff --git a/tests/auto/corelib/tools/qhashfunctions/.gitignore b/tests/auto/corelib/tools/qhashfunctions/.gitignore new file mode 100644 index 0000000000..ca8886e200 --- /dev/null +++ b/tests/auto/corelib/tools/qhashfunctions/.gitignore @@ -0,0 +1 @@ +tst_qhashfunctions diff --git a/tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro b/tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro new file mode 100644 index 0000000000..21426a4f55 --- /dev/null +++ b/tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro @@ -0,0 +1,5 @@ +CONFIG += testcase parallel_test +TARGET = tst_qhashfunctions +QT = core testlib +SOURCES = $$PWD/tst_qhashfunctions.cpp +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp new file mode 100644 index 0000000000..38d39d247c --- /dev/null +++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <qhash.h> +#include <qtypetraits.h> + +#include <iterator> +#include <sstream> +#include <algorithm> + +class tst_QHashFunctions : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void qhash(); + void fp_qhash_of_zero_is_zero(); + void qthash_data(); + void qthash(); + void range(); + void rangeCommutative(); +}; + +void tst_QHashFunctions::qhash() +{ + { + QBitArray a1; + QBitArray a2; + QVERIFY(qHash(a1) == 0); + + a1.resize(1); + a1.setBit(0, true); + + a2.resize(1); + a2.setBit(0, false); + + uint h1 = qHash(a1); + uint h2 = qHash(a2); + + QVERIFY(h1 != h2); + + a2.setBit(0, true); + QVERIFY(h1 == qHash(a2)); + + a1.fill(true, 8); + a1.resize(7); + + h1 = qHash(a1); + + a2.fill(true, 7); + h2 = qHash(a2); + + QVERIFY(h1 == h2); + + a2.setBit(0, false); + uint h3 = qHash(a2); + QVERIFY(h2 != h3); + + a2.setBit(0, true); + QVERIFY(h2 == qHash(a2)); + + a2.setBit(6, false); + uint h4 = qHash(a2); + QVERIFY(h2 != h4); + + a2.setBit(6, true); + QVERIFY(h2 == qHash(a2)); + + QVERIFY(h3 != h4); + } + + { + QPair<int, int> p12(1, 2); + QPair<int, int> p21(2, 1); + + QVERIFY(qHash(p12) == qHash(p12)); + QVERIFY(qHash(p21) == qHash(p21)); + QVERIFY(qHash(p12) != qHash(p21)); + + QPair<int, int> pA(0x12345678, 0x12345678); + QPair<int, int> pB(0x12345675, 0x12345675); + + QVERIFY(qHash(pA) != qHash(pB)); + } +} + +void tst_QHashFunctions::fp_qhash_of_zero_is_zero() +{ + QCOMPARE(qHash(-0.0f), 0U); + QCOMPARE(qHash( 0.0f), 0U); + + QCOMPARE(qHash(-0.0 ), 0U); + QCOMPARE(qHash( 0.0 ), 0U); + +#ifndef Q_OS_DARWIN + QCOMPARE(qHash(-0.0L), 0U); + QCOMPARE(qHash( 0.0L), 0U); +#endif +} + +void tst_QHashFunctions::qthash_data() +{ + QTest::addColumn<QString>("key"); + QTest::addColumn<uint>("hash"); + + QTest::newRow("null") << QString() << 0u; + QTest::newRow("empty") << QStringLiteral("") << 0u; + QTest::newRow("abcdef") << QStringLiteral("abcdef") << 108567222u; + QTest::newRow("tqbfjotld") << QStringLiteral("The quick brown fox jumps over the lazy dog") << 140865879u; + QTest::newRow("42") << QStringLiteral("42") << 882u; +} + +void tst_QHashFunctions::qthash() +{ + QFETCH(QString, key); + const uint result = qt_hash(key); + QTEST(result, "hash"); +} + +namespace SomeNamespace { + struct Hashable { int i; }; + inline uint qHash(Hashable h, uint seed = 0) + { return QT_PREPEND_NAMESPACE(qHash)(h.i, seed); } +} + +void tst_QHashFunctions::range() +{ + static const int ints[] = {0, 1, 2, 3, 4, 5}; + static const size_t numInts = sizeof ints / sizeof *ints; + + // empty range just gives the seed: + QCOMPARE(qHashRange(ints, ints, 0xdeadbeefU), 0xdeadbeefU); + // verify that order matters: + QVERIFY(qHashRange(ints, ints + numInts) != + qHashRange(std::reverse_iterator<const int*>(ints + numInts), std::reverse_iterator<const int*>(ints))); + + { + // verify that the input iterator category suffices: + std::stringstream sstream; + Q_STATIC_ASSERT((QtPrivate::is_same<std::input_iterator_tag, std::istream_iterator<int>::iterator_category>::value)); + std::copy(ints, ints + numInts, std::ostream_iterator<int>(sstream, " ")); + sstream.seekg(0); + std::istream_iterator<int> it(sstream), end; + QCOMPARE(qHashRange(ints, ints + numInts), qHashRange(it, end)); + } + + SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}}; + static const size_t numHashables = sizeof hashables / sizeof *hashables; + // compile check: is qHash() found using ADL? + (void)qHashRange(hashables, hashables + numHashables); +} + +void tst_QHashFunctions::rangeCommutative() +{ + int ints[] = {0, 1, 2, 3, 4, 5}; + static const size_t numInts = sizeof ints / sizeof *ints; + + // empty range just gives the seed: + QCOMPARE(qHashRangeCommutative(ints, ints, 0xdeadbeefU), 0xdeadbeefU); + // verify that order doesn't matter: + QCOMPARE(qHashRangeCommutative(ints, ints + numInts), + qHashRangeCommutative(std::reverse_iterator<int*>(ints + numInts), std::reverse_iterator<int*>(ints))); + + { + // verify that the input iterator category suffices: + std::stringstream sstream; + std::copy(ints, ints + numInts, std::ostream_iterator<int>(sstream, " ")); + sstream.seekg(0); + std::istream_iterator<int> it(sstream), end; + QCOMPARE(qHashRangeCommutative(ints, ints + numInts), qHashRangeCommutative(it, end)); + } + + SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}}; + static const size_t numHashables = sizeof hashables / sizeof *hashables; + // compile check: is qHash() found using ADL? + (void)qHashRangeCommutative(hashables, hashables + numHashables); +} + +QTEST_APPLESS_MAIN(tst_QHashFunctions) +#include "tst_qhashfunctions.moc" diff --git a/tests/auto/corelib/tools/qline/qline.pro b/tests/auto/corelib/tools/qline/qline.pro index acdba32db1..56f852ac52 100644 --- a/tests/auto/corelib/tools/qline/qline.pro +++ b/tests/auto/corelib/tools/qline/qline.pro @@ -2,5 +2,5 @@ CONFIG += testcase parallel_test TARGET = tst_qline QT = core testlib SOURCES = tst_qline.cpp -unix:!mac:!vxworks:LIBS+=-lm +unix:!mac:!vxworks:!haiku:LIBS+=-lm DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp index db22f99cb8..1b6fe2aefe 100644 --- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp @@ -237,6 +237,95 @@ void consistencyCheck(const QRegularExpressionMatchIterator &iterator) } +template<typename Result> +static void prepareResultForNoMatchType(Result *r, const Result &orig) +{ + Q_UNUSED(r); + Q_UNUSED(orig); +} + +static void prepareResultForNoMatchType(Match *m, const Match &orig) +{ + m->isValid = orig.isValid; +} + +template<typename QREMatch, typename QREMatchFunc, typename Subject, typename Result> +static void testMatchImpl(const QRegularExpression ®exp, + QREMatchFunc matchingMethod, + const Subject &subject, + int offset, + QRegularExpression::MatchType matchType, + QRegularExpression::MatchOptions matchOptions, + const Result &result) +{ + { + const QREMatch m = (regexp.*matchingMethod)(subject, offset, matchType, matchOptions); + consistencyCheck(m); + QVERIFY(m == result); + QCOMPARE(m.regularExpression(), regexp); + QCOMPARE(m.matchType(), matchType); + QCOMPARE(m.matchOptions(), matchOptions); + } + { + // ignore the expected results provided by the match object -- + // we'll never get any result when testing the NoMatch type. + // Just check the validity of the match here. + Result realMatch; + prepareResultForNoMatchType(&realMatch, result); + + const QREMatch m = (regexp.*matchingMethod)(subject, offset, QRegularExpression::NoMatch, matchOptions); + consistencyCheck(m); + QVERIFY(m == realMatch); + QCOMPARE(m.regularExpression(), regexp); + QCOMPARE(m.matchType(), QRegularExpression::NoMatch); + QCOMPARE(m.matchOptions(), matchOptions); + } +} + +template<typename QREMatch, typename QREMatchFuncForString, typename QREMatchFuncForStringRef, typename Result> +static void testMatch(const QRegularExpression ®exp, + QREMatchFuncForString matchingMethodForString, + QREMatchFuncForStringRef matchingMethodForStringRef, + const QString &subject, + int offset, + QRegularExpression::MatchType matchType, + QRegularExpression::MatchOptions matchOptions, + const Result &result) +{ + if (forceOptimize) + regexp.optimize(); + + // test with QString as subject type + testMatchImpl<QREMatch>(regexp, matchingMethodForString, subject, offset, matchType, matchOptions, result); + + // test with QStringRef as subject type + testMatchImpl<QREMatch>(regexp, + matchingMethodForStringRef, + QStringRef(&subject, 0, subject.length()), + offset, + matchType, + matchOptions, + result); + + // offset <= 0 tested above; now also test stringrefs not spanning over + // the entire subject. Note that the offset can be negative, hence the above + // tests can't be merged into this one + for (int i = 1; i <= offset; ++i) { + testMatchImpl<QREMatch>(regexp, + matchingMethodForStringRef, + QStringRef(&subject, i, subject.length() - i), + offset - i, + matchType, + matchOptions, + result); + } +} + +typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const; +typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringRefPMF)(const QStringRef &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const; +typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const; +typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringRefPMF)(const QStringRef &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const; + void tst_QRegularExpression::provideRegularExpressions() { QTest::addColumn<QString>("pattern"); @@ -526,6 +615,7 @@ void tst_QRegularExpression::normalMatch_data() QTest::addColumn<Match>("match"); Match m; + int offset = 0; m.clear(); m.isValid = true; m.hasMatch = true; @@ -577,20 +667,28 @@ void tst_QRegularExpression::normalMatch_data() m.clear(); m.isValid = true; m.hasMatch = true; m.captured << "c123def" << "c12" << "3" << "def"; - QTest::newRow("match06") << QRegularExpression("(\\w*)(\\d+)(\\w*)") - << "abc123def" - << 2 - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 2; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("match06-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("(\\w*)(\\d+)(\\w*)") + << QStringLiteral("abc123def").mid(offset - i) + << i + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } m.clear(); m.isValid = true; m.hasMatch = true; m.captured << QString(""); - QTest::newRow("match07") << QRegularExpression("\\w*") - << "abc123def" - << 9 - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 9; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("match07-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("\\w*") + << QStringLiteral("abc123def").mid(offset - i) + << i + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } m.clear(); m.isValid = true; m.hasMatch = true; @@ -648,19 +746,27 @@ void tst_QRegularExpression::normalMatch_data() m.clear(); m.isValid = true; - QTest::newRow("nomatch02") << QRegularExpression("(\\w+) (\\w+)") - << "a string" - << 1 - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 1; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("nomatch02-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("(\\w+) (\\w+)") + << QStringLiteral("a string").mid(offset - i) + << i + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } m.clear(); m.isValid = true; - QTest::newRow("nomatch03") << QRegularExpression("\\w+") - << "abc123def" - << 9 - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 9; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("nomatch03-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("\\w+") + << QStringLiteral("abc123def").mid(offset - i) + << i + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } // *** @@ -728,32 +834,14 @@ void tst_QRegularExpression::normalMatch() QFETCH(QRegularExpression::MatchOptions, matchOptions); QFETCH(Match, match); - if (forceOptimize) - regexp.optimize(); - - { - QRegularExpressionMatch m = regexp.match(subject, offset, QRegularExpression::NormalMatch, matchOptions); - consistencyCheck(m); - QVERIFY(m == match); - QCOMPARE(m.regularExpression(), regexp); - QCOMPARE(m.matchType(), QRegularExpression::NormalMatch); - QCOMPARE(m.matchOptions(), matchOptions); - } - { - // ignore the expected results provided by the match object -- - // we'll never get any result when testing the NoMatch type. - // Just check the validity of the match here. - Match realMatch; - realMatch.clear(); - realMatch.isValid = match.isValid; - - QRegularExpressionMatch m = regexp.match(subject, offset, QRegularExpression::NoMatch, matchOptions); - consistencyCheck(m); - QVERIFY(m == realMatch); - QCOMPARE(m.regularExpression(), regexp); - QCOMPARE(m.matchType(), QRegularExpression::NoMatch); - QCOMPARE(m.matchOptions(), matchOptions); - } + testMatch<QRegularExpressionMatch>(regexp, + static_cast<QREMatchStringPMF>(&QRegularExpression::match), + static_cast<QREMatchStringRefPMF>(&QRegularExpression::match), + subject, + offset, + QRegularExpression::NormalMatch, + matchOptions, + match); } void tst_QRegularExpression::partialMatch_data() @@ -766,6 +854,7 @@ void tst_QRegularExpression::partialMatch_data() QTest::addColumn<Match>("match"); Match m; + int offset = 0; m.clear(); m.isValid = true; m.hasPartialMatch = true; @@ -840,12 +929,16 @@ void tst_QRegularExpression::partialMatch_data() m.clear(); m.isValid = true; m.hasPartialMatch = true; m.captured << "def"; - QTest::newRow("softmatch08") << QRegularExpression("abc\\w+X|defY") - << "abcdef" - << 1 - << QRegularExpression::PartialPreferCompleteMatch - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 1; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("softmatch08-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("abc\\w+X|defY") + << QStringLiteral("abcdef").mid(offset - i) + << i + << QRegularExpression::PartialPreferCompleteMatch + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } // *** @@ -922,12 +1015,16 @@ void tst_QRegularExpression::partialMatch_data() m.clear(); m.isValid = true; m.hasPartialMatch = true; m.captured << "def"; - QTest::newRow("hardmatch08") << QRegularExpression("abc\\w+X|defY") - << "abcdef" - << 1 - << QRegularExpression::PartialPreferFirstMatch - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 1; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("hardmatch08-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("abc\\w+X|defY") + << QStringLiteral("abcdef").mid(offset - i) + << i + << QRegularExpression::PartialPreferFirstMatch + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } m.clear(); m.isValid = true; m.hasPartialMatch = true; @@ -1009,32 +1106,14 @@ void tst_QRegularExpression::partialMatch() QFETCH(QRegularExpression::MatchOptions, matchOptions); QFETCH(Match, match); - if (forceOptimize) - regexp.optimize(); - - { - QRegularExpressionMatch m = regexp.match(subject, offset, matchType, matchOptions); - consistencyCheck(m); - QVERIFY(m == match); - QCOMPARE(m.regularExpression(), regexp); - QCOMPARE(m.matchType(), matchType); - QCOMPARE(m.matchOptions(), matchOptions); - } - { - // ignore the expected results provided by the match object -- - // we'll never get any result when testing the NoMatch type. - // Just check the validity of the match here. - Match realMatch; - realMatch.clear(); - realMatch.isValid = match.isValid; - - QRegularExpressionMatch m = regexp.match(subject, offset, QRegularExpression::NoMatch, matchOptions); - consistencyCheck(m); - QVERIFY(m == realMatch); - QCOMPARE(m.regularExpression(), regexp); - QCOMPARE(m.matchType(), QRegularExpression::NoMatch); - QCOMPARE(m.matchOptions(), matchOptions); - } + testMatch<QRegularExpressionMatch>(regexp, + static_cast<QREMatchStringPMF>(&QRegularExpression::match), + static_cast<QREMatchStringRefPMF>(&QRegularExpression::match), + subject, + offset, + matchType, + matchOptions, + match); } void tst_QRegularExpression::globalMatch_data() @@ -1304,31 +1383,14 @@ void tst_QRegularExpression::globalMatch() QFETCH(QRegularExpression::MatchOptions, matchOptions); QFETCH(QList<Match>, matchList); - if (forceOptimize) - regexp.optimize(); - - { - QRegularExpressionMatchIterator iterator = regexp.globalMatch(subject, offset, matchType, matchOptions); - consistencyCheck(iterator); - QVERIFY(iterator == matchList); - QCOMPARE(iterator.regularExpression(), regexp); - QCOMPARE(iterator.matchType(), matchType); - QCOMPARE(iterator.matchOptions(), matchOptions); - } - { - // ignore the expected results provided by the match object -- - // we'll never get any result when testing the NoMatch type. - // Just check the validity of the match here. - QList<Match> realMatchList; - - QRegularExpressionMatchIterator iterator = regexp.globalMatch(subject, offset, QRegularExpression::NoMatch, matchOptions); - consistencyCheck(iterator); - QVERIFY(iterator == realMatchList); - QCOMPARE(iterator.regularExpression(), regexp); - QCOMPARE(iterator.matchType(), QRegularExpression::NoMatch); - QCOMPARE(iterator.matchOptions(), matchOptions); - } - + testMatch<QRegularExpressionMatchIterator>(regexp, + static_cast<QREGlobalMatchStringPMF>(&QRegularExpression::globalMatch), + static_cast<QREGlobalMatchStringRefPMF>(&QRegularExpression::globalMatch), + subject, + offset, + matchType, + matchOptions, + matchList); } void tst_QRegularExpression::serialize_data() diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp index d892125c87..33f1b25519 100644 --- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp +++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp @@ -294,16 +294,16 @@ void tst_QRingBuffer::readLine() char stringBuf[102]; stringBuf[101] = 0; // non-crash terminator QVERIFY(ringBuffer.readLine(stringBuf, sizeof(stringBuf) - 2) == ba1.size()); - QVERIFY(QByteArray(stringBuf, strlen(stringBuf)) == ba1); + QVERIFY(QByteArray(stringBuf, int(strlen(stringBuf))) == ba1); // check first empty string reading - stringBuf[0] = 0xFF; - QCOMPARE(ringBuffer.readLine(stringBuf, sizeof(stringBuf) - 2), ba2.size()); + stringBuf[0] = char(0xFF); + QCOMPARE(ringBuffer.readLine(stringBuf, int(sizeof(stringBuf)) - 2), ba2.size()); QVERIFY(stringBuf[0] == ba2[0]); - QVERIFY(ringBuffer.readLine(stringBuf, sizeof(stringBuf) - 2) == (ba3.size() + ba4.size() + QVERIFY(ringBuffer.readLine(stringBuf, int(sizeof(stringBuf)) - 2) == (ba3.size() + ba4.size() + ba2.size())); - QVERIFY(QByteArray(stringBuf, strlen(stringBuf)) == (ba3 + ba4 + ba2)); + QVERIFY(QByteArray(stringBuf, int(strlen(stringBuf))) == (ba3 + ba4 + ba2)); QVERIFY(ringBuffer.size() == 0); } diff --git a/tests/auto/corelib/tools/qset/tst_qset.cpp b/tests/auto/corelib/tools/qset/tst_qset.cpp index f04eefad51..30f7e3741d 100644 --- a/tests/auto/corelib/tools/qset/tst_qset.cpp +++ b/tests/auto/corelib/tools/qset/tst_qset.cpp @@ -72,6 +72,7 @@ private slots: void javaMutableIterator(); void makeSureTheComfortFunctionsCompile(); void initializerList(); + void qhash(); }; struct IdentityTracker { @@ -137,6 +138,16 @@ void tst_QSet::operator_eq() QVERIFY(a != b); QVERIFY(!(a == b)); } + + { + QSet<int> s1, s2; + s1.reserve(100); + s2.reserve(4); + QVERIFY(s1 == s2); + s1 << 100 << 200 << 300 << 400; + s2 << 400 << 300 << 200 << 100; + QVERIFY(s1 == s2); + } } void tst_QSet::swap() @@ -958,6 +969,67 @@ void tst_QSet::initializerList() #endif } +QT_BEGIN_NAMESPACE +extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; // from qhash.cpp +QT_END_NAMESPACE + +class QtQHashSeedSaver { + int oldSeed, newSeed; +public: + explicit QtQHashSeedSaver(int seed) + : oldSeed(qt_qhash_seed.fetchAndStoreRelaxed(seed)), + newSeed(seed) + {} + ~QtQHashSeedSaver() + { + // only restore when no-one else changed the seed in the meantime: + qt_qhash_seed.testAndSetRelaxed(newSeed, oldSeed); + } +}; + +void tst_QSet::qhash() +{ + // + // check that sets containing the same elements hash to the same value + // + { + // create some deterministic initial state: + const QtQHashSeedSaver seed1(0); + + QSet<int> s1; + s1.reserve(4); + s1 << 400 << 300 << 200 << 100; + + // also change the seed: + const QtQHashSeedSaver seed2(0x10101010); + + QSet<int> s2; + s2.reserve(100); // provoke different bucket counts + s2 << 100 << 200 << 300 << 400; // and insert elements in different order, too + + QVERIFY(s1.capacity() != s2.capacity()); + QCOMPARE(s1, s2); + QVERIFY(!std::equal(s1.cbegin(), s1.cend(), s2.cbegin())); // verify that the order _is_ different + QCOMPARE(qHash(s1), qHash(s2)); + } + + // + // check that sets of sets work: + // + { +#ifdef Q_COMPILER_INITIALIZER_LISTS + QSet<QSet<int> > intSetSet = { { 0, 1, 2 }, { 0, 1 }, { 1, 2 } }; +#else + QSet<QSet<int> > intSetSet; + QSet<int> intSet01, intSet12; + intSet01 << 0 << 1; + intSet12 << 1 << 2; + intSetSet << intSet01 << intSet12 << (intSet01|intSet12); +#endif + QCOMPARE(intSetSet.size(), 3); + } +} + QTEST_APPLESS_MAIN(tst_QSet) #include "tst_qset.moc" diff --git a/tests/auto/corelib/tools/qstring/qstring.pro b/tests/auto/corelib/tools/qstring/qstring.pro index 971e2fb782..1eda27e1ff 100644 --- a/tests/auto/corelib/tools/qstring/qstring.pro +++ b/tests/auto/corelib/tools/qstring/qstring.pro @@ -4,6 +4,7 @@ QT = core testlib SOURCES = tst_qstring.cpp DEFINES += QT_NO_CAST_TO_ASCII contains(QT_CONFIG,icu):DEFINES += QT_USE_ICU +contains(QT_CONFIG,c++11): CONFIG += c++11 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 mac { diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index ea40c64c89..356724916b 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -59,6 +59,7 @@ #include <locale.h> #include <qhash.h> +#include <string> #define CREATE_REF(string) \ const QString padded = QString::fromLatin1(" %1 ").arg(string); \ @@ -155,6 +156,7 @@ private slots: void lastIndexOfInvalidRegex(); void indexOf_data(); void indexOf(); + void indexOfInvalidRegex(); void indexOf2_data(); void indexOf2(); void indexOf3_data(); @@ -262,6 +264,7 @@ private slots: void assignQLatin1String(); void isRightToLeft_data(); void isRightToLeft(); + void unicodeStrings(); }; template <class T> const T &verifyZeroTermination(const T &t) { return t; } @@ -325,75 +328,6 @@ QString verifyZeroTermination(const QString &str) typedef QList<int> IntList; -// This next bit is needed for the NAN and INF in string -> number conversion tests -#include <float.h> -#include <limits.h> -#include <math.h> -#if defined (Q_OS_WIN) -# include <windows.h> -// mingw defines NAN and INFINITY to 0/0 and x/0 -# if defined(Q_CC_GNU) -# undef NAN -# undef INFINITY -# else -# define isnan(d) _isnan(d) -# endif -#endif -#if defined (Q_OS_MAC) && !defined isnan -#define isnan(d) __isnand(d) -#endif -#if defined (Q_OS_SOLARIS) -# include <ieeefp.h> -#endif -#if defined (Q_OS_OSF) && (defined(__DECC) || defined(__DECCXX)) -# define INFINITY DBL_INFINITY -# define NAN DBL_QNAN -#endif -#if defined(Q_OS_IRIX) && defined(Q_CC_GNU) -# include <ieeefp.h> -# define isnan(d) isnand(d) -#endif - -enum { - LittleEndian, - BigEndian -#ifdef Q_BYTE_ORDER -# if Q_BYTE_ORDER == Q_BIG_ENDIAN - , ByteOrder = BigEndian -# elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN - , ByteOrder = LittleEndian -# else -# error "undefined byte order" -# endif -}; -#else -}; -static const unsigned int one = 1; -static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian); -#endif -#if !defined(INFINITY) -static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0,0 }; -static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; -static inline double inf() -{ - if (ByteOrder == BigEndian) - return *reinterpret_cast<const double *>(be_inf_bytes); - return *reinterpret_cast<const double *>(le_inf_bytes); -} -# define INFINITY (::inf()) -#endif -#if !defined(NAN) -static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0,0 }; -static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; -static inline double nan() -{ - if (ByteOrder == BigEndian) - return *reinterpret_cast<const double *>(be_nan_bytes); - return *reinterpret_cast<const double *>(le_nan_bytes); -} -# define NAN (::nan()) -#endif - tst_QString::tst_QString() { QTextCodec::setCodecForLocale(QTextCodec::codecForName("ISO 8859-1")); @@ -812,10 +746,8 @@ void tst_QString::acc_01() } } -#ifdef Q_CC_GNU -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wformat-security" -#endif +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Wformat-security") void tst_QString::isNull() { @@ -827,9 +759,7 @@ void tst_QString::isNull() QVERIFY(!a.isNull()); } -#ifdef Q_CC_GNU -# pragma GCC diagnostic pop -#endif +QT_WARNING_POP void tst_QString::isEmpty() { @@ -1182,6 +1112,18 @@ void tst_QString::indexOf() QRegularExpression re(QRegularExpression::escape(needle), options); QCOMPARE( haystack.indexOf(re, startpos), resultpos ); + QCOMPARE(haystack.indexOf(re, startpos, Q_NULLPTR), resultpos); + + QRegularExpressionMatch match; + QVERIFY(!match.hasMatch()); + QCOMPARE(haystack.indexOf(re, startpos, &match), resultpos); + QCOMPARE(match.hasMatch(), resultpos != -1); + if (resultpos > -1 && needleIsLatin) { + if (bcs) + QVERIFY(match.captured() == needle); + else + QVERIFY(match.captured().toLower() == needle.toLower()); + } } if (cs == Qt::CaseSensitive) { @@ -1290,6 +1232,20 @@ void tst_QString::indexOf2() } } +void tst_QString::indexOfInvalidRegex() +{ + QTest::ignoreMessage(QtWarningMsg, "QString::indexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\")), -1); + QTest::ignoreMessage(QtWarningMsg, "QString::indexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, Q_NULLPTR), -1); + + QRegularExpressionMatch match; + QVERIFY(!match.hasMatch()); + QTest::ignoreMessage(QtWarningMsg, "QString::indexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, &match), -1); + QVERIFY(!match.hasMatch()); +} + void tst_QString::lastIndexOf_data() { QTest::addColumn<QString>("haystack" ); @@ -1379,6 +1335,17 @@ void tst_QString::lastIndexOf() QRegularExpression re(QRegularExpression::escape(needle), options); QCOMPARE(haystack.lastIndexOf(re, from), expected); + QCOMPARE(haystack.lastIndexOf(re, from, Q_NULLPTR), expected); + QRegularExpressionMatch match; + QVERIFY(!match.hasMatch()); + QCOMPARE(haystack.lastIndexOf(re, from, &match), expected); + QCOMPARE(match.hasMatch(), expected > -1); + if (expected > -1) { + if (caseSensitive) + QCOMPARE(match.captured(), needle); + else + QCOMPARE(match.captured().toLower(), needle.toLower()); + } } } @@ -1403,7 +1370,15 @@ void tst_QString::lastIndexOf() void tst_QString::lastIndexOfInvalidRegex() { QTest::ignoreMessage(QtWarningMsg, "QString::lastIndexOf: invalid QRegularExpression object"); - QCOMPARE(QString("").lastIndexOf(QRegularExpression("invalid regex\\"), 0), -1); + QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), 0), -1); + QTest::ignoreMessage(QtWarningMsg, "QString::lastIndexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, Q_NULLPTR), -1); + + QRegularExpressionMatch match; + QVERIFY(!match.hasMatch()); + QTest::ignoreMessage(QtWarningMsg, "QString::lastIndexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, &match), -1); + QVERIFY(!match.hasMatch()); } void tst_QString::count() @@ -1838,6 +1813,7 @@ void tst_QString::toUpper() { QCOMPARE( QString().toUpper(), QString() ); QCOMPARE( QString("").toUpper(), QString("") ); + QCOMPARE( QStringLiteral("text").toUpper(), QString("TEXT") ); QCOMPARE( QString("text").toUpper(), QString("TEXT") ); QCOMPARE( QString("Text").toUpper(), QString("TEXT") ); QCOMPARE( QString("tExt").toUpper(), QString("TEXT") ); @@ -1898,6 +1874,7 @@ void tst_QString::toLower() QCOMPARE( QString().toLower(), QString() ); QCOMPARE( QString("").toLower(), QString("") ); QCOMPARE( QString("text").toLower(), QString("text") ); + QCOMPARE( QStringLiteral("Text").toLower(), QString("text") ); QCOMPARE( QString("Text").toLower(), QString("text") ); QCOMPARE( QString("tExt").toLower(), QString("text") ); QCOMPARE( QString("teXt").toLower(), QString("text") ); @@ -2019,6 +1996,13 @@ void tst_QString::trimmed() QCOMPARE(a,(QString)" "); a=" a "; QCOMPARE(a.trimmed(),(QString)"a"); + + a="Text"; + QCOMPARE(qMove(a).trimmed(),(QString)"Text"); + a=" "; + QCOMPARE(qMove(a).trimmed(),(QString)""); + a=" a "; + QCOMPARE(qMove(a).trimmed(),(QString)"a"); } void tst_QString::simplified_data() @@ -2063,9 +2047,12 @@ void tst_QString::simplified() QVERIFY2(result.isEmpty() && !result.isNull(), qPrintable("'" + full + "' did not yield empty: " + result)); } else { QCOMPARE(result, simple); - if (full == simple) - QVERIFY(result.isSharedWith(full)); } + + // force a detach + if (!full.isEmpty()) + full[0] = full[0]; + QCOMPARE(qMove(full).simplified(), simple); } void tst_QString::insert() @@ -4454,6 +4441,8 @@ void tst_QString::section() QCOMPARE( wholeString.section( QRegExp(sep), start, end, QString::SectionFlag(flags) ), sectionString ); QCOMPARE( wholeString.section( QRegularExpression(sep), start, end, QString::SectionFlag(flags) ), sectionString ); } else { + if (sep.size() == 1) + QCOMPARE( wholeString.section( sep[0], start, end, QString::SectionFlag(flags) ), sectionString ); 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 ); @@ -5235,6 +5224,27 @@ void tst_QString::fromUtf16_char16() #endif } +void tst_QString::unicodeStrings() +{ +#ifdef Q_COMPILER_UNICODE_STRINGS + QString s1, s2; + static const std::u16string u16str1(u"Hello Unicode World"); + static const std::u32string u32str1(U"Hello Unicode World"); + s1 = QString::fromStdU16String(u16str1); + s2 = QString::fromStdU32String(u32str1); + QCOMPARE(s1, QString("Hello Unicode World")); + QCOMPARE(s1, s2); + + QCOMPARE(s2.toStdU16String(), u16str1); + QCOMPARE(s1.toStdU32String(), u32str1); + + s1 = QString::fromStdU32String(std::u32string(U"\u221212\U000020AC\U00010000")); + QCOMPARE(s1, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200")); +#else + QSKIP("Compiler does not support C++11 unicode strings"); +#endif +} + void tst_QString::latin1String() { QString s("Hello"); @@ -5257,7 +5267,7 @@ void tst_QString::nanAndInf() #define CHECK_DOUBLE(str, expected_ok, expected_inf) \ d = QString(str).toDouble(&ok); \ QVERIFY(ok == expected_ok); \ - QVERIFY((d == INFINITY) == expected_inf); + QVERIFY(qIsInf(d) == expected_inf); CHECK_DOUBLE("inf", true, true) CHECK_DOUBLE("INF", true, true) @@ -5285,17 +5295,15 @@ void tst_QString::nanAndInf() #define CHECK_NAN(str, expected_ok, expected_nan) \ d = QString(str).toDouble(&ok); \ QVERIFY(ok == expected_ok); \ - QVERIFY((bool)isnan(d) == expected_nan); \ + QVERIFY(qIsNaN(d) == expected_nan); CHECK_NAN("nan", true, true) CHECK_NAN("NAN", true, true) CHECK_NAN("nan ", true, true) CHECK_NAN("\t NAN", true, true) CHECK_NAN("\t NAN ", true, true) -#ifndef QT_QLOCALE_USES_FCVT //In case we use glibc this tests will fail CHECK_NAN("-nan", false, false) CHECK_NAN("+NAN", false, false) -#endif CHECK_NAN("NaN", true, true) CHECK_NAN("nAn", true, true) CHECK_NAN("NANe-10", false, false) @@ -5305,7 +5313,7 @@ void tst_QString::nanAndInf() d = QString("-INF").toDouble(&ok); QVERIFY(ok); - QVERIFY(d == -INFINITY); + QVERIFY(d == -qInf()); QString("INF").toLong(&ok); QVERIFY(!ok); diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 9a79d48472..c9e8a5f657 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -575,6 +575,18 @@ void tst_QVector::append() const QCOMPARE(v.last(), SimpleValue<T>::at(0)); } #endif + { + QVector<int> v; + v << 1 << 2 << 3; + QVector<int> x; + x << 4 << 5 << 6; + v.append(x); + + QVector<int> combined; + combined << 1 << 2 << 3 << 4 << 5 << 6; + + QCOMPARE(v, combined); + } } void tst_QVector::appendInt() const diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro index ce37ccb18b..9024a1a1bb 100644 --- a/tests/auto/corelib/tools/tools.pro +++ b/tests/auto/corelib/tools/tools.pro @@ -23,6 +23,7 @@ SUBDIRS=\ qfreelist \ qhash \ qhash_strictiterators \ + qhashfunctions \ qline \ qlinkedlist \ qlist \ |