diff options
Diffstat (limited to 'tests/auto/corelib/tools')
14 files changed, 486 insertions, 35 deletions
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..ba2adddca0 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,54 @@ void tst_QArrayData::allocate() } } +void tst_QArrayData::reallocate() +{ + QFETCH(size_t, objectSize); + QFETCH(size_t, alignment); + QFETCH(QArrayData::AllocationOptions, allocateOptions); + QFETCH(bool, isCapacityReserved); + QFETCH(const QArrayData *, commonEmpty); + + // 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 fb436b67d6..13898ace7b 100644 --- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp +++ b/tests/auto/corelib/tools/qchar/tst_qchar.cpp @@ -108,7 +108,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 4604e664b0..5f9f5fbb6f 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -77,8 +77,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(); @@ -153,8 +155,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(); } }; Q_DECLARE_METATYPE(Qt::TimeSpec) @@ -606,10 +606,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") @@ -687,8 +685,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); @@ -794,6 +792,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"); @@ -831,6 +851,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"); @@ -3145,17 +3208,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/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 42bfb3603d..f56cff4d29 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -1791,6 +1791,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/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 414ba2d8cf..6ed7b74277 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -6070,6 +6070,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; 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..abb5b50229 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); @@ -367,6 +370,56 @@ void tst_QTimeZone::isTimeZoneIdAvailable() QCOMPARE(QTimeZonePrivate::isValidId("12345678901234/123456789012345"), false); } +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() { if (debug) { @@ -704,9 +757,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 +779,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 +798,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 +956,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 +} |