diff options
Diffstat (limited to 'tests/auto/corelib/tools')
19 files changed, 793 insertions, 104 deletions
diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp index af270ded98..38366e86ff 100644 --- a/tests/auto/corelib/tools/collections/tst_collections.cpp +++ b/tests/auto/corelib/tools/collections/tst_collections.cpp @@ -3208,19 +3208,31 @@ public: }; Q_STATIC_ASSERT(Q_ALIGNOF(Aligned4) % 4 == 0); -class Q_DECL_ALIGN(128) Aligned128 +#if defined(Q_PROCESSOR_ARM) +# if defined(Q_COMPILER_ALIGNAS) && defined(__BIGGEST_ALIGNMENT__) + // On ARM __BIGGEST_ALIGNMENT__ must be multiplied by 8 to + // get the same limit as enforced by alignas() +# define BIGGEST_ALIGNMENT_TO_TEST (__BIGGEST_ALIGNMENT__ << 3) +# endif +#endif + +#if !defined(BIGGEST_ALIGNMENT_TO_TEST) +# define BIGGEST_ALIGNMENT_TO_TEST 128 +#endif + +class Q_DECL_ALIGN(BIGGEST_ALIGNMENT_TO_TEST) AlignedBiggest { char i; public: - Aligned128(int i = 0) : i(i) {} + AlignedBiggest(int i = 0) : i(i) {} - enum { PreferredAlignment = 128 }; + enum { PreferredAlignment = BIGGEST_ALIGNMENT_TO_TEST }; - 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); } + inline bool operator==(const AlignedBiggest &other) const { return i == other.i; } + inline bool operator<(const AlignedBiggest &other) const { return i < other.i; } + friend inline int qHash(const AlignedBiggest &a) { return qHash(a.i); } }; -Q_STATIC_ASSERT(Q_ALIGNOF(Aligned128) % 128 == 0); +Q_STATIC_ASSERT(Q_ALIGNOF(AlignedBiggest) % BIGGEST_ALIGNMENT_TO_TEST == 0); template<typename C> void testVectorAlignment() @@ -3278,17 +3290,17 @@ void testAssociativeContainerAlignment() void tst_Collections::alignment() { testVectorAlignment<QVector<Aligned4> >(); - testVectorAlignment<QVector<Aligned128> >(); + testVectorAlignment<QVector<AlignedBiggest> >(); testContiguousCacheAlignment<QContiguousCache<Aligned4> >(); - testContiguousCacheAlignment<QContiguousCache<Aligned128> >(); + testContiguousCacheAlignment<QContiguousCache<AlignedBiggest> >(); testAssociativeContainerAlignment<QMap<Aligned4, Aligned4> >(); - testAssociativeContainerAlignment<QMap<Aligned4, Aligned128> >(); - testAssociativeContainerAlignment<QMap<Aligned128, Aligned4> >(); - testAssociativeContainerAlignment<QMap<Aligned128, Aligned128> >(); + testAssociativeContainerAlignment<QMap<Aligned4, AlignedBiggest> >(); + testAssociativeContainerAlignment<QMap<AlignedBiggest, Aligned4> >(); + testAssociativeContainerAlignment<QMap<AlignedBiggest, AlignedBiggest> >(); testAssociativeContainerAlignment<QHash<Aligned4, Aligned4> >(); - testAssociativeContainerAlignment<QHash<Aligned4, Aligned128> >(); - testAssociativeContainerAlignment<QHash<Aligned128, Aligned4> >(); - testAssociativeContainerAlignment<QHash<Aligned128, Aligned128> >(); + testAssociativeContainerAlignment<QHash<Aligned4, AlignedBiggest> >(); + testAssociativeContainerAlignment<QHash<AlignedBiggest, Aligned4> >(); + testAssociativeContainerAlignment<QHash<AlignedBiggest, AlignedBiggest> >(); } #else diff --git a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp index c14e9fadf7..e13c2894af 100644 --- a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp +++ b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp @@ -1076,22 +1076,22 @@ void tst_QAlgorithms::popCount_data_impl(size_t sizeof_T_Int) const uint bits = bitsSetInByte(byte); const quint64 value = static_cast<quint64>(byte); const quint64 input = value << ((i % sizeof_T_Int) * 8U); - newRow(qPrintable(QString::asprintf("0x%016llx", input))) << input << bits; + QTest::addRow("0x%016llx", input) << input << bits; } // and some random ones: if (sizeof_T_Int >= 8) for (size_t i = 0; i < 1000; ++i) { const quint64 input = quint64(qrand()) << 32 | quint32(qrand()); - newRow(qPrintable(QString::asprintf("0x%016llx", input))) << input << bitsSetInInt64(input); + QTest::addRow("0x%016llx", input) << input << bitsSetInInt64(input); } else if (sizeof_T_Int >= 2) for (size_t i = 0; i < 1000 ; ++i) { const quint32 input = qrand(); if (sizeof_T_Int >= 4) - newRow(qPrintable(QString::asprintf("0x%08x", input))) << quint64(input) << bitsSetInInt(input); + QTest::addRow("0x%08x", input) << quint64(input) << bitsSetInInt(input); else - newRow(qPrintable(QString::asprintf("0x%04x", quint16(input & 0xFFFF)))) << quint64(input & 0xFFFF) << bitsSetInShort(input & 0xFFFF); + QTest::addRow("0x%04x", quint16(input & 0xFFFF)) << quint64(input & 0xFFFF) << bitsSetInShort(input & 0xFFFF); } } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 3be8379d29..a00c962510 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -65,6 +65,8 @@ private slots: void simpleVectorReserve(); void allocate_data(); void allocate(); + void reallocate_data() { allocate_data(); } + void reallocate(); void alignment_data(); void alignment(); void typedData(); @@ -742,6 +744,53 @@ void tst_QArrayData::allocate() } } +void tst_QArrayData::reallocate() +{ + QFETCH(size_t, objectSize); + QFETCH(size_t, alignment); + QFETCH(QArrayData::AllocationOptions, allocateOptions); + QFETCH(bool, isCapacityReserved); + + // Maximum alignment that can be requested is that of QArrayData, + // otherwise, we can't use reallocate(). + Q_ASSERT(alignment <= Q_ALIGNOF(QArrayData)); + + // 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)); + + int capacity = 10; + Deallocator keeper(objectSize, minAlignment); + QArrayData *data = QArrayData::allocate(objectSize, minAlignment, capacity, + QArrayData::AllocationOptions(allocateOptions) & ~QArrayData::Grow); + keeper.headers.append(data); + + memset(data->data(), 'A', objectSize * capacity); + data->size = capacity; + + // now try to reallocate + int newCapacity = 40; + data = QArrayData::reallocateUnaligned(data, objectSize, newCapacity, + QArrayData::AllocationOptions(allocateOptions)); + QVERIFY(data); + keeper.headers.clear(); + keeper.headers.append(data); + + QCOMPARE(data->size, capacity); + if (allocateOptions & QArrayData::Grow) + QVERIFY(data->alloc > uint(newCapacity)); + else + QCOMPARE(data->alloc, uint(newCapacity)); + QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) + QFETCH(bool, isSharable); + QCOMPARE(data->ref.isSharable(), isSharable); +#endif + + for (int i = 0; i < capacity; ++i) + QCOMPARE(static_cast<char *>(data->data())[i], 'A'); +} + class Unaligned { char dummy[8]; diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 310c5f6fd3..16a9c03351 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -43,6 +43,8 @@ public: tst_QByteArray(); private slots: void swap(); + void qChecksum_data(); + void qChecksum(); void qCompress_data(); #ifndef QT_NO_COMPRESS void qCompress(); @@ -239,6 +241,34 @@ tst_QByteArray::tst_QByteArray() { } +void tst_QByteArray::qChecksum_data() +{ + QTest::addColumn<QByteArray>("data"); + QTest::addColumn<uint>("len"); + QTest::addColumn<Qt::ChecksumType>("standard"); + QTest::addColumn<uint>("checksum"); + + // Examples from ISO 14443-3 + QTest::newRow("1") << QByteArray("\x00\x00") << 2U << Qt::ChecksumItuV41 << 0x1EA0U; + QTest::newRow("2") << QByteArray("\x12\x34") << 2U << Qt::ChecksumItuV41 << 0xCF26U; + QTest::newRow("3") << QByteArray("\x00\x00\x00") << 3U << Qt::ChecksumIso3309 << 0xC6CCU; + QTest::newRow("4") << QByteArray("\x0F\xAA\xFF") << 3U << Qt::ChecksumIso3309 << 0xD1FCU; + QTest::newRow("5") << QByteArray("\x0A\x12\x34\x56") << 4U << Qt::ChecksumIso3309 << 0xF62CU; +} + +void tst_QByteArray::qChecksum() +{ + QFETCH(QByteArray, data); + QFETCH(uint, len); + QFETCH(Qt::ChecksumType, standard); + QFETCH(uint, checksum); + + if (standard == Qt::ChecksumIso3309) { + QCOMPARE(::qChecksum(data.constData(), len), static_cast<quint16>(checksum)); + } + QCOMPARE(::qChecksum(data.constData(), len, standard), static_cast<quint16>(checksum)); +} + void tst_QByteArray::qCompress_data() { QTest::addColumn<QByteArray>("ba"); @@ -1443,61 +1473,97 @@ void tst_QByteArray::appendAfterFromRawData() void tst_QByteArray::toFromHex_data() { QTest::addColumn<QByteArray>("str"); + QTest::addColumn<char>("sep"); QTest::addColumn<QByteArray>("hex"); QTest::addColumn<QByteArray>("hex_alt1"); - QTest::newRow("Qt is great!") + QTest::newRow("Qt is great! (default)") << QByteArray("Qt is great!") + << '\0' << QByteArray("517420697320677265617421") << QByteArray("51 74 20 69 73 20 67 72 65 61 74 21"); + QTest::newRow("Qt is great! (with space)") + << QByteArray("Qt is great!") + << ' ' + << QByteArray("51 74 20 69 73 20 67 72 65 61 74 21") + << QByteArray("51 74 20 69 73 20 67 72 65 61 74 21"); + + QTest::newRow("Qt is great! (with minus)") + << QByteArray("Qt is great!") + << '-' + << QByteArray("51-74-20-69-73-20-67-72-65-61-74-21") + << QByteArray("51-74-20-69-73-20-67-72-65-61-74-21"); + QTest::newRow("Qt is so great!") << QByteArray("Qt is so great!") + << '\0' << QByteArray("517420697320736f20677265617421") << QByteArray("51 74 20 69 73 20 73 6f 20 67 72 65 61 74 21"); QTest::newRow("default-constructed") << QByteArray() + << '\0' + << QByteArray() + << QByteArray(); + + QTest::newRow("default-constructed (with space)") + << QByteArray() + << ' ' << QByteArray() << QByteArray(); QTest::newRow("empty") << QByteArray("") + << '\0' + << QByteArray("") + << QByteArray(""); + + QTest::newRow("empty (with space)") + << QByteArray("") + << ' ' << QByteArray("") << QByteArray(""); QTest::newRow("array-of-null") << QByteArray("\0", 1) + << '\0' << QByteArray("00") << QByteArray("0"); QTest::newRow("no-leading-zero") << QByteArray("\xf") + << '\0' << QByteArray("0f") << QByteArray("f"); QTest::newRow("single-byte") << QByteArray("\xaf") + << '\0' << QByteArray("af") << QByteArray("xaf"); QTest::newRow("no-leading-zero") << QByteArray("\xd\xde\xad\xc0\xde") + << '\0' << QByteArray("0ddeadc0de") << QByteArray("ddeadc0de"); QTest::newRow("garbage") << QByteArray("\xC\xde\xeC\xea\xee\xDe\xee\xee") + << '\0' << QByteArray("0cdeeceaeedeeeee") << QByteArray("Code less. Create more. Deploy everywhere."); QTest::newRow("under-defined-1") << QByteArray("\x1\x23") + << '\0' << QByteArray("0123") << QByteArray("x123"); QTest::newRow("under-defined-2") << QByteArray("\x12\x34") + << '\0' << QByteArray("1234") << QByteArray("x1234"); } @@ -1505,16 +1571,23 @@ void tst_QByteArray::toFromHex_data() void tst_QByteArray::toFromHex() { QFETCH(QByteArray, str); + QFETCH(char, sep); QFETCH(QByteArray, hex); QFETCH(QByteArray, hex_alt1); - { + if (sep == 0) { const QByteArray th = str.toHex(); QCOMPARE(th.size(), hex.size()); QCOMPARE(th, hex); } { + const QByteArray th = str.toHex(sep); + QCOMPARE(th.size(), hex.size()); + QCOMPARE(th, hex); + } + + { const QByteArray fh = QByteArray::fromHex(hex); QCOMPARE(fh.size(), str.size()); QCOMPARE(fh, str); diff --git a/tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro b/tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro index 0624e1886c..9d4d5964c9 100644 --- a/tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro +++ b/tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro @@ -2,3 +2,4 @@ CONFIG += testcase TARGET = tst_qbytearraymatcher QT = core testlib SOURCES = tst_qbytearraymatcher.cpp +contains(QT_CONFIG, c++14):CONFIG += c++14 diff --git a/tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp b/tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp index 82cc432d55..647a3ae379 100644 --- a/tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp +++ b/tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp @@ -43,10 +43,9 @@ class tst_QByteArrayMatcher : public QObject private slots: void interface(); void indexIn(); + void staticByteArrayMatcher(); }; -static QByteArrayMatcher matcher1; - void tst_QByteArrayMatcher::interface() { const char needle[] = "abc123"; @@ -56,6 +55,8 @@ void tst_QByteArrayMatcher::interface() haystack.insert(42, "abc123"); haystack.insert(84, "abc123"); + QByteArrayMatcher matcher1; + matcher1 = QByteArrayMatcher(QByteArray(needle)); QByteArrayMatcher matcher2; matcher2.setPattern(QByteArray(needle)); @@ -90,8 +91,10 @@ void tst_QByteArrayMatcher::interface() QCOMPARE(matcher7.indexIn(haystack), 42); } - -static QByteArrayMatcher matcher; +#define LONG_STRING__32 "abcdefghijklmnopqrstuvwxyz012345" +#define LONG_STRING__64 LONG_STRING__32 LONG_STRING__32 +#define LONG_STRING_128 LONG_STRING__64 LONG_STRING__64 +#define LONG_STRING_256 LONG_STRING_128 LONG_STRING_128 void tst_QByteArrayMatcher::indexIn() { @@ -101,6 +104,8 @@ void tst_QByteArrayMatcher::indexIn() QByteArray haystack(8, '\0'); haystack[7] = 0x1; + QByteArrayMatcher matcher; + matcher = QByteArrayMatcher(pattern); QCOMPARE(matcher.indexIn(haystack, 0), 5); QCOMPARE(matcher.indexIn(haystack, 1), 5); @@ -110,7 +115,103 @@ void tst_QByteArrayMatcher::indexIn() QCOMPARE(matcher.indexIn(haystack, 0), 5); QCOMPARE(matcher.indexIn(haystack, 1), 5); QCOMPARE(matcher.indexIn(haystack, 2), 5); + + QByteArray allChars(256, Qt::Uninitialized); + for (int i = 0; i < 256; ++i) + allChars[i] = char(i); + + matcher = QByteArrayMatcher(allChars); + haystack = LONG_STRING__32 "x" + matcher.pattern(); + QCOMPARE(matcher.indexIn(haystack, 0), 33); + QCOMPARE(matcher.indexIn(haystack, 1), 33); + QCOMPARE(matcher.indexIn(haystack, 2), 33); + QCOMPARE(matcher.indexIn(haystack, 33), 33); + QCOMPARE(matcher.indexIn(haystack, 34), -1); + + matcher = QByteArrayMatcher(LONG_STRING_256); + haystack = LONG_STRING__32 "x" + matcher.pattern(); + QCOMPARE(matcher.indexIn(haystack, 0), 33); + QCOMPARE(matcher.indexIn(haystack, 1), 33); + QCOMPARE(matcher.indexIn(haystack, 2), 33); + QCOMPARE(matcher.indexIn(haystack, 33), 33); + QCOMPARE(matcher.indexIn(haystack, 34), -1); } +void tst_QByteArrayMatcher::staticByteArrayMatcher() +{ + { + static Q_RELAXED_CONSTEXPR auto smatcher = qMakeStaticByteArrayMatcher("Hello"); + QCOMPARE(smatcher.pattern(), QByteArrayLiteral("Hello")); + + QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!")), 0); + QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!"), 0), 0); + QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!"), 1), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aHello, World!")), 1); + QCOMPARE(smatcher.indexIn(QByteArray("aaHello, World!")), 2); + QCOMPARE(smatcher.indexIn(QByteArray("aaaHello, World!")), 3); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaHello, World!")), 4); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHello, World!")), 5); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHello, World!")), 6); + QCOMPARE(smatcher.indexIn(QByteArray("HHello, World!")), 1); + QCOMPARE(smatcher.indexIn(QByteArray("HeHello, World!")), 2); + QCOMPARE(smatcher.indexIn(QByteArray("HelHello, World!")), 3); + QCOMPARE(smatcher.indexIn(QByteArray("HellHello, World!")), 4); + QCOMPARE(smatcher.indexIn(QByteArray("HellaHello, World!")), 5); + QCOMPARE(smatcher.indexIn(QByteArray("HellauHello, World!")), 6); + QCOMPARE(smatcher.indexIn(QByteArray("aHella, World!")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaHella, World!")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaaHella, World!")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaHella, World!")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHella, World!")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHella, World!")), -1); + + QCOMPARE(smatcher.indexIn(QByteArray("aHello")), 1); + QCOMPARE(smatcher.indexIn(QByteArray("aaHello")), 2); + QCOMPARE(smatcher.indexIn(QByteArray("aaaHello")), 3); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaHello")), 4); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHello")), 5); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHello")), 6); + QCOMPARE(smatcher.indexIn(QByteArray("HHello")), 1); + QCOMPARE(smatcher.indexIn(QByteArray("HeHello")), 2); + QCOMPARE(smatcher.indexIn(QByteArray("HelHello")), 3); + QCOMPARE(smatcher.indexIn(QByteArray("HellHello")), 4); + QCOMPARE(smatcher.indexIn(QByteArray("HellaHello")), 5); + QCOMPARE(smatcher.indexIn(QByteArray("HellauHello")), 6); + QCOMPARE(smatcher.indexIn(QByteArray("aHella")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaHella")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaaHella")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaHella")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHella")), -1); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHella")), -1); + } + + { + static Q_RELAXED_CONSTEXPR auto smatcher = qMakeStaticByteArrayMatcher(LONG_STRING_256); + QCOMPARE(smatcher.pattern(), QByteArrayLiteral(LONG_STRING_256)); + + QCOMPARE(smatcher.indexIn(QByteArray("a" LONG_STRING_256)), 1); + QCOMPARE(smatcher.indexIn(QByteArray("aa" LONG_STRING_256)), 2); + QCOMPARE(smatcher.indexIn(QByteArray("aaa" LONG_STRING_256)), 3); + QCOMPARE(smatcher.indexIn(QByteArray("aaaa" LONG_STRING_256)), 4); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaa" LONG_STRING_256)), 5); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaa" LONG_STRING_256)), 6); + QCOMPARE(smatcher.indexIn(QByteArray("a" LONG_STRING_256 "a")), 1); + QCOMPARE(smatcher.indexIn(QByteArray("aa" LONG_STRING_256 "a")), 2); + QCOMPARE(smatcher.indexIn(QByteArray("aaa" LONG_STRING_256 "a")), 3); + QCOMPARE(smatcher.indexIn(QByteArray("aaaa" LONG_STRING_256 "a")), 4); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaa" LONG_STRING_256 "a")), 5); + QCOMPARE(smatcher.indexIn(QByteArray("aaaaaa" LONG_STRING_256 "a")), 6); + QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING__32 "x" LONG_STRING_256)), 33); + QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING__64 "x" LONG_STRING_256)), 65); + QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING_128 "x" LONG_STRING_256)), 129); + } + +} + +#undef LONG_STRING_256 +#undef LONG_STRING_128 +#undef LONG_STRING__64 +#undef LONG_STRING__32 + QTEST_APPLESS_MAIN(tst_QByteArrayMatcher) #include "tst_qbytearraymatcher.moc" diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/tools/qchar/tst_qchar.cpp index b42be94da3..e5a6e953d3 100644 --- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp +++ b/tests/auto/corelib/tools/qchar/tst_qchar.cpp @@ -127,7 +127,7 @@ void tst_QChar::operators_data() for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) - QTest::newRow(qPrintable(QString::asprintf("'\\%d' (op) '\\%d'", i, j))) + QTest::addRow("'\\%d' (op) '\\%d'", i, j) << QChar(ushort(i)) << QChar(ushort(j)); } } diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index b6c740998e..28ad2d193c 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -80,8 +80,10 @@ private slots: void fromMSecsSinceEpoch(); void toString_isoDate_data(); void toString_isoDate(); + void toString_isoDate_extra(); void toString_textDate_data(); void toString_textDate(); + void toString_textDate_extra(); void toString_rfcDate_data(); void toString_rfcDate(); void toString_enumformat(); @@ -158,8 +160,6 @@ private: QDateTime invalidDateTime() const { return QDateTime(invalidDate(), invalidTime()); } QDate invalidDate() const { return QDate(); } QTime invalidTime() const { return QTime(-1, -1, -1); } - qint64 minJd() const { return QDateTimePrivate::minJd(); } - qint64 maxJd() const { return QDateTimePrivate::maxJd(); } class TimeZoneRollback { @@ -642,10 +642,8 @@ void tst_QDateTime::setMSecsSinceEpoch_data() << QDateTime(QDate::fromJulianDay(0x7fffffff), QTime(21, 59, 59, 999), Qt::UTC) << QDateTime(QDate::fromJulianDay(0x7fffffff), QTime(23, 59, 59, 999)); QTest::newRow("min") - // + 1 because, in the reference check below, calling addMSecs(qint64min) - // will internally apply unary minus to -qint64min, resulting in a - // positive value 1 too big for qint64max, causing an overflow. - << std::numeric_limits<qint64>::min() + 1 + // Use -max(), which is min() + 1, to simplify filtering out overflow cases: + << -std::numeric_limits<qint64>::max() << QDateTime(QDate(-292275056, 5, 16), QTime(16, 47, 4, 193), Qt::UTC) << QDateTime(QDate(-292275056, 5, 16), QTime(17, 47, 4, 193), Qt::LocalTime); QTest::newRow("max") @@ -746,8 +744,8 @@ void tst_QDateTime::fromMSecsSinceEpoch() QDateTime dtUtc = QDateTime::fromMSecsSinceEpoch(msecs, Qt::UTC); QDateTime dtOffset = QDateTime::fromMSecsSinceEpoch(msecs, Qt::OffsetFromUTC, 60*60); - // LocalTime will overflow for min or max, depending on whether you're - // East or West of Greenwich. The test passes at GMT. + // LocalTime will overflow for "min" or "max" tests, depending on whether + // you're East or West of Greenwich. In UTC, we won't overflow. if (localTimeType == LocalTimeIsUtc || msecs != std::numeric_limits<qint64>::max() * localTimeType) QCOMPARE(dtLocal, utc); @@ -853,6 +851,28 @@ void tst_QDateTime::toString_isoDate() QLocale::setDefault(oldLocale); } +void tst_QDateTime::toString_isoDate_extra() +{ + QDateTime dt = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC); + QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1970-01-01T00:00:00Z")); +#if QT_CONFIG(timezone) + QTimeZone PST("America/Vancouver"); + if (PST.isValid()) { + dt = QDateTime::fromMSecsSinceEpoch(0, PST); + QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1969-12-31T16:00:00-08:00")); + } else { + qDebug("Missed zone test: no America/Vancouver zone available"); + } + QTimeZone CET("Europe/Berlin"); + if (CET.isValid()) { + dt = QDateTime::fromMSecsSinceEpoch(0, CET); + QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1970-01-01T01:00:00+01:00")); + } else { + qDebug("Missed zone test: no Europe/Berlin zone available"); + } +#endif // timezone +} + void tst_QDateTime::toString_textDate_data() { QTest::addColumn<QDateTime>("datetime"); @@ -890,6 +910,49 @@ void tst_QDateTime::toString_textDate() QCOMPARE(resultDatetime.utcOffset(), datetime.utcOffset()); } +void tst_QDateTime::toString_textDate_extra() +{ + QLatin1String GMT("GMT"); + QDateTime dt = QDateTime::fromMSecsSinceEpoch(0, Qt::LocalTime); + QVERIFY(!dt.toString().endsWith(GMT)); + dt = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC).toLocalTime(); + QVERIFY(!dt.toString().endsWith(GMT)); + if (QTimeZone::systemTimeZone().offsetFromUtc(dt)) + QVERIFY(dt.toString() != QLatin1String("Thu Jan 1 00:00:00 1970")); + else + QCOMPARE(dt.toString(), QLatin1String("Thu Jan 1 00:00:00 1970")); +#if QT_CONFIG(timezone) + QTimeZone PST("America/Vancouver"); + if (PST.isValid()) { + dt = QDateTime::fromMSecsSinceEpoch(0, PST); +# if defined Q_OS_UNIX && !defined Q_OS_DARWIN + QCOMPARE(dt.toString(), QLatin1String("Wed Dec 31 16:00:00 1969 PST")); +# else // QTBUG-57320, QTBUG-57298 + QVERIFY(dt.toString().startsWith(QLatin1String("Wed Dec 31 16:00:00 1969 "))); +# endif + dt = dt.toLocalTime(); + QVERIFY(!dt.toString().endsWith(GMT)); + } else { + qDebug("Missed zone test: no America/Vancouver zone available"); + } + QTimeZone CET("Europe/Berlin"); + if (CET.isValid()) { + dt = QDateTime::fromMSecsSinceEpoch(0, CET); +# if defined Q_OS_UNIX && !defined Q_OS_DARWIN + QCOMPARE(dt.toString(), QLatin1String("Thu Jan 1 01:00:00 1970 CET")); +# else // QTBUG-57320, QTBUG-57298 + QVERIFY(dt.toString().startsWith(QLatin1String("Thu Jan 1 01:00:00 1970 "))); +# endif + dt = dt.toLocalTime(); + QVERIFY(!dt.toString().endsWith(GMT)); + } else { + qDebug("Missed zone test: no Europe/Berlin zone available"); + } +#endif // timezone + dt = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC); + QVERIFY(dt.toString().endsWith(GMT)); +} + void tst_QDateTime::toString_rfcDate_data() { QTest::addColumn<QDateTime>("dt"); @@ -3232,17 +3295,17 @@ void tst_QDateTime::timeZones() const // Test local to MSecs // - Test first occurrence 02:00:00 = 1 hour before tran hourBeforeStd = QDateTime(QDate(2013, 10, 27), QTime(2, 0, 0), cet); + QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); QCOMPARE(hourBeforeStd.toMSecsSinceEpoch(), dstToStdMSecs - 3600000); // - Test first occurrence 02:59:59.999 = 1 msec before tran msecBeforeStd = QDateTime(QDate(2013, 10, 27), QTime(2, 59, 59, 999), cet); + QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); QCOMPARE(msecBeforeStd.toMSecsSinceEpoch(), dstToStdMSecs - 1); // - Test second occurrence 02:00:00 = at tran atStd = QDateTime(QDate(2013, 10, 27), QTime(2, 0, 0), cet); - QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); QCOMPARE(atStd.toMSecsSinceEpoch(), dstToStdMSecs); // - Test second occurrence 03:00:00 = 59 mins after tran afterStd = QDateTime(QDate(2013, 10, 27), QTime(2, 59, 59, 999), cet); - QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); QCOMPARE(afterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000 - 1); // - Test 03:00:00 = 1 hour after tran hourAfterStd = QDateTime(QDate(2013, 10, 27), QTime(3, 0, 0), cet); diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 0b864e71d4..0c5f1a7afb 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -1053,6 +1053,10 @@ void tst_QHash::keyIterator() QCOMPARE(*(--key_it), (--it).key()); QCOMPARE(std::count(hash.keyBegin(), hash.keyEnd(), 99), 1); + + // DefaultConstructible test + typedef QHash<int, int>::key_iterator keyIterator; + Q_STATIC_ASSERT(std::is_default_constructible<keyIterator>::value); } void tst_QHash::rehash_isnt_quadratic() diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp index 0c890eafbc..4a81adf9fe 100644 --- a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp +++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp @@ -37,11 +37,22 @@ class tst_QHashFunctions : public QObject { Q_OBJECT +public: + enum { + // random value + RandomSeed = 1045982819 + }; + uint seed; + +public slots: + void initTestCase(); + void init(); + private Q_SLOTS: void qhash(); void qhash_of_empty_and_null_qstring(); void qhash_of_empty_and_null_qbytearray(); - void fp_qhash_of_zero_is_zero(); + void fp_qhash_of_zero_is_seed(); void qthash_data(); void qthash(); void range(); @@ -50,12 +61,27 @@ private Q_SLOTS: void setGlobalQHashSeed(); }; +void tst_QHashFunctions::initTestCase() +{ + Q_STATIC_ASSERT(int(RandomSeed) > 0); + + QTest::addColumn<uint>("seedValue"); + QTest::newRow("zero-seed") << 0U; + QTest::newRow("non-zero-seed") << uint(RandomSeed); +} + +void tst_QHashFunctions::init() +{ + QFETCH_GLOBAL(uint, seedValue); + seed = seedValue; +} + void tst_QHashFunctions::qhash() { { QBitArray a1; QBitArray a2; - QVERIFY(qHash(a1) == 0); + QCOMPARE(qHash(a1, seed), seed); a1.resize(1); a1.setBit(0, true); @@ -63,53 +89,53 @@ void tst_QHashFunctions::qhash() a2.resize(1); a2.setBit(0, false); - uint h1 = qHash(a1); - uint h2 = qHash(a2); + uint h1 = qHash(a1, seed); + uint h2 = qHash(a2, seed); - QVERIFY(h1 != h2); + QVERIFY(h1 != h2); // not guaranteed a2.setBit(0, true); - QVERIFY(h1 == qHash(a2)); + QVERIFY(h1 == qHash(a2, seed)); a1.fill(true, 8); a1.resize(7); - h1 = qHash(a1); + h1 = qHash(a1, seed); a2.fill(true, 7); - h2 = qHash(a2); + h2 = qHash(a2, seed); QVERIFY(h1 == h2); a2.setBit(0, false); - uint h3 = qHash(a2); - QVERIFY(h2 != h3); + uint h3 = qHash(a2, seed); + QVERIFY(h2 != h3); // not guaranteed a2.setBit(0, true); - QVERIFY(h2 == qHash(a2)); + QVERIFY(h2 == qHash(a2, seed)); a2.setBit(6, false); - uint h4 = qHash(a2); - QVERIFY(h2 != h4); + uint h4 = qHash(a2, seed); + QVERIFY(h2 != h4); // not guaranteed a2.setBit(6, true); - QVERIFY(h2 == qHash(a2)); + QVERIFY(h2 == qHash(a2, seed)); - QVERIFY(h3 != h4); + QVERIFY(h3 != h4); // not guaranteed } { 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)); + QVERIFY(qHash(p12, seed) == qHash(p12, seed)); + QVERIFY(qHash(p21, seed) == qHash(p21, seed)); + QVERIFY(qHash(p12, seed) != qHash(p21, seed)); // not guaranteed QPair<int, int> pA(0x12345678, 0x12345678); QPair<int, int> pB(0x12345675, 0x12345675); - QVERIFY(qHash(pA) != qHash(pB)); + QVERIFY(qHash(pA, seed) != qHash(pB, seed)); // not guaranteed } { @@ -118,14 +144,14 @@ void tst_QHashFunctions::qhash() using QT_PREPEND_NAMESPACE(qHash); - QVERIFY(qHash(p12) == qHash(p12)); - QVERIFY(qHash(p21) == qHash(p21)); - QVERIFY(qHash(p12) != qHash(p21)); + QVERIFY(qHash(p12, seed) == qHash(p12, seed)); + QVERIFY(qHash(p21, seed) == qHash(p21, seed)); + QVERIFY(qHash(p12, seed) != qHash(p21, seed)); // not guaranteed std::pair<int, int> pA(0x12345678, 0x12345678); std::pair<int, int> pB(0x12345675, 0x12345675); - QVERIFY(qHash(pA) != qHash(pB)); + QVERIFY(qHash(pA, seed) != qHash(pB, seed)); // not guaranteed } } @@ -133,27 +159,27 @@ void tst_QHashFunctions::qhash_of_empty_and_null_qstring() { QString null, empty(""); QCOMPARE(null, empty); - QCOMPARE(qHash(null), qHash(empty)); + QCOMPARE(qHash(null, seed), qHash(empty, seed)); } void tst_QHashFunctions::qhash_of_empty_and_null_qbytearray() { QByteArray null, empty(""); QCOMPARE(null, empty); - QCOMPARE(qHash(null), qHash(empty)); + QCOMPARE(qHash(null, seed), qHash(empty, seed)); } -void tst_QHashFunctions::fp_qhash_of_zero_is_zero() +void tst_QHashFunctions::fp_qhash_of_zero_is_seed() { - QCOMPARE(qHash(-0.0f), 0U); - QCOMPARE(qHash( 0.0f), 0U); + QCOMPARE(qHash(-0.0f, seed), seed); + QCOMPARE(qHash( 0.0f, seed), seed); - QCOMPARE(qHash(-0.0 ), 0U); - QCOMPARE(qHash( 0.0 ), 0U); + QCOMPARE(qHash(-0.0 , seed), seed); + QCOMPARE(qHash( 0.0 , seed), seed); #ifndef Q_OS_DARWIN - QCOMPARE(qHash(-0.0L), 0U); - QCOMPARE(qHash( 0.0L), 0U); + QCOMPARE(qHash(-0.0L, seed), seed); + QCOMPARE(qHash( 0.0L, seed), seed); #endif } @@ -188,10 +214,10 @@ void tst_QHashFunctions::range() 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))); + QCOMPARE(qHashRange(ints, ints, seed), seed); + // verify that order matters (test not guaranteed): + QVERIFY(qHashRange(ints, ints + numInts, seed) != + qHashRange(std::reverse_iterator<const int*>(ints + numInts), std::reverse_iterator<const int*>(ints), seed)); { // verify that the input iterator category suffices: @@ -200,13 +226,13 @@ void tst_QHashFunctions::range() 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)); + QCOMPARE(qHashRange(ints, ints + numInts, seed), qHashRange(it, end, seed)); } 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)qHashRange(hashables, hashables + numHashables, seed); } void tst_QHashFunctions::rangeCommutative() @@ -215,10 +241,10 @@ void tst_QHashFunctions::rangeCommutative() 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))); + QCOMPARE(qHashRangeCommutative(ints, ints, seed), seed); + // verify that order doesn't matter (test not guaranteed): + QCOMPARE(qHashRangeCommutative(ints, ints + numInts, seed), + qHashRangeCommutative(std::reverse_iterator<int*>(ints + numInts), std::reverse_iterator<int*>(ints), seed)); { // verify that the input iterator category suffices: @@ -226,13 +252,13 @@ void tst_QHashFunctions::rangeCommutative() 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)); + QCOMPARE(qHashRangeCommutative(ints, ints + numInts, seed), qHashRangeCommutative(it, end, seed)); } 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); + (void)qHashRangeCommutative(hashables, hashables + numHashables, seed); } void tst_QHashFunctions::setGlobalQHashSeed() diff --git a/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp b/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp index 06e2e1cc45..a68671d899 100644 --- a/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp +++ b/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp @@ -176,9 +176,9 @@ void tst_QLatin1String::relationalOperators_data() for (Data *lhs = data; lhs != data + sizeof data / sizeof *data; ++lhs) { for (Data *rhs = data; rhs != data + sizeof data / sizeof *data; ++rhs) { QLatin1StringContainer l = { lhs->l1 }, r = { rhs->l1 }; - QTest::newRow(qPrintable(QString::asprintf("\"%s\" <> \"%s\"", - lhs->l1.data() ? lhs->l1.data() : "nullptr", - rhs->l1.data() ? rhs->l1.data() : "nullptr"))) + QTest::addRow("\"%s\" <> \"%s\"", + lhs->l1.data() ? lhs->l1.data() : "nullptr", + rhs->l1.data() ? rhs->l1.data() : "nullptr") << l << lhs->order << r << rhs->order; } } diff --git a/tests/auto/corelib/tools/qlocale/test/test.pro b/tests/auto/corelib/tools/qlocale/test/test.pro index 595ee258e7..c87e29e764 100644 --- a/tests/auto/corelib/tools/qlocale/test/test.pro +++ b/tests/auto/corelib/tools/qlocale/test/test.pro @@ -1,5 +1,4 @@ CONFIG += console testcase -CONFIG -= app_bundle QT = core testlib core-private embedded: QT += gui SOURCES = ../tst_qlocale.cpp diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index d18af71e20..5d13d9e454 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -1601,9 +1601,7 @@ void tst_QLocale::macDefaultLocale() // To run this test make sure "Curreny" is US Dollar in System Preferences->Language & Region->Advanced. if (locale.currencySymbol() == QString("$")) { QCOMPARE(locale.toCurrencyString(qulonglong(1234)), systemLocaleFormatNumber(QString("$1,234.00"))); - QCOMPARE(locale.toCurrencyString(qlonglong(-1234)), systemLocaleFormatNumber(QString("($1,234.00)"))); QCOMPARE(locale.toCurrencyString(double(1234.56)), systemLocaleFormatNumber(QString("$1,234.56"))); - QCOMPARE(locale.toCurrencyString(double(-1234.56)), systemLocaleFormatNumber(QString("($1,234.56)"))); } // Depending on the configured time zone, the time string might not @@ -1803,6 +1801,30 @@ void tst_QLocale::numberOptions() QVERIFY(ok); locale.toDouble(QString("1.24e+01"), &ok); QVERIFY(!ok); + + QCOMPARE(locale.toString(12.4, 'g', 5), QString("12.4")); + locale.setNumberOptions(QLocale::IncludeTrailingZeroesAfterDot); + QCOMPARE(locale.numberOptions(), QLocale::IncludeTrailingZeroesAfterDot); + QCOMPARE(locale.toString(12.4, 'g', 5), QString("12.400")); + + locale.toDouble(QString("1.24e+01"), &ok); + QVERIFY(ok); + locale.toDouble(QString("1.2400e+01"), &ok); + QVERIFY(ok); + locale.toDouble(QString("12.4"), &ok); + QVERIFY(ok); + locale.toDouble(QString("12.400"), &ok); + QVERIFY(ok); + locale.setNumberOptions(QLocale::RejectTrailingZeroesAfterDot); + QCOMPARE(locale.numberOptions(), QLocale::RejectTrailingZeroesAfterDot); + locale.toDouble(QString("1.24e+01"), &ok); + QVERIFY(ok); + locale.toDouble(QString("1.2400e+01"), &ok); + QVERIFY(!ok); + locale.toDouble(QString("12.4"), &ok); + QVERIFY(ok); + locale.toDouble(QString("12.400"), &ok); + QVERIFY(!ok); } void tst_QLocale::negativeNumbers() diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index 8aa7a3e518..f42ffc0471 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -857,6 +857,10 @@ void tst_QMap::keyIterator() QCOMPARE(*(--key_it), (--it).key()); QCOMPARE(std::count(map.keyBegin(), map.keyEnd(), 99), 1); + + // DefaultConstructible test + typedef QMap<int, int>::key_iterator keyIterator; + Q_STATIC_ASSERT(std::is_default_constructible<keyIterator>::value); } void tst_QMap::keys_values_uniqueKeys() diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 414ba2d8cf..03436375dd 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -1066,6 +1066,7 @@ void tst_QString::acc_01() QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wformat-security") +QT_WARNING_DISABLE_CLANG("-Wformat-security") void tst_QString::isNull() { @@ -3817,7 +3818,7 @@ void tst_QString::startsWith() QVERIFY( !a.startsWith(QLatin1Char('x')) ); QVERIFY( !a.startsWith(QChar()) ); - a = QString::null; + a = QString(); QVERIFY( !a.startsWith("") ); QVERIFY( a.startsWith(QString::null) ); QVERIFY( !a.startsWith("ABC") ); @@ -3927,7 +3928,7 @@ void tst_QString::endsWith() QVERIFY( a.endsWith(QLatin1String(0)) ); QVERIFY( !a.endsWith(QLatin1String("ABC")) ); - a = QString::null; + a = QString(); QVERIFY( !a.endsWith("") ); QVERIFY( a.endsWith(QString::null) ); QVERIFY( !a.endsWith("ABC") ); @@ -4272,11 +4273,7 @@ void tst_QString::local8Bit_data() QTest::addColumn<QString>("local8Bit"); QTest::addColumn<QByteArray>("result"); -/* - QString::local8Bit() called on a null QString returns an _empty_ - QByteArray. -*/ - QTest::newRow("nullString") << QString() << QByteArray(""); + QTest::newRow("nullString") << QString() << QByteArray(); QTest::newRow("emptyString") << QString("") << QByteArray(""); QTest::newRow("string") << QString("test") << QByteArray("test"); @@ -6070,6 +6067,14 @@ void tst_QString::compare_data() lower += QChar(QChar::lowSurrogate(0x10428)); QTest::newRow("data8") << upper << lower << -1 << 0; + QTest::newRow("vectorized-boundaries-7") << QString("1234567") << QString("abcdefg") << -1 << -1; + QTest::newRow("vectorized-boundaries-8") << QString("12345678") << QString("abcdefgh") << -1 << -1; + QTest::newRow("vectorized-boundaries-9") << QString("123456789") << QString("abcdefghi") << -1 << -1; + + QTest::newRow("vectorized-boundaries-15") << QString("123456789012345") << QString("abcdefghiklmnop") << -1 << -1; + QTest::newRow("vectorized-boundaries-16") << QString("1234567890123456") << QString("abcdefghiklmnopq") << -1 << -1; + QTest::newRow("vectorized-boundaries-17") << QString("12345678901234567") << QString("abcdefghiklmnopqr") << -1 << -1; + // embedded nulls // These don't work as of now. It's OK that these don't work since \0 is not a valid unicode /*QTest::newRow("data10") << QString(QByteArray("\0", 1)) << QString(QByteArray("\0", 1)) << 0 << 0; @@ -6337,7 +6342,7 @@ void tst_QString::repeatedSignature() const { /* repated() should be a const member. */ const QString string; - string.repeated(3); + (void) string.repeated(3); } void tst_QString::repeated() const diff --git a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp index 7305a00d94..9d9b47b61e 100644 --- a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -34,6 +34,7 @@ #include <QChar> #include <QStringRef> #include <QLatin1String> +#include <QVector> #include <QTest> @@ -71,6 +72,10 @@ class tst_QStringApiSymmetry : public QObject { Q_OBJECT + // + // Mixed UTF-16, UTF-8, Latin-1 checks: + // + void compare_data(bool hasConceptOfNullAndEmpty=true); template <typename LHS, typename RHS> void compare_impl() const; @@ -155,6 +160,44 @@ private Q_SLOTS: //void compare_const_char_star_const_char_star_data() { compare_data(); } //void compare_const_char_star_const_char_star() { compare_impl<const char *, const char *>(); } + // + // UTF-16-only checks: + // +private: + + void toLocal8Bit_data(); + template <typename String> void toLocal8Bit_impl(); + + void toLatin1_data(); + template <typename String> void toLatin1_impl(); + + void toUtf8_data(); + template <typename String> void toUtf8_impl(); + + void toUcs4_data(); + template <typename String> void toUcs4_impl(); + +private Q_SLOTS: + + void toLocal8Bit_QString_data() { toLocal8Bit_data(); } + void toLocal8Bit_QString() { toLocal8Bit_impl<QString>(); } + void toLocal8Bit_QStringRef_data() { toLocal8Bit_data(); } + void toLocal8Bit_QStringRef() { toLocal8Bit_impl<QStringRef>(); } + + void toLatin1_QString_data() { toLatin1_data(); } + void toLatin1_QString() { toLatin1_impl<QString>(); } + void toLatin1_QStringRef_data() { toLatin1_data(); } + void toLatin1_QStringRef() { toLatin1_impl<QStringRef>(); } + + void toUtf8_QString_data() { toUtf8_data(); } + void toUtf8_QString() { toUtf8_impl<QString>(); } + void toUtf8_QStringRef_data() { toUtf8_data(); } + void toUtf8_QStringRef() { toUtf8_impl<QStringRef>(); } + + void toUcs4_QString_data() { toUcs4_data(); } + void toUcs4_QString() { toUcs4_impl<QString>(); } + void toUcs4_QStringRef_data() { toUcs4_data(); } + void toUcs4_QStringRef() { toUcs4_impl<QStringRef>(); } }; void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty) @@ -257,6 +300,159 @@ void tst_QStringApiSymmetry::compare_impl() const #undef CHECK } +// +// +// UTF-16-only checks: +// +// + +template <class Str> Str make(const QString &s); +template <> QStringRef make(const QString &s) { return QStringRef(&s); } +template <> QString make(const QString &s) { return s; } + +#define REPEAT_16X(X) X X X X X X X X X X X X X X X X +#define LONG_STRING_256 REPEAT_16X("0123456789abcdef") + +void tst_QStringApiSymmetry::toLocal8Bit_data() +{ + QTest::addColumn<QString>("unicode"); + QTest::addColumn<QByteArray>("local"); + + auto add = [](const char *local) { + const QByteArray ba(local); + QString s; + for (char c : ba) + s += QLatin1Char(c); + QTest::addRow("\"%s\" (%d)", ba.left(16).constData(), ba.size()) << s << ba; + }; + + QTest::addRow("null") << QString() << QByteArray(); + QTest::addRow("empty") << QString("") << QByteArray(""); + + add("Moebius"); + add(LONG_STRING_256); +} + +template <typename String> +void tst_QStringApiSymmetry::toLocal8Bit_impl() +{ + QFETCH(const QString, unicode); + QFETCH(const QByteArray, local); + + const auto str = make<String>(unicode); + + const auto result = str.toLocal8Bit(); + + QCOMPARE(result, local); + QCOMPARE(unicode.isEmpty(), result.isEmpty()); + QCOMPARE(unicode.isNull(), result.isNull()); +} + +void tst_QStringApiSymmetry::toLatin1_data() +{ + QTest::addColumn<QString>("unicode"); + QTest::addColumn<QByteArray>("latin1"); + + auto add = [](const char *l1) { + const QByteArray ba(l1); + QString s; + for (char c : ba) + s += QLatin1Char(c); + QTest::addRow("\"%s\" (%d)", ba.left(16).constData(), ba.size()) << s << ba; + }; + + QTest::addRow("null") << QString() << QByteArray(); + QTest::addRow("empty") << QString("") << QByteArray(""); + + add("M\xF6" "bius"); + add(LONG_STRING_256); +} + +template <typename String> +void tst_QStringApiSymmetry::toLatin1_impl() +{ + QFETCH(const QString, unicode); + QFETCH(const QByteArray, latin1); + + const auto str = make<String>(unicode); + + const auto result = str.toLatin1(); + + QCOMPARE(result, latin1); + QCOMPARE(unicode.isEmpty(), result.isEmpty()); + QCOMPARE(unicode.isNull(), result.isNull()); +} + +void tst_QStringApiSymmetry::toUtf8_data() +{ + QTest::addColumn<QString>("unicode"); + QTest::addColumn<QByteArray>("utf8"); + + auto add = [](const char *u8) { + QByteArray ba(u8); + QString s = ba; + QTest::addRow("\"%s\" (%d)", ba.left(16).constData(), ba.size()) << s << ba; + }; + + QTest::addRow("null") << QString() << QByteArray(); + QTest::addRow("empty") << QString("") << QByteArray(""); + + add("M\xC3\xB6" "bius"); + add(LONG_STRING_256); +} + +template <typename String> +void tst_QStringApiSymmetry::toUtf8_impl() +{ + QFETCH(const QString, unicode); + QFETCH(const QByteArray, utf8); + + const auto str = make<String>(unicode); + + const auto result = str.toUtf8(); + + QCOMPARE(result, utf8); + QCOMPARE(unicode.isEmpty(), result.isEmpty()); + QCOMPARE(unicode.isNull(), result.isNull()); +} + +void tst_QStringApiSymmetry::toUcs4_data() +{ + QTest::addColumn<QString>("unicode"); + QTest::addColumn<QVector<uint>>("ucs4"); + + auto add = [](const char *l1) { + const QByteArray ba(l1); + QString s; + QVector<uint> ucs4; + for (char c : ba) { + s += QLatin1Char(c); + ucs4.append(uint(uchar(c))); + } + QTest::addRow("\"%s\" (%d)", ba.left(16).constData(), ba.size()) << s << ucs4; + }; + + QTest::addRow("null") << QString() << QVector<uint>(); + QTest::addRow("empty") << QString("") << QVector<uint>(); + + add("M\xF6" "bius"); + add(LONG_STRING_256); +} + +template <typename String> +void tst_QStringApiSymmetry::toUcs4_impl() +{ + QFETCH(const QString, unicode); + QFETCH(const QVector<uint>, ucs4); + + const auto str = make<String>(unicode); + + const auto result = str.toUcs4(); + + QCOMPARE(result, ucs4); + QCOMPARE(unicode.isEmpty(), ucs4.isEmpty()); +} + QTEST_APPLESS_MAIN(tst_QStringApiSymmetry) #include "tst_qstringapisymmetry.moc" diff --git a/tests/auto/corelib/tools/qtimezone/qtimezone.pro b/tests/auto/corelib/tools/qtimezone/qtimezone.pro index afc4c59dfe..19ebc13306 100644 --- a/tests/auto/corelib/tools/qtimezone/qtimezone.pro +++ b/tests/auto/corelib/tools/qtimezone/qtimezone.pro @@ -5,3 +5,8 @@ SOURCES = tst_qtimezone.cpp qtConfig(icu) { DEFINES += QT_USE_ICU } + +darwin { + OBJECTIVE_SOURCES += tst_qtimezone_darwin.mm + LIBS += -framework Foundation +} diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp index c631b395f8..c1f2822b74 100644 --- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp @@ -45,6 +45,8 @@ private slots: void dataStreamTest(); void isTimeZoneIdAvailable(); void availableTimeZoneIds(); + void transitionEachZone_data(); + void transitionEachZone(); void stressTest(); void windowsId(); void isValidId_data(); @@ -54,23 +56,24 @@ private slots: void icuTest(); void tzTest(); void macTest(); + void darwinTypes(); void winTest(); private: - void printTimeZone(const QTimeZone tz); + void printTimeZone(const QTimeZone &tz); #ifdef QT_BUILD_INTERNAL void testCetPrivate(const QTimeZonePrivate &tzp); #endif // QT_BUILD_INTERNAL - bool debug; + const bool debug; }; tst_QTimeZone::tst_QTimeZone() -{ // Set to true to print debug output, test Display Names and run long stress tests - debug = false; + : debug(false) +{ } -void tst_QTimeZone::printTimeZone(const QTimeZone tz) +void tst_QTimeZone::printTimeZone(const QTimeZone &tz) { QDateTime now = QDateTime::currentDateTime(); QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC); @@ -343,6 +346,7 @@ void tst_QTimeZone::isTimeZoneIdAvailable() foreach (const QByteArray &id, available) QVERIFY(QTimeZone::isTimeZoneIdAvailable(id)); +#ifdef QT_BUILD_INTERNAL // a-z, A-Z, 0-9, '.', '-', '_' are valid chars // Can't start with '-' // Parts separated by '/', each part min 1 and max of 14 chars @@ -365,6 +369,57 @@ void tst_QTimeZone::isTimeZoneIdAvailable() QCOMPARE(QTimeZonePrivate::isValidId("123456789012345"), false); QCOMPARE(QTimeZonePrivate::isValidId("123456789012345/12345678901234"), false); QCOMPARE(QTimeZonePrivate::isValidId("12345678901234/123456789012345"), false); +#endif // QT_BUILD_INTERNAL +} + +void tst_QTimeZone::transitionEachZone_data() +{ + QTest::addColumn<QByteArray>("zone"); + QTest::addColumn<qint64>("secs"); + QTest::addColumn<int>("start"); + QTest::addColumn<int>("stop"); + + struct { + qint64 baseSecs; + int start, stop; + int year; + } table[] = { + { 25666200, 3, 12, 1970 }, // 1970-10-25 01:30 UTC; North America + { 1288488600, -4, 8, 2010 } // 2010-10-31 01:30 UTC; Europe, Russia + }; + + QString name; + for (int k = sizeof(table) / sizeof(table[0]); k-- > 0; ) { + foreach (QByteArray zone, QTimeZone::availableTimeZoneIds()) { + name.sprintf("%s@%d", zone.constData(), table[k].year); + QTest::newRow(name.toUtf8().constData()) + << zone + << table[k].baseSecs + << table[k].start + << table[k].stop; + } + } +} + +void tst_QTimeZone::transitionEachZone() +{ + // Regression test: round-trip fromMsecs/toMSecs should be idempotent; but + // various zones failed during fall-back transitions. + QFETCH(QByteArray, zone); + QFETCH(qint64, secs); + QFETCH(int, start); + QFETCH(int, stop); + QTimeZone named(zone); + + for (int i = start; i < stop; i++) { + qint64 here = secs + i * 3600; + QDateTime when = QDateTime::fromMSecsSinceEpoch(here * 1000, named); + qint64 stamp = when.toMSecsSinceEpoch(); + if (here * 1000 != stamp) // (The +1 is due to using *1*:30 as baseSecs.) + qDebug() << "Failing for" << zone << "at half past" << (i + 1) << "UTC"; + QCOMPARE(stamp % 1000, 0); + QCOMPARE(here - stamp / 1000, 0); + } } void tst_QTimeZone::availableTimeZoneIds() @@ -704,9 +759,9 @@ void tst_QTimeZone::tzTest() // Test display names by type, either ICU or abbreviation only QLocale enUS("en_US"); -#ifdef QT_USE_ICU // Only test names in debug mode, names used can vary by ICU version installed if (debug) { +#ifdef QT_USE_ICU QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS), QString("Central European Standard Time")); QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS), @@ -726,9 +781,7 @@ void tst_QTimeZone::tzTest() QString("GMT+01:00")); QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS), QString("UTC+01:00")); - } #else - if (debug) { QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS), QString("CET")); QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS), @@ -747,10 +800,8 @@ void tst_QTimeZone::tzTest() QString("CET")); QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS), QString("CET")); - } #endif // QT_USE_ICU - if (debug) { // Test Abbreviations QCOMPARE(tzp.abbreviation(std), QString("CET")); QCOMPARE(tzp.abbreviation(dst), QString("CEST")); @@ -907,6 +958,16 @@ void tst_QTimeZone::macTest() #endif // Q_OS_MAC } +void tst_QTimeZone::darwinTypes() +{ +#ifndef Q_OS_DARWIN + QSKIP("This is an Apple-only test"); +#else + extern void tst_QTimeZone_darwinTypes(); // in tst_qtimezone_darwin.mm + tst_QTimeZone_darwinTypes(); +#endif +} + void tst_QTimeZone::winTest() { #if defined(QT_BUILD_INTERNAL) && defined(Q_OS_WIN) diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone_darwin.mm b/tests/auto/corelib/tools/qtimezone/tst_qtimezone_darwin.mm new file mode 100644 index 0000000000..de801e55d0 --- /dev/null +++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone_darwin.mm @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QTimeZone> +#include <QtTest/QtTest> + +#include <CoreFoundation/CoreFoundation.h> +#include <Foundation/Foundation.h> + +void tst_QTimeZone_darwinTypes() +{ +#if !defined(QT_NO_SYSTEMLOCALE) + // QTimeZone <-> CFTimeZone + { + QTimeZone qtTimeZone("America/Los_Angeles"); + const CFTimeZoneRef cfTimeZone = qtTimeZone.toCFTimeZone(); + QCOMPARE(QTimeZone::fromCFTimeZone(cfTimeZone), qtTimeZone); + CFRelease(cfTimeZone); + } + { + CFTimeZoneRef cfTimeZone = CFTimeZoneCreateWithName(kCFAllocatorDefault, + CFSTR("America/Los_Angeles"), false); + const QTimeZone qtTimeZone = QTimeZone::fromCFTimeZone(cfTimeZone); + QVERIFY(CFEqual(qtTimeZone.toCFTimeZone(), cfTimeZone)); + CFRelease(cfTimeZone); + } + // QTimeZone <-> NSTimeZone + { + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QTimeZone qtTimeZone("America/Los_Angeles"); + const NSTimeZone *nsTimeZone = qtTimeZone.toNSTimeZone(); + QCOMPARE(QTimeZone::fromNSTimeZone(nsTimeZone), qtTimeZone); + [autoreleasepool release]; + } + { + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + NSTimeZone *nsTimeZone = [NSTimeZone timeZoneWithName:@"America/Los_Angeles"]; + const QTimeZone qtTimeZone = QTimeZone::fromNSTimeZone(nsTimeZone); + QVERIFY([qtTimeZone.toNSTimeZone() isEqual:nsTimeZone]); + [autoreleasepool release]; + } +#endif +} |