diff options
Diffstat (limited to 'tests/auto/corelib')
59 files changed, 2259 insertions, 1251 deletions
diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp index 1568855032..be75f5b3cc 100644 --- a/tests/auto/corelib/global/qflags/tst_qflags.cpp +++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp @@ -49,7 +49,7 @@ void tst_QFlags::testFlag() const QVERIFY(btn.testFlag(Qt::LeftButton)); QVERIFY(!btn.testFlag(Qt::MidButton)); - btn = 0; + btn = { }; QVERIFY(!btn.testFlag(Qt::LeftButton)); } diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp index 94f0afa5ed..a661b0388e 100644 --- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp +++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp @@ -430,6 +430,13 @@ void tst_qfloat16::finite() QVERIFY(!qIsInf(value)); QVERIFY(!qIsNaN(value)); QCOMPARE(qFpClassify(value), mode); + + // *NOT* using QCOMPARE() on finite qfloat16 values, since that uses fuzzy + // comparison, and we need exact here. + const qfloat16 zero(0), plus(+1), minus(-1); + const qfloat16 magnitude = (value < zero) ? -value : value; + QVERIFY(value.copySign(plus) == magnitude); + QVERIFY(value.copySign(minus) == -magnitude); } void tst_qfloat16::properties() @@ -534,7 +541,9 @@ void tst_qfloat16::limits() // See also: qNaN() and infinity() QVERIFY(Bounds::denorm_min() / rose == zero); if (overOptimized) QEXPECT_FAIL("", "Over-optimized on ARM", Continue); - QVERIFY(-Bounds::denorm_min() / rose == -zero); + const qfloat16 under = (-Bounds::denorm_min()) / rose; + QVERIFY(under == -zero); + QCOMPARE(qfloat16(1).copySign(under), qfloat16(-1)); } QTEST_APPLESS_MAIN(tst_qfloat16) diff --git a/tests/auto/corelib/global/qglobal/qglobal.c b/tests/auto/corelib/global/qglobal/qglobal.c index c7124454d0..7a2266ae94 100644 --- a/tests/auto/corelib/global/qglobal/qglobal.c +++ b/tests/auto/corelib/global/qglobal/qglobal.c @@ -28,7 +28,7 @@ #include <QtCore/qglobal.h> -#if QT_HAS_INCLUDE(<stdbool.h>) || __STDC_VERSION__ >= 199901L +#if __has_include(<stdbool.h>) || __STDC_VERSION__ >= 199901L # include <stdbool.h> #else # undef true diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index 6c0470c8fe..6c6f3a2168 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com> ** Contact: https://www.qt.io/licensing/ ** @@ -767,18 +767,18 @@ void tst_qmessagehandler::qMessagePattern_data() QTest::qWait(10000); QTest::newRow("time") << "/%{time yyyy - MM - d}/%{message}" << true << (QList<QByteArray>() - << ('/' + QDateTime::currentDateTime().toString("yyyy - MM - d").toUtf8() + "/qDebug")); + << ('/' + QDateTime::currentDateTime().toString("yyyy - MM - d").toLocal8Bit() + "/qDebug")); QTest::newRow("time-time") << "/%{time yyyy - MM - d}/%{time dd-MM-yy}/%{message}" << true << (QList<QByteArray>() - << ('/' + QDateTime::currentDateTime().toString("yyyy - MM - d").toUtf8() - + '/' + QDateTime::currentDateTime().toString("dd-MM-yy").toUtf8() + << ('/' + QDateTime::currentDateTime().toString("yyyy - MM - d").toLocal8Bit() + + '/' + QDateTime::currentDateTime().toString("dd-MM-yy").toLocal8Bit() + "/qDebug")); QTest::newRow("skipped-time-shown-time") << "/%{if-warning}%{time yyyy - MM - d}%{endif}%{if-debug}%{time dd-MM-yy}%{endif}/%{message}" << true << (QList<QByteArray>() - << ('/' + QDateTime::currentDateTime().toString("dd-MM-yy").toUtf8() + "/qDebug")); + << ('/' + QDateTime::currentDateTime().toString("dd-MM-yy").toLocal8Bit() + "/qDebug")); // %{time} should have a padding of 6 so if it takes less than 10 seconds to show // the first message, there should be 5 spaces diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index 52e7ebadb1..a6775ec2b6 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -528,7 +528,7 @@ void tst_QDir::removeRecursivelyFailure() #ifdef Q_OS_UNIX QFile dirAsFile(path); // yay, I have to use QFile to change a dir's permissions... - QVERIFY(dirAsFile.setPermissions(QFile::Permissions(0))); // no permissions + QVERIFY(dirAsFile.setPermissions({})); // no permissions QVERIFY(!QDir().rmdir(path)); QDir dir(path); diff --git a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp index 0b125925bb..00e1c74d07 100644 --- a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp +++ b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp @@ -236,7 +236,7 @@ void tst_QDirIterator::iterateRelativeDirectory_data() QTest::addColumn<QStringList>("entries"); QTest::newRow("no flags") - << QString("entrylist") << QDirIterator::IteratorFlags(0) + << QString("entrylist") << QDirIterator::IteratorFlags{} << QDir::Filters(QDir::NoFilter) << QStringList("*") << QString( "entrylist/.," @@ -252,7 +252,7 @@ void tst_QDirIterator::iterateRelativeDirectory_data() "entrylist/writable").split(','); QTest::newRow("NoDot") - << QString("entrylist") << QDirIterator::IteratorFlags(0) + << QString("entrylist") << QDirIterator::IteratorFlags{} << QDir::Filters(QDir::AllEntries | QDir::NoDot) << QStringList("*") << QString( "entrylist/..," @@ -267,7 +267,7 @@ void tst_QDirIterator::iterateRelativeDirectory_data() "entrylist/writable").split(','); QTest::newRow("NoDotDot") - << QString("entrylist") << QDirIterator::IteratorFlags(0) + << QString("entrylist") << QDirIterator::IteratorFlags{} << QDir::Filters(QDir::AllEntries | QDir::NoDotDot) << QStringList("*") << QString( "entrylist/.," @@ -282,7 +282,7 @@ void tst_QDirIterator::iterateRelativeDirectory_data() "entrylist/writable").split(','); QTest::newRow("NoDotAndDotDot") - << QString("entrylist") << QDirIterator::IteratorFlags(0) + << QString("entrylist") << QDirIterator::IteratorFlags{} << QDir::Filters(QDir::AllEntries | QDir::NoDotAndDotDot) << QStringList("*") << QString( "entrylist/file," @@ -335,12 +335,12 @@ void tst_QDirIterator::iterateRelativeDirectory_data() "entrylist/writable").split(','); QTest::newRow("empty, default") - << QString("empty") << QDirIterator::IteratorFlags(0) + << QString("empty") << QDirIterator::IteratorFlags{} << QDir::Filters(QDir::NoFilter) << QStringList("*") << QString("empty/.,empty/..").split(','); QTest::newRow("empty, QDir::NoDotAndDotDot") - << QString("empty") << QDirIterator::IteratorFlags(0) + << QString("empty") << QDirIterator::IteratorFlags{} << QDir::Filters(QDir::NoDotAndDotDot) << QStringList("*") << QStringList(); } @@ -399,13 +399,13 @@ void tst_QDirIterator::iterateResource_data() QTest::addColumn<QStringList>("nameFilters"); QTest::addColumn<QStringList>("entries"); - QTest::newRow("invalid") << QString::fromLatin1(":/testdata/burpaburpa") << QDirIterator::IteratorFlags(0) + QTest::newRow("invalid") << QString::fromLatin1(":/testdata/burpaburpa") << QDirIterator::IteratorFlags{} << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*")) << QStringList(); - QTest::newRow(":/testdata") << QString::fromLatin1(":/testdata/") << QDirIterator::IteratorFlags(0) + QTest::newRow(":/testdata") << QString::fromLatin1(":/testdata/") << QDirIterator::IteratorFlags{} << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*")) << QString::fromLatin1(":/testdata/entrylist").split(QLatin1String(",")); - QTest::newRow(":/testdata/entrylist") << QString::fromLatin1(":/testdata/entrylist") << QDirIterator::IteratorFlags(0) + QTest::newRow(":/testdata/entrylist") << QString::fromLatin1(":/testdata/entrylist") << QDirIterator::IteratorFlags{} << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*")) << QString::fromLatin1(":/testdata/entrylist/directory,:/testdata/entrylist/file").split(QLatin1String(",")); QTest::newRow(":/testdata recursive") << QString::fromLatin1(":/testdata") << QDirIterator::IteratorFlags(QDirIterator::Subdirectories) diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index b8ae95dd93..16a30af892 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -499,7 +499,7 @@ void tst_QFile::initTestCase() file.write("b", 1); file.close(); #ifndef Q_OS_WIN // Not supported on Windows. - QVERIFY2(file.setPermissions(0), qPrintable(file.errorString())); + QVERIFY2(file.setPermissions({ }), qPrintable(file.errorString())); #else QVERIFY2(file.open(QFile::WriteOnly), msgOpenFailed(file).constData()); #endif @@ -2211,7 +2211,7 @@ public: QStringList entryList(QDir::Filters, const QStringList &) const { return QStringList(); } bool caseSensitive() const { return false; } bool isRelativePath() const { return false; } - FileFlags fileFlags(FileFlags) const { return 0; } + FileFlags fileFlags(FileFlags) const { return { }; } bool chmod(uint) { return false; } QString fileName(FileName) const { return name; } uint ownerId(FileOwner) const { return 0; } diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 744e047c45..ebb9a0a44c 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -1813,19 +1813,22 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks() QVERIFY2(creationResult == ERROR_SUCCESS, qPrintable(errorMessage)); QFileInfo fi(path); - const bool actualIsSymLink = fi.isSymbolicLink(); + auto guard = qScopeGuard([&fi, this]() { + // Ensure that junctions, mountpoints are removed. If this fails, do not remove + // temporary directory to prevent it from trashing the system. + if (fi.isDir()) { + if (!QDir().rmdir(fi.filePath())) { + qWarning("Unable to remove NTFS junction '%ls', keeping '%ls'.", + qUtf16Printable(fi.fileName()), + qUtf16Printable(QDir::toNativeSeparators(m_dir.path()))); + m_dir.setAutoRemove(false); + } + } + }); const QString actualSymLinkTarget = isSymLink ? fi.symLinkTarget() : QString(); const QString actualCanonicalFilePath = isSymLink ? fi.canonicalFilePath() : QString(); - // Ensure that junctions, mountpoints are removed. If this fails, do not remove - // temporary directory to prevent it from trashing the system. - if (fi.isDir()) { - if (!QDir().rmdir(fi.filePath())) { - qWarning("Unable to remove NTFS junction '%s'', keeping '%s'.", - qPrintable(fi.fileName()), qPrintable(QDir::toNativeSeparators(m_dir.path()))); - m_dir.setAutoRemove(false); - } - } - QCOMPARE(actualIsSymLink, isSymLink); + QCOMPARE(fi.isJunction(), resource.type == NtfsTestResource::Junction); + QCOMPARE(fi.isSymbolicLink(), isSymLink); if (isSymLink) { QCOMPARE(actualSymLinkTarget, linkTarget); QCOMPARE(actualCanonicalFilePath, canonicalFilePath); diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index cdd1f6361e..7d88601e54 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -34,6 +34,9 @@ #include <QElapsedTimer> #include <QTextStream> #include <QDir> +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +#include <windows.h> +#endif /* All tests need to run in temporary directories not used * by the application to avoid non-deterministic failures on Windows @@ -79,6 +82,9 @@ private slots: void signalsEmittedAfterFileMoved(); void watchUnicodeCharacters(); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + void watchDirectoryAttributeChanges(); +#endif private: QString m_tempDirPattern; @@ -813,5 +819,27 @@ void tst_QFileSystemWatcher::watchUnicodeCharacters() QTRY_COMPARE(changedSpy.count(), 1); } +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +void tst_QFileSystemWatcher::watchDirectoryAttributeChanges() +{ + QTemporaryDir temporaryDirectory(m_tempDirPattern); + QVERIFY2(temporaryDirectory.isValid(), qPrintable(temporaryDirectory.errorString())); + + QDir testDir(temporaryDirectory.path()); + const QString subDir(QString::fromLatin1("attrib_test")); + QVERIFY(testDir.mkdir(subDir)); + testDir = QDir(temporaryDirectory.path() + QDir::separator() + subDir); + + QFileSystemWatcher watcher; + QVERIFY(watcher.addPath(temporaryDirectory.path())); + FileSystemWatcherSpy changedSpy(&watcher, FileSystemWatcherSpy::SpyOnDirectoryChanged); + QCOMPARE(changedSpy.count(), 0); + QVERIFY(SetFileAttributes(reinterpret_cast<LPCWSTR>(testDir.absolutePath().utf16()), FILE_ATTRIBUTE_HIDDEN) != 0); + QTRY_COMPARE(changedSpy.count(), 1); + QVERIFY(SetFileAttributes(reinterpret_cast<LPCWSTR>(testDir.absolutePath().utf16()), FILE_ATTRIBUTE_NORMAL) != 0); + QTRY_COMPARE(changedSpy.count(), 2); +} +#endif + QTEST_MAIN(tst_QFileSystemWatcher) #include "tst_qfilesystemwatcher.moc" diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp index 8703b15dda..4969e417f4 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -444,7 +444,7 @@ void tst_QLockFile::noPermissions() const QString fileName = dir.path() + "/staleLock"; QFile dirAsFile(dir.path()); // I have to use QFile to change a dir's permissions... - QVERIFY2(dirAsFile.setPermissions(QFile::Permissions(0)), qPrintable(dir.path())); // no permissions + QVERIFY2(dirAsFile.setPermissions(QFile::Permissions{}), qPrintable(dir.path())); // no permissions PermissionRestorer permissionRestorer(dir.path()); QLockFile lockFile(fileName); diff --git a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp index b05c89a8bb..cf2079a407 100644 --- a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp +++ b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -65,7 +65,7 @@ void tst_QNoDebug::noDebugOutput() const void tst_QNoDebug::streaming() const { QDateTime dt(QDate(1,2,3),QTime(4,5,6)); - const QByteArray debugString = dt.toString(u"yyyy-MM-dd HH:mm:ss.zzz t").toLatin1(); + const QByteArray debugString = dt.toString(u"yyyy-MM-dd HH:mm:ss.zzz t").toLocal8Bit(); const QByteArray message = "QDateTime(" + debugString + " Qt::LocalTime)"; QTest::ignoreMessage(QtWarningMsg, message.constData()); qWarning() << dt; diff --git a/tests/auto/corelib/io/qresourceengine/compressed.qrc b/tests/auto/corelib/io/qresourceengine/compressed.qrc new file mode 100644 index 0000000000..f7c7cbc20f --- /dev/null +++ b/tests/auto/corelib/io/qresourceengine/compressed.qrc @@ -0,0 +1,5 @@ +<RCC version="1.0"> + <qresource> + <file>zero.txt</file> + </qresource> +</RCC> diff --git a/tests/auto/corelib/io/qresourceengine/generateResources.sh b/tests/auto/corelib/io/qresourceengine/generateResources.sh new file mode 100755 index 0000000000..9894f6bfb7 --- /dev/null +++ b/tests/auto/corelib/io/qresourceengine/generateResources.sh @@ -0,0 +1,7 @@ +#!/bin/sh +count=`awk '/ZERO_FILE_LEN/ { print $3 }' tst_qresourceengine.cpp` +dd if=/dev/zero of=zero.txt bs=1 count=$count +rcc --binary -o uncompressed.rcc --no-compress compressed.qrc +rcc --binary -o zlib.rcc --compress-algo zlib --compress 9 compressed.qrc +rcc --binary -o zstd.rcc --compress-algo zstd --compress 19 compressed.qrc +rm zero.txt diff --git a/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro b/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro index f523116cc9..345e3d13b9 100644 --- a/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro +++ b/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro @@ -1,7 +1,7 @@ CONFIG += testcase TARGET = tst_qresourceengine -QT = core testlib +QT = core-private testlib SOURCES = tst_qresourceengine.cpp RESOURCES += testqrc/test.qrc @@ -15,7 +15,8 @@ QMAKE_DISTCLEAN += $${runtime_resource.target} TESTDATA += \ parentdir.txt \ - testqrc/* + testqrc/* \ + *.rcc GENERATED_TESTDATA = $${runtime_resource.target} android:!android-embedded { diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index 44c8c4b681..902e6db12a 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -27,10 +27,10 @@ ** ****************************************************************************/ - #include <QtTest/QtTest> #include <QtCore/QCoreApplication> -#include <QtCore/QMimeDatabase> +#include <QtCore/QScopeGuard> +#include <QtCore/private/qglobal_p.h> class tst_QResourceEngine: public QObject { @@ -51,6 +51,8 @@ private slots: void checkUnregisterResource_data(); void checkUnregisterResource(); + void compressedResource_data(); + void compressedResource(); void checkStructure_data(); void checkStructure(); void searchPath_data(); @@ -106,6 +108,75 @@ void tst_QResourceEngine::cleanupTestCase() QVERIFY(QResource::unregisterResource(m_runtimeResourceRcc, "/secondary_root/")); } +void tst_QResourceEngine::compressedResource_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<int>("compressionAlgo"); + QTest::addColumn<bool>("supported"); + + QTest::newRow("uncompressed") + << QFINDTESTDATA("uncompressed.rcc") << int(QResource::NoCompression) << true; + QTest::newRow("zlib") + << QFINDTESTDATA("zlib.rcc") << int(QResource::ZlibCompression) << true; + QTest::newRow("zstd") + << QFINDTESTDATA("zstd.rcc") << int(QResource::ZstdCompression) << QT_CONFIG(zstd); +} + +// Note: generateResource.sh parses this line. Make sure it's a simple number. +#define ZERO_FILE_LEN 16384 +// End note +void tst_QResourceEngine::compressedResource() +{ + QFETCH(QString, fileName); + QFETCH(int, compressionAlgo); + QFETCH(bool, supported); + const QByteArray expectedData(ZERO_FILE_LEN, '\0'); + + QVERIFY(!QResource("zero.txt").isValid()); + QCOMPARE(QResource::registerResource(fileName), supported); + if (!supported) + return; + + auto unregister = qScopeGuard([=] { QResource::unregisterResource(fileName); }); + + QResource resource("zero.txt"); + QVERIFY(resource.isValid()); + QVERIFY(resource.size() > 0); + QVERIFY(resource.data()); + QCOMPARE(resource.compressionAlgorithm(), QResource::Compression(compressionAlgo)); + + if (compressionAlgo == QResource::NoCompression) { + QCOMPARE(resource.size(), ZERO_FILE_LEN); + QCOMPARE(memcmp(resource.data(), expectedData.data(), ZERO_FILE_LEN), 0); + + // API guarantees it will be QByteArray::fromRawData: + QCOMPARE(static_cast<const void *>(resource.uncompressedData().constData()), + static_cast<const void *>(resource.data())); + } else { + // reasonable expectation: + QVERIFY(resource.size() < ZERO_FILE_LEN); + } + + // using the engine + QFile f(":/zero.txt"); + QVERIFY(f.exists()); + QVERIFY(f.open(QIODevice::ReadOnly)); + + // verify that we can decompress correctly + QCOMPARE(resource.uncompressedSize(), ZERO_FILE_LEN); + QCOMPARE(f.size(), ZERO_FILE_LEN); + + QByteArray data = resource.uncompressedData(); + QCOMPARE(data.size(), expectedData.size()); + QCOMPARE(data, expectedData); + + // decompression through the engine + data = f.readAll(); + QCOMPARE(data.size(), expectedData.size()); + QCOMPARE(data, expectedData); +} + + void tst_QResourceEngine::checkStructure_data() { QTest::addColumn<QString>("pathName"); @@ -119,24 +190,20 @@ void tst_QResourceEngine::checkStructure_data() QStringList rootContents; rootContents << QLatin1String("aliasdir") +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) + << QLatin1String("android_testdata") +#endif << QLatin1String("otherdir") - << QLatin1String("qt-project.org") << QLatin1String("runtime_resource") << QLatin1String("searchpath1") << QLatin1String("searchpath2") << QLatin1String("secondary_root") << QLatin1String("staticplugin") << QLatin1String("test") - << QLatin1String("withoutslashes"); - -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) - rootContents.insert(1, QLatin1String("android_testdata")); -#endif - #if defined(BUILTIN_TESTDATA) - rootContents.insert(9, QLatin1String("testqrc")); + << QLatin1String("testqrc") #endif - + << QLatin1String("withoutslashes"); QTest::newRow("root dir") << QString(":/") << QByteArray() @@ -145,7 +212,13 @@ void tst_QResourceEngine::checkStructure_data() << "parentdir.txt" << "runtime_resource.rcc" #endif - << "search_file.txt") + << "search_file.txt" +#if defined(BUILTIN_TESTDATA) + << "uncompressed.rcc" + << "zlib.rcc" + << "zstd.rcc" +#endif + ) << rootContents << QLocale::c() << qlonglong(0); @@ -352,11 +425,6 @@ void tst_QResourceEngine::checkStructure() QFETCH(QLocale, locale); QFETCH(qlonglong, contentsSize); - // We rely on the existence of the root "qt-project.org" in resources. For - // static builds on MSVC these resources are only added if they are used. - QMimeDatabase db; - Q_UNUSED(db); - bool directory = (containedDirs.size() + containedFiles.size() > 0); QLocale::setDefault(locale); diff --git a/tests/auto/corelib/io/qresourceengine/uncompressed.rcc b/tests/auto/corelib/io/qresourceengine/uncompressed.rcc Binary files differnew file mode 100644 index 0000000000..4b009f73d5 --- /dev/null +++ b/tests/auto/corelib/io/qresourceengine/uncompressed.rcc diff --git a/tests/auto/corelib/io/qresourceengine/zlib.rcc b/tests/auto/corelib/io/qresourceengine/zlib.rcc Binary files differnew file mode 100644 index 0000000000..66f79fa630 --- /dev/null +++ b/tests/auto/corelib/io/qresourceengine/zlib.rcc diff --git a/tests/auto/corelib/io/qresourceengine/zstd.rcc b/tests/auto/corelib/io/qresourceengine/zstd.rcc Binary files differnew file mode 100644 index 0000000000..672fa05d14 --- /dev/null +++ b/tests/auto/corelib/io/qresourceengine/zstd.rcc diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp index f1327933c4..8e500d7c8e 100644 --- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp +++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp @@ -356,7 +356,7 @@ void tst_QSaveFile::transactionalWriteErrorRenaming() #ifdef Q_OS_UNIX // Make rename() fail for lack of permissions in the directory QFile dirAsFile(dir.path()); // yay, I have to use QFile to change a dir's permissions... - QVERIFY(dirAsFile.setPermissions(QFile::Permissions(0))); // no permissions + QVERIFY(dirAsFile.setPermissions(QFile::Permissions{})); // no permissions PermissionRestorer permissionRestorer(dir.path()); #else // Windows: Make rename() fail for lack of permissions on an existing target file diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index bcf6d6c32b..5c6e633749 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -848,7 +848,7 @@ void tst_QUrlInternal::correctEncodedMistakes() QString dataTag = QTest::currentDataTag(); QString output = dataTag; - if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), 0)) + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), { })) output += input; QCOMPARE(output, dataTag + expected); diff --git a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp index adb93b7a75..4406d40986 100644 --- a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp @@ -136,7 +136,7 @@ void tst_QAbstractProxyModel::flags_data() { QTest::addColumn<QModelIndex>("index"); QTest::addColumn<Qt::ItemFlags>("flags"); - QTest::newRow("null") << QModelIndex() << (Qt::ItemFlags)0; + QTest::newRow("null") << QModelIndex() << Qt::ItemFlags{}; } // public Qt::ItemFlags flags(QModelIndex const& index) const diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp index c76052a38b..149d272594 100644 --- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -32,6 +32,7 @@ #include <QStandardItemModel> #include <QStringListModel> #include <QTest> +#include <QTransposeProxyModel> #include <QLoggingCategory> #include "dynamictreemodel.h" @@ -69,6 +70,7 @@ private slots: void insertRows(); void removeRows(); void moveRows(); + void moveColumns(); void reset(); void dataChanged(); @@ -235,47 +237,24 @@ void tst_QIdentityProxyModel::removeRows() void tst_QIdentityProxyModel::moveRows() { - DynamicTreeModel model; - - { - ModelInsertCommand insertCommand(&model); - insertCommand.setStartRow(0); - insertCommand.setEndRow(9); - insertCommand.doCommand(); - } - { - ModelInsertCommand insertCommand(&model); - insertCommand.setAncestorRowNumbers(QList<int>() << 5); - insertCommand.setStartRow(0); - insertCommand.setEndRow(9); - insertCommand.doCommand(); - } + QStringListModel model({"A", "B", "C", "D", "E", "F"}); m_proxy->setSourceModel(&model); verifyIdentity(&model); - QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved); - QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved); - QSignalSpy proxyBeforeSpy(m_proxy, &QIdentityProxyModel::rowsAboutToBeMoved); - QSignalSpy proxyAfterSpy(m_proxy, &QIdentityProxyModel::rowsMoved); - - QVERIFY(modelBeforeSpy.isValid()); - QVERIFY(modelAfterSpy.isValid()); - QVERIFY(proxyBeforeSpy.isValid()); - QVERIFY(proxyAfterSpy.isValid()); + QSignalSpy modelBeforeSpy(&model, &QAbstractItemModel::rowsAboutToBeMoved); + QSignalSpy modelAfterSpy(&model, &QAbstractItemModel::rowsMoved); + QSignalSpy proxyBeforeSpy(m_proxy, &QAbstractItemModel::rowsAboutToBeMoved); + QSignalSpy proxyAfterSpy(m_proxy, &QAbstractItemModel::rowsMoved); - { - ModelMoveCommand moveCommand(&model, 0); - moveCommand.setAncestorRowNumbers(QList<int>() << 5); - moveCommand.setStartRow(3); - moveCommand.setEndRow(4); - moveCommand.setDestRow(1); - moveCommand.doCommand(); - } + QVERIFY(m_proxy->moveRows(QModelIndex(), 1, 2, QModelIndex(), 5)); + QCOMPARE(model.stringList(), QStringList({"A", "D", "E", "B", "C", "F"})); - QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); - QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + QCOMPARE(modelBeforeSpy.size(), 1); + QCOMPARE(proxyBeforeSpy.size(), 1); + QCOMPARE(modelAfterSpy.size(), 1); + QCOMPARE(proxyAfterSpy.size(), 1); QCOMPARE(modelBeforeSpy.first().first().value<QModelIndex>(), m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>())); QCOMPARE(modelBeforeSpy.first().at(1), proxyBeforeSpy.first().at(1)); @@ -289,9 +268,62 @@ void tst_QIdentityProxyModel::moveRows() QCOMPARE(modelAfterSpy.first().at(3).value<QModelIndex>(), m_proxy->mapToSource(proxyAfterSpy.first().at(3).value<QModelIndex>())); QCOMPARE(modelAfterSpy.first().at(4), proxyAfterSpy.first().at(4)); + QVERIFY(m_proxy->moveRows(QModelIndex(), 3, 2, QModelIndex(), 1)); + QCOMPARE(model.stringList(), QStringList({"A", "B", "C", "D", "E", "F"})); + QVERIFY(m_proxy->moveRows(QModelIndex(), 0, 3, QModelIndex(), 6)); + QCOMPARE(model.stringList(), QStringList({"D", "E", "F", "A", "B", "C"})); + verifyIdentity(&model); - m_proxy->setSourceModel(0); + m_proxy->setSourceModel(nullptr); +} + +void tst_QIdentityProxyModel::moveColumns() +{ + // QStringListModel implements moveRows but not moveColumns + // so we have to use a QTransposeProxyModel inbetween to check if + // QIdentityProxyModel::moveColumns works as expected + QStringListModel model({"A", "B", "C", "D", "E", "F"}); + QTransposeProxyModel tpm; + tpm.setSourceModel(&model); + + m_proxy->setSourceModel(&tpm); + + verifyIdentity(&tpm); + + QSignalSpy modelBeforeSpy(&tpm, &QAbstractItemModel::columnsAboutToBeMoved); + QSignalSpy modelAfterSpy(&tpm, &QAbstractItemModel::columnsMoved); + QSignalSpy proxyBeforeSpy(m_proxy, &QAbstractItemModel::columnsAboutToBeMoved); + QSignalSpy proxyAfterSpy(m_proxy, &QAbstractItemModel::columnsMoved); + + QVERIFY(m_proxy->moveColumns(QModelIndex(), 1, 2, QModelIndex(), 5)); + QCOMPARE(model.stringList(), QStringList({"A", "D", "E", "B", "C", "F"})); + + QCOMPARE(proxyBeforeSpy.size(), 1); + QCOMPARE(modelBeforeSpy.size(), 1); + QCOMPARE(modelAfterSpy.size(), 1); + QCOMPARE(proxyAfterSpy.size(), 1); + + QCOMPARE(modelBeforeSpy.first().first().value<QModelIndex>(), m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>())); + QCOMPARE(modelBeforeSpy.first().at(1), proxyBeforeSpy.first().at(1)); + QCOMPARE(modelBeforeSpy.first().at(2), proxyBeforeSpy.first().at(2)); + QCOMPARE(modelBeforeSpy.first().at(3).value<QModelIndex>(), m_proxy->mapToSource(proxyBeforeSpy.first().at(3).value<QModelIndex>())); + QCOMPARE(modelBeforeSpy.first().at(4), proxyBeforeSpy.first().at(4)); + + QCOMPARE(modelAfterSpy.first().first().value<QModelIndex>(), m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>())); + QCOMPARE(modelAfterSpy.first().at(1), proxyAfterSpy.first().at(1)); + QCOMPARE(modelAfterSpy.first().at(2), proxyAfterSpy.first().at(2)); + QCOMPARE(modelAfterSpy.first().at(3).value<QModelIndex>(), m_proxy->mapToSource(proxyAfterSpy.first().at(3).value<QModelIndex>())); + QCOMPARE(modelAfterSpy.first().at(4), proxyAfterSpy.first().at(4)); + + QVERIFY(m_proxy->moveColumns(QModelIndex(), 3, 2, QModelIndex(), 1)); + QCOMPARE(model.stringList(), QStringList({"A", "B", "C", "D", "E", "F"})); + QVERIFY(m_proxy->moveColumns(QModelIndex(), 0, 3, QModelIndex(), 6)); + QCOMPARE(model.stringList(), QStringList({"D", "E", "F", "A", "B", "C"})); + + verifyIdentity(&tpm); + + m_proxy->setSourceModel(nullptr); } void tst_QIdentityProxyModel::reset() diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp index c74101928a..6b59a6f1af 100644 --- a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -2037,12 +2037,16 @@ void tst_QItemSelectionModel::rowIntersectsSelection3() QModelIndex parent; QVERIFY(!selectionModel.rowIntersectsSelection(0, parent)); + QVERIFY(!selectionModel.columnIntersectsSelection(0, parent)); parent = model.index(0, 0, parent); QVERIFY(selectionModel.rowIntersectsSelection(0, parent)); + QVERIFY(selectionModel.columnIntersectsSelection(0, parent)); parent = model.index(0, 0, parent); QVERIFY(!selectionModel.rowIntersectsSelection(0, parent)); + QVERIFY(!selectionModel.columnIntersectsSelection(0, parent)); parent = model.index(0, 0, parent); QVERIFY(!selectionModel.rowIntersectsSelection(0, parent)); + QVERIFY(!selectionModel.columnIntersectsSelection(0, parent)); } void tst_QItemSelectionModel::unselectable() @@ -2059,7 +2063,7 @@ void tst_QItemSelectionModel::unselectable() QCOMPARE(selectionModel.selectedIndexes().count(), 10); QCOMPARE(selectionModel.selectedRows().count(), 10); for (int j = 0; j < 10; ++j) - model.item(j)->setFlags(0); + model.item(j)->setFlags({ }); QCOMPARE(selectionModel.selectedIndexes().count(), 0); QCOMPARE(selectionModel.selectedRows().count(), 0); } diff --git a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp index 3919472b96..7182553f27 100644 --- a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp +++ b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp @@ -103,28 +103,25 @@ void tst_QStringListModel::moveRowsInvalid_data() QTest::addColumn<QModelIndex>("destinationParent"); QTest::addColumn<int>("destination"); - QStringListModel* tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); - QTest::addRow("destination_equal_source") << tempModel << QModelIndex() << 0 << 1 << QModelIndex() << 1; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); - QTest::addRow("count_equal_0") << tempModel << QModelIndex() << 0 << 0 << QModelIndex() << 2; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); + const auto createModel = [this]() { + return new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); + }; + constexpr int rowCount = 6; + + QTest::addRow("destination_equal_source") << createModel() << QModelIndex() << 0 << 1 << QModelIndex() << 0; + QTest::addRow("count_equal_0") << createModel() << QModelIndex() << 0 << 0 << QModelIndex() << 2; + QStringListModel *tempModel = createModel(); QTest::addRow("move_child") << tempModel << tempModel->index(0, 0) << 0 << 1 << QModelIndex() << 2; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); + tempModel = createModel(); QTest::addRow("move_to_child") << tempModel << QModelIndex() << 0 << 1 << tempModel->index(0, 0) << 2; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); - QTest::addRow("negative_count") << tempModel << QModelIndex() << 0 << -1 << QModelIndex() << 2; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); - QTest::addRow("negative_source_row") << tempModel << QModelIndex() << -1 << 1 << QModelIndex() << 2; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); - QTest::addRow("negative_destination_row") << tempModel << QModelIndex() << 0 << 1 << QModelIndex() << -1; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); - QTest::addRow("source_row_equal_rowCount") << tempModel << QModelIndex() << tempModel->rowCount() << 1 << QModelIndex() << 1; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); - QTest::addRow("destination_row_greater_rowCount") << tempModel << QModelIndex() << 0 << 1 << QModelIndex() << tempModel->rowCount() + 1; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); - QTest::addRow("move_row_within_source_range") << tempModel << QModelIndex() << 0 << 3 << QModelIndex() << 2; - tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this); - QTest::addRow("destination_row_before_0") << tempModel << QModelIndex() << 1 << 1 << QModelIndex() << 0; + QTest::addRow("negative_count") << createModel() << QModelIndex() << 0 << -1 << QModelIndex() << 2; + QTest::addRow("negative_source_row") << createModel() << QModelIndex() << -1 << 1 << QModelIndex() << 2; + QTest::addRow("negative_destination_row") << createModel() << QModelIndex() << 0 << 1 << QModelIndex() << -1; + QTest::addRow("source_row_equal_rowCount") << createModel() << QModelIndex() << rowCount << 1 << QModelIndex() << 1; + QTest::addRow("source_row_equal_destination_row") << createModel() << QModelIndex() << 2 << 1 << QModelIndex() << 2; + QTest::addRow("source_row_equal_destination_row_plus_1") << createModel() << QModelIndex() << 2 << 1 << QModelIndex() << 3; + QTest::addRow("destination_row_greater_rowCount") << createModel() << QModelIndex() << 0 << 1 << QModelIndex() << rowCount + 1; + QTest::addRow("move_row_within_source_range") << createModel() << QModelIndex() << 0 << 3 << QModelIndex() << 2; } void tst_QStringListModel::moveRowsInvalid() @@ -155,20 +152,20 @@ void tst_QStringListModel::moveRows_data() QTest::newRow("1_Item_from_top_to_middle") << 0 << 1 << 3 << QStringList{"B", "C", "A", "D", "E", "F"}; QTest::newRow("1_Item_from_top_to_bottom") << 0 << 1 << 6 << QStringList{"B", "C", "D", "E", "F", "A"}; - QTest::newRow("1_Item_from_middle_to_top") << 2 << 1 << 1 << QStringList{"C", "A", "B", "D", "E", "F"}; - QTest::newRow("1_Item_from_bottom_to_middle") << 5 << 1 << 3 << QStringList{"A", "B", "F", "C", "D", "E"}; - QTest::newRow("1_Item_from_bottom to_top") << 5 << 1 << 1 << QStringList{"F", "A", "B", "C", "D", "E"}; + QTest::newRow("1_Item_from_middle_to_top") << 2 << 1 << 0 << QStringList{"C", "A", "B", "D", "E", "F"}; + QTest::newRow("1_Item_from_bottom_to_middle") << 5 << 1 << 2 << QStringList{"A", "B", "F", "C", "D", "E"}; + QTest::newRow("1_Item_from_bottom to_top") << 5 << 1 << 0 << QStringList{"F", "A", "B", "C", "D", "E"}; QTest::newRow("1_Item_from_middle_to_bottom") << 2 << 1 << 6 << QStringList{"A", "B", "D", "E", "F", "C"}; - QTest::newRow("1_Item_from_middle_to_middle_before") << 2 << 1 << 1 << QStringList{"C", "A", "B", "D", "E", "F"}; + QTest::newRow("1_Item_from_middle_to_middle_before") << 2 << 1 << 1 << QStringList{"A", "C", "B", "D", "E", "F"}; QTest::newRow("1_Item_from_middle_to_middle_after") << 2 << 1 << 4 << QStringList{"A", "B", "D", "C", "E", "F"}; QTest::newRow("2_Items_from_top_to_middle") << 0 << 2 << 3 << QStringList{"C", "A", "B", "D", "E", "F"}; QTest::newRow("2_Items_from_top_to_bottom") << 0 << 2 << 6 << QStringList{"C", "D", "E", "F", "A", "B"}; - QTest::newRow("2_Items_from_middle_to_top") << 2 << 2 << 1 << QStringList{"C", "D", "A", "B", "E", "F"}; - QTest::newRow("2_Items_from_bottom_to_middle") << 4 << 2 << 3 << QStringList{"A", "B", "E", "F", "C", "D"}; - QTest::newRow("2_Items_from_bottom_to_top") << 4 << 2 << 1 << QStringList{"E", "F", "A", "B", "C", "D"}; + QTest::newRow("2_Items_from_middle_to_top") << 2 << 2 << 0 << QStringList{"C", "D", "A", "B", "E", "F"}; + QTest::newRow("2_Items_from_bottom_to_middle") << 4 << 2 << 2 << QStringList{"A", "B", "E", "F", "C", "D"}; + QTest::newRow("2_Items_from_bottom_to_top") << 4 << 2 << 0 << QStringList{"E", "F", "A", "B", "C", "D"}; QTest::newRow("2_Items_from_middle_to_bottom") << 2 << 2 << 6 << QStringList{"A", "B", "E", "F", "C", "D"}; - QTest::newRow("2_Items_from_middle_to_middle_before") << 3 << 2 << 2 << QStringList{"A", "D", "E", "B", "C", "F"}; + QTest::newRow("2_Items_from_middle_to_middle_before") << 3 << 2 << 1 << QStringList{"A", "D", "E", "B", "C", "F"}; QTest::newRow("2_Items_from_middle_to_middle_after") << 1 << 2 << 5 << QStringList{"A", "D", "E", "B", "C", "F"}; } diff --git a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp index 4ca68550b9..4e105d7dc7 100644 --- a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp +++ b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp @@ -32,7 +32,7 @@ #include <QtCore/QElapsedTimer> #include <QtTest/QtTest> -#if QT_HAS_INCLUDE(<chrono>) +#if __has_include(<chrono>) # include <chrono> #endif @@ -519,7 +519,7 @@ void tst_QDeadlineTimer::expire() void tst_QDeadlineTimer::stdchrono() { -#if !QT_HAS_INCLUDE(<chrono>) +#if !__has_include(<chrono>) QSKIP("std::chrono not found on this system"); #else using namespace std::chrono; diff --git a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp index 49c10c6a24..365508024b 100644 --- a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp +++ b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp @@ -67,6 +67,7 @@ private slots: void sendPostedEvents_data(); void sendPostedEvents(); void processEventsOnlySendsQueuedEvents(); + void eventLoopExit(); }; bool tst_QEventDispatcher::event(QEvent *e) @@ -314,5 +315,49 @@ void tst_QEventDispatcher::processEventsOnlySendsQueuedEvents() QCOMPARE(object.eventsReceived, 4); } +void tst_QEventDispatcher::eventLoopExit() +{ + // This test was inspired by QTBUG-79477. A particular + // implementation detail in QCocoaEventDispatcher allowed + // QEventLoop::exit() to fail to really exit the event loop. + // Thus this test is a part of the dispatcher auto-test. + + // Imitates QApplication::exec(): + QEventLoop mainLoop; + // The test itself is a lambda: + QTimer::singleShot(0, [&mainLoop]() { + // Two more single shots, both will be posted as events + // (zero timeout) and supposed to be processes by the + // mainLoop: + + QTimer::singleShot(0, [&mainLoop]() { + // wakeUp triggers QCocoaEventDispatcher into incrementing + // its 'serialNumber': + mainLoop.wakeUp(); + // QCocoaEventDispatcher::processEvents() will process + // posted events and execute the second lambda defined below: + QCoreApplication::processEvents(); + }); + + QTimer::singleShot(0, [&mainLoop]() { + // With QCocoaEventDispatcher this is executed while in the + // processEvents (see above) and would fail to actually + // interrupt the loop. + mainLoop.exit(); + }); + }); + + bool timeoutObserved = false; + QTimer::singleShot(500, [&timeoutObserved, &mainLoop]() { + // In case the QEventLoop::exit above failed, we have to bail out + // early, not wasting time: + mainLoop.exit(); + timeoutObserved = true; + }); + + mainLoop.exec(); + QVERIFY(!timeoutObserved); +} + QTEST_MAIN(tst_QEventDispatcher) #include "tst_qeventdispatcher.moc" diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 9fe7d63727..14719f36f8 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -1702,9 +1702,10 @@ void tst_QMetaObjectBuilder::classNameFirstInStringData() builder.setClassName(QByteArrayLiteral("TestClass")); QMetaObject *mo = builder.toMetaObject(); - QByteArrayDataPtr header; - header.ptr = const_cast<QByteArrayData*>(mo->d.stringdata); - QCOMPARE(QByteArray(header), QByteArrayLiteral("TestClass")); + uint offset = mo->d.stringdata[0]; + uint len = mo->d.stringdata[1]; + QByteArray className(reinterpret_cast<const char *>(mo->d.stringdata) + offset, len); + QCOMPARE(className, QByteArrayLiteral("TestClass")); free(mo); } diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index d300c31001..4e30f210b1 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -120,11 +120,10 @@ private slots: void constRefs(); void convertCustomType_data(); void convertCustomType(); - void compareCustomType_data(); - void compareCustomType(); void compareCustomEqualOnlyType(); void customDebugStream(); void unknownType(); + void fromType(); }; struct BaseGenericType @@ -482,6 +481,7 @@ void tst_QMetaType::id() { QCOMPARE(QMetaType(QMetaType::QString).id(), QMetaType::QString); QCOMPARE(QMetaType(::qMetaTypeId<TestSpace::Foo>()).id(), ::qMetaTypeId<TestSpace::Foo>()); + QCOMPARE(QMetaType::fromType<TestSpace::Foo>().id(), ::qMetaTypeId<TestSpace::Foo>()); } void tst_QMetaType::qMetaTypeId() @@ -602,6 +602,12 @@ void tst_QMetaType::typeName() QCOMPARE(name, aTypeName); QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData())); QCOMPARE(rawname == nullptr, aTypeName.isNull()); + + QMetaType mt(aType); + if (mt.isValid()) { // Gui type are not valid + QCOMPARE(QString::fromLatin1(QMetaType(aType).name()), aTypeName); + } + } void tst_QMetaType::type_data() @@ -1730,6 +1736,7 @@ void tst_QMetaType::automaticTemplateRegistration() const int type = QMetaType::type(tn); \ const int expectedType = ::qMetaTypeId<CONTAINER< __VA_ARGS__ > >(); \ QCOMPARE(type, expectedType); \ + QCOMPARE((QMetaType::fromType<CONTAINER< __VA_ARGS__ >>().id()), expectedType); \ } #define FOR_EACH_1ARG_TEMPLATE_TYPE(F, TYPE) \ @@ -2010,7 +2017,7 @@ void tst_QMetaType::metaObject_data() QTest::newRow("MyGadget") << ::qMetaTypeId<MyGadget>() << &MyGadget::staticMetaObject << true << false << false; QTest::newRow("MyGadget*") << ::qMetaTypeId<MyGadget*>() << &MyGadget::staticMetaObject << false << true << false; QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false << false; - QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &QObject::staticQtMetaObject << false << false << false; + QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &Qt::staticMetaObject << false << false << false; QTest::newRow("MyQObjectFromGadget*") << ::qMetaTypeId<MyQObjectFromGadget*>() << &MyQObjectFromGadget::staticMetaObject << false << false << true; QTest::newRow("GadgetDerivedAndTyped<int>") << ::qMetaTypeId<GadgetDerivedAndTyped<int>>() << &GadgetDerivedAndTyped<int>::staticMetaObject << true << false << false; @@ -2132,7 +2139,7 @@ struct CustomConvertibleType }; bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) -{ return lhs.m_foo < rhs.m_foo; } +{ return lhs.m_foo.toString() < rhs.m_foo.toString(); } bool operator==(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) { return lhs.m_foo == rhs.m_foo; } bool operator!=(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) @@ -2422,43 +2429,6 @@ void tst_QMetaType::convertCustomType() QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo); } -void tst_QMetaType::compareCustomType_data() -{ - QMetaType::registerComparators<CustomConvertibleType>(); - - QTest::addColumn<QVariantList>("unsorted"); - QTest::addColumn<QVariantList>("sorted"); - - QTest::newRow("int") << (QVariantList() << 37 << 458 << 1 << 243 << -4 << 383) - << (QVariantList() << -4 << 1 << 37 << 243 << 383 << 458); - - QTest::newRow("dobule") << (QVariantList() << 4934.93 << 0.0 << 302.39 << -39.0) - << (QVariantList() << -39.0 << 0.0 << 302.39 << 4934.93); - - QTest::newRow("QString") << (QVariantList() << "Hello" << "World" << "this" << "is" << "a" << "test") - << (QVariantList() << "a" << "Hello" << "is" << "test" << "this" << "World"); - - QTest::newRow("QTime") << (QVariantList() << QTime(14, 39) << QTime(0, 0) << QTime(18, 18) << QTime(9, 27)) - << (QVariantList() << QTime(0, 0) << QTime(9, 27) << QTime(14, 39) << QTime(18, 18)); - - QTest::newRow("QDate") << (QVariantList() << QDate(2013, 3, 23) << QDate(1900, 12, 1) << QDate(2001, 2, 2) << QDate(1982, 12, 16)) - << (QVariantList() << QDate(1900, 12, 1) << QDate(1982, 12, 16) << QDate(2001, 2, 2) << QDate(2013, 3, 23)); - - QTest::newRow("mixed") << (QVariantList() << "Hello" << "World" << QChar('a') << 38 << QChar('z') << -39 << 4.6) - << (QVariantList() << -39 << 4.6 << 38 << QChar('a') << "Hello" << "World" << QChar('z')); - - QTest::newRow("custom") << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(100)) << QVariant::fromValue(CustomConvertibleType(50))) - << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(50)) << QVariant::fromValue(CustomConvertibleType(100))); -} - -void tst_QMetaType::compareCustomType() -{ - QFETCH(QVariantList, unsorted); - QFETCH(QVariantList, sorted); - std::sort(unsorted.begin(), unsorted.end()); - QCOMPARE(unsorted, sorted); -} - void tst_QMetaType::compareCustomEqualOnlyType() { int metaTypeId = qRegisterMetaType<CustomEqualsOnlyType>(); @@ -2480,11 +2450,6 @@ void tst_QMetaType::compareCustomEqualOnlyType() QCOMPARE(variant100, variant100x); QCOMPARE(variant100, variant100); - // compare always fails - QVERIFY(!(variant50 < variant50)); - QVERIFY(!(variant50 < variant100)); - QVERIFY(!(variant100 < variant50)); - // check QMetaType::compare works/doesn't crash for equals only comparators bool wasSuccess = QMetaType::compare(variant50.constData(), variant50.constData(), metaTypeId, &result); @@ -2574,6 +2539,26 @@ void tst_QMetaType::unknownType() invalid.construct(&buffer); QCOMPARE(buffer, 0xBAD); } + +void tst_QMetaType::fromType() +{ + #define FROMTYPE_CHECK(MetaTypeName, MetaTypeId, RealType) \ + QCOMPARE(QMetaType::fromType<RealType>(), QMetaType(MetaTypeId)); \ + QVERIFY(QMetaType::fromType<RealType>() == QMetaType(MetaTypeId)); \ + QVERIFY(!(QMetaType::fromType<RealType>() != QMetaType(MetaTypeId))); \ + QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId); + + FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK) + + QVERIFY(QMetaType::fromType<QString>() != QMetaType()); + QCOMPARE(QMetaType(), QMetaType()); + QCOMPARE(QMetaType(QMetaType::UnknownType), QMetaType()); + + FROMTYPE_CHECK(_, ::qMetaTypeId<Whity<int>>(), Whity<int>) + #undef FROMTYPE_CHECK +} + + // Compile-time test, it should be possible to register function pointer types class Undefined; diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 91ea83be3d..5ce70f7a0e 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -6671,16 +6671,16 @@ void tst_QObject::connectWarnings() ReceiverObject r1; r1.reset(); - QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid null parameter"); + QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid nullptr parameter"); connect(static_cast<const SenderObject *>(nullptr), &SubSender::signal1, &r1, &ReceiverObject::slot1); - QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SubSender, Unknown): invalid null parameter"); + QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SubSender, Unknown): invalid nullptr parameter"); connect(&sub, &SubSender::signal1, static_cast<ReceiverObject *>(nullptr), &ReceiverObject::slot1); - QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid null parameter"); + QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid nullptr parameter"); connect(static_cast<const SenderObject *>(nullptr), &SenderObject::signal1, &r1, &ReceiverObject::slot1); - QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, Unknown): invalid null parameter"); + QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, Unknown): invalid nullptr parameter"); connect(&obj, &SenderObject::signal1, static_cast<ReceiverObject *>(nullptr), &ReceiverObject::slot1); } diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp index 8e0bdac520..1bd27cd0ce 100644 --- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp +++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp @@ -223,7 +223,7 @@ void tst_QTimer::remainingTimeDuringActivation() namespace { -#if QT_HAS_INCLUDE(<chrono>) +#if __has_include(<chrono>) template <typename T> std::chrono::milliseconds to_ms(T t) { return std::chrono::duration_cast<std::chrono::milliseconds>(t); } @@ -233,7 +233,7 @@ namespace { void tst_QTimer::basic_chrono() { -#if !QT_HAS_INCLUDE(<chrono>) +#if !__has_include(<chrono>) QSKIP("This test requires C++11 <chrono> support"); #else // duplicates zeroTimer, singleShotTimeout, interval and remainingTime @@ -871,7 +871,7 @@ void tst_QTimer::singleShotToFunctors() void tst_QTimer::singleShot_chrono() { -#if !QT_HAS_INCLUDE(<chrono>) +#if !__has_include(<chrono>) QSKIP("This test requires C++11 <chrono> support"); #else // duplicates singleShotStaticFunctionZeroTimeout and singleShotToFunctors diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 074cb07092..9f022b3b14 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -31,6 +31,7 @@ #include <QtTest/QtTest> #include <qvariant.h> +#include <QtCore/private/qvariant_p.h> #include <qbitarray.h> #include <qbytearraylist.h> #include <qdatetime.h> @@ -45,7 +46,7 @@ #include <limits.h> #include <float.h> #include <cmath> -#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L +#if __has_include(<variant>) && __cplusplus >= 201703L #include <variant> #endif #include <QLinkedList> @@ -189,8 +190,6 @@ private slots: void operator_eq_eq_data(); void operator_eq_eq(); void operator_eq_eq_rhs(); - void compareNumbers_data() const; - void compareNumbers() const; void typeName_data(); void typeName(); @@ -269,15 +268,16 @@ private slots: void enums(); void metaEnums(); - void compareSanity_data(); - void compareSanity(); - void compareRich(); void nullConvert(); void accessSequentialContainerKey(); - + void shouldDeleteVariantDataWorksForSequential(); + void shouldDeleteVariantDataWorksForAssociative(); void fromStdVariant(); + void qt4UuidDataStream(); + + void preferDirectConversionOverInterfaces(); private: void dataStream_data(QDataStream::Version version); @@ -1725,344 +1725,6 @@ void tst_QVariant::operator_eq_eq_rhs() #endif } -void tst_QVariant::compareNumbers_data() const -{ - typedef signed char schar; - QTest::addColumn<QVariant>("v1"); - QTest::addColumn<QVariant>("v2"); - QTest::addColumn<int>("expected"); - - // sanity checking: same types - QTest::newRow("bool1") << QVariant(false) << QVariant(false) << 0; - QTest::newRow("bool2") << QVariant(true) << QVariant(true) << 0; - QTest::newRow("bool3") << QVariant(false) << QVariant(true) << -1; - QTest::newRow("bool4") << QVariant(true) << QVariant(false) << +1; - - QTest::newRow("char1") << QVariant::fromValue(char(0)) << QVariant::fromValue(char(0)) << 0; - QTest::newRow("char2") << QVariant::fromValue(CHAR_MAX) << QVariant::fromValue(CHAR_MAX) << 0; - QTest::newRow("char3") << QVariant::fromValue(CHAR_MIN) << QVariant::fromValue(CHAR_MIN) << 0; - QTest::newRow("char4") << QVariant::fromValue(CHAR_MIN) << QVariant::fromValue(CHAR_MAX) << -1; - QTest::newRow("char5") << QVariant::fromValue(CHAR_MAX) << QVariant::fromValue(CHAR_MIN) << +1; - - QTest::newRow("schar1") << QVariant::fromValue(schar(0)) << QVariant::fromValue(schar(0)) << 0; - QTest::newRow("schar2") << QVariant::fromValue(SCHAR_MAX) << QVariant::fromValue(SCHAR_MAX) << 0; - QTest::newRow("schar3") << QVariant::fromValue(SCHAR_MIN) << QVariant::fromValue(SCHAR_MIN) << 0; - QTest::newRow("schar4") << QVariant::fromValue(SCHAR_MIN) << QVariant::fromValue(SCHAR_MAX) << -1; - QTest::newRow("schar5") << QVariant::fromValue(SCHAR_MAX) << QVariant::fromValue(SCHAR_MIN) << +1; - - QTest::newRow("uchar1") << QVariant::fromValue(uchar(0)) << QVariant::fromValue(uchar(0)) << 0; - QTest::newRow("uchar2") << QVariant::fromValue(UCHAR_MAX) << QVariant::fromValue(UCHAR_MAX) << 0; - QTest::newRow("uchar3") << QVariant::fromValue(uchar(0)) << QVariant::fromValue(UCHAR_MAX) << -1; - QTest::newRow("uchar4") << QVariant::fromValue(UCHAR_MAX) << QVariant::fromValue(uchar(0)) << +1; - - QTest::newRow("short1") << QVariant::fromValue(short(0)) << QVariant::fromValue(short(0)) << 0; - QTest::newRow("short2") << QVariant::fromValue(SHRT_MAX) << QVariant::fromValue(SHRT_MAX) << 0; - QTest::newRow("short3") << QVariant::fromValue(SHRT_MIN) << QVariant::fromValue(SHRT_MIN) << 0; - QTest::newRow("short4") << QVariant::fromValue(SHRT_MIN) << QVariant::fromValue(SHRT_MAX) << -1; - QTest::newRow("short5") << QVariant::fromValue(SHRT_MAX) << QVariant::fromValue(SHRT_MIN) << +1; - - QTest::newRow("ushort1") << QVariant::fromValue(ushort(0)) << QVariant::fromValue(ushort(0)) << 0; - QTest::newRow("ushort2") << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(USHRT_MAX) << 0; - QTest::newRow("ushort3") << QVariant::fromValue(ushort(0)) << QVariant::fromValue(USHRT_MAX) << -1; - QTest::newRow("ushort4") << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(ushort(0)) << +1; - - QTest::newRow("int1") << QVariant::fromValue(int(0)) << QVariant::fromValue(int(0)) << 0; - QTest::newRow("int2") << QVariant::fromValue(INT_MAX) << QVariant::fromValue(INT_MAX) << 0; - QTest::newRow("int3") << QVariant::fromValue(INT_MIN) << QVariant::fromValue(INT_MIN) << 0; - QTest::newRow("int4") << QVariant::fromValue(INT_MIN) << QVariant::fromValue(INT_MAX) << -1; - QTest::newRow("int5") << QVariant::fromValue(INT_MAX) << QVariant::fromValue(INT_MIN) << +1; - - QTest::newRow("uint1") << QVariant::fromValue(uint(0)) << QVariant::fromValue(uint(0)) << 0; - QTest::newRow("uint2") << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(UINT_MAX) << 0; - QTest::newRow("uint3") << QVariant::fromValue(uint(0)) << QVariant::fromValue(UINT_MAX) << -1; - QTest::newRow("uint4") << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(uint(0)) << +1; - - QTest::newRow("long1") << QVariant::fromValue(long(0)) << QVariant::fromValue(long(0)) << 0; - QTest::newRow("long2") << QVariant::fromValue(LONG_MAX) << QVariant::fromValue(LONG_MAX) << 0; - QTest::newRow("long3") << QVariant::fromValue(LONG_MIN) << QVariant::fromValue(LONG_MIN) << 0; - QTest::newRow("long4") << QVariant::fromValue(LONG_MIN) << QVariant::fromValue(LONG_MAX) << -1; - QTest::newRow("long5") << QVariant::fromValue(LONG_MAX) << QVariant::fromValue(LONG_MIN) << +1; - - QTest::newRow("ulong1") << QVariant::fromValue(ulong(0)) << QVariant::fromValue(ulong(0)) << 0; - QTest::newRow("ulong2") << QVariant::fromValue(ULONG_MAX) << QVariant::fromValue(ULONG_MAX) << 0; - QTest::newRow("ulong3") << QVariant::fromValue(ulong(0)) << QVariant::fromValue(ULONG_MAX) << -1; - QTest::newRow("ulong4") << QVariant::fromValue(ULONG_MAX) << QVariant::fromValue(ulong(0)) << +1; - - QTest::newRow("llong1") << QVariant::fromValue(qlonglong(0)) << QVariant::fromValue(qlonglong(0)) << 0; - QTest::newRow("llong2") << QVariant::fromValue(LLONG_MAX) << QVariant::fromValue(LLONG_MAX) << 0; - QTest::newRow("llong3") << QVariant::fromValue(LLONG_MIN) << QVariant::fromValue(LLONG_MIN) << 0; - QTest::newRow("llong4") << QVariant::fromValue(LLONG_MIN) << QVariant::fromValue(LLONG_MAX) << -1; - QTest::newRow("llong5") << QVariant::fromValue(LLONG_MAX) << QVariant::fromValue(LLONG_MIN) << +1; - - QTest::newRow("ullong1") << QVariant::fromValue(qulonglong(0)) << QVariant::fromValue(qulonglong(0)) << 0; - QTest::newRow("ullong2") << QVariant::fromValue(ULLONG_MAX) << QVariant::fromValue(ULLONG_MAX) << 0; - QTest::newRow("ullong3") << QVariant::fromValue(qulonglong(0)) << QVariant::fromValue(ULLONG_MAX) << -1; - QTest::newRow("ullong4") << QVariant::fromValue(ULLONG_MAX) << QVariant::fromValue(qulonglong(0)) << +1; - - QTest::newRow("float1") << QVariant::fromValue(0.f) << QVariant::fromValue(0.f) << 0; - QTest::newRow("float2") << QVariant::fromValue(-1.f) << QVariant::fromValue(0.f) << -1; - QTest::newRow("float3") << QVariant::fromValue(0.f) << QVariant::fromValue(-1.f) << +1; - QTest::newRow("float4") << QVariant::fromValue(-float(qInf())) << QVariant::fromValue(0.f) << -1; - QTest::newRow("float5") << QVariant::fromValue(0.f) << QVariant::fromValue(-float(qInf())) << +1; - QTest::newRow("float6") << QVariant::fromValue(-float(qInf())) << QVariant::fromValue(-float(qInf())) << 0; - QTest::newRow("float7") << QVariant::fromValue(float(qInf())) << QVariant::fromValue(float(qInf())) << 0; - - QTest::newRow("double1") << QVariant::fromValue(0.) << QVariant::fromValue(0.) << 0; - QTest::newRow("double2") << QVariant::fromValue(-1.) << QVariant::fromValue(0.) << -1; - QTest::newRow("double3") << QVariant::fromValue(0.) << QVariant::fromValue(-1.) << +1; - QTest::newRow("double4") << QVariant::fromValue(-qInf()) << QVariant::fromValue(0.) << -1; - QTest::newRow("double5") << QVariant::fromValue(0.) << QVariant::fromValue(-qInf()) << +1; - QTest::newRow("double6") << QVariant::fromValue(-double(qInf())) << QVariant::fromValue(-qInf()) << 0; - QTest::newRow("double7") << QVariant::fromValue(qInf()) << QVariant::fromValue(qInf()) << 0; - QTest::newRow("double8") << QVariant::fromValue(-qInf()) << QVariant::fromValue(qInf()) << -1; - QTest::newRow("double9") << QVariant::fromValue(qQNaN()) << QVariant::fromValue(0.) << INT_MAX; - QTest::newRow("double10") << QVariant::fromValue(0.) << QVariant::fromValue(qQNaN()) << INT_MAX; - QTest::newRow("double11") << QVariant::fromValue(qQNaN()) << QVariant::fromValue(qQNaN()) << INT_MAX; - - // mixed comparisons - // fp + fp - QTest::newRow("float+double1") << QVariant::fromValue(0.f) << QVariant::fromValue(0.) << 0; - QTest::newRow("float+double2") << QVariant::fromValue(-1.f) << QVariant::fromValue(0.) << -1; - QTest::newRow("float+double3") << QVariant::fromValue(0.f) << QVariant::fromValue(-1.) << +1; - QTest::newRow("float+double4") << QVariant::fromValue(-float(qInf())) << QVariant::fromValue(0.) << -1; - QTest::newRow("float+double5") << QVariant::fromValue(0.f) << QVariant::fromValue(-qInf()) << +1; - QTest::newRow("float+double6") << QVariant::fromValue(-float(qInf())) << QVariant::fromValue(-qInf()) << 0; - QTest::newRow("float+double7") << QVariant::fromValue(float(qInf())) << QVariant::fromValue(qInf()) << 0; - QTest::newRow("float+double8") << QVariant::fromValue(-float(qInf())) << QVariant::fromValue(qInf()) << -1; - QTest::newRow("float+double9") << QVariant::fromValue(qQNaN()) << QVariant::fromValue(0.) << INT_MAX; - QTest::newRow("float+double10") << QVariant::fromValue(0.) << QVariant::fromValue(qQNaN()) << INT_MAX; - QTest::newRow("float+double11") << QVariant::fromValue(qQNaN()) << QVariant::fromValue(qQNaN()) << INT_MAX; - - // fp + int - QTest::newRow("float+int1") << QVariant::fromValue(0.f) << QVariant::fromValue(0) << 0; - QTest::newRow("double+int1") << QVariant::fromValue(0.) << QVariant::fromValue(0) << 0; - QTest::newRow("float+int2") << QVariant::fromValue(-1.f) << QVariant::fromValue(0) << -1; - QTest::newRow("double+int2") << QVariant::fromValue(-1.) << QVariant::fromValue(0) << -1; - QTest::newRow("float+int3") << QVariant::fromValue(0.f) << QVariant::fromValue(-1) << +1; - QTest::newRow("double+int3") << QVariant::fromValue(0.) << QVariant::fromValue(-1) << +1; - QTest::newRow("float+int4") << QVariant::fromValue(1.5f) << QVariant::fromValue(1) << +1; - QTest::newRow("double+int4") << QVariant::fromValue(1.5) << QVariant::fromValue(1) << +1; - QTest::newRow("double+int5") << QVariant::fromValue(qInf()) << QVariant::fromValue(1) << +1; - - // fp + uint - QTest::newRow("float+uint1") << QVariant::fromValue(0.f) << QVariant::fromValue(0U) << 0; - QTest::newRow("double+uint1") << QVariant::fromValue(0.) << QVariant::fromValue(0U) << 0; - QTest::newRow("float+uint2") << QVariant::fromValue(-1.f) << QVariant::fromValue(0U) << -1; - QTest::newRow("double+uint2") << QVariant::fromValue(-1.) << QVariant::fromValue(0U) << -1; - QTest::newRow("float+uint3") << QVariant::fromValue(0.f) << QVariant::fromValue(1U) << -1; - QTest::newRow("double+uint3") << QVariant::fromValue(0.) << QVariant::fromValue(1U) << -1; - QTest::newRow("float+uint4") << QVariant::fromValue(1.5f) << QVariant::fromValue(1U) << +1; - QTest::newRow("double+uint4") << QVariant::fromValue(1.5) << QVariant::fromValue(1U) << +1; - - // lower ranked + int - QTest::newRow("bool+int1") << QVariant::fromValue(false) << QVariant::fromValue(0) << 0; - QTest::newRow("bool+int2") << QVariant::fromValue(false) << QVariant::fromValue(1) << -1; - QTest::newRow("bool+int3") << QVariant::fromValue(true) << QVariant::fromValue(0) << +1; - QTest::newRow("bool+int4") << QVariant::fromValue(true) << QVariant::fromValue(1) << 0; - QTest::newRow("bool+int5") << QVariant::fromValue(true) << QVariant::fromValue(2) << -1; - - QTest::newRow("char+int1") << QVariant::fromValue(char(0)) << QVariant::fromValue(0) << 0; - QTest::newRow("char+int2") << QVariant::fromValue(char(0)) << QVariant::fromValue(1) << -1; - QTest::newRow("char+int3") << QVariant::fromValue(char(1)) << QVariant::fromValue(0) << +1; - QTest::newRow("char+int4") << QVariant::fromValue(char(1)) << QVariant::fromValue(1) << 0; - if (std::numeric_limits<char>::is_signed) { - QTest::newRow("char+int5") << QVariant::fromValue(char(-1)) << QVariant::fromValue(0) << -1; - QTest::newRow("char+int6") << QVariant::fromValue(char(-1)) << QVariant::fromValue(-1) << 0; - } - - QTest::newRow("schar+int1") << QVariant::fromValue(schar(0)) << QVariant::fromValue(0) << 0; - QTest::newRow("schar+int2") << QVariant::fromValue(schar(0)) << QVariant::fromValue(1) << -1; - QTest::newRow("schar+int3") << QVariant::fromValue(schar(1)) << QVariant::fromValue(0) << +1; - QTest::newRow("schar+int4") << QVariant::fromValue(schar(1)) << QVariant::fromValue(1) << 0; - QTest::newRow("schar+int5") << QVariant::fromValue(schar(-1)) << QVariant::fromValue(0) << -1; - QTest::newRow("schar+int6") << QVariant::fromValue(schar(-1)) << QVariant::fromValue(-1) << 0; - - QTest::newRow("uchar+int1") << QVariant::fromValue(uchar(0)) << QVariant::fromValue(0) << 0; - QTest::newRow("uchar+int2") << QVariant::fromValue(uchar(0)) << QVariant::fromValue(1) << -1; - QTest::newRow("uchar+int3") << QVariant::fromValue(uchar(1)) << QVariant::fromValue(0) << +1; - QTest::newRow("uchar+int4") << QVariant::fromValue(uchar(1)) << QVariant::fromValue(1) << 0; - - QTest::newRow("short+int1") << QVariant::fromValue(short(0)) << QVariant::fromValue(0) << 0; - QTest::newRow("short+int2") << QVariant::fromValue(short(0)) << QVariant::fromValue(1) << -1; - QTest::newRow("short+int3") << QVariant::fromValue(short(1)) << QVariant::fromValue(0) << +1; - QTest::newRow("short+int4") << QVariant::fromValue(short(1)) << QVariant::fromValue(1) << 0; - QTest::newRow("short+int5") << QVariant::fromValue(short(-1)) << QVariant::fromValue(0) << -1; - QTest::newRow("short+int6") << QVariant::fromValue(short(-1)) << QVariant::fromValue(-1) << 0; - - QTest::newRow("ushort+int1") << QVariant::fromValue(ushort(0)) << QVariant::fromValue(0) << 0; - QTest::newRow("ushort+int2") << QVariant::fromValue(ushort(0)) << QVariant::fromValue(1) << -1; - QTest::newRow("ushort+int3") << QVariant::fromValue(ushort(1)) << QVariant::fromValue(0) << +1; - QTest::newRow("ushort+int4") << QVariant::fromValue(ushort(1)) << QVariant::fromValue(1) << 0; - - // lower ranked + uint (without sign change) - QTest::newRow("bool+uint1") << QVariant::fromValue(false) << QVariant::fromValue(0U) << 0; - QTest::newRow("bool+uint2") << QVariant::fromValue(false) << QVariant::fromValue(1U) << -1; - QTest::newRow("bool+uint3") << QVariant::fromValue(true) << QVariant::fromValue(0U) << +1; - QTest::newRow("bool+uint4") << QVariant::fromValue(true) << QVariant::fromValue(1U) << 0; - QTest::newRow("bool+uint5") << QVariant::fromValue(true) << QVariant::fromValue(2U) << -1; - - QTest::newRow("char+uint1") << QVariant::fromValue(char(0)) << QVariant::fromValue(0U) << 0; - QTest::newRow("char+uint2") << QVariant::fromValue(char(0)) << QVariant::fromValue(1U) << -1; - QTest::newRow("char+uint3") << QVariant::fromValue(char(1)) << QVariant::fromValue(0U) << +1; - QTest::newRow("char+uint4") << QVariant::fromValue(char(1)) << QVariant::fromValue(1U) << 0; - - QTest::newRow("schar+uint1") << QVariant::fromValue(schar(0)) << QVariant::fromValue(0U) << 0; - QTest::newRow("schar+uint2") << QVariant::fromValue(schar(0)) << QVariant::fromValue(1U) << -1; - QTest::newRow("schar+uint3") << QVariant::fromValue(schar(1)) << QVariant::fromValue(0U) << +1; - QTest::newRow("schar+uint4") << QVariant::fromValue(schar(1)) << QVariant::fromValue(1U) << 0; - - QTest::newRow("uchar+uint1") << QVariant::fromValue(uchar(0)) << QVariant::fromValue(0U) << 0; - QTest::newRow("uchar+uint2") << QVariant::fromValue(uchar(0)) << QVariant::fromValue(1U) << -1; - QTest::newRow("uchar+uint3") << QVariant::fromValue(uchar(1)) << QVariant::fromValue(0U) << +1; - QTest::newRow("uchar+uint4") << QVariant::fromValue(uchar(1)) << QVariant::fromValue(1U) << 0; - - QTest::newRow("short+uint1") << QVariant::fromValue(short(0)) << QVariant::fromValue(0U) << 0; - QTest::newRow("short+uint2") << QVariant::fromValue(short(0)) << QVariant::fromValue(1U) << -1; - QTest::newRow("short+uint3") << QVariant::fromValue(short(1)) << QVariant::fromValue(0U) << +1; - QTest::newRow("short+uint4") << QVariant::fromValue(short(1)) << QVariant::fromValue(1U) << 0; - - QTest::newRow("ushort+uint1") << QVariant::fromValue(ushort(0)) << QVariant::fromValue(0U) << 0; - QTest::newRow("ushort+uint2") << QVariant::fromValue(ushort(0)) << QVariant::fromValue(1U) << -1; - QTest::newRow("ushort+uint3") << QVariant::fromValue(ushort(1)) << QVariant::fromValue(0U) << +1; - QTest::newRow("ushort+uint4") << QVariant::fromValue(ushort(1)) << QVariant::fromValue(1U) << 0; - - // int + qlonglong - QTest::newRow("int+qlonglong1") << QVariant::fromValue(0) << QVariant::fromValue(Q_INT64_C(0)) << 0; - QTest::newRow("int+qlonglong2") << QVariant::fromValue(1) << QVariant::fromValue(Q_INT64_C(0)) << +1; - QTest::newRow("int+qlonglong3") << QVariant::fromValue(0) << QVariant::fromValue(Q_INT64_C(1)) << -1; - QTest::newRow("int+qlonglong4") << QVariant::fromValue(1) << QVariant::fromValue(Q_INT64_C(1)) << 0; - QTest::newRow("int+qlonglong5") << QVariant::fromValue(0) << QVariant::fromValue(Q_INT64_C(-1)) << +1; - QTest::newRow("int+qlonglong6") << QVariant::fromValue(-1) << QVariant::fromValue(Q_INT64_C(0)) << -1; - QTest::newRow("int+qlonglong7") << QVariant::fromValue(-1) << QVariant::fromValue(Q_INT64_C(-1)) << 0; - - // uint + qulonglong - QTest::newRow("uint+qulonglong1") << QVariant::fromValue(0U) << QVariant::fromValue(Q_UINT64_C(0)) << 0; - QTest::newRow("uint+qulonglong2") << QVariant::fromValue(1U) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - QTest::newRow("uint+qulonglong3") << QVariant::fromValue(0U) << QVariant::fromValue(Q_UINT64_C(1)) << -1; - QTest::newRow("uint+qulonglong4") << QVariant::fromValue(1U) << QVariant::fromValue(Q_UINT64_C(1)) << 0; - - // int + uint (without sign change) - QTest::newRow("int+uint1") << QVariant::fromValue(0) << QVariant::fromValue(0U) << 0; - QTest::newRow("int+uint2") << QVariant::fromValue(1) << QVariant::fromValue(0U) << +1; - QTest::newRow("int+uint3") << QVariant::fromValue(0) << QVariant::fromValue(1U) << -1; - QTest::newRow("int+uint4") << QVariant::fromValue(1) << QVariant::fromValue(1U) << 0; - - // uint + qlonglong - QTest::newRow("uint+qlonglong1") << QVariant::fromValue(0U) << QVariant::fromValue(Q_INT64_C(0)) << 0; - QTest::newRow("uint+qlonglong2") << QVariant::fromValue(1U) << QVariant::fromValue(Q_INT64_C(0)) << +1; - QTest::newRow("uint+qlonglong3") << QVariant::fromValue(0U) << QVariant::fromValue(Q_INT64_C(1)) << -1; - QTest::newRow("uint+qlonglong4") << QVariant::fromValue(1U) << QVariant::fromValue(Q_INT64_C(1)) << 0; - QTest::newRow("uint+qlonglong5") << QVariant::fromValue(0U) << QVariant::fromValue(Q_INT64_C(-1)) << +1; - - // boundary conditions - QTest::newRow("charmax+intmax") << QVariant::fromValue(CHAR_MAX) << QVariant::fromValue(INT_MAX) << -1; - QTest::newRow("charmax+uintmax") << QVariant::fromValue(CHAR_MAX) << QVariant::fromValue(UINT_MAX) << -1; - QTest::newRow("scharmax+intmax") << QVariant::fromValue(SCHAR_MAX) << QVariant::fromValue(INT_MAX) << -1; - QTest::newRow("scharmax+uintmax") << QVariant::fromValue(SCHAR_MAX) << QVariant::fromValue(UINT_MAX) << -1; - QTest::newRow("ucharmax+intmax") << QVariant::fromValue(UCHAR_MAX) << QVariant::fromValue(INT_MAX) << -1; - QTest::newRow("ucharmax+uintmax") << QVariant::fromValue(UCHAR_MAX) << QVariant::fromValue(UINT_MAX) << -1; - QTest::newRow("shortmax+intmax") << QVariant::fromValue(SHRT_MAX) << QVariant::fromValue(INT_MAX) << -1; - QTest::newRow("shortmax+uintmax") << QVariant::fromValue(SHRT_MAX) << QVariant::fromValue(UINT_MAX) << -1; - QTest::newRow("ushortmax+intmax") << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(INT_MAX) << -1; - QTest::newRow("ushortmax+uintmax") << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(UINT_MAX) << -1; - - QTest::newRow("intmin+qlonglongmin") << QVariant::fromValue(INT_MIN) << QVariant::fromValue(LLONG_MIN) << +1; - QTest::newRow("intmax+uintmax") << QVariant::fromValue(INT_MAX) << QVariant::fromValue(UINT_MAX) << -1; - QTest::newRow("intmax+qlonglongmax") << QVariant::fromValue(INT_MAX) << QVariant::fromValue(LLONG_MAX) << -1; - QTest::newRow("uintmax+qlonglongmax") << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(LLONG_MAX) << -1; - QTest::newRow("intmax+qulonglongmax") << QVariant::fromValue(INT_MAX) << QVariant::fromValue(ULLONG_MAX) << -1; - QTest::newRow("qlonglongmax+qulonglongmax") << QVariant::fromValue(LLONG_MAX) << QVariant::fromValue(ULLONG_MAX) << -1; - QTest::newRow("uintmax+qlonglongmin") << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(LLONG_MIN) << +1; - - // check for no sign-extension issues - QTest::newRow("ushortmax+intzero") << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(0) << +1; - QTest::newRow("ushortmax+qlonglongzero") << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(Q_INT64_C(0)) << +1; - QTest::newRow("uintmax+qlonglongzero") << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(Q_INT64_C(0)) << +1; - - // sign changes - // the tests below check that a signed negative number sign-changes to a non-zero unsigned number and that - // signed -1 sign-changes to unsigned maximum (all bits set, ~0). This works on two's complement machines - // (all that Qt supports), and would also work on one's complement. - if (std::numeric_limits<char>::is_signed) { - QTest::newRow("signchange-char+uint") << QVariant::fromValue(char(-1)) << QVariant::fromValue(0U) << +1; - QTest::newRow("signchange-char+uintmax") << QVariant::fromValue(char(-1)) << QVariant::fromValue(UINT_MAX) << 0; - QTest::newRow("signchange-charmin+uint") << QVariant::fromValue(CHAR_MIN) << QVariant::fromValue(0U) << +1; - QTest::newRow("signchange-char+qulonglong") << QVariant::fromValue(char(-1)) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - QTest::newRow("signchange-char+qulonglongmax") << QVariant::fromValue(char(-1)) << QVariant::fromValue(ULLONG_MAX) << 0; - QTest::newRow("signchange-charmin+qulonglong") << QVariant::fromValue(CHAR_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - } - QTest::newRow("signchange-schar+uint") << QVariant::fromValue(schar(-1)) << QVariant::fromValue(0U) << +1; - QTest::newRow("signchange-schar+uintmax") << QVariant::fromValue(schar(-1)) << QVariant::fromValue(UINT_MAX) << 0; - QTest::newRow("signchange-scharmin+uint") << QVariant::fromValue(SCHAR_MIN) << QVariant::fromValue(0U) << +1; - QTest::newRow("signchange-schar+qulonglong") << QVariant::fromValue(schar(-1)) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - QTest::newRow("signchange-schar+qulonglongmax") << QVariant::fromValue(schar(-1)) << QVariant::fromValue(ULLONG_MAX) << 0; - QTest::newRow("signchange-scharmin+qulonglong") << QVariant::fromValue(SCHAR_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - QTest::newRow("signchange-short+uint") << QVariant::fromValue(short(-1)) << QVariant::fromValue(0U) << +1; - QTest::newRow("signchange-short+uintmax") << QVariant::fromValue(short(-1)) << QVariant::fromValue(UINT_MAX) << 0; - QTest::newRow("signchange-shortmin+uint") << QVariant::fromValue(SHRT_MIN) << QVariant::fromValue(0U) << +1; - QTest::newRow("signchange-short+qulonglong") << QVariant::fromValue(short(-1)) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - QTest::newRow("signchange-short+qulonglongmax") << QVariant::fromValue(short(-1)) << QVariant::fromValue(ULLONG_MAX) << 0; - QTest::newRow("signchange-shortmin+qulonglong") << QVariant::fromValue(SHRT_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - QTest::newRow("signchange-int+uint") << QVariant::fromValue(-1) << QVariant::fromValue(0U) << +1; - QTest::newRow("signchange-int+uintmax") << QVariant::fromValue(-1) << QVariant::fromValue(UINT_MAX) << 0; - QTest::newRow("signchange-intmin+uint") << QVariant::fromValue(INT_MIN) << QVariant::fromValue(0U) << +1; - QTest::newRow("signchange-int+qulonglong") << QVariant::fromValue(-1) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - QTest::newRow("signchange-int+qulonglongmax") << QVariant::fromValue(-1) << QVariant::fromValue(ULLONG_MAX) << 0; - QTest::newRow("signchange-intmin+qulonglong") << QVariant::fromValue(INT_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - // no qlonglong+uint, since that should promote to qlonglong and then the comparison is signed (tested above) - QTest::newRow("signchange-qlonglong+qulonglong") << QVariant::fromValue(Q_INT64_C(-1)) << QVariant::fromValue(Q_UINT64_C(0)) << +1; - QTest::newRow("signchange-qlonglong+qulonglongmax") << QVariant::fromValue(Q_INT64_C(-1)) << QVariant::fromValue(ULLONG_MAX) << 0; - QTest::newRow("signchange-qlonglongmin+qulonglong") << QVariant::fromValue(LLONG_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; -} - -void tst_QVariant::compareNumbers() const -{ - QFETCH(QVariant, v1); - QFETCH(QVariant, v2); - QFETCH(int, expected); - - if (expected == -1) { - QVERIFY(v1 < v2); - QVERIFY(v1 <= v2); - QVERIFY(!(v1 == v2)); - QVERIFY(!(v1 > v2)); - QVERIFY(!(v1 >= v2)); - - QVERIFY(!(v2 < v1)); - QVERIFY(!(v2 <= v1)); - QVERIFY(!(v2 == v1)); - QVERIFY(v2 >= v1); - QVERIFY(v2 > v1); - } else if (expected == 0) { - QVERIFY(!(v1 < v2)); - QVERIFY(v1 <= v2); - QCOMPARE(v1, v2); - QVERIFY(!(v1 > v2)); - QVERIFY(v1 >= v2); - - QVERIFY(!(v2 < v1)); - QVERIFY(v2 <= v1); - QCOMPARE(v2, v1); - QVERIFY(v2 >= v1); - QVERIFY(!(v2 > v1)); - } else if (expected == +1) { - QVERIFY(!(v1 < v2)); - QVERIFY(!(v1 <= v2)); - QVERIFY(!(v1 == v2)); - QVERIFY(v1 > v2); - QVERIFY(v1 >= v2); - - QVERIFY(v2 < v1); - QVERIFY(v2 <= v1); - QVERIFY(!(v2 == v1)); - QVERIFY(!(v2 >= v1)); - QVERIFY(!(v2 > v1)); - } else { - // unorderable (NaN) - QVERIFY(!(v1 == v2)); - } -} - void tst_QVariant::typeName_data() { QTest::addColumn<int>("type"); @@ -3956,8 +3618,7 @@ Q_DECLARE_METATYPE(Convertible); struct BigConvertible { double d; - double dummy; - double dummy2; + double dummy[sizeof(QVariant) / sizeof(double)]; operator int() const { return (int)d; } operator double() const { return d; } operator QString() const { return QString::number(d); } @@ -4858,86 +4519,6 @@ void tst_QVariant::metaEnums() METAENUMS_TEST(MetaEnumTest_Enum8_value); } -void tst_QVariant::compareSanity_data() -{ - QTest::addColumn<QVariant>("value1"); - QTest::addColumn<QVariant>("value2"); - - QTest::newRow( "int <>/== QUrl" ) << QVariant( 97 ) << QVariant(QUrl("a")); - QTest::newRow( "int <>/== QChar" ) << QVariant( 97 ) << QVariant(QChar('a')); - QTest::newRow( "int <>/== QString" ) << QVariant( 97 ) << QVariant(QString("a")); - QTest::newRow( "QUrl <>/== QChar" ) << QVariant(QUrl("a")) << QVariant(QChar('a')); - QTest::newRow( "QUrl <>/== QString" ) << QVariant(QUrl("a")) << QVariant(QString("a")); - QTest::newRow( "QChar <>/== QString" ) << QVariant(QChar('a')) << QVariant(QString("a")); -} - -void tst_QVariant::compareSanity() -{ - QFETCH(QVariant, value1); - QFETCH(QVariant, value2); - - if (value1 == value2) { - QVERIFY(!(value1 < value2) && !(value1 > value2)); - } else { - QVERIFY(value1 != value2); - QVERIFY((value1 < value2) || (value1 > value2)); - } -} - -static void richComparison(const QVariant& less, const QVariant& more) -{ - QVERIFY(less.type() == more.type()); - - QVERIFY(less < more); - QVERIFY(!(more < less)); - - QVERIFY(more > less); - QVERIFY(!(less > more)); - - QVERIFY(less <= more); - QVERIFY(!(more <= less)); - QVERIFY(less <= less); - - QVERIFY(more >= less); - QVERIFY(!(less >= more)); - QVERIFY(more >= more); -} - -void tst_QVariant::compareRich() -{ - richComparison(QUuid("{49d8ad2a-2ee8-4c3d-949f-1b5a3765ddf0}"), - QUuid("{f6d56824-16e9-4543-a375-add2877c2d05}")); - richComparison(QByteArray::fromRawData("a", 1), - QByteArray::fromRawData("b", 1)); - richComparison(QStringLiteral("a"), QStringLiteral("b")); - richComparison(QLatin1String("a"), QLatin1String("b")); - richComparison(QChar('a'), QChar('b')); - richComparison(QDate(2016, 7, 23), QDate(2016, 7, 24)); - richComparison(QTime(0, 0), QTime(0, 1)); - richComparison(QDateTime(QDate(2016, 7, 23), QTime(0, 0)), - QDateTime(QDate(2016, 7, 23), QTime(0, 1))); - - richComparison(QStringList(), QStringList() << QStringLiteral("a")); - richComparison(QStringList(), QStringList() << QStringLiteral("a") - << QStringLiteral("b")); - richComparison(QStringList() << QStringLiteral("a"), - QStringList() << QStringLiteral("b")); - richComparison(QStringList() << QStringLiteral("a"), - QStringList() << QStringLiteral("b") - << QStringLiteral("c")); - richComparison(QStringList() << QStringLiteral("a") - << QStringLiteral("c"), - QStringList() << QStringLiteral("b")); - richComparison(QStringList() << QStringLiteral("a") - << QStringLiteral("c"), - QStringList() << QStringLiteral("b") - << QStringLiteral("d")); - richComparison(QStringList() << QStringLiteral("a") - << QStringLiteral("c"), - QStringList() << QStringLiteral("a") - << QStringLiteral("d")); -} - void tst_QVariant::nullConvert() { // Test quirks with QVariants different types of null states. @@ -4989,9 +4570,102 @@ void tst_QVariant::accessSequentialContainerKey() QCOMPARE(nameResult, QStringLiteral("Seven")); } +void tst_QVariant::shouldDeleteVariantDataWorksForSequential() +{ + QCOMPARE(instanceCount, 0); + { + QtMetaTypePrivate::QSequentialIterableImpl iterator {}; + iterator._iteratorCapabilities = QtMetaTypePrivate::RandomAccessCapability | + QtMetaTypePrivate::BiDirectionalCapability | + QtMetaTypePrivate::ForwardCapability; + iterator._metaType_flags = QVariantConstructionFlags::ShouldDeleteVariantData; + + iterator._size = [](const void *) {return 1;}; + iterator._metaType_id = qMetaTypeId<MyType>(); + iterator._moveToBegin = [](const void *, void **) {}; + iterator._moveToEnd = [](const void *, void **) {}; + iterator._advance = [](void **, int) {}; + iterator._destroyIter = [](void **){}; + iterator._equalIter = [](void * const *, void * const *){return true; /*all iterators are nullptr*/}; + iterator._destroyIter = [](void **){}; + iterator._at = [](const void *, int ) -> void const * { + MyType mytype {1, "eins"}; + return QMetaType::create(qMetaTypeId<MyType>(), &mytype); + }; + iterator._get = [](void * const *, int, uint) -> QtMetaTypePrivate::VariantData { + MyType mytype {2, "zwei"}; + return {qMetaTypeId<MyType>(), QMetaType::create(qMetaTypeId<MyType>(), &mytype), QVariantConstructionFlags::ShouldDeleteVariantData}; + }; + QSequentialIterable iterable {iterator}; + QVariant value1 = iterable.at(0); + QVERIFY(value1.canConvert<MyType>()); + QCOMPARE(value1.value<MyType>().number, 1); + QVariant value2 = *iterable.begin(); + QVERIFY(value2.canConvert<MyType>()); + QCOMPARE(value2.value<MyType>().number, 2); + } + QCOMPARE(instanceCount, 0); +} + +void tst_QVariant::shouldDeleteVariantDataWorksForAssociative() +{ + QCOMPARE(instanceCount, 0); + { + QtMetaTypePrivate::QAssociativeIterableImpl iterator {}; + iterator._metaType_flags_key = QVariantConstructionFlags::ShouldDeleteVariantData; + iterator._metaType_flags_value = QVariantConstructionFlags::ShouldDeleteVariantData; + + iterator._size = [](const void *) {return 1;}; + iterator._metaType_id_value = qMetaTypeId<MyType>(); + iterator._metaType_id_key = qMetaTypeId<MyType>(); + iterator._begin = [](const void *, void **) {}; + iterator._end = [](const void *, void **) {}; + iterator._advance = [](void **, int) {}; + iterator._destroyIter = [](void **){}; + iterator._equalIter = [](void * const *, void * const *){return true; /*all iterators are nullptr*/}; + iterator._destroyIter = [](void **){}; + iterator._find = [](const void *, const void *, void **iterator ) -> void { + (*iterator) = reinterpret_cast<void *>(quintptr(42)); + }; + iterator._getKey = [](void * const *iterator, int, uint) -> QtMetaTypePrivate::VariantData { + MyType mytype {1, "key"}; + if (reinterpret_cast<quintptr>(*iterator) == 42) { + mytype.number = 42; + mytype.text = "find_key"; + } + return {qMetaTypeId<MyType>(), QMetaType::create(qMetaTypeId<MyType>(), &mytype), QVariantConstructionFlags::ShouldDeleteVariantData}; + }; + iterator._getValue = [](void * const *iterator, int, uint) -> QtMetaTypePrivate::VariantData { + MyType mytype {2, "value"}; + if (reinterpret_cast<quintptr>(*iterator) == 42) { + mytype.number = 42; + mytype.text = "find_value"; + } + return {qMetaTypeId<MyType>(), QMetaType::create(qMetaTypeId<MyType>(), &mytype), QVariantConstructionFlags::ShouldDeleteVariantData}; + }; + QAssociativeIterable iterable {iterator}; + auto it = iterable.begin(); + QVariant value1 = it.key(); + QVERIFY(value1.canConvert<MyType>()); + QCOMPARE(value1.value<MyType>().number, 1); + QCOMPARE(value1.value<MyType>().text, "key"); + QVariant value2 = it.value(); + QVERIFY(value2.canConvert<MyType>()); + QCOMPARE(value2.value<MyType>().number, 2); + auto findIt = iterable.find(QVariant::fromValue(MyType {})); + value1 = findIt.key(); + QCOMPARE(value1.value<MyType>().number, 42); + QCOMPARE(value1.value<MyType>().text, "find_key"); + value2 = findIt.value(); + QCOMPARE(value2.value<MyType>().number, 42); + QCOMPARE(value2.value<MyType>().text, "find_value"); + } + QCOMPARE(instanceCount, 0); +} + void tst_QVariant::fromStdVariant() { -#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L +#if __has_include(<variant>) && __cplusplus >= 201703L { typedef std::variant<int, bool> intorbool_t; intorbool_t stdvar = 5; @@ -5025,5 +4699,66 @@ void tst_QVariant::fromStdVariant() #endif } +void tst_QVariant::qt4UuidDataStream() +{ + qRegisterMetaTypeStreamOperators<QUuid>(); + + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + stream.setVersion(QDataStream::Qt_4_8); + QUuid source(0x12345678,0x1234,0x1234,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89); + stream << QVariant::fromValue(source); + const QByteArray qt4Data = QByteArray::fromHex("0000007f000000000651557569640012345678123412341223344556677889"); + QCOMPARE(data, qt4Data); + + QDataStream input(&data, QIODevice::ReadOnly); + input.setVersion(QDataStream::Qt_4_8); + QVariant result; + input >> result; + QCOMPARE(result.value<QUuid>(), source); +} + +void tst_QVariant::preferDirectConversionOverInterfaces() +{ + using namespace QtMetaTypePrivate; + bool calledCorrectConverter = false; + QMetaType::registerConverter<MyType, QSequentialIterableImpl>([](const MyType &) { + return QSequentialIterableImpl {}; + }); + QMetaType::registerConverter<MyType, QVariantList>([&calledCorrectConverter](const MyType &) { + calledCorrectConverter = true; + return QVariantList {}; + }); + QMetaType::registerConverter<MyType, QAssociativeIterableImpl>([](const MyType &) { + return QAssociativeIterableImpl {}; + }); + QMetaType::registerConverter<MyType, QVariantHash>([&calledCorrectConverter](const MyType &) { + calledCorrectConverter = true; + return QVariantHash {}; + }); + QMetaType::registerConverter<MyType, QVariantMap>([&calledCorrectConverter](const MyType &) { + calledCorrectConverter = true; + return QVariantMap {}; + }); + auto holder = QVariant::fromValue(MyType {}); + + QVERIFY(holder.canConvert<QSequentialIterableImpl>()); + QVERIFY(holder.canConvert<QVariantList>()); + QVERIFY(holder.canConvert<QAssociativeIterableImpl>()); + QVERIFY(holder.canConvert<QVariantHash>()); + QVERIFY(holder.canConvert<QVariantMap>()); + + holder.value<QVariantList>(); + QVERIFY(calledCorrectConverter); + calledCorrectConverter = false; + + holder.value<QVariantHash>(); + QVERIFY(calledCorrectConverter); + calledCorrectConverter = false; + + holder.value<QVariantMap>(); + QVERIFY(calledCorrectConverter); +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index fd3cc18af5..60017d53fa 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -73,12 +73,12 @@ static inline QString testSuiteWarning() str << "\nCannot find the shared-mime-info test suite\nstarting from: " << QDir::toNativeSeparators(QDir::currentPath()) << "\n" "cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n" - "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-10.zip\n" - "unzip Release-1-10.zip\n"; + "wget https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/Release-1-10/shared-mime-info-Release-1-10.zip\n" + "unzip shared-mime-info-Release-1-10.zip\n"; #ifdef Q_OS_WIN - str << "mkdir testfiles\nxcopy /s Release-1-10 s-m-i\n"; + str << "mkdir testfiles\nxcopy /s shared-mime-info-Release-1-10 s-m-i\n"; #else - str << "ln -s Release-1-10 s-m-i\n"; + str << "ln -s shared-mime-info-Release-1-10 s-m-i\n"; #endif return result; } diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp index c4a366d7c6..8d548f5260 100644 --- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp @@ -243,7 +243,7 @@ void tst_QPluginLoader::loadHints() QSKIP("This test requires Qt to create shared libraries."); #endif QPluginLoader loader; - QCOMPARE(loader.loadHints(), (QLibrary::LoadHints)0); //Do not crash + QCOMPARE(loader.loadHints(), QLibrary::LoadHints{}); //Do not crash loader.setLoadHints(QLibrary::ResolveAllSymbolsHint); loader.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint); diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 50d3ab1f6b..4c85482c6a 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -587,6 +587,8 @@ void tst_QtJson::testObjectSmallKeys() QVERIFY(data1.contains(QStringLiteral("123"))); QCOMPARE(data1.value(QStringLiteral("123")).type(), QJsonValue::Double); QCOMPARE(data1.value(QStringLiteral("123")).toDouble(), (double)323); + QCOMPARE(data1.constEnd() - data1.constBegin(), 3); + QCOMPARE(data1.end() - data1.begin(), 3); } void tst_QtJson::testArraySimple() diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index c6733205e5..d5a9012f9f 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -40,6 +40,7 @@ #include <QtCore/qcborvalue.h> #include <QtTest> +Q_DECLARE_METATYPE(QCborKnownTags) Q_DECLARE_METATYPE(QCborValue) Q_DECLARE_METATYPE(QCborValue::EncodingOptions) @@ -294,34 +295,77 @@ void tst_QCborValue::tagged() void tst_QCborValue::extendedTypes_data() { QTest::addColumn<QCborValue>("extended"); - QTest::addColumn<QCborValue>("tagged"); + QTest::addColumn<QCborKnownTags>("tag"); + QTest::addColumn<QCborValue>("taggedValue"); + QTest::addColumn<QCborValue>("correctedTaggedValue"); + QCborValue v(QCborValue::Invalid); QDateTime dt = QDateTime::currentDateTimeUtc(); + QDateTime dtTzOffset(dt.date(), dt.time(), Qt::OffsetFromUTC, dt.offsetFromUtc()); QUuid uuid = QUuid::createUuid(); + // non-correcting extended types (tagged value remains unchanged) QTest::newRow("DateTime") << QCborValue(dt) - << QCborValue(QCborKnownTags::DateTimeString, dt.toString(Qt::ISODateWithMs)); + << QCborKnownTags::DateTimeString << QCborValue(dt.toString(Qt::ISODateWithMs)) << v; + QTest::newRow("DateTime:TzOffset") << QCborValue(dtTzOffset) + << QCborKnownTags::DateTimeString << QCborValue(dtTzOffset.toString(Qt::ISODateWithMs)) << v; QTest::newRow("Url:Empty") << QCborValue(QUrl()) - << QCborValue(QCborKnownTags::Url, QString()); + << QCborKnownTags::Url << QCborValue(QString()) << v; QTest::newRow("Url:Authority") << QCborValue(QUrl("https://example.com")) - << QCborValue(QCborKnownTags::Url, "https://example.com"); + << QCborKnownTags::Url << QCborValue("https://example.com") << v; QTest::newRow("Url:Path") << QCborValue(QUrl("file:///tmp/none")) - << QCborValue(QCborKnownTags::Url, "file:///tmp/none"); + << QCborKnownTags::Url << QCborValue("file:///tmp/none") << v; QTest::newRow("Url:QueryFragment") << QCborValue(QUrl("whatever:?a=b&c=d#e")) - << QCborValue(QCborKnownTags::Url, "whatever:?a=b&c=d#e"); + << QCborKnownTags::Url << QCborValue("whatever:?a=b&c=d#e") << v; QTest::newRow("Regex:Empty") << QCborValue(QRegularExpression()) - << QCborValue(QCborKnownTags::RegularExpression, QString()); + << QCborKnownTags::RegularExpression << QCborValue(QString()) << v; QTest::newRow("Regex") << QCborValue(QRegularExpression("^.*$")) - << QCborValue(QCborKnownTags::RegularExpression, QString("^.*$")); + << QCborKnownTags::RegularExpression << QCborValue(QString("^.*$")) << v; QTest::newRow("Uuid") << QCborValue(uuid) - << QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122()); + << QCborKnownTags::Uuid << QCborValue(uuid.toRfc4122()) << v; + + // correcting extended types + QDateTime dtNoMsecs = dt.fromSecsSinceEpoch(dt.toSecsSinceEpoch(), Qt::UTC); + QUrl url("https://example.com/\xc2\xa9 "); + QTest::newRow("UnixTime_t:Integer") << QCborValue(dtNoMsecs) << QCborKnownTags::UnixTime_t + << QCborValue(dtNoMsecs.toSecsSinceEpoch()) + << QCborValue(dtNoMsecs.toString(Qt::ISODateWithMs)); + QTest::newRow("UnixTime_t:Double") << QCborValue(dt) << QCborKnownTags::UnixTime_t + << QCborValue(dt.toMSecsSinceEpoch() / 1000.) + << QCborValue(dt.toString(Qt::ISODateWithMs)); + QTest::newRow("DateTime::JustDate") << QCborValue(QDateTime({2018, 1, 1}, {})) + << QCborKnownTags::DateTimeString + << QCborValue("2018-01-01") << QCborValue("2018-01-01T00:00:00.000"); + QTest::newRow("DateTime::TzOffset") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::UTC)) + << QCborKnownTags::DateTimeString + << QCborValue("2018-01-01T09:00:00.000+00:00") + << QCborValue("2018-01-01T09:00:00.000Z"); + QTest::newRow("Url:NotNormalized") << QCborValue(url) << QCborKnownTags::Url + << QCborValue("HTTPS://EXAMPLE.COM/%c2%a9%20") + << QCborValue(url.toString()); + QTest::newRow("Uuid:Zero") << QCborValue(QUuid()) << QCborKnownTags::Uuid + << QCborValue(QByteArray()) + << QCborValue(QByteArray(sizeof(QUuid), 0)); + QTest::newRow("Uuid:TooShort") << QCborValue(QUuid(0x12345678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + << QCborKnownTags::Uuid + << QCborValue(raw("\x12\x34\x56\x78")) + << QCborValue(raw("\x12\x34\x56\x78" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0")); + QTest::newRow("Uuid:TooLong") << QCborValue(uuid) << QCborKnownTags::Uuid + << QCborValue(uuid.toRfc4122() + "\1\2\3\4") << QCborValue(uuid.toRfc4122()); } void tst_QCborValue::extendedTypes() { QFETCH(QCborValue, extended); - QFETCH(QCborValue, tagged); + QFETCH(QCborKnownTags, tag); + QFETCH(QCborValue, taggedValue); + QFETCH(QCborValue, correctedTaggedValue); + if (correctedTaggedValue.isInvalid()) + correctedTaggedValue = taggedValue; + + QCborValue tagged(tag, taggedValue); QVERIFY(extended.isTag()); QVERIFY(tagged.isTag()); + QCOMPARE(tagged.taggedValue(), correctedTaggedValue); QVERIFY(extended == tagged); QVERIFY(tagged == extended); @@ -340,7 +384,7 @@ void tst_QCborValue::copyCompare() QCOMPARE(v, other); QVERIFY(!(v != other)); QVERIFY(!(v < other)); -#if 0 && QT_HAS_INCLUDE(<compare>) +#if 0 && __has_include(<compare>) QVERIFY(v <= other); QVERIFY(v >= other); QVERIFY(!(v > other)); @@ -777,9 +821,37 @@ void tst_QCborValue::mapMutation() QVERIFY(v.isUndefined()); // now mutate the list + // simple -> HasByteData + const QString strValue = QStringLiteral("value"); + v = strValue; + QVERIFY(v.isString()); + QCOMPARE(v, QCborValue(strValue)); + QCOMPARE(m, QCborMap({{42, strValue}})); + + // HasByteData -> HasByteData + const QLatin1String otherStrValue("othervalue"); + v = otherStrValue; + QVERIFY(v.isString()); + QCOMPARE(v, QCborValue(otherStrValue)); + QCOMPARE(m, QCborMap({{42, otherStrValue}})); + + // HasByteData -> simple + v = 42; + QVERIFY(v.isInteger()); + QCOMPARE(v, QCborValue(42)); + QCOMPARE(m, QCborMap({{42, 42}})); + + // simple -> container + v = QCborArray{1, 2, 3}; + QVERIFY(v.isArray()); + QCOMPARE(v, QCborArray({1, 2, 3})); + QCOMPARE(m, QCborMap({{42, QCborArray{1, 2, 3}}})); + + // container -> simple v = true; QVERIFY(v.isBool()); QVERIFY(v.isTrue()); + QCOMPARE(m, QCborMap({{42, true}})); QVERIFY(m.begin()->isTrue()); QVERIFY(m.begin().value() == v); QVERIFY(v == m.begin().value()); @@ -1224,8 +1296,11 @@ void tst_QCborValue::sorting() QCborValue va1(QCborValue::Array), va2(QCborArray{1}), va3(QCborArray{0, 0}); QCborValue vm1(QCborValue::Map), vm2(QCborMap{{1, 0}}), vm3(QCborMap{{0, 0}, {1, 0}}); QCborValue vdt1(QDateTime::fromMSecsSinceEpoch(0, Qt::UTC)), vdt2(QDateTime::currentDateTimeUtc()); - QCborValue vtagged1(QCborKnownTags::UnixTime_t, 0), vtagged2(QCborKnownTags::UnixTime_t, 0.0), - vtagged3(QCborKnownTags::Signature, 0), vtagged4(QCborTag(-2), 0), vtagged5(QCborTag(-1), 0); + QCborValue vtagged1(QCborKnownTags::PositiveBignum, QByteArray()), + vtagged2(QCborKnownTags::PositiveBignum, 0.0), // bignums are supposed to have byte arrays... + vtagged3(QCborKnownTags::Signature, 0), + vtagged4(QCborTag(-2), 0), + vtagged5(QCborTag(-1), 0); QCborValue vurl1(QUrl("https://example.net")), vurl2(QUrl("https://example.com/")); QCborValue vuuid1{QUuid()}, vuuid2(QUuid::createUuid()); QCborValue vsimple1(QCborSimpleType(1)), vsimple32(QCborSimpleType(32)), vsimple255(QCborSimpleType(255)); @@ -1391,6 +1466,9 @@ static void addCommonCborData() QTest::newRow("Url") << QCborValue(QUrl("HTTPS://example.com/{%30%31}?q=%3Ca+b%20%C2%A9%3E&%26")) << raw("\xd8\x20\x78\x27" "https://example.com/{01}?q=<a+b \xC2\xA9>&%26") << noxfrm; + QTest::newRow("Url:NonAscii") << QCborValue(QUrl("https://example.com/\xc2\xa0")) + << raw("\xd8\x20\x76" "https://example.com/\xc2\xa0") + << noxfrm; QTest::newRow("Regex:Empty") << QCborValue(QRegularExpression()) << raw("\xd8\x23\x60") << noxfrm; QTest::newRow("Regex") << QCborValue(QRegularExpression("^.*$")) << raw("\xd8\x23\x64" "^.*$") << noxfrm; diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp index 92a0d8bbfa..12279133a2 100644 --- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp @@ -221,7 +221,7 @@ static QString documentElement(const QByteArray &document) * * See \l {http://www.w3.org/XML/Test/} {Extensible Markup Language (XML) Conformance Test Suites} */ -class TestSuiteHandler : public QXmlDefaultHandler +class TestSuiteHandler { public: /** @@ -286,29 +286,33 @@ public: m_baseURI.push(baseURI); } - virtual bool characters(const QString &chars) + bool runTests(QFile *file) { - m_ch = chars; - return true; + QXmlStreamReader reader(file); + while (!reader.atEnd() && !reader.hasError()) { + reader.readNext(); + + if (reader.isStartElement() && !startElement(reader.attributes())) + return false; + + if (reader.isEndElement() && !endElement(reader.name().toString())) + return false; + } + return !reader.hasError(); } - virtual bool startElement(const QString &, - const QString &, - const QString &, - const QXmlAttributes &atts) + bool startElement(const QXmlStreamAttributes &atts) { m_atts.push(atts); - const int i = atts.index(QLatin1String("xml:base")); - if(i != -1) - m_baseURI.push(m_baseURI.top().resolved(atts.value(i))); + const auto attr = atts.value(QLatin1String("xml:base")); + if (!attr.isEmpty()) + m_baseURI.push(m_baseURI.top().resolved(attr.toString())); return true; } - virtual bool endElement(const QString &, - const QString &localName, - const QString &) + bool endElement(const QString &localName) { if(localName == QLatin1String("TEST")) { @@ -329,19 +333,19 @@ public: return true; } - const QString inputFilePath(m_baseURI.top().resolved(m_atts.top().value(QString(), QLatin1String("URI"))) - .toLocalFile()); - const QString id(m_atts.top().value(QString(), QLatin1String("ID"))); - const QString type(m_atts.top().value(QString(), QLatin1String("TYPE"))); + const QString inputFilePath( + m_baseURI.top() + .resolved( + m_atts.top().value(QString(), QLatin1String("URI")).toString()) + .toLocalFile()); + const QString id(m_atts.top().value(QString(), QLatin1String("ID")).toString()); + const QString type(m_atts.top().value(QString(), QLatin1String("TYPE")).toString()); QString expectedFilePath; - const int index = m_atts.top().index(QString(), QLatin1String("OUTPUT")); - if(index != -1) - { - expectedFilePath = m_baseURI.top().resolved(m_atts.top().value(QString(), - QLatin1String("OUTPUT"))).toLocalFile(); - } + const auto attr = m_atts.top().value(QString(), QLatin1String("OUTPUT")); + if (!attr.isEmpty()) + expectedFilePath = m_baseURI.top().resolved(attr.toString()).toLocalFile(); /* testcases.dtd: 'No parser should accept a "not-wf" testcase * unless it's a nonvalidating parser and the test contains @@ -349,7 +353,7 @@ public: * * We also let this apply to "valid", "invalid" and "error" tests, although * I'm not fully sure this is correct. */ - const QString ents(m_atts.top().value(QString(), QLatin1String("ENTITIES"))); + const QString ents(m_atts.top().value(QString(), QLatin1String("ENTITIES")).toString()); m_atts.pop(); if(ents == QLatin1String("both") || @@ -455,8 +459,8 @@ public: qFatal("The input catalog is invalid."); return false; } - } - else if(localName == QLatin1String("TESTCASES") && m_atts.top().index(QLatin1String("xml:base")) != -1) + } else if (localName == QLatin1String("TESTCASES") + && m_atts.top().hasAttribute(QLatin1String("xml:base"))) m_baseURI.pop(); m_atts.pop(); @@ -516,9 +520,8 @@ public: } private: - QStack<QXmlAttributes> m_atts; - QString m_ch; - QStack<QUrl> m_baseURI; + QStack<QXmlStreamAttributes> m_atts; + QStack<QUrl> m_baseURI; }; QT_BEGIN_NAMESPACE Q_DECLARE_SHARED(TestSuiteHandler::MissedBaseline) @@ -592,11 +595,7 @@ void tst_QXmlStream::initTestCase() QVERIFY2(file.open(QIODevice::ReadOnly), qPrintable(QString::fromLatin1("Failed to open the test suite catalog; %1").arg(file.fileName()))); - QXmlInputSource source(&file); - QXmlSimpleReader reader; - reader.setContentHandler(&m_handler); - - QVERIFY(reader.parse(&source, false)); + QVERIFY(m_handler.runTests(&file)); } void tst_QXmlStream::cleanupTestCase() diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index 90dfcaef25..e3009a78fb 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -149,36 +149,17 @@ private slots: void stdString(); }; -static const struct StaticByteArrays { - struct Standard { - QByteArrayData data; - const char string[8]; - } standard; - struct NotNullTerminated { - QByteArrayData data; - const char string[8]; - } notNullTerminated; - struct Shifted { - QByteArrayData data; - const char dummy; // added to change offset of string - const char string[8]; - } shifted; - struct ShiftedNotNullTerminated { - QByteArrayData data; - const char dummy; // added to change offset of string - const char string[8]; - } shiftedNotNullTerminated; - -} statics = {{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(4), "data"} - ,{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(4), "dataBAD"} - ,{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(4, sizeof(QByteArrayData) + sizeof(char)), 0, "data"} - ,{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(4, sizeof(QByteArrayData) + sizeof(char)), 0, "dataBAD"} - }; - -static const QByteArrayDataPtr staticStandard = { const_cast<QByteArrayData *>(&statics.standard.data) }; -static const QByteArrayDataPtr staticNotNullTerminated = { const_cast<QByteArrayData *>(&statics.notNullTerminated.data) }; -static const QByteArrayDataPtr staticShifted = { const_cast<QByteArrayData *>(&statics.shifted.data) }; -static const QByteArrayDataPtr staticShiftedNotNullTerminated = { const_cast<QByteArrayData *>(&statics.shiftedNotNullTerminated.data) }; +static const QArrayData staticDataFlags = { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0 }; +static const QByteArray::DataPointer staticStandard = { + static_cast<QTypedArrayData<char> *>(const_cast<QArrayData *>(&staticDataFlags)), + const_cast<char *>("data"), + 4 +}; +static const QByteArray::DataPointer staticNotNullTerminated = { + static_cast<QTypedArrayData<char> *>(const_cast<QArrayData *>(&staticDataFlags)), + const_cast<char *>("dataBAD"), + 4 +}; template <class T> const T &verifyZeroTermination(const T &t) { return t; } @@ -186,11 +167,10 @@ QByteArray verifyZeroTermination(const QByteArray &ba) { // This test does some evil stuff, it's all supposed to work. - QByteArray::DataPtr baDataPtr = const_cast<QByteArray &>(ba).data_ptr(); + QByteArray::DataPointer baDataPtr = const_cast<QByteArray &>(ba).data_ptr(); // Skip if isStatic() or fromRawData(), as those offer no guarantees - if (baDataPtr->ref.isStatic() - || baDataPtr->offset != QByteArray().data_ptr()->offset) + if (baDataPtr->isStatic() || baDataPtr->flags() & QArrayData::RawDataType) return ba; int baSize = ba.size(); @@ -201,7 +181,7 @@ QByteArray verifyZeroTermination(const QByteArray &ba) .arg(baTerminator, 2, 16, QChar('0')).toLatin1(); // Skip mutating checks on shared strings - if (baDataPtr->ref.isShared()) + if (baDataPtr->isShared()) return ba; const char *baData = ba.constData(); @@ -239,6 +219,8 @@ QByteArray verifyZeroTermination(const QByteArray &ba) } while (0) \ /**/ +Q_DECLARE_METATYPE(QByteArray::Base64DecodingStatus); + tst_QByteArray::tst_QByteArray() { } @@ -251,11 +233,11 @@ void tst_QByteArray::qChecksum_data() 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; + QTest::newRow("1") << QByteArray("\x00\x00", 2) << 2U << Qt::ChecksumItuV41 << 0x1EA0U; + QTest::newRow("2") << QByteArray("\x12\x34", 2) << 2U << Qt::ChecksumItuV41 << 0xCF26U; + QTest::newRow("3") << QByteArray("\x00\x00\x00", 3) << 3U << Qt::ChecksumIso3309 << 0xC6CCU; + QTest::newRow("4") << QByteArray("\x0F\xAA\xFF", 3) << 3U << Qt::ChecksumIso3309 << 0xD1FCU; + QTest::newRow("5") << QByteArray("\x0A\x12\x34\x56", 4) << 4U << Qt::ChecksumIso3309 << 0xF62CU; } void tst_QByteArray::qChecksum() @@ -265,6 +247,7 @@ void tst_QByteArray::qChecksum() QFETCH(Qt::ChecksumType, standard); QFETCH(uint, checksum); + QCOMPARE(data.length(), int(len)); if (standard == Qt::ChecksumIso3309) { QCOMPARE(::qChecksum(data.constData(), len), static_cast<quint16>(checksum)); } @@ -637,9 +620,16 @@ void tst_QByteArray::base64() { QFETCH(QByteArray, rawdata); QFETCH(QByteArray, base64); + QByteArray::FromBase64Result result; + + result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(result); + QCOMPARE(result.decoded, rawdata); - QByteArray arr = QByteArray::fromBase64(base64); - QCOMPARE(arr, rawdata); + QByteArray arr = base64; + result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(result); + QCOMPARE(result.decoded, rawdata); QByteArray arr64 = rawdata.toBase64(); QCOMPARE(arr64, base64); @@ -668,21 +658,22 @@ void tst_QByteArray::fromBase64_data() { QTest::addColumn<QByteArray>("rawdata"); QTest::addColumn<QByteArray>("base64"); - - QTest::newRow("1") << QByteArray("") << QByteArray(" "); - QTest::newRow("2") << QByteArray("1") << QByteArray("MQ"); - QTest::newRow("3") << QByteArray("12") << QByteArray("MTI "); - QTest::newRow("4") << QByteArray("123") << QByteArray("M=TIz"); - QTest::newRow("5") << QByteArray("1234") << QByteArray("MTI zN A "); - QTest::newRow("6") << QByteArray("\n") << QByteArray("Cg"); - QTest::newRow("7") << QByteArray("a\n") << QByteArray("======YQo="); - QTest::newRow("8") << QByteArray("ab\n") << QByteArray("Y\nWIK"); - QTest::newRow("9") << QByteArray("abc\n") << QByteArray("YWJjCg=="); - QTest::newRow("a") << QByteArray("abcd\n") << QByteArray("YWJ\1j\x9cZAo="); - QTest::newRow("b") << QByteArray("abcde\n") << QByteArray("YW JjZ\n G\tUK"); - QTest::newRow("c") << QByteArray("abcdef\n") << QByteArray("YWJjZGVmCg="); - QTest::newRow("d") << QByteArray("abcdefg\n") << QByteArray("YWJ\rjZGVmZwo"); - QTest::newRow("e") << QByteArray("abcdefgh\n") << QByteArray("YWJjZGVmZ2gK"); + QTest::addColumn<QByteArray::Base64DecodingStatus>("status"); + + QTest::newRow("1") << QByteArray("") << QByteArray(" ") << QByteArray::Base64DecodingStatus::IllegalCharacter; + QTest::newRow("2") << QByteArray("1") << QByteArray("MQ=") << QByteArray::Base64DecodingStatus::IllegalInputLength; + QTest::newRow("3") << QByteArray("12") << QByteArray("MTI ") << QByteArray::Base64DecodingStatus::IllegalCharacter; + QTest::newRow("4") << QByteArray("123") << QByteArray("M=TIz") << QByteArray::Base64DecodingStatus::IllegalInputLength; + QTest::newRow("5") << QByteArray("1234") << QByteArray("MTI zN A ") << QByteArray::Base64DecodingStatus::IllegalCharacter; + QTest::newRow("6") << QByteArray("\n") << QByteArray("Cg@") << QByteArray::Base64DecodingStatus::IllegalCharacter; + QTest::newRow("7") << QByteArray("a\n") << QByteArray("======YQo=") << QByteArray::Base64DecodingStatus::IllegalInputLength; + QTest::newRow("8") << QByteArray("ab\n") << QByteArray("Y\nWIK ") << QByteArray::Base64DecodingStatus::IllegalCharacter; + QTest::newRow("9") << QByteArray("abc\n") << QByteArray("YWJjCg=") << QByteArray::Base64DecodingStatus::IllegalInputLength; + QTest::newRow("a") << QByteArray("abcd\n") << QByteArray("YWJ\1j\x9cZAo=") << QByteArray::Base64DecodingStatus::IllegalCharacter; + QTest::newRow("b") << QByteArray("abcde\n") << QByteArray("YW JjZ\n G\tUK") << QByteArray::Base64DecodingStatus::IllegalCharacter; + QTest::newRow("c") << QByteArray("abcdef\n") << QByteArray("YWJjZGVmCg=") << QByteArray::Base64DecodingStatus::IllegalInputLength; + QTest::newRow("d") << QByteArray("abcdefg\n") << QByteArray("YWJ\rjZGVmZwo") << QByteArray::Base64DecodingStatus::IllegalCharacter; + QTest::newRow("e") << QByteArray("abcdefgh\n") << QByteArray("YWJjZGVmZ2gK====") << QByteArray::Base64DecodingStatus::IllegalPadding; QByteArray ba; ba.resize(256); @@ -692,13 +683,12 @@ void tst_QByteArray::fromBase64_data() "c4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1u\n" "b3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpa\n" "anqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd\n" - "3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w== "); + "3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w== ") << QByteArray::Base64DecodingStatus::IllegalCharacter; - QTest::newRow("g") << QByteArray("foo\0bar", 7) << QByteArray("Zm9vAGJhcg"); - QTest::newRow("h") << QByteArray("f\xd1oo\x9ctar") << QByteArray("ZtFvb5x0YXI="); - QTest::newRow("i") << QByteArray("\"\0\0\0\0\0\0\"", 8) << QByteArray("IgAAAAAAACI"); - + QTest::newRow("g") << QByteArray("foo\0bar", 7) << QByteArray("Zm9vAGJhcg=") << QByteArray::Base64DecodingStatus::IllegalInputLength; + QTest::newRow("h") << QByteArray("f\xd1oo\x9ctar") << QByteArray("ZtFvb5x 0YXI") << QByteArray::Base64DecodingStatus::IllegalCharacter; + QTest::newRow("i") << QByteArray("\"\0\0\0\0\0\0\"", 8) << QByteArray("IgAAAAAAACI ") << QByteArray::Base64DecodingStatus::IllegalCharacter; } @@ -706,25 +696,120 @@ void tst_QByteArray::fromBase64() { QFETCH(QByteArray, rawdata); QFETCH(QByteArray, base64); - - QByteArray arr = QByteArray::fromBase64(base64); - QCOMPARE(arr, rawdata); - - arr = QByteArray::fromBase64(base64, QByteArray::Base64Encoding); - QCOMPARE(arr, rawdata); + QFETCH(QByteArray::Base64DecodingStatus, status); + + QByteArray::FromBase64Result result; + + result = QByteArray::fromBase64Encoding(base64); + QVERIFY(result); + QCOMPARE(result.decoded, rawdata); + + result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64Encoding); + QVERIFY(result); + QCOMPARE(result.decoded, rawdata); + + result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(!result); + QCOMPARE(result.decodingStatus, status); + QVERIFY(result.decoded.isEmpty()); + + QByteArray arr = base64; + QVERIFY(!arr.isDetached()); + result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(!arr.isEmpty()); + QVERIFY(!result); + QCOMPARE(result.decodingStatus, status); + QVERIFY(result.decoded.isEmpty()); + + arr.detach(); + QVERIFY(arr.isDetached()); + result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(arr.isEmpty()); + QVERIFY(!result); + QCOMPARE(result.decodingStatus, status); + QVERIFY(result.decoded.isEmpty()); // try "base64url" encoding QByteArray base64url = base64; base64url.replace('/', '_').replace('+', '-'); - arr = QByteArray::fromBase64(base64url, QByteArray::Base64UrlEncoding); - QCOMPARE(arr, rawdata); + result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64UrlEncoding); + QVERIFY(result); + QCOMPARE(result.decoded, rawdata); + + result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(!result); + QCOMPARE(result.decodingStatus, status); + QVERIFY(result.decoded.isEmpty()); + + arr = base64url; + arr.detach(); + result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(arr.isEmpty()); + QVERIFY(!result); + QCOMPARE(result.decodingStatus, status); + QVERIFY(result.decoded.isEmpty()); if (base64 != base64url) { // check that the invalid decodings fail - arr = QByteArray::fromBase64(base64, QByteArray::Base64UrlEncoding); - QVERIFY(arr != rawdata); - arr = QByteArray::fromBase64(base64url, QByteArray::Base64Encoding); - QVERIFY(arr != rawdata); + result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64UrlEncoding); + QVERIFY(result); + QVERIFY(result.decoded != rawdata); + result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64Encoding); + QVERIFY(result); + QVERIFY(result.decoded != rawdata); + + result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(!result); + QVERIFY(result.decoded.isEmpty()); + + arr = base64; + arr.detach(); + result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(arr.isEmpty()); + QVERIFY(!result); + QVERIFY(result.decoded.isEmpty()); + + result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(!result); + QVERIFY(result.decoded.isEmpty()); + + arr = base64url; + arr.detach(); + result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(arr.isEmpty()); + QVERIFY(!result); + QVERIFY(result.decoded.isEmpty()); + } + + // also remove padding, if any, and test again. note that by doing + // that we might be sanitizing the illegal input, so we can't assume now + // that result will be invalid in all cases + { + auto rightmostNotEqualSign = std::find_if_not(base64url.rbegin(), base64url.rend(), [](char c) { return c == '='; }); + base64url.chop(std::distance(base64url.rbegin(), rightmostNotEqualSign)); // no QByteArray::erase... + } + + result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64UrlEncoding); + QVERIFY(result); + QCOMPARE(result.decoded, rawdata); + + result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors); + if (result) { + QCOMPARE(result.decoded, rawdata); + } else { + QCOMPARE(result.decodingStatus, status); + QVERIFY(result.decoded.isEmpty()); + } + + arr = base64url; + arr.detach(); + result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors); + QVERIFY(arr.isEmpty()); + if (result) { + QCOMPARE(result.decoded, rawdata); + } else { + QCOMPARE(result.decodingStatus, status); + QVERIFY(result.decoded.isEmpty()); } } @@ -950,9 +1035,7 @@ void tst_QByteArray::prependExtended_data() QTest::addColumn<QByteArray>("array"); QTest::newRow("literal") << QByteArray(QByteArrayLiteral("data")); QTest::newRow("standard") << QByteArray(staticStandard); - QTest::newRow("shifted") << QByteArray(staticShifted); QTest::newRow("notNullTerminated") << QByteArray(staticNotNullTerminated); - QTest::newRow("shiftedNotNullTerminated") << QByteArray(staticShiftedNotNullTerminated); QTest::newRow("non static data") << QByteArray("data"); QTest::newRow("from raw data") << QByteArray::fromRawData("data", 4); QTest::newRow("from raw data not terminated") << QByteArray::fromRawData("dataBAD", 4); @@ -2018,21 +2101,13 @@ void tst_QByteArray::repeated_data() const << QByteArray(staticStandard) << QByteArray("datadatadatadata") << 4; - QTest::newRow("static shifted not null terminated") - << QByteArray(staticShiftedNotNullTerminated) - << QByteArray("datadatadatadata") - << 4; - QTest::newRow("static shifted") - << QByteArray(staticShifted) - << QByteArray("datadatadatadata") - << 4; } void tst_QByteArray::byteRefDetaching() const { { QByteArray str = "str"; - QByteArray copy; + QByteArray copy = str; copy[0] = 'S'; QCOMPARE(str, QByteArray("str")); @@ -2162,7 +2237,7 @@ void tst_QByteArray::movablity() const int newSize = size + 2; const bool newIsEmpty = false; const bool newIsNull = false; - const int newCapacity = 16; + const int newCapacity = memSpace.capacity(); // move back memSpace -> array array.~QByteArray(); @@ -2197,8 +2272,7 @@ void tst_QByteArray::literals() QVERIFY(str.length() == 4); QVERIFY(str == "abcd"); - QVERIFY(str.data_ptr()->ref.isStatic()); - QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData)); + QVERIFY(str.data_ptr()->isStatic()); const char *s = str.constData(); QByteArray str2 = str; diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 3aa3d97dbc..7b2d92f9cb 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -147,6 +147,8 @@ private slots: void systemLocale_data(); void systemLocale(); + void IndianNumberGrouping(); + // *** ORDER-DEPENDENCY *** (This Is Bad.) // Test order is determined by order of declaration here: *all* tests that // QLocale::setDefault() *must* appear *after* all other tests ! @@ -595,10 +597,7 @@ void tst_QLocale::emptyCtor_data() ADD_CTOR_TEST("zz_zz", "C"); ADD_CTOR_TEST("zz...", "C"); ADD_CTOR_TEST("en.bla", "en_US"); -#if !(defined(Q_OS_DARWIN) && QT_HAS_FEATURE(address_sanitizer)) - // See QTBUG-69875 ADD_CTOR_TEST("en@bla", "en_US"); -#endif ADD_CTOR_TEST("en_blaaa", "en_US"); ADD_CTOR_TEST("en_zz", "en_US"); ADD_CTOR_TEST("en_GB.bla", "en_GB"); @@ -607,10 +606,7 @@ void tst_QLocale::emptyCtor_data() // Empty optional fields, but with punctuators supplied ADD_CTOR_TEST("en.", "en_US"); -#if !(defined(Q_OS_DARWIN) && QT_HAS_FEATURE(address_sanitizer)) - // See QTBUG-69875 ADD_CTOR_TEST("en@", "en_US"); -#endif ADD_CTOR_TEST("en.@", "en_US"); ADD_CTOR_TEST("en_", "en_US"); ADD_CTOR_TEST("en_.", "en_US"); @@ -1346,7 +1342,7 @@ void tst_QLocale::long_long_conversion() void tst_QLocale::long_long_conversion_extra() { QLocale l(QLocale::C); - l.setNumberOptions(0); + l.setNumberOptions({ }); QCOMPARE(l.toString((qlonglong)1), QString("1")); QCOMPARE(l.toString((qlonglong)12), QString("12")); QCOMPARE(l.toString((qlonglong)123), QString("123")); @@ -2093,7 +2089,7 @@ void tst_QLocale::numberOptions() QVERIFY(ok); QCOMPARE(locale.toString(12345), QString("12345")); - locale.setNumberOptions(0); + locale.setNumberOptions({ }); QCOMPARE(locale.numberOptions(), 0); QCOMPARE(locale.toInt(QString("12,345"), &ok), 12345); QVERIFY(ok); @@ -2997,5 +2993,56 @@ void tst_QLocale::systemLocale() QCOMPARE(QLocale::system(), originalSystemLocale); } +void tst_QLocale::IndianNumberGrouping() +{ + QLocale indian(QLocale::Hindi, QLocale::India); + + qint8 int8 = 100; + QString strResult8("100"); + QCOMPARE(indian.toString(int8), strResult8); + QCOMPARE(indian.toShort(strResult8), short(int8)); + + quint8 uint8 = 100; + QCOMPARE(indian.toString(uint8), strResult8); + QCOMPARE(indian.toShort(strResult8), short(uint8)); + + // Boundary case 1000 for short and ushort + short shortInt = 1000; + QString strResult16("1,000"); + QCOMPARE(indian.toString(shortInt), strResult16); + QCOMPARE(indian.toShort(strResult16), shortInt); + + ushort uShortInt = 1000; + QCOMPARE(indian.toString(uShortInt), strResult16); + QCOMPARE(indian.toUShort(strResult16), uShortInt); + + shortInt = 10000; + strResult16 = "10,000"; + QCOMPARE(indian.toString(shortInt), strResult16); + QCOMPARE(indian.toShort(strResult16), shortInt); + + uShortInt = 10000; + QCOMPARE(indian.toString(uShortInt), strResult16); + QCOMPARE(indian.toUShort(strResult16), uShortInt); + + int intInt = 1000000000; + QString strResult32("1,00,00,00,000"); + QCOMPARE(indian.toString(intInt), strResult32); + QCOMPARE(indian.toInt(strResult32), intInt); + + uint uIntInt = 1000000000; + QCOMPARE(indian.toString(uIntInt), strResult32); + QCOMPARE(indian.toUInt(strResult32), uIntInt); + + QString strResult64("10,00,00,00,00,00,00,00,000"); + qint64 int64 = Q_INT64_C(1000000000000000000); + QCOMPARE(indian.toString(int64), strResult64); + QCOMPARE(indian.toLongLong(strResult64), int64); + + quint64 uint64 = Q_UINT64_C(1000000000000000000); + QCOMPARE(indian.toString(uint64), strResult64); + QCOMPARE(indian.toULongLong(strResult64), uint64); +} + QTEST_MAIN(tst_QLocale) #include "tst_qlocale.moc" diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp index c02756d76a..83f9c17a42 100644 --- a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp @@ -365,22 +365,22 @@ void tst_QRegularExpression::provideRegularExpressions() QTest::addColumn<QRegularExpression::PatternOptions>("patternOptions"); QTest::newRow("emptynull01") << QString() - << QRegularExpression::PatternOptions(0); + << QRegularExpression::PatternOptions{}; QTest::newRow("emptynull02") << QString() << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption | QRegularExpression::MultilineOption); QTest::newRow("emptynull03") << "" - << QRegularExpression::PatternOptions(0); + << QRegularExpression::PatternOptions{}; QTest::newRow("emptynull04") << "" << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption | QRegularExpression::MultilineOption); QTest::newRow("regexp01") << "a pattern" - << QRegularExpression::PatternOptions(0); + << QRegularExpression::PatternOptions{}; QTest::newRow("regexp02") << "^a (.*) more complicated(?<P>pattern)$" - << QRegularExpression::PatternOptions(0); + << QRegularExpression::PatternOptions{}; QTest::newRow("regexp03") << "(?:a) pAttErN" << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption); QTest::newRow("regexp04") << "a\nmultiline\npattern" @@ -397,13 +397,13 @@ void tst_QRegularExpression::provideRegularExpressions() | QRegularExpression::InvertedGreedinessOption); QTest::newRow("unicode01") << QString::fromUtf8("^s[ome] latin-1 \xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99 chars$") - << QRegularExpression::PatternOptions(0); + << QRegularExpression::PatternOptions{}; QTest::newRow("unicode02") << QString::fromUtf8("^s[ome] latin-1 \xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99 chars$") << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption | QRegularExpression::InvertedGreedinessOption); QTest::newRow("unicode03") << QString::fromUtf8("Unicode \xf0\x9d\x85\x9d \xf0\x9d\x85\x9e\xf0\x9d\x85\x9f") - << QRegularExpression::PatternOptions(0); + << QRegularExpression::PatternOptions{}; QTest::newRow("unicode04") << QString::fromUtf8("Unicode \xf0\x9d\x85\x9d \xf0\x9d\x85\x9e\xf0\x9d\x85\x9f") << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index 2108e99f20..e5b5e526de 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -459,8 +459,8 @@ private slots: void trimmed(); void toUpper(); void toLower(); - void isUpper(); - void isLower(); + void isLower_isUpper_data(); + void isLower_isUpper(); void toCaseFolded(); void rightJustified(); void leftJustified(); @@ -596,6 +596,8 @@ private slots: void assignQChar(); void isRightToLeft_data(); void isRightToLeft(); + void isValidUtf16_data(); + void isValidUtf16(); void unicodeStrings(); }; @@ -605,11 +607,10 @@ QString verifyZeroTermination(const QString &str) { // This test does some evil stuff, it's all supposed to work. - QString::DataPtr strDataPtr = const_cast<QString &>(str).data_ptr(); + QString::DataPointer strDataPtr = const_cast<QString &>(str).data_ptr(); // Skip if isStatic() or fromRawData(), as those offer no guarantees - if (strDataPtr->ref.isStatic() - || strDataPtr->offset != QString().data_ptr()->offset) + if (strDataPtr->isStatic() || !strDataPtr->isMutable()) return str; int strSize = str.size(); @@ -620,7 +621,7 @@ QString verifyZeroTermination(const QString &str) .arg(strTerminator.unicode(), 4, 16, QChar('0')); // Skip mutating checks on shared strings - if (strDataPtr->ref.isShared()) + if (strDataPtr->isShared()) return str; const QChar *strData = str.constData(); @@ -984,28 +985,6 @@ void tst_QString::acc_01() f[7]='F'; QCOMPARE(text[7],'!'); - a=""; - a[0]='A'; - QCOMPARE(a, QLatin1String("A")); - QCOMPARE(a.length(),1); - a[1]='B'; - QCOMPARE(a, QLatin1String("AB")); - QCOMPARE(a.length(),2); - a[2]='C'; - QCOMPARE(a, QLatin1String("ABC")); - QCOMPARE(a.length(),3); - a = QString(); - QVERIFY(a.isNull()); - a[0]='A'; - QCOMPARE(a, QLatin1String("A")); - QCOMPARE(a.length(),1); - a[1]='B'; - QCOMPARE(a, QLatin1String("AB")); - QCOMPARE(a.length(),2); - a[2]='C'; - QCOMPARE(a, QLatin1String("ABC")); - QCOMPARE(a.length(),3); - a="123"; b="456"; a[0]=a[1]; @@ -2311,44 +2290,83 @@ void tst_QString::toLower() #endif // icu } -void tst_QString::isUpper() -{ - QVERIFY(!QString().isUpper()); - QVERIFY(!QString("").isUpper()); - QVERIFY(QString("TEXT").isUpper()); - QVERIFY(!QString("text").isUpper()); - QVERIFY(!QString("Text").isUpper()); - QVERIFY(!QString("tExt").isUpper()); - QVERIFY(!QString("teXt").isUpper()); - QVERIFY(!QString("texT").isUpper()); - QVERIFY(!QString("TExt").isUpper()); - QVERIFY(!QString("teXT").isUpper()); - QVERIFY(!QString("tEXt").isUpper()); - QVERIFY(!QString("tExT").isUpper()); - QVERIFY(!QString("@ABYZ[").isUpper()); - QVERIFY(!QString("@abyz[").isUpper()); - QVERIFY(!QString("`ABYZ{").isUpper()); - QVERIFY(!QString("`abyz{").isUpper()); -} - -void tst_QString::isLower() -{ - QVERIFY(!QString().isLower()); - QVERIFY(!QString("").isLower()); - QVERIFY(QString("text").isLower()); - QVERIFY(!QString("Text").isLower()); - QVERIFY(!QString("tExt").isLower()); - QVERIFY(!QString("teXt").isLower()); - QVERIFY(!QString("texT").isLower()); - QVERIFY(!QString("TExt").isLower()); - QVERIFY(!QString("teXT").isLower()); - QVERIFY(!QString("tEXt").isLower()); - QVERIFY(!QString("tExT").isLower()); - QVERIFY(!QString("TEXT").isLower()); - QVERIFY(!QString("@ABYZ[").isLower()); - QVERIFY(!QString("@abyz[").isLower()); - QVERIFY(!QString("`ABYZ{").isLower()); - QVERIFY(!QString("`abyz{").isLower()); +void tst_QString::isLower_isUpper_data() +{ + QTest::addColumn<QString>("string"); + QTest::addColumn<bool>("isLower"); + QTest::addColumn<bool>("isUpper"); + + int row = 0; + QTest::addRow("lower-and-upper-%02d", row++) << QString() << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString("") << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString(" ") << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString("123") << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString("@123$#") << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString("𝄞𝄴𝆏♫") << true << true; // Unicode Block 'Musical Symbols' + // not foldable + QTest::addRow("lower-and-upper-%02d", row++) << QString("𝚊𝚋𝚌𝚍𝚎") << true << true; // MATHEMATICAL MONOSPACE SMALL A, ... E + QTest::addRow("lower-and-upper-%02d", row++) << QString("𝙖,𝙗,𝙘,𝙙,𝙚") << true << true; // MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A, ... E + QTest::addRow("lower-and-upper-%02d", row++) << QString("𝗔𝗕𝗖𝗗𝗘") << true << true; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A, ... E + QTest::addRow("lower-and-upper-%02d", row++) << QString("𝐀,𝐁,𝐂,𝐃,𝐄") << true << true; // MATHEMATICAL BOLD CAPITAL A, ... E + + row = 0; + QTest::addRow("only-lower-%02d", row++) << QString("text") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("àaa") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("øæß") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("text ") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString(" text") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("hello, world!") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("123@abyz[") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("`abyz{") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("a𝙖a|b𝙗b|c𝙘c|d𝙙d|e𝙚e") << true << false; // MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A, ... E + QTest::addRow("only-lower-%02d", row++) << QString("𐐨") << true << false; // DESERET SMALL LETTER LONG I + // uppercase letters, not foldable + QTest::addRow("only-lower-%02d", row++) << QString("text𝗔text") << true << false; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A + + row = 0; + QTest::addRow("only-upper-%02d", row++) << QString("TEXT") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("ÀAA") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("ØÆẞ") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("TEXT ") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString(" TEXT") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("HELLO, WORLD!") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("123@ABYZ[") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("`ABYZ{") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("A𝐀A|B𝐁B|C𝐂C|D𝐃D|E𝐄E") << false << true; // MATHEMATICAL BOLD CAPITAL A, ... E + QTest::addRow("only-upper-%02d", row++) << QString("𐐀") << false << true; // DESERET CAPITAL LETTER LONG I + // lowercase letters, not foldable + QTest::addRow("only-upper-%02d", row++) << QString("TEXT𝚊TEXT") << false << true; // MATHEMATICAL MONOSPACE SMALL A + + row = 0; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("Text") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("tExt") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("teXt") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("texT") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("TExt") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("teXT") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("tEXt") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("tExT") << false << false; + // not foldable + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("TEXT𝚊text") << false << false; // MATHEMATICAL MONOSPACE SMALL A + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("text𝗔TEXT") << false << false; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A + // titlecase, foldable + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("abcLjdef") << false << false; // LATIN CAPITAL LETTER L WITH SMALL LETTER J + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("ABCLjDEF") << false << false; // LATIN CAPITAL LETTER L WITH SMALL LETTER J +} + +void tst_QString::isLower_isUpper() +{ + QFETCH(QString, string); + QFETCH(bool, isLower); + QFETCH(bool, isUpper); + + QCOMPARE(string.isLower(), isLower); + QCOMPARE(string.toLower() == string, isLower); + QVERIFY(string.toLower().isLower()); + + QCOMPARE(string.isUpper(), isUpper); + QCOMPARE(string.toUpper() == string, isUpper); + QVERIFY(string.toUpper().isUpper()); } void tst_QString::toCaseFolded() @@ -4069,8 +4087,9 @@ void tst_QString::setRawData() QVERIFY(cstr.constData() == ptr); QVERIFY(cstr == QString(ptr, 1)); + QSKIP("This is currently not working."); // This actually tests the recycling of the shared data object - QString::DataPtr csd = cstr.data_ptr(); + QString::DataPointer csd = cstr.data_ptr(); cstr.setRawData(ptr2, 1); QVERIFY(cstr.isDetached()); QVERIFY(cstr.constData() == ptr2); @@ -6416,7 +6435,7 @@ void tst_QString::QCharRefDetaching() const { { QString str = QString::fromLatin1("str"); - QString copy; + QString copy = str; copy[0] = QLatin1Char('S'); QCOMPARE(str, QString::fromLatin1("str")); @@ -6637,8 +6656,7 @@ void tst_QString::literals() QVERIFY(str.length() == 4); QVERIFY(str == QLatin1String("abcd")); - QVERIFY(str.data_ptr()->ref.isStatic()); - QVERIFY(str.data_ptr()->offset == sizeof(QStringData)); + QVERIFY(str.data_ptr()->isStatic()); const QChar *s = str.constData(); QString str2 = str; @@ -7025,6 +7043,52 @@ void tst_QString::isRightToLeft() QCOMPARE(unicode.isRightToLeft(), rtl); } +void tst_QString::isValidUtf16_data() +{ + QTest::addColumn<QString>("string"); + QTest::addColumn<bool>("valid"); + + int row = 0; + QTest::addRow("valid-%02d", row++) << QString() << true; + QTest::addRow("valid-%02d", row++) << QString("") << true; + QTest::addRow("valid-%02d", row++) << QString("abc def") << true; + QTest::addRow("valid-%02d", row++) << QString("àbç") << true; + QTest::addRow("valid-%02d", row++) << QString("ßẞ") << true; + QTest::addRow("valid-%02d", row++) << QString("𝐀𝐁𝐂abc𝐃𝐄𝐅def") << true; + QTest::addRow("valid-%02d", row++) << QString("abc𝐀𝐁𝐂def𝐃𝐄𝐅") << true; + QTest::addRow("valid-%02d", row++) << (QString("abc") + QChar(0x0000) + QString("def")) << true; + QTest::addRow("valid-%02d", row++) << (QString("abc") + QChar(0xFFFF) + QString("def")) << true; + // check that BOM presence doesn't make any difference + QTest::addRow("valid-%02d", row++) << (QString() + QChar(0xFEFF) + QString("abc𝐀𝐁𝐂def𝐃𝐄𝐅")) << true; + QTest::addRow("valid-%02d", row++) << (QString() + QChar(0xFFFE) + QString("abc𝐀𝐁𝐂def𝐃𝐄𝐅")) << true; + + row = 0; + QTest::addRow("stray-high-%02d", row++) << (QString() + QChar(0xD800)) << false; + QTest::addRow("stray-high-%02d", row++) << (QString() + QString("abc") + QChar(0xD800)) << false; + QTest::addRow("stray-high-%02d", row++) << (QString() + QChar(0xD800) + QString("def")) << false; + QTest::addRow("stray-high-%02d", row++) << (QString() + QString("abc") + QChar(0xD800) + QString("def")) << false; + QTest::addRow("stray-high-%02d", row++) << (QString() + QChar(0xD800) + QChar(0xD800)) << false; + QTest::addRow("stray-high-%02d", row++) << (QString() + QString("abc") + QChar(0xD800) + QChar(0xD800)) << false; + QTest::addRow("stray-high-%02d", row++) << (QString() + QChar(0xD800) + QChar(0xD800) + QString("def")) << false; + QTest::addRow("stray-high-%02d", row++) << (QString() + QString("abc") + QChar(0xD800) + QChar(0xD800) + QString("def")) << false; + + row = 0; + QTest::addRow("stray-low-%02d", row++) << (QString() + QChar(0xDC00)) << false; + QTest::addRow("stray-low-%02d", row++) << (QString() + QString("abc") + QChar(0xDC00)) << false; + QTest::addRow("stray-low-%02d", row++) << (QString() + QChar(0xDC00) + QString("def")) << false; + QTest::addRow("stray-low-%02d", row++) << (QString() + QString("abc") + QChar(0xDC00) + QString("def")) << false; + QTest::addRow("stray-low-%02d", row++) << (QString() + QChar(0xDC00) + QChar(0xDC00)) << false; + QTest::addRow("stray-low-%02d", row++) << (QString() + QString("abc") + QChar(0xDC00) + QChar(0xDC00)) << false; + QTest::addRow("stray-low-%02d", row++) << (QString() + QChar(0xDC00) + QChar(0xDC00) + QString("def")) << false; + QTest::addRow("stray-low-%02d", row++) << (QString() + QString("abc") + QChar(0xDC00) + QChar(0xDC00) + QString("def")) << false; +} + +void tst_QString::isValidUtf16() +{ + QFETCH(QString, string); + QTEST(string.isValidUtf16(), "valid"); +} + QTEST_APPLESS_MAIN(tst_QString) #include "tst_qstring.moc" diff --git a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp index 47ce9a6f63..631bcce508 100644 --- a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp +++ b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp @@ -221,6 +221,8 @@ private Q_SLOTS: void comparison(); + void overloadResolution(); + private: template <typename String> void conversion_tests(String arg) const; @@ -678,5 +680,61 @@ void tst_QStringView::comparison() QVERIFY(bb.compare(aa) > 0); } +namespace QStringViewOverloadResolution { +static void test(QString) = delete; +static void test(QStringView) {} +} + +// Compile-time only test: overload resolution prefers QStringView over QString +void tst_QStringView::overloadResolution() +{ + { + QChar qcharArray[42] = {}; + QStringViewOverloadResolution::test(qcharArray); + QChar *qcharPointer = qcharArray; + QStringViewOverloadResolution::test(qcharPointer); + } + + { + ushort ushortArray[42] = {}; + QStringViewOverloadResolution::test(ushortArray); + ushort *ushortPointer = ushortArray; + QStringViewOverloadResolution::test(ushortPointer); + } + + { + QStringRef stringRef; + QStringViewOverloadResolution::test(stringRef); + QStringViewOverloadResolution::test(qAsConst(stringRef)); + QStringViewOverloadResolution::test(std::move(stringRef)); + } + +#if defined(Q_OS_WIN) + { + wchar_t wchartArray[42] = {}; + QStringViewOverloadResolution::test(wchartArray); + QStringViewOverloadResolution::test(L"test"); + } +#endif + +#if defined(Q_COMPILER_UNICODE_STRINGS) + { + char16_t char16Array[] = u"test"; + QStringViewOverloadResolution::test(char16Array); + char16_t *char16Pointer = char16Array; + QStringViewOverloadResolution::test(char16Pointer); + } +#endif + +#if defined(Q_STDLIB_UNICODE_STRINGS) + { + std::u16string string; + QStringViewOverloadResolution::test(string); + QStringViewOverloadResolution::test(qAsConst(string)); + QStringViewOverloadResolution::test(std::move(string)); + } +#endif +} + QTEST_APPLESS_MAIN(tst_QStringView) #include "tst_qstringview.moc" diff --git a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp index 749aa45916..11f34343ab 100644 --- a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp @@ -89,7 +89,7 @@ enum { waitTime = 100 }; -#if QT_HAS_INCLUDE(<chrono>) +#if __has_include(<chrono>) static Q_CONSTEXPR std::chrono::milliseconds waitTimeAsDuration(waitTime); #endif @@ -100,7 +100,7 @@ void tst_QMutex::convertToMilliseconds_data() QTest::addColumn<qint64>("intValue"); QTest::addColumn<qint64>("expected"); -#if !QT_HAS_INCLUDE(<chrono>) +#if !__has_include(<chrono>) QSKIP("This test requires <chrono>"); #endif @@ -156,7 +156,7 @@ void tst_QMutex::convertToMilliseconds_data() void tst_QMutex::convertToMilliseconds() { -#if !QT_HAS_INCLUDE(<chrono>) +#if !__has_include(<chrono>) QSKIP("This test requires <chrono>"); #else QFETCH(TimeUnit, unit); @@ -325,7 +325,7 @@ void tst_QMutex::tryLock_non_recursive() } void tst_QMutex::try_lock_for_non_recursive() { -#if !QT_HAS_INCLUDE(<chrono>) +#if !__has_include(<chrono>) QSKIP("This test requires <chrono>"); #else class Thread : public QThread @@ -454,7 +454,7 @@ void tst_QMutex::try_lock_for_non_recursive() { void tst_QMutex::try_lock_until_non_recursive() { -#if !QT_HAS_INCLUDE(<chrono>) +#if !__has_include(<chrono>) QSKIP("This test requires <chrono>"); #else class Thread : public QThread @@ -707,7 +707,7 @@ void tst_QMutex::tryLock_recursive() void tst_QMutex::try_lock_for_recursive() { -#if !QT_HAS_INCLUDE(<chrono>) +#if !__has_include(<chrono>) QSKIP("This test requires <chrono>"); #else class Thread : public QThread @@ -836,7 +836,7 @@ void tst_QMutex::try_lock_for_recursive() void tst_QMutex::try_lock_until_recursive() { -#if !QT_HAS_INCLUDE(<chrono>) +#if !__has_include(<chrono>) QSKIP("This test requires <chrono>"); #else class Thread : public QThread diff --git a/tests/auto/corelib/time/qdate/tst_qdate.cpp b/tests/auto/corelib/time/qdate/tst_qdate.cpp index 73384c35f4..567209dcf6 100644 --- a/tests/auto/corelib/time/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/time/qdate/tst_qdate.cpp @@ -88,7 +88,7 @@ private slots: void toStringDateFormat(); void isLeapYear(); void yearsZeroToNinetyNine(); - void negativeYear() const; + void printNegativeYear_data() const; void printNegativeYear() const; void roundtripGermanLocale() const; #if QT_CONFIG(textdate) && QT_DEPRECATED_SINCE(5, 10) @@ -1136,8 +1136,14 @@ void tst_QDate::fromStringDateFormat_data() // Test Qt::RFC2822Date format (RFC 2822). QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100") << Qt::RFC2822Date << QDate(1987, 2, 13); + QTest::newRow("RFC 2822 after space") + << QString::fromLatin1(" 13 Feb 1987 13:24:51 +0100") + << Qt::RFC2822Date << QDate(1987, 2, 13); QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000") << Qt::RFC2822Date << QDate(1970, 1, 1); + QTest::newRow("RFC 2822 with day after space") + << QString::fromLatin1(" Thu, 01 Jan 1970 00:12:34 +0000") + << Qt::RFC2822Date << QDate(1970, 1, 1); // No timezone QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34") << Qt::RFC2822Date << QDate(1970, 1, 1); @@ -1153,38 +1159,56 @@ void tst_QDate::fromStringDateFormat_data() << Qt::RFC2822Date << QDate(); QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100") << Qt::RFC2822Date << QDate(); - // Test invalid characters (should ignore invalid characters at end of string). - QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") + // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038). + QTest::newRow("RFC 2822 invalid character at end") + << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") + << Qt::RFC2822Date << QDate(2012, 1, 1); + QTest::newRow("RFC 2822 invalid character at front") + << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 2822 invalid character both ends") + << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100!") << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 2822 invalid character at front, 2 at back") + << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100..") << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 2822 invalid character 2 at front") + << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << QDate(); + // The common date text used by the "invalid character" tests, just to be + // sure *it's* not what's invalid: + QTest::newRow("RFC 2822 (not invalid)") + << QString::fromLatin1("01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << QDate(2012, 1, 1); - QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000") - << Qt::RFC2822Date << QDate(); - QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!") - << Qt::RFC2822Date << QDate(); - QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..") - << Qt::RFC2822Date << QDate(); - QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000") - << Qt::RFC2822Date << QDate(); - // Test Qt::RFC2822Date format (RFC 850 and 1036). + // Test Qt::RFC2822Date format (RFC 850 and 1036, permissive). QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100") << Qt::RFC2822Date << QDate(1987, 2, 13); + QTest::newRow("RFC 850 and 1036 after space") + << QString::fromLatin1(" Fri Feb 13 13:24:51 1987 +0100") + << Qt::RFC2822Date << QDate(1987, 2, 13); // No timezone QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970") << Qt::RFC2822Date << QDate(1970, 1, 1); // No time specified QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002") << Qt::RFC2822Date << QDate(2002, 11, 1); - // Test invalid characters (should ignore invalid characters at end of string). - QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!") + // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038). + QTest::newRow("RFC 850 and 1036 invalid character at end") + << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!") << Qt::RFC2822Date << QDate(2012, 1, 1); - QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000") + QTest::newRow("RFC 850 and 1036 invalid character at front") + << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100") << Qt::RFC2822Date << QDate(); - QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!") + QTest::newRow("RFC 850 and 1036 invalid character both ends") + << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100!") << Qt::RFC2822Date << QDate(); - QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..") + QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") + << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100..") << Qt::RFC2822Date << QDate(); - QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000") + QTest::newRow("RFC 850 and 1036 invalid character 2 at front") + << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0100") << Qt::RFC2822Date << QDate(); + // Again, check the text in the "invalid character" tests isn't the source of invalidity: + QTest::newRow("RFC 850 and 1036 (not invalid)") + << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100") + << Qt::RFC2822Date << QDate(2012, 1, 1); QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << QDate(); } @@ -1434,33 +1458,28 @@ void tst_QDate::yearsZeroToNinetyNine() } } - -void tst_QDate::negativeYear() const +void tst_QDate::printNegativeYear_data() const { - QDate y(-20, 3, 4); - QVERIFY(y.isValid()); - QCOMPARE(y.year(), -20); + QTest::addColumn<int>("year"); + QTest::addColumn<QString>("expect"); + QTest::newRow("millennium") << -1000 << QStringLiteral("-1000"); + QTest::newRow("century") << -500 << QStringLiteral("-0500"); + QTest::newRow("decade") << -20 << QStringLiteral("-0020"); + QTest::newRow("year") << -7 << QStringLiteral("-0007"); } void tst_QDate::printNegativeYear() const { - { - QDate date(-500, 3, 4); - QVERIFY(date.isValid()); - QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0500")); - } - - { - QDate date(-10, 3, 4); - QVERIFY(date.isValid()); - QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0010")); - } + QFETCH(int, year); + QFETCH(QString, expect); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + expect.replace(QLatin1Char('-'), QLocale().negativeSign()); +#endif - { - QDate date(-2, 3, 4); - QVERIFY(date.isValid()); - QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0002")); - } + QDate date(year, 3, 4); + QVERIFY(date.isValid()); + QCOMPARE(date.year(), year); + QCOMPARE(date.toString(QLatin1String("yyyy")), expect); } void tst_QDate::roundtripGermanLocale() const diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index 216ae1f79e..6aae91f62f 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -150,6 +150,7 @@ private slots: void timeZones() const; void systemTimeZoneChange() const; + void invalid_data() const; void invalid() const; void range() const; @@ -1003,8 +1004,9 @@ void tst_QDateTime::toString_rfcDate() // Set to non-English locale to confirm still uses English QLocale oldLocale; QLocale::setDefault(QLocale("de_DE")); - QCOMPARE(dt.toString(Qt::RFC2822Date), formatted); + QString actual(dt.toString(Qt::RFC2822Date)); QLocale::setDefault(oldLocale); + QCOMPARE(actual, formatted); } void tst_QDateTime::toString_enumformat() @@ -2208,6 +2210,55 @@ void tst_QDateTime::fromStringDateFormat_data() << Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 456)); // Test Qt::ISODate format. + QTest::newRow("trailing space") // QTBUG-80445 + << QString("2000-01-02 03:04:05.678 ") + << Qt::ISODate << QDateTime(QDate(2000, 1, 2), QTime(3, 4, 5, 678)); + + // Invalid spaces (but keeping field widths correct): + QTest::newRow("space before millis") + << QString("2000-01-02 03:04:05. 678") << Qt::ISODate << QDateTime(); + QTest::newRow("space after seconds") + << QString("2000-01-02 03:04:5 .678") << Qt::ISODate << QDateTime(); + QTest::newRow("space before seconds") + << QString("2000-01-02 03:04: 5.678") << Qt::ISODate << QDateTime(); + QTest::newRow("space after minutes") + << QString("2000-01-02 03:4 :05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("space before minutes") + << QString("2000-01-02 03: 4:05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("space after hour") + << QString("2000-01-02 3 :04:05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("space before hour") + << QString("2000-01-02 3:04:05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("space after day") + << QString("2000-01-2 03:04:05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("space before day") + << QString("2000-01- 2 03:04:05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("space after month") + << QString("2000-1 -02 03:04:05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("space before month") + << QString("2000- 1-02 03:04:05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("space after year") + << QString("200 -01-02 03:04:05.678") << Qt::ISODate << QDateTime(); + + // Spaces as separators: + QTest::newRow("sec-milli space") + << QString("2000-01-02 03:04:05 678") << Qt::ISODate +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + << invalidDateTime(); +#else + // Should be invalid, but we ignore trailing cruft (in some cases) + << QDateTime(QDate(2000, 1, 2), QTime(3, 4, 5)); +#endif + QTest::newRow("min-sec space") + << QString("2000-01-02 03:04 05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("hour-min space") + << QString("2000-01-02 03 04:05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("mon-day space") + << QString("2000-01 02 03:04:05.678") << Qt::ISODate << QDateTime(); + QTest::newRow("year-mon space") + << QString("2000 01-02 03:04:05.678") << Qt::ISODate << QDateTime(); + + // Normal usage: QTest::newRow("ISO +01:00") << QString::fromLatin1("1987-02-13T13:24:51+01:00") << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); QTest::newRow("ISO +00:01") << QString::fromLatin1("1987-02-13T13:24:51+00:01") @@ -2228,11 +2279,17 @@ void tst_QDateTime::fromStringDateFormat_data() << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9), Qt::UTC); QTest::newRow("ISO zzz-3") << QString::fromLatin1("2014-12-15T12:37:09.745-3") << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9, 745), Qt::UTC); + QTest::newRow("ISO lower-case") << QString::fromLatin1("2005-06-28T07:57:30.002z") + << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), Qt::UTC); // No time specified - defaults to Qt::LocalTime. QTest::newRow("ISO data3") << QString::fromLatin1("2002-10-01") << Qt::ISODate << QDateTime(QDate(2002, 10, 1), QTime(0, 0, 0, 0), Qt::LocalTime); + // Excess digits in milliseconds, round correctly: QTest::newRow("ISO") << QString::fromLatin1("2005-06-28T07:57:30.0010000000Z") << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), Qt::UTC); + QTest::newRow("ISO rounding") << QString::fromLatin1("2005-06-28T07:57:30.0015Z") + << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), Qt::UTC); + // ... and accept comma as separator: QTest::newRow("ISO with comma 1") << QString::fromLatin1("2005-06-28T07:57:30,0040000000Z") << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 4), Qt::UTC); QTest::newRow("ISO with comma 2") << QString::fromLatin1("2005-06-28T07:57:30,0015Z") @@ -2279,7 +2336,11 @@ void tst_QDateTime::fromStringDateFormat_data() << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); // Test invalid characters (should ignore invalid characters at end of string). QTest::newRow("ISO invalid character at end") << QString::fromLatin1("2012-01-01T08:00:00!") +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + << Qt::ISODate << invalidDateTime(); +#else << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); +#endif QTest::newRow("ISO invalid character at front") << QString::fromLatin1("!2012-01-01T08:00:00") << Qt::ISODate << invalidDateTime(); QTest::newRow("ISO invalid character both ends") << QString::fromLatin1("!2012-01-01T08:00:00!") @@ -2310,8 +2371,14 @@ void tst_QDateTime::fromStringDateFormat_data() // Test Qt::RFC2822Date format (RFC 2822). QTest::newRow("RFC 2822 +0100") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100") << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); + QTest::newRow("RFC 2822 after space +0100") + << QString::fromLatin1(" 13 Feb 1987 13:24:51 +0100") + << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); QTest::newRow("RFC 2822 with day +0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 +0100") << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); + QTest::newRow("RFC 2822 with day after space +0100") + << QString::fromLatin1(" Fri, 13 Feb 1987 13:24:51 +0100") + << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); QTest::newRow("RFC 2822 -0100") << QString::fromLatin1("13 Feb 1987 13:24:51 -0100") << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC); QTest::newRow("RFC 2822 with day -0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 -0100") @@ -2324,6 +2391,11 @@ void tst_QDateTime::fromStringDateFormat_data() << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); QTest::newRow("RFC 2822 with day +0000") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000") << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + // Should be invalid, but current implementation would just ignore the + // offset as trailing junk if we insist on the space: + QTest::newRow("RFC 2822 missing space before +0100") + << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34+0100") << Qt::RFC2822Date + << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::OffsetFromUTC, 3600); // No timezone assume UTC QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34") << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); @@ -2339,21 +2411,34 @@ void tst_QDateTime::fromStringDateFormat_data() << Qt::RFC2822Date << invalidDateTime(); QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100") << Qt::RFC2822Date << invalidDateTime(); - // Test invalid characters (should ignore invalid characters at end of string). - QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") + // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038). + QTest::newRow("RFC 2822 invalid character at end") + << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC); - QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000") + QTest::newRow("RFC 2822 invalid character at front") + << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << invalidDateTime(); - QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!") + QTest::newRow("RFC 2822 invalid character both ends") + << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100!") << Qt::RFC2822Date << invalidDateTime(); - QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..") + QTest::newRow("RFC 2822 invalid character at front, 2 at back") + << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100..") << Qt::RFC2822Date << invalidDateTime(); - QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000") + QTest::newRow("RFC 2822 invalid character 2 at front") + << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << invalidDateTime(); + // The common date text used by the "invalid character" tests, just to be + // sure *it's* not what's invalid: + QTest::newRow("RFC 2822 (not invalid)") + << QString::fromLatin1("01 Jan 2012 08:00:00 +0100") + << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC); - // Test Qt::RFC2822Date format (RFC 850 and 1036). + // Test Qt::RFC2822Date format (RFC 850 and 1036, permissive). QTest::newRow("RFC 850 and 1036 +0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100") << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); + QTest::newRow("RFC 1036 after space +0100") + << QString::fromLatin1(" Fri Feb 13 13:24:51 1987 +0100") + << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); QTest::newRow("RFC 850 and 1036 -0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 -0100") << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC); QTest::newRow("RFC 850 and 1036 +0000") << QString::fromLatin1("Thu Jan 01 00:12:34 1970 +0000") @@ -2364,19 +2449,29 @@ void tst_QDateTime::fromStringDateFormat_data() QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970") << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); // No time specified - QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002") + QTest::newRow("RFC 850 and 1036 date only") + << QString::fromLatin1("Fri Nov 01 2002") << Qt::RFC2822Date << invalidDateTime(); - // Test invalid characters (should ignore invalid characters at end of string). - QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!") + // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038). + QTest::newRow("RFC 850 and 1036 invalid character at end") + << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!") << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC); - QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000") + QTest::newRow("RFC 850 and 1036 invalid character at front") + << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100") << Qt::RFC2822Date << invalidDateTime(); - QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!") + QTest::newRow("RFC 850 and 1036 invalid character both ends") + << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100!") << Qt::RFC2822Date << invalidDateTime(); - QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..") + QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") + << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100..") << Qt::RFC2822Date << invalidDateTime(); - QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000") + QTest::newRow("RFC 850 and 1036 invalid character 2 at front") + << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0100") << Qt::RFC2822Date << invalidDateTime(); + // Again, check the text in the "invalid character" tests isn't the source of invalidity: + QTest::newRow("RFC 850 and 1036 (not invalid)") + << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100") + << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC); QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidDateTime(); } @@ -2423,6 +2518,7 @@ void tst_QDateTime::fromStringStringFormat_data() if (southBrazil.isValid()) { QTest::newRow("spring-forward-midnight") << QString("2008-10-19 23:45.678 America/Sao_Paulo") << QString("yyyy-MM-dd mm:ss.zzz t") + // That's in the hour skipped - expect the matching time after the spring-forward, in DST: << QDateTime(QDate(2008, 10, 19), QTime(1, 23, 45, 678), southBrazil); } #endif @@ -3324,6 +3420,9 @@ void tst_QDateTime::timeZones() const QCOMPARE(utc.date(), utcDst.date()); QCOMPARE(utc.time(), utcDst.time()); + // Crash test, QTBUG-80146: + QVERIFY(!nzStd.toTimeZone(QTimeZone()).isValid()); + // Sydney is 2 hours behind New Zealand QTimeZone ausTz = QTimeZone("Australia/Sydney"); QDateTime aus = nzStd.toTimeZone(ausTz); @@ -3493,23 +3592,42 @@ void tst_QDateTime::systemTimeZoneChange() const QCOMPARE(tzDate.toMSecsSinceEpoch(), tzMsecs); } -void tst_QDateTime::invalid() const +void tst_QDateTime::invalid_data() const { - QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1)); - QCOMPARE(invalidDate.isValid(), false); - QCOMPARE(invalidDate.timeSpec(), Qt::LocalTime); + QTest::addColumn<QDateTime>("when"); + QTest::addColumn<Qt::TimeSpec>("spec"); + QTest::addColumn<bool>("goodZone"); + QTest::newRow("default") << QDateTime() << Qt::LocalTime << true; - QDateTime utcDate = invalidDate.toUTC(); - QCOMPARE(utcDate.isValid(), false); - QCOMPARE(utcDate.timeSpec(), Qt::UTC); - - QDateTime offsetDate = invalidDate.toOffsetFromUtc(3600); - QCOMPARE(offsetDate.isValid(), false); - QCOMPARE(offsetDate.timeSpec(), Qt::OffsetFromUTC); + QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1)); + QTest::newRow("simple") << invalidDate << Qt::LocalTime << true; + QTest::newRow("UTC") << invalidDate.toUTC() << Qt::UTC << true; + QTest::newRow("offset") + << invalidDate.toOffsetFromUtc(3600) << Qt::OffsetFromUTC << true; + QTest::newRow("CET") + << invalidDate.toTimeZone(QTimeZone("Europe/Oslo")) << Qt::TimeZone << true; + + // Crash tests, QTBUG-80146: + QTest::newRow("nozone+construct") + << QDateTime(QDate(1970, 1, 1), QTime(12, 0), QTimeZone()) << Qt::TimeZone << false; + QTest::newRow("nozone+fromMSecs") + << QDateTime::fromMSecsSinceEpoch(42, QTimeZone()) << Qt::TimeZone << false; + QDateTime valid(QDate(1970, 1, 1), QTime(12, 0), Qt::UTC); + QTest::newRow("tonozone") << valid.toTimeZone(QTimeZone()) << Qt::TimeZone << false; +} - QDateTime tzDate = invalidDate.toTimeZone(QTimeZone("Europe/Oslo")); - QCOMPARE(tzDate.isValid(), false); - QCOMPARE(tzDate.timeSpec(), Qt::TimeZone); +void tst_QDateTime::invalid() const +{ + QFETCH(QDateTime, when); + QFETCH(Qt::TimeSpec, spec); + QFETCH(bool, goodZone); + QVERIFY(!when.isValid()); + QCOMPARE(when.timeSpec(), spec); + QCOMPARE(when.timeZoneAbbreviation(), QString()); + if (!goodZone) + QCOMPARE(when.toMSecsSinceEpoch(), 0); + QVERIFY(!when.isDaylightTime()); + QCOMPARE(when.timeZone().isValid(), goodZone); } void tst_QDateTime::range() const diff --git a/tests/auto/corelib/time/qtime/tst_qtime.cpp b/tests/auto/corelib/time/qtime/tst_qtime.cpp index 3403c5bf7f..f85e0ea74e 100644 --- a/tests/auto/corelib/time/qtime/tst_qtime.cpp +++ b/tests/auto/corelib/time/qtime/tst_qtime.cpp @@ -590,7 +590,12 @@ void tst_QTime::fromStringDateFormat_data() QTest::newRow("TextDate - invalid, minutes") << QString::fromLatin1("23:XX:00") << Qt::TextDate << invalidTime(); QTest::newRow("TextDate - invalid, minute fraction") << QString::fromLatin1("23:00.123456") << Qt::TextDate << invalidTime(); QTest::newRow("TextDate - invalid, seconds") << QString::fromLatin1("23:00:XX") << Qt::TextDate << invalidTime(); - QTest::newRow("TextDate - invalid, milliseconds") << QString::fromLatin1("23:01:01:XXXX") << Qt::TextDate << QTime(23, 1, 1, 0); + QTest::newRow("TextDate - invalid, milliseconds") << QString::fromLatin1("23:01:01:XXXX") << Qt::TextDate +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + << invalidTime(); +#else + << QTime(23, 1, 1, 0); +#endif QTest::newRow("TextDate - midnight 24") << QString("24:00:00") << Qt::TextDate << QTime(); QTest::newRow("IsoDate - valid, start of day, omit seconds") << QString::fromLatin1("00:00") << Qt::ISODate << QTime(0, 0, 0); @@ -607,8 +612,12 @@ void tst_QTime::fromStringDateFormat_data() QTest::newRow("IsoDate - invalid, not enough minutes") << QString::fromLatin1("23:0") << Qt::ISODate << invalidTime(); QTest::newRow("IsoDate - invalid, minute fraction") << QString::fromLatin1("23:00,XX") << Qt::ISODate << invalidTime(); QTest::newRow("IsoDate - invalid, seconds") << QString::fromLatin1("23:00:XX") << Qt::ISODate << invalidTime(); - QTest::newRow("IsoDate - invalid, milliseconds") << QString::fromLatin1("23:01:01:XXXX") << Qt::ISODate << QTime(23, 1, 1, 0); - + QTest::newRow("IsoDate - invalid, milliseconds") << QString::fromLatin1("23:01:01:XXXX") << Qt::ISODate +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + << invalidTime(); +#else + << QTime(23, 1, 1, 0); +#endif QTest::newRow("IsoDate - data0") << QString("00:00:00") << Qt::ISODate << QTime(0,0,0,0); QTest::newRow("IsoDate - data1") << QString("10:12:34") << Qt::ISODate << QTime(10,12,34,0); QTest::newRow("IsoDate - data2") << QString("19:03:54.998601") << Qt::ISODate << QTime(19, 3, 54, 999); @@ -619,8 +628,14 @@ void tst_QTime::fromStringDateFormat_data() // Test Qt::RFC2822Date format (RFC 2822). QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100") << Qt::RFC2822Date << QTime(13, 24, 51); + QTest::newRow("RFC 2822 after space") + << QString::fromLatin1(" 13 Feb 1987 13:24:51 +0100") + << Qt::RFC2822Date << QTime(13, 24, 51); QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000") << Qt::RFC2822Date << QTime(0, 12, 34); + QTest::newRow("RFC 2822 with day after space") + << QString::fromLatin1(" Thu, 01 Jan 1970 00:12:34 +0000") + << Qt::RFC2822Date << QTime(0, 12, 34); // No timezone QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34") << Qt::RFC2822Date << QTime(0, 12, 34); @@ -636,36 +651,58 @@ void tst_QTime::fromStringDateFormat_data() << Qt::RFC2822Date << QTime(13, 24, 51); QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100") << Qt::RFC2822Date << QTime(13, 24, 51); - // Test invalid characters (should ignore invalid characters at end of string). - QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") + // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038). + QTest::newRow("RFC 2822 invalid character at end") + << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") << Qt::RFC2822Date << QTime(8, 0, 0); - QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000") + QTest::newRow("RFC 2822 invalid character at front") + << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << invalidTime(); - QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!") + QTest::newRow("RFC 2822 invalid character both ends") + << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100!") << Qt::RFC2822Date << invalidTime(); - QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..") + QTest::newRow("RFC 2822 invalid character at front, 2 at back") + << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100..") << Qt::RFC2822Date << invalidTime(); - QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000") + QTest::newRow("RFC 2822 invalid character 2 at front") + << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << invalidTime(); + // The common date text used by the "invalid character" tests, just to be + // sure *it's* not what's invalid: + QTest::newRow("RFC 2822 invalid character at end") + << QString::fromLatin1("01 Jan 2012 08:00:00 +0100") + << Qt::RFC2822Date << QTime(8, 0, 0); - // Test Qt::RFC2822Date format (RFC 850 and 1036). + // Test Qt::RFC2822Date format (RFC 850 and 1036, permissive). QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100") << Qt::RFC2822Date << QTime(13, 24, 51); + QTest::newRow("RFC 850 and 1036 after space") + << QString::fromLatin1(" Fri Feb 13 13:24:51 1987 +0100") + << Qt::RFC2822Date << QTime(13, 24, 51); // No timezone QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970") << Qt::RFC2822Date << QTime(0, 12, 34); // No time specified QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002") << Qt::RFC2822Date << invalidTime(); - // Test invalid characters (should ignore invalid characters at end of string). - QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!") + // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038). + QTest::newRow("RFC 850 and 1036 invalid character at end") + << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!") << Qt::RFC2822Date << QTime(8, 0, 0); - QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000") + QTest::newRow("RFC 850 and 1036 invalid character at front") + << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100") << Qt::RFC2822Date << invalidTime(); - QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!") + QTest::newRow("RFC 850 and 1036 invalid character both ends") + << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100!") << Qt::RFC2822Date << invalidTime(); - QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..") + QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") + << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100..") << Qt::RFC2822Date << invalidTime(); + // The common date text used by the "invalid character" tests, just to be + // sure *it's* not what's invalid: + QTest::newRow("RFC 850 and 1036 invalid character at end") + << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100") + << Qt::RFC2822Date << QTime(8, 0, 0); QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidTime(); } diff --git a/tests/auto/corelib/time/qtimezone/BLACKLIST b/tests/auto/corelib/time/qtimezone/BLACKLIST index 840c3b1181..b820bab3d9 100644 --- a/tests/auto/corelib/time/qtimezone/BLACKLIST +++ b/tests/auto/corelib/time/qtimezone/BLACKLIST @@ -2,10 +2,6 @@ [dataStreamTest] android -# QTBUG-69128 -[isTimeZoneIdAvailable] -android - # QTBUG-69129 [specificTransition] android @@ -75,10 +71,14 @@ android android [transitionEachZone:Asia/Chita@1970] android +[transitionEachZone:Asia/Choibalsan@1970] +android [transitionEachZone:Asia/Dushanbe@1970] android [transitionEachZone:Asia/Ho_Chi_Minh@1970] android +[transitionEachZone:Asia/Hovd@1970] +android [transitionEachZone:Asia/Kathmandu@1970] android [transitionEachZone:Asia/Katmandu@1970] @@ -109,6 +109,10 @@ android android [transitionEachZone:Asia/Thimphu@1970] android +[transitionEachZone:Asia/Ulaanbaatar@1970] +android +[transitionEachZone:Asia/Ulan_Bator@1970] +android [transitionEachZone:Asia/Ust-Nera@1970] android [transitionEachZone:Atlantic/Cape_Verde@1970] diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp index 5b1bde8ea3..332a00efb5 100644 --- a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp @@ -46,6 +46,7 @@ private slots: // Public class default system tests void createTest(); void nullTest(); + void systemZone(); void dataStreamTest(); void isTimeZoneIdAvailable(); void availableTimeZoneIds(); @@ -317,6 +318,14 @@ void tst_QTimeZone::nullTest() QCOMPARE(data.daylightTimeOffset, std::numeric_limits<int>::min()); } +void tst_QTimeZone::systemZone() +{ + const QTimeZone zone = QTimeZone::systemTimeZone(); + QVERIFY(zone.isValid()); + QCOMPARE(zone.id(), QTimeZone::systemTimeZoneId()); + QCOMPARE(zone, QTimeZone(QTimeZone::systemTimeZoneId())); +} + void tst_QTimeZone::dataStreamTest() { // Test the OffsetFromUtc backend serialization. First with a custom timezone: @@ -818,6 +827,10 @@ void tst_QTimeZone::isValidId_data() QTest::addColumn<QByteArray>("input"); QTest::addColumn<bool>("valid"); + // 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 + // (Android has parts with lengths up to 17, so tolerates this as a special case.) #define TESTSET(name, section, valid) \ QTest::newRow(name " front") << QByteArray(section "/xyz/xyz") << valid; \ QTest::newRow(name " middle") << QByteArray("xyz/" section "/xyz") << valid; \ @@ -828,11 +841,16 @@ void tst_QTimeZone::isValidId_data() // Parts separated by '/', each part min 1 and max of 14 chars TESTSET("empty", "", false); TESTSET("minimal", "m", true); +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) + TESTSET("maximal", "East-Saskatchewan", true); // Android actually uses this + TESTSET("too long", "North-Saskatchewan", false); // ... but thankfully not this. +#else TESTSET("maximal", "12345678901234", true); TESTSET("maximal twice", "12345678901234/12345678901234", true); TESTSET("too long", "123456789012345", false); TESTSET("too-long/maximal", "123456789012345/12345678901234", false); TESTSET("maximal/too-long", "12345678901234/123456789012345", false); +#endif TESTSET("bad hyphen", "-hyphen", false); TESTSET("good hyphen", "hy-phen", true); @@ -879,6 +897,31 @@ void tst_QTimeZone::isValidId_data() TESTSET("invalid char ' '", " ", false); #undef TESTSET + + QTest::newRow("az alone") << QByteArray("az") << true; + QTest::newRow("AZ alone") << QByteArray("AZ") << true; + QTest::newRow("09 alone") << QByteArray("09") << true; + QTest::newRow("a/z alone") << QByteArray("a/z") << true; + QTest::newRow("a.z alone") << QByteArray("a.z") << true; + QTest::newRow("a-z alone") << QByteArray("a-z") << true; + QTest::newRow("a_z alone") << QByteArray("a_z") << true; + QTest::newRow(".z alone") << QByteArray(".z") << true; + QTest::newRow("_z alone") << QByteArray("_z") << true; + QTest::newRow("a z alone") << QByteArray("a z") << false; + QTest::newRow("a\\z alone") << QByteArray("a\\z") << false; + QTest::newRow("a,z alone") << QByteArray("a,z") << false; + QTest::newRow("/z alone") << QByteArray("/z") << false; + QTest::newRow("-z alone") << QByteArray("-z") << false; +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) + QTest::newRow("long alone") << QByteArray("12345678901234567") << true; + QTest::newRow("over-long alone") << QByteArray("123456789012345678") << false; +#else + QTest::newRow("long alone") << QByteArray("12345678901234") << true; + QTest::newRow("over-long alone") << QByteArray("123456789012345") << false; +#endif + +#else + QSKIP("This test requires a Qt -developer-build."); #endif // QT_BUILD_INTERNAL } @@ -889,8 +932,6 @@ void tst_QTimeZone::isValidId() QFETCH(bool, valid); QCOMPARE(QTimeZonePrivate::isValidId(input), valid); -#else - QSKIP("This test requires a Qt -developer-build."); #endif } diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp index 5ba8545b61..023b22b4ba 100644 --- a/tests/auto/corelib/tools/collections/tst_collections.cpp +++ b/tests/auto/corelib/tools/collections/tst_collections.cpp @@ -3583,30 +3583,8 @@ template<class Container> void insert_remove_loop_impl() } -//Add insert(int, int, T) so it has the same interface as QVector and QVarLengthArray for the test. template<typename T> -struct ExtList : QList<T> { - using QList<T>::insert; - void insert(int before, int n, const T&x) { - while (n--) { - this->insert(before, x ); - } - } - void insert(typename QList<T>::iterator before, int n, const T&x) { - while (n--) { - before = this->insert(before, x); - } - } - - void remove(int i) { - this->removeAt(i); - } - void remove(int i, int n) { - while (n--) { - this->removeAt(i); - } - } -}; +using ExtList = QList<T>; void tst_Collections::insert_remove_loop() { diff --git a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp index 7a1e13e83d..0e4517e740 100644 --- a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp +++ b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp @@ -51,7 +51,7 @@ #ifdef Q_CC_MSVC #define COMPILER_HAS_STDLIB_INCLUDE(x) 1 #else -#define COMPILER_HAS_STDLIB_INCLUDE(x) QT_HAS_INCLUDE(x) +#define COMPILER_HAS_STDLIB_INCLUDE(x) __has_include(x) #endif #if COMPILER_HAS_STDLIB_INCLUDE(<forward_list>) @@ -795,8 +795,6 @@ template <> QStringView make(int size) { return QStringView(s_string).left(siz template <> QLatin1String make(int size) { return QLatin1String("\1\2\3\4\5\6\7", size); } template <typename T> T clean(T &&t) { return std::forward<T>(t); } -inline QChar clean(QCharRef ch) { return ch; } -inline char clean(QByteRef ch) { return ch; } inline char clean(QLatin1Char ch) { return ch.toLatin1(); } template <typename Container> diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index e587ad27b5..94cee5d887 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -76,21 +76,32 @@ public: { } - explicit SimpleVector(Data *ptr) - : d(ptr) + template <size_t N> + explicit SimpleVector(QStaticArrayData<T, N> &ptr) + : d(static_cast<Data *>(&ptr.header), ptr.data, N) + { + } + + SimpleVector(Data *header, T *data, size_t len = 0) + : d(header, data, len) + { + } + + explicit SimpleVector(QPair<Data*, T*> ptr, size_t len = 0) + : d(ptr, len) { } - bool empty() const { return d->size == 0; } + bool empty() const { return d.size == 0; } bool isNull() const { return d.isNull(); } bool isEmpty() const { return this->empty(); } - bool isStatic() const { return d->ref.isStatic(); } - bool isShared() const { return d->ref.isShared(); } + bool isStatic() const { return d->isStatic(); } + bool isShared() const { return d->isShared(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } - size_t size() const { return d->size; } - size_t capacity() const { return d->alloc; } + size_t size() const { return d.size; } + size_t capacity() const { return d->constAllocatedCapacity(); } iterator begin() { detach(); return d->begin(); } iterator end() { detach(); return d->end(); } @@ -139,10 +150,10 @@ public: return; if (n <= capacity()) { - if (d->capacityReserved) + if (d->flags() & Data::CapacityReserved) return; - if (!d->ref.isShared()) { - d->capacityReserved = 1; + if (!d->isShared()) { + d->flags() |= Data::CapacityReserved; return; } } @@ -159,7 +170,7 @@ public: if (size() == newSize) return; - if (d.needsDetach() || newSize > capacity()) { + if (d->needsDetach() || newSize > capacity()) { SimpleVector detached(Data::allocate( d->detachCapacity(newSize), d->detachFlags())); if (newSize) { @@ -195,11 +206,11 @@ public: return; T *const begin = d->begin(); - if (d.needsDetach() + if (d->needsDetach() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( d->detachCapacity(size() + (last - first)), - d->detachFlags() | Data::Grow)); + d->detachFlags() | Data::GrowsForward)); detached.d->copyAppend(first, last); detached.d->copyAppend(begin, begin + d->size); @@ -216,11 +227,11 @@ public: if (first == last) return; - if (d.needsDetach() + if (d->needsDetach() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( d->detachCapacity(size() + (last - first)), - d->detachFlags() | Data::Grow)); + d->detachFlags() | Data::GrowsForward)); if (d->size) { const T *const begin = constBegin(); @@ -256,11 +267,11 @@ public: const iterator begin = d->begin(); const iterator where = begin + position; const iterator end = begin + d->size; - if (d.needsDetach() + if (d->needsDetach() || capacity() - size() < size_t(last - first)) { SimpleVector detached(Data::allocate( d->detachCapacity(size() + (last - first)), - d->detachFlags() | Data::Grow)); + d->detachFlags() | Data::GrowsForward)); if (position) detached.d->copyAppend(begin, where); @@ -294,7 +305,7 @@ public: const T *const begin = d->begin(); const T *const end = begin + d->size; - if (d.needsDetach()) { + if (d->needsDetach()) { SimpleVector detached(Data::allocate( d->detachCapacity(size() - (last - first)), d->detachFlags())); @@ -328,7 +339,7 @@ public: } static SimpleVector fromRawData(const T *data, size_t size, - QArrayData::AllocationOptions options = Data::Default) + QArrayData::ArrayOptions options = Data::DefaultRawFlags) { return SimpleVector(Data::fromRawData(data, size, options)); } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 47bdc2fd38..1366eebf97 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -37,8 +37,8 @@ struct SharedNullVerifier { SharedNullVerifier() { - Q_ASSERT(QArrayData::shared_null[0].ref.isStatic()); - Q_ASSERT(QArrayData::shared_null[0].ref.isShared()); + Q_ASSERT(QArrayData::shared_null[0].isStatic()); + Q_ASSERT(QArrayData::shared_null[0].isShared()); } }; @@ -56,7 +56,6 @@ class tst_QArrayData : public QObject private slots: void referenceCounting(); void sharedNullEmpty(); - void staticData(); void simpleVector(); void simpleVectorReserve_data(); void simpleVectorReserve(); @@ -84,43 +83,42 @@ void tst_QArrayData::referenceCounting() { { // Reference counting initialized to 1 (owned) - QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(1) }, 0, 0, 0, 0 }; + QArrayData array = { Q_BASIC_ATOMIC_INITIALIZER(1), QArrayData::DefaultRawFlags, 0 }; - QCOMPARE(array.ref.atomic.loadRelaxed(), 1); + QCOMPARE(array.ref_.loadRelaxed(), 1); - QVERIFY(!array.ref.isStatic()); + QVERIFY(!array.isStatic()); - QVERIFY(array.ref.ref()); - QCOMPARE(array.ref.atomic.loadRelaxed(), 2); + QVERIFY(array.ref()); + QCOMPARE(array.ref_.loadRelaxed(), 2); - QVERIFY(array.ref.deref()); - QCOMPARE(array.ref.atomic.loadRelaxed(), 1); + QVERIFY(array.deref()); + QCOMPARE(array.ref_.loadRelaxed(), 1); - QVERIFY(array.ref.ref()); - QCOMPARE(array.ref.atomic.loadRelaxed(), 2); + QVERIFY(array.ref()); + QCOMPARE(array.ref_.loadRelaxed(), 2); - QVERIFY(array.ref.deref()); - QCOMPARE(array.ref.atomic.loadRelaxed(), 1); + QVERIFY(array.deref()); + QCOMPARE(array.ref_.loadRelaxed(), 1); - QVERIFY(!array.ref.deref()); - QCOMPARE(array.ref.atomic.loadRelaxed(), 0); + QVERIFY(!array.deref()); + QCOMPARE(array.ref_.loadRelaxed(), 0); // Now would be a good time to free/release allocated data } - { // Reference counting initialized to -1 (static read-only data) - QArrayData array = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 }; + QArrayData array = { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0 }; - QCOMPARE(array.ref.atomic.loadRelaxed(), -1); + QCOMPARE(array.ref_.loadRelaxed(), -1); - QVERIFY(array.ref.isStatic()); + QVERIFY(array.isStatic()); - QVERIFY(array.ref.ref()); - QCOMPARE(array.ref.atomic.loadRelaxed(), -1); + QVERIFY(array.ref()); + QCOMPARE(array.ref_.loadRelaxed(), -1); - QVERIFY(array.ref.deref()); - QCOMPARE(array.ref.atomic.loadRelaxed(), -1); + QVERIFY(array.deref()); + QCOMPARE(array.ref_.loadRelaxed(), -1); } } @@ -128,69 +126,39 @@ void tst_QArrayData::referenceCounting() void tst_QArrayData::sharedNullEmpty() { QArrayData *null = const_cast<QArrayData *>(QArrayData::shared_null); - QArrayData *empty = QArrayData::allocate(1, alignof(QArrayData), 0); - - QVERIFY(null->ref.isStatic()); - QVERIFY(null->ref.isShared()); + QArrayData *empty; + QArrayData::allocate(&empty, 1, alignof(QArrayData), 0); - QVERIFY(empty->ref.isStatic()); - QVERIFY(empty->ref.isShared()); + QVERIFY(null->isStatic()); + QVERIFY(null->isShared()); - QCOMPARE(null->ref.atomic.loadRelaxed(), -1); - QCOMPARE(empty->ref.atomic.loadRelaxed(), -1); + QVERIFY(empty->isStatic()); + QVERIFY(empty->isShared()); - QVERIFY(null->ref.ref()); - QVERIFY(empty->ref.ref()); + QCOMPARE(null->ref_.loadRelaxed(), -1); + QCOMPARE(empty->ref_.loadRelaxed(), -1); - QCOMPARE(null->ref.atomic.loadRelaxed(), -1); - QCOMPARE(empty->ref.atomic.loadRelaxed(), -1); + QCOMPARE(null->ref_.loadRelaxed(), -1); + QCOMPARE(empty->ref_.loadRelaxed(), -1); - QVERIFY(null->ref.deref()); - QVERIFY(empty->ref.deref()); + QVERIFY(null->deref()); + QVERIFY(empty->deref()); - QCOMPARE(null->ref.atomic.loadRelaxed(), -1); - QCOMPARE(empty->ref.atomic.loadRelaxed(), -1); + QCOMPARE(null->ref_.loadRelaxed(), -1); + QCOMPARE(empty->ref_.loadRelaxed(), -1); QVERIFY(null != empty); - QCOMPARE(null->size, 0); - QCOMPARE(null->alloc, 0u); - QCOMPARE(null->capacityReserved, 0u); + QCOMPARE(null->allocatedCapacity(), size_t(0)); - QCOMPARE(empty->size, 0); - QCOMPARE(empty->alloc, 0u); - QCOMPARE(empty->capacityReserved, 0u); -} - -void tst_QArrayData::staticData() -{ - QStaticArrayData<char, 10> charArray = { - Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(char, 10), - { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } - }; - QStaticArrayData<int, 10> intArray = { - Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10), - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } - }; - QStaticArrayData<double, 10> doubleArray = { - Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(double, 10), - { 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f } - }; - - QCOMPARE(charArray.header.size, 10); - QCOMPARE(intArray.header.size, 10); - QCOMPARE(doubleArray.header.size, 10); - - QCOMPARE(charArray.header.data(), reinterpret_cast<void *>(&charArray.data)); - QCOMPARE(intArray.header.data(), reinterpret_cast<void *>(&intArray.data)); - QCOMPARE(doubleArray.header.data(), reinterpret_cast<void *>(&doubleArray.data)); + QCOMPARE(empty->allocatedCapacity(), size_t(0)); } void tst_QArrayData::simpleVector() { - QArrayData data0 = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 }; + QArrayData data0 = { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0 }; QStaticArrayData<int, 7> data1 = { - Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 7), + { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0 }, { 0, 1, 2, 3, 4, 5, 6 } }; @@ -198,10 +166,10 @@ void tst_QArrayData::simpleVector() SimpleVector<int> v1; SimpleVector<int> v2(v1); - SimpleVector<int> v3(static_cast<QTypedArrayData<int> *>(&data0)); - SimpleVector<int> v4(static_cast<QTypedArrayData<int> *>(&data1.header)); - SimpleVector<int> v5(static_cast<QTypedArrayData<int> *>(&data0)); - SimpleVector<int> v6(static_cast<QTypedArrayData<int> *>(&data1.header)); + SimpleVector<int> v3(static_cast<QTypedArrayData<int> *>(&data0), 0, 0); + SimpleVector<int> v4(data1); + SimpleVector<int> v5(static_cast<QTypedArrayData<int> *>(&data0), 0, 0); + SimpleVector<int> v6(data1); SimpleVector<int> v7(10, 5); SimpleVector<int> v8(array, array + sizeof(array)/sizeof(*array)); @@ -461,11 +429,13 @@ void tst_QArrayData::simpleVectorReserve_data() QTest::newRow("non-empty") << SimpleVector<int>(5, 42) << size_t(5) << size_t(5); static const QStaticArrayData<int, 15> array = { - Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 15), + { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0 }, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } }; - QArrayDataPointerRef<int> p = { + const QArrayDataPointerRef<int> p = { static_cast<QTypedArrayData<int> *>( - const_cast<QArrayData *>(&array.header)) }; + const_cast<QArrayData *>(&array.header)), + const_cast<int *>(array.data), + sizeof(array.data) / sizeof(array.data[0]) }; QTest::newRow("static") << SimpleVector<int>(p) << size_t(0) << size_t(15); QTest::newRow("raw-data") << SimpleVector<int>::fromRawData(array.data, 15) << size_t(0) << size_t(15); @@ -528,13 +498,13 @@ struct Deallocator }; Q_DECLARE_METATYPE(const QArrayData *) -Q_DECLARE_METATYPE(QArrayData::AllocationOptions) +Q_DECLARE_METATYPE(QArrayData::ArrayOptions) void tst_QArrayData::allocate_data() { QTest::addColumn<size_t>("objectSize"); QTest::addColumn<size_t>("alignment"); - QTest::addColumn<QArrayData::AllocationOptions>("allocateOptions"); + QTest::addColumn<QArrayData::ArrayOptions>("allocateOptions"); QTest::addColumn<bool>("isCapacityReserved"); QTest::addColumn<const QArrayData *>("commonEmpty"); @@ -548,18 +518,19 @@ void tst_QArrayData::allocate_data() { "void *", sizeof(void *), alignof(void *) } }; - QArrayData *shared_empty = QArrayData::allocate(0, alignof(QArrayData), 0); + QArrayData *shared_empty; + QArrayData::allocate(&shared_empty, 1, alignof(QArrayData), 0); QVERIFY(shared_empty); struct { char const *description; - QArrayData::AllocationOptions allocateOptions; + QArrayData::ArrayOptions allocateOptions; bool isCapacityReserved; const QArrayData *commonEmpty; } options[] = { - { "Default", QArrayData::Default, false, shared_empty }, + { "Default", QArrayData::DefaultAllocationFlags, false, shared_empty }, { "Reserved", QArrayData::CapacityReserved, true, shared_empty }, - { "Grow", QArrayData::Grow, false, shared_empty } + { "Grow", QArrayData::GrowsForward, false, shared_empty } }; for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i) @@ -577,7 +548,7 @@ void tst_QArrayData::allocate() { QFETCH(size_t, objectSize); QFETCH(size_t, alignment); - QFETCH(QArrayData::AllocationOptions, allocateOptions); + QFETCH(QArrayData::ArrayOptions, allocateOptions); QFETCH(bool, isCapacityReserved); QFETCH(const QArrayData *, commonEmpty); @@ -586,27 +557,29 @@ void tst_QArrayData::allocate() size_t minAlignment = qMax(alignment, alignof(QArrayData)); // Shared Empty - QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0, - QArrayData::AllocationOptions(allocateOptions)), commonEmpty); + QArrayData *empty; + QCOMPARE((QArrayData::allocate(&empty, objectSize, minAlignment, 0, + QArrayData::ArrayOptions(allocateOptions)), empty), commonEmpty); Deallocator keeper(objectSize, minAlignment); keeper.headers.reserve(1024); for (int capacity = 1; capacity <= 1024; capacity <<= 1) { - QArrayData *data = QArrayData::allocate(objectSize, minAlignment, - capacity, QArrayData::AllocationOptions(allocateOptions)); + QArrayData *data; + void *dataPointer = QArrayData::allocate(&data, objectSize, minAlignment, + capacity, QArrayData::ArrayOptions(allocateOptions)); + keeper.headers.append(data); - QCOMPARE(data->size, 0); - if (allocateOptions & QArrayData::Grow) - QVERIFY(data->alloc > uint(capacity)); + if (allocateOptions & QArrayData::GrowsForward) + QVERIFY(data->allocatedCapacity() > uint(capacity)); else - QCOMPARE(data->alloc, uint(capacity)); - QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); + QCOMPARE(data->allocatedCapacity(), size_t(capacity)); + QCOMPARE(bool(data->flags & QArrayData::CapacityReserved), isCapacityReserved); // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. - ::memset(data->data(), 'A', objectSize * capacity); + ::memset(dataPointer, 'A', objectSize * capacity); } } @@ -614,43 +587,40 @@ void tst_QArrayData::reallocate() { QFETCH(size_t, objectSize); QFETCH(size_t, alignment); - QFETCH(QArrayData::AllocationOptions, allocateOptions); + QFETCH(QArrayData::ArrayOptions, allocateOptions); QFETCH(bool, isCapacityReserved); - // Maximum alignment that can be requested is that of QArrayData, - // otherwise, we can't use reallocate(). - Q_ASSERT(alignment <= 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, alignof(QArrayData)); int capacity = 10; Deallocator keeper(objectSize, minAlignment); - QArrayData *data = QArrayData::allocate(objectSize, minAlignment, capacity, - QArrayData::AllocationOptions(allocateOptions) & ~QArrayData::Grow); + QArrayData *data; + void *dataPointer = QArrayData::allocate(&data, objectSize, minAlignment, capacity, + QArrayData::ArrayOptions(allocateOptions) & ~QArrayData::GrowsForward); keeper.headers.append(data); - memset(data->data(), 'A', objectSize * capacity); - data->size = capacity; + memset(dataPointer, 'A', objectSize * capacity); // now try to reallocate int newCapacity = 40; - data = QArrayData::reallocateUnaligned(data, objectSize, newCapacity, - QArrayData::AllocationOptions(allocateOptions)); + auto pair = QArrayData::reallocateUnaligned(data, dataPointer, objectSize, newCapacity, + QArrayData::ArrayOptions(allocateOptions)); + data = pair.first; + dataPointer = pair.second; QVERIFY(data); keeper.headers.clear(); keeper.headers.append(data); - QCOMPARE(data->size, capacity); - if (allocateOptions & QArrayData::Grow) - QVERIFY(data->alloc > uint(newCapacity)); + if (allocateOptions & QArrayData::GrowsForward) + QVERIFY(data->allocatedCapacity() > size_t(newCapacity)); else - QCOMPARE(data->alloc, uint(newCapacity)); - QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); + QCOMPARE(data->allocatedCapacity(), size_t(newCapacity)); + QCOMPARE(!(data->flags & QArrayData::CapacityReserved), !isCapacityReserved); for (int i = 0; i < capacity; ++i) - QCOMPARE(static_cast<char *>(data->data())[i], 'A'); + QCOMPARE(static_cast<char *>(dataPointer)[i], 'A'); } class Unaligned @@ -680,89 +650,46 @@ void tst_QArrayData::alignment() keeper.headers.reserve(100); for (int i = 0; i < 100; ++i) { - QArrayData *data = QArrayData::allocate(sizeof(Unaligned), - minAlignment, 8, QArrayData::Default); + QArrayData *data; + void *dataPointer = QArrayData::allocate(&data, sizeof(Unaligned), + minAlignment, 8, QArrayData::DefaultAllocationFlags); keeper.headers.append(data); QVERIFY(data); - QCOMPARE(data->size, 0); - QVERIFY(data->alloc >= uint(8)); + QVERIFY(data->allocatedCapacity() >= uint(8)); // These conditions should hold as long as header and array are // allocated together - QVERIFY(data->offset >= qptrdiff(sizeof(QArrayData))); - QVERIFY(data->offset <= qptrdiff(sizeof(QArrayData) + qptrdiff offset = reinterpret_cast<char *>(dataPointer) - + reinterpret_cast<char *>(data); + QVERIFY(offset >= qptrdiff(sizeof(QArrayData))); + QVERIFY(offset <= qptrdiff(sizeof(QArrayData) + minAlignment - alignof(QArrayData))); // Data is aligned - QCOMPARE(quintptr(quintptr(data->data()) % alignment), quintptr(0u)); + QCOMPARE(quintptr(quintptr(dataPointer) % alignment), quintptr(0u)); // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. - ::memset(data->data(), 'A', sizeof(Unaligned) * 8); + ::memset(dataPointer, 'A', sizeof(Unaligned) * 8); } } void tst_QArrayData::typedData() { - QStaticArrayData<int, 10> data = { - Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10), - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } - }; - QCOMPARE(data.header.size, 10); - - { - QTypedArrayData<int> *array = - static_cast<QTypedArrayData<int> *>(&data.header); - QCOMPARE(array->data(), data.data); - - int j = 0; - for (QTypedArrayData<int>::iterator iter = array->begin(); - iter != array->end(); ++iter, ++j) - QCOMPARE((const int *)iter, data.data + j); - QCOMPARE(j, 10); - } - - { - const QTypedArrayData<int> *array = - static_cast<const QTypedArrayData<int> *>(&data.header); - - QCOMPARE(array->data(), data.data); - - int j = 0; - for (QTypedArrayData<int>::const_iterator iter = array->begin(); - iter != array->end(); ++iter, ++j) - QCOMPARE((const int *)iter, data.data + j); - QCOMPARE(j, 10); - } - - { - QTypedArrayData<int> *null = QTypedArrayData<int>::sharedNull(); - QTypedArrayData<int> *empty = QTypedArrayData<int>::allocate(0); - - QVERIFY(null != empty); - - QCOMPARE(null->size, 0); - QCOMPARE(empty->size, 0); - - QCOMPARE(null->begin(), null->end()); - QCOMPARE(empty->begin(), empty->end()); - } - - { Deallocator keeper(sizeof(char), alignof(QTypedArrayData<char>::AlignmentDummy)); - QArrayData *array = QTypedArrayData<char>::allocate(10); + QPair<QTypedArrayData<char> *, char *> pair = QTypedArrayData<char>::allocate(10); + QArrayData *array = pair.first; keeper.headers.append(array); QVERIFY(array); - QCOMPARE(array->size, 0); - QCOMPARE(array->alloc, 10u); + QCOMPARE(array->allocatedCapacity(), size_t(10)); // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. - ::memset(array->data(), 0, 10 * sizeof(char)); + ::memset(pair.second, 0, 10 * sizeof(char)); keeper.headers.clear(); QTypedArrayData<short>::deallocate(array); @@ -773,16 +700,16 @@ void tst_QArrayData::typedData() { Deallocator keeper(sizeof(short), alignof(QTypedArrayData<short>::AlignmentDummy)); - QArrayData *array = QTypedArrayData<short>::allocate(10); + QPair<QTypedArrayData<short> *, short *> pair = QTypedArrayData<short>::allocate(10); + QArrayData *array = pair.first; keeper.headers.append(array); QVERIFY(array); - QCOMPARE(array->size, 0); - QCOMPARE(array->alloc, 10u); + QCOMPARE(array->allocatedCapacity(), size_t(10)); // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. - ::memset(array->data(), 0, 10 * sizeof(short)); + ::memset(pair.second, 0, 10 * sizeof(short)); keeper.headers.clear(); QTypedArrayData<short>::deallocate(array); @@ -793,16 +720,16 @@ void tst_QArrayData::typedData() { Deallocator keeper(sizeof(double), alignof(QTypedArrayData<double>::AlignmentDummy)); - QArrayData *array = QTypedArrayData<double>::allocate(10); + QPair<QTypedArrayData<double> *, double *> pair = QTypedArrayData<double>::allocate(10); + QArrayData *array = pair.first; keeper.headers.append(array); QVERIFY(array); - QCOMPARE(array->size, 0); - QCOMPARE(array->alloc, 10u); + QCOMPARE(array->allocatedCapacity(), size_t(10)); // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. - ::memset(array->data(), 0, 10 * sizeof(double)); + ::memset(pair.second, 0, 10 * sizeof(double)); keeper.headers.clear(); QTypedArrayData<double>::deallocate(array); @@ -1253,7 +1180,7 @@ void fromRawData_impl() { // Default: Immutable, sharable SimpleVector<T> raw = SimpleVector<T>::fromRawData(array, - sizeof(array)/sizeof(array[0]), QArrayData::Default); + sizeof(array)/sizeof(array[0]), QArrayData::DefaultRawFlags); QCOMPARE(raw.size(), size_t(11)); QCOMPARE((const T *)raw.constBegin(), array); @@ -1298,17 +1225,17 @@ void tst_QArrayData::literals() { { QArrayDataPointer<char> d = Q_ARRAY_LITERAL(char, "ABCDEFGHIJ"); - QCOMPARE(d->size, 10 + 1); + QCOMPARE(d.size, 10u + 1u); for (int i = 0; i < 10; ++i) - QCOMPARE(d->data()[i], char('A' + i)); + QCOMPARE(d.data()[i], char('A' + i)); } { // wchar_t is not necessarily 2-bytes QArrayDataPointer<wchar_t> d = Q_ARRAY_LITERAL(wchar_t, L"ABCDEFGHIJ"); - QCOMPARE(d->size, 10 + 1); + QCOMPARE(d.size, 10u + 1u); for (int i = 0; i < 10; ++i) - QCOMPARE(d->data()[i], wchar_t('A' + i)); + QCOMPARE(d.data()[i], wchar_t('A' + i)); } { @@ -1346,26 +1273,26 @@ void tst_QArrayData::variadicLiterals() { QArrayDataPointer<int> d = Q_ARRAY_LITERAL(int, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); - QCOMPARE(d->size, 10); + QCOMPARE(d.size, 10u); for (int i = 0; i < 10; ++i) - QCOMPARE(d->data()[i], i); + QCOMPARE(d.data()[i], i); } { QArrayDataPointer<char> d = Q_ARRAY_LITERAL(char, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'); - QCOMPARE(d->size, 10); + QCOMPARE(d.size, 10u); for (int i = 0; i < 10; ++i) - QCOMPARE(d->data()[i], char('A' + i)); + QCOMPARE(d.data()[i], char('A' + i)); } { QArrayDataPointer<const char *> d = Q_ARRAY_LITERAL(const char *, "A", "B", "C", "D", "E", "F", "G", "H", "I", "J"); - QCOMPARE(d->size, 10); + QCOMPARE(d.size, 10u); for (int i = 0; i < 10; ++i) { - QCOMPARE(d->data()[i][0], char('A' + i)); - QCOMPARE(d->data()[i][1], '\0'); + QCOMPARE(d.data()[i][0], char('A' + i)); + QCOMPARE(d.data()[i][1], '\0'); } } diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp index 9a7c099228..b2c7915aa0 100644 --- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp +++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp @@ -86,6 +86,9 @@ private slots: void resize(); void fromBits_data(); void fromBits(); + + void toUInt32_data(); + void toUInt32(); }; void tst_QBitArray::size_data() @@ -667,5 +670,95 @@ void tst_QBitArray::fromBits() QCOMPARE(QBitArray::fromBits(fromBits.bits(), fromBits.size()), expected); } +void tst_QBitArray::toUInt32_data() +{ + QTest::addColumn<QBitArray>("data"); + QTest::addColumn<int>("endianness"); + QTest::addColumn<bool>("check"); + QTest::addColumn<quint32>("result"); + + QTest::newRow("ctor") << QBitArray() + << static_cast<int>(QSysInfo::Endian::LittleEndian) + << true + << quint32(0); + + QTest::newRow("empty") << QBitArray(0) + << static_cast<int>(QSysInfo::Endian::LittleEndian) + << true + << quint32(0); + + QTest::newRow("LittleEndian4") << QStringToQBitArray(QString("0111")) + << static_cast<int>(QSysInfo::Endian::LittleEndian) + << true + << quint32(14); + + QTest::newRow("BigEndian4") << QStringToQBitArray(QString("0111")) + << static_cast<int>(QSysInfo::Endian::BigEndian) + << true + << quint32(7); + + QTest::newRow("LittleEndian8") << QStringToQBitArray(QString("01111111")) + << static_cast<int>(QSysInfo::Endian::LittleEndian) + << true + << quint32(254); + + QTest::newRow("BigEndian8") << QStringToQBitArray(QString("01111111")) + << static_cast<int>(QSysInfo::Endian::BigEndian) + << true + << quint32(127); + + QTest::newRow("LittleEndian16") << QStringToQBitArray(QString("0111111111111111")) + << static_cast<int>(QSysInfo::Endian::LittleEndian) + << true + << quint32(65534); + + QTest::newRow("BigEndian16") << QStringToQBitArray(QString("0111111111111111")) + << static_cast<int>(QSysInfo::Endian::BigEndian) + << true + << quint32(32767); + + QTest::newRow("LittleEndian31") << QBitArray(31, true) + << static_cast<int>(QSysInfo::Endian::LittleEndian) + << true + << quint32(2147483647); + + QTest::newRow("BigEndian31") << QBitArray(31, true) + << static_cast<int>(QSysInfo::Endian::BigEndian) + << true + << quint32(2147483647); + + QTest::newRow("LittleEndian32") << QBitArray(32, true) + << static_cast<int>(QSysInfo::Endian::LittleEndian) + << true + << quint32(4294967295); + + QTest::newRow("BigEndian32") << QBitArray(32, true) + << static_cast<int>(QSysInfo::Endian::BigEndian) + << true + << quint32(4294967295); + + QTest::newRow("LittleEndian33") << QBitArray(33, true) + << static_cast<int>(QSysInfo::Endian::LittleEndian) + << false + << quint32(0); + + QTest::newRow("BigEndian33") << QBitArray(33, true) + << static_cast<int>(QSysInfo::Endian::BigEndian) + << false + << quint32(0); +} + +void tst_QBitArray::toUInt32() +{ + QFETCH(QBitArray, data); + QFETCH(int, endianness); + QFETCH(bool, check); + QFETCH(quint32, result); + bool ok = false; + + QCOMPARE(data.toUInt32(static_cast<QSysInfo::Endian>(endianness), &ok), result); + QCOMPARE(ok, check); +} + QTEST_APPLESS_MAIN(tst_QBitArray) #include "tst_qbitarray.moc" diff --git a/tests/auto/corelib/tools/qflatmap/qflatmap.pro b/tests/auto/corelib/tools/qflatmap/qflatmap.pro new file mode 100644 index 0000000000..3927cee30c --- /dev/null +++ b/tests/auto/corelib/tools/qflatmap/qflatmap.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qflatmap +QT = core-private testlib +SOURCES = tst_qflatmap.cpp diff --git a/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp b/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp new file mode 100644 index 0000000000..a5ae6f5f44 --- /dev/null +++ b/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp @@ -0,0 +1,453 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 <QtTest/QtTest> + +#include <private/qflatmap_p.h> +#include <qbytearray.h> +#include <qstring.h> +#include <qstringview.h> +#include <qvarlengtharray.h> +#include <qvector.h> + +#include <algorithm> +#include <list> +#include <tuple> + +class tst_QFlatMap : public QObject +{ + Q_OBJECT +private slots: + void constructing(); + void constAccess(); + void insertion(); + void removal(); + void extraction(); + void iterators(); + void statefulComparator(); + void transparency(); + void viewIterators(); + void varLengthArray(); +}; + +void tst_QFlatMap::constructing() +{ + using Map = QFlatMap<int, QByteArray>; + Map fmDefault; + QVERIFY(fmDefault.isEmpty()); + QCOMPARE(fmDefault.size(), Map::size_type(0)); + QCOMPARE(fmDefault.size(), fmDefault.count()); + + auto key_compare = fmDefault.key_comp(); + auto selfbuilt_value_compare + = [&key_compare](const Map::value_type &a, const Map::value_type &b) + { + return key_compare(a.first, b.first); + }; + auto value_compare = fmDefault.value_comp(); + + Map::key_container_type kv = { 6, 2, 1 }; + Map::mapped_container_type mv = { "foo", "bar", "baz" }; + Map fmCopy{kv, mv}; + QCOMPARE(fmCopy.size(), Map::size_type(3)); + QVERIFY(std::is_sorted(fmCopy.begin(), fmCopy.end(), selfbuilt_value_compare)); + QVERIFY(std::is_sorted(fmCopy.begin(), fmCopy.end(), value_compare)); + + Map fmMove{ + Map::key_container_type{ 6, 2, 1 }, + Map::mapped_container_type{ "foo", "bar", "baz" } + }; + QCOMPARE(fmMove.size(), Map::size_type(3)); + QVERIFY(std::is_sorted(fmMove.begin(), fmMove.end(), value_compare)); + + auto fmInitList = Map{ { 1, 2 }, { "foo", "bar" } }; + QVERIFY(std::is_sorted(fmInitList.begin(), fmInitList.end(), value_compare)); + + auto fmRange = Map(fmCopy.begin(), fmCopy.end()); + QVERIFY(std::is_sorted(fmRange.begin(), fmRange.end(), value_compare)); + + kv.clear(); + mv.clear(); + std::vector<Map::value_type> sv; + for (auto it = fmRange.begin(); it != fmRange.end(); ++it) { + kv.push_back(it->first); + mv.push_back(it->second); + sv.push_back(*it); + } + auto fmFromSortedVectorCopy = Map(Qt::OrderedUniqueRange, kv, mv); + auto fmFromSortedVectorMove = Map(Qt::OrderedUniqueRange, Map::key_container_type(kv), + Map::mapped_container_type(mv)); + auto fmFromSortedInitList = Map(Qt::OrderedUniqueRange, { { 1, "foo" }, { 2, "bar" } }); + auto fmFromSortedRange = Map(Qt::OrderedUniqueRange, sv.begin(), sv.end()); +} + +void tst_QFlatMap::constAccess() +{ + using Map = QFlatMap<QByteArray, QByteArray>; + const Map m{ { { "foo", "FOO" }, { "bar", "BAR" } } }; + + const std::vector<Map::value_type> v{ { "foo", "FOO" }, { "bar", "BAR" } }; + + QCOMPARE(m.value("foo").data(), "FOO"); + QCOMPARE(m.value("bar").data(), "BAR"); + QCOMPARE(m.value("nix"), QByteArray()); + QCOMPARE(m.value("nix", "NIX").data(), "NIX"); + QCOMPARE(m["foo"].data(), "FOO"); + QCOMPARE(m["bar"].data(), "BAR"); + QCOMPARE(m["nix"], QByteArray()); + QVERIFY(m.contains("foo")); + QVERIFY(!m.contains("nix")); +} + +void tst_QFlatMap::insertion() +{ + using Map = QFlatMap<QByteArray, QByteArray>; + Map m; + QByteArray foo = "foo"; + m[foo] = foo.toUpper(); + m["bar"] = "BAR"; + m["baz"] = "BAZ"; + QVERIFY(m.insert("oof", "eek").second); + QVERIFY(!m.insert("oof", "OOF").second); + const std::vector<Map::value_type> container = { { "bla", "BLA" }, { "blubb", "BLUBB" } }; + m.insert(container.begin(), container.end()); + QCOMPARE(m.value("foo").data(), "FOO"); + QCOMPARE(m.value("bar").data(), "BAR"); + QCOMPARE(m.value("baz").data(), "BAZ"); + QCOMPARE(m.value("oof").data(), "OOF"); + QCOMPARE(m.value("bla").data(), "BLA"); + QCOMPARE(m.value("blubb").data(), "BLUBB"); + + Map::value_type a1[] = { { "narf", "NARF" }, + { "zort", "ZORT" }, + { "troz", "TROZ" } }; + Map::value_type a2[] = { { "gnampf", "GNAMPF" }, + { "narf", "NARFFFF" }, + { "narf", "NARFFFFF" }, + { "narf", "NARFFFFFF" } }; + m.insert(std::begin(a1), std::end(a1)); + m.insert(Qt::OrderedUniqueRange, std::begin(a2), std::end(a2)); + QCOMPARE(m.size(), 10); + QCOMPARE(m.value("narf").data(), "NARFFFFFF"); + QCOMPARE(m.value("gnampf").data(), "GNAMPF"); +} + +void tst_QFlatMap::extraction() +{ + using Map = QFlatMap<int, QByteArray>; + Map::key_container_type expectedKeys = { 1, 2, 3 }; + Map::mapped_container_type expectedValues = { "een", "twee", "dree" }; + Map m(expectedKeys, expectedValues); + auto keys = m.keys(); + auto values = m.values(); + QCOMPARE(keys, expectedKeys); + QCOMPARE(values, expectedValues); + Map::containers c = std::move(m).extract(); + QCOMPARE(c.keys, expectedKeys); + QCOMPARE(c.values, expectedValues); +} + +void tst_QFlatMap::iterators() +{ + using Map = QFlatMap<int, QByteArray>; + auto m = Map{ { 1, "foo" }, { 2, "bar" }, { 3, "baz" } }; + { + // forward / backward + Map::iterator a = m.begin(); + QVERIFY(a != m.end()); + QCOMPARE(a.key(), 1); + QCOMPARE(a.value(), "foo"); + ++a; + QCOMPARE(a.key(), 2); + QCOMPARE(a.value(), "bar"); + Map::iterator b = a++; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz")); + QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(2, "bar")); + QCOMPARE(++a, m.end()); + --a; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz")); + a.value() = "buzz"; + b = a--; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar")); + QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(3, "buzz")); + b.value() = "baz"; + + // random access + a = m.begin(); + a += 2; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz")); + a = m.begin() + 1; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar")); + a = 1 + m.begin(); + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar")); + a = m.end() - 1; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz")); + b = m.end(); + b -= 1; + QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(3, "baz")); + QCOMPARE(m.end() - m.begin(), m.size()); + + // comparison + a = m.begin() + m.size() - 1; + b = m.end() - 1; + QVERIFY(a == b); + a = m.begin(); + b = m.end(); + QVERIFY(a < b); + QVERIFY(a <= b); + QVERIFY(b > a); + QVERIFY(b >= a); + a = b; + QVERIFY(!(a < b)); + QVERIFY(a <= b); + QVERIFY(!(b > a)); + QVERIFY(b >= a); + + // de-referencing + a = m.begin(); + auto ref0 = *a; + QCOMPARE(ref0.first, 1); + QCOMPARE(ref0.second, "foo"); + auto ref1 = a[1]; + QCOMPARE(ref1.first, 2); + QCOMPARE(ref1.second, "bar"); + } + { + // forward / backward + Map::const_iterator a = m.cbegin(); + QVERIFY(a != m.cend()); + QCOMPARE(a.key(), 1); + QCOMPARE(a.value(), "foo"); + ++a; + QCOMPARE(a.key(), 2); + QCOMPARE(a.value(), "bar"); + Map::const_iterator b = a++; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz")); + QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(2, "bar")); + QCOMPARE(++a, m.cend()); + --a; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz")); + b = a--; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar")); + + // random access + a = m.cbegin(); + a += 2; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz")); + a = m.cbegin() + 1; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar")); + a = 1 + m.cbegin(); + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar")); + a = m.cend() - 1; + QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz")); + b = m.cend(); + b -= 1; + QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(3, "baz")); + QCOMPARE(m.cend() - m.cbegin(), m.size()); + + // comparison + a = m.cbegin() + m.size() - 1; + b = m.cend() - 1; + QVERIFY(a == b); + a = m.cbegin(); + b = m.cend(); + QVERIFY(a < b); + QVERIFY(a <= b); + QVERIFY(b > a); + QVERIFY(b >= a); + a = b; + QVERIFY(!(a < b)); + QVERIFY(a <= b); + QVERIFY(!(b > a)); + QVERIFY(b >= a); + + // de-referencing + a = m.cbegin(); + auto ref0 = *a; + QCOMPARE(ref0.first, 1); + QCOMPARE(ref0.second, "foo"); + auto ref1 = a[1]; + QCOMPARE(ref1.first, 2); + QCOMPARE(ref1.second, "bar"); + } + { + Map::iterator it = m.begin(); + Map::const_iterator cit = it; + Q_UNUSED(it); + Q_UNUSED(cit); + } + { + std::list<Map::value_type> revlst; + std::copy(m.begin(), m.end(), std::front_inserter(revlst)); + std::vector<Map::value_type> v0; + std::copy(revlst.begin(), revlst.end(), std::back_inserter(v0)); + std::vector<Map::value_type> v1; + std::copy(m.rbegin(), m.rend(), std::back_inserter(v1)); + const Map cm = m; + std::vector<Map::value_type> v2; + std::copy(cm.rbegin(), cm.rend(), std::back_inserter(v2)); + std::vector<Map::value_type> v3; + std::copy(m.crbegin(), m.crend(), std::back_inserter(v3)); + QCOMPARE(v0, v1); + QCOMPARE(v1, v2); + QCOMPARE(v2, v3); + } +} + +void tst_QFlatMap::removal() +{ + using Map = QFlatMap<int, QByteArray>; + Map m({ { 2, "bar" }, { 3, "baz" }, { 1, "foo" } }); + QCOMPARE(m.value(2).data(), "bar"); + QCOMPARE(m.take(2).data(), "bar"); + QVERIFY(!m.contains(2)); + QCOMPARE(m.size(), Map::size_type(2)); + QVERIFY(m.remove(1)); + QVERIFY(!m.contains(1)); + QVERIFY(!m.remove(1)); + QCOMPARE(m.size(), Map::size_type(1)); + m.clear(); + QVERIFY(m.isEmpty()); + QVERIFY(m.empty()); + + m[1] = "een"; + m[2] = "twee"; + m[3] = "dree"; + auto it = m.lower_bound(1); + QCOMPARE(it.key(), 1); + it = m.erase(it); + QCOMPARE(it.key(), 2); + QVERIFY(!m.contains(1)); +} + +void tst_QFlatMap::statefulComparator() +{ + struct CountingCompare { + mutable int count = 0; + + bool operator()(const QString &lhs, const QString &rhs) const + { + ++count; + return lhs < rhs; + } + }; + + using Map = QFlatMap<QString, QString, CountingCompare>; + auto m1 = Map{ { "en", "een"}, { "to", "twee" }, { "tre", "dree" } }; + QVERIFY(m1.key_comp().count > 0); + auto m2 = Map(m1.key_comp()); + QCOMPARE(m2.key_comp().count, m1.key_comp().count); + m2.insert(m1.begin(), m1.end()); + QVERIFY(m2.key_comp().count > m1.key_comp().count); +} + +void tst_QFlatMap::transparency() +{ + struct StringViewCompare + { + using is_transparent = void; + bool operator()(const QStringView &lhs, const QStringView &rhs) const + { + return lhs < rhs; + } + }; + + using Map = QFlatMap<QString, QString, StringViewCompare>; + auto m = Map{ { "one", "een" }, { "two", "twee" }, { "three", "dree" } }; + + const QString numbers = "one two three"; + const QStringView sv1{numbers.constData(), 3}; + const QStringView sv2{numbers.constData() + 4, 3}; + const QStringView sv3{numbers.constData() + 8, 5}; + QCOMPARE(m.lower_bound(sv1).value(), "een"); + QCOMPARE(m.lower_bound(sv2).value(), "twee"); + QCOMPARE(m.lower_bound(sv3).value(), "dree"); +} + +void tst_QFlatMap::viewIterators() +{ + using Map = QFlatMap<QByteArray, QByteArray>; + Map m({ { "yksi", "een"}, { "kaksi", "twee" }, { "kolme", "dree" } }); + { + std::vector<QByteArray> keys; + std::transform(m.begin(), m.end(), std::back_inserter(keys), + [](const Map::value_type &v) + { + return v.first; + }); + auto it = keys.begin(); + QCOMPARE(*it, "kaksi"); + QCOMPARE(it->length(), 5); + ++it; + QCOMPARE(*it, "kolme"); + it++; + QCOMPARE(*it, "yksi"); + ++it; + QCOMPARE(it, keys.end()); + --it; + QCOMPARE(*it, "yksi"); + it--; + QCOMPARE(*it, "kolme"); + } + { + std::vector<QByteArray> values; + std::transform(m.begin(), m.end(), std::back_inserter(values), + [](const Map::value_type &v) + { + return v.second; + }); + auto it = values.begin(); + QCOMPARE(*it, "twee"); + QCOMPARE(it->length(), 4); + ++it; + QCOMPARE(*it, "dree"); + it++; + QCOMPARE(*it, "een"); + ++it; + QCOMPARE(it, values.end()); + --it; + QCOMPARE(*it, "een"); + it--; + QCOMPARE(*it, "dree"); + } +} + +void tst_QFlatMap::varLengthArray() +{ + using Map = QFlatMap<int, QByteArray, std::less<int>, + QVarLengthArray<int, 1024>, QVarLengthArray<QByteArray, 1024>>; + Map m{ { 2, "twee" } }; + m.insert(1, "een"); + m.remove(1); + QVERIFY(!m.isEmpty()); + m.remove(2); + QVERIFY(m.isEmpty()); +} + +QTEST_APPLESS_MAIN(tst_QFlatMap) +#include "tst_qflatmap.moc" diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index f0eeb70ccb..91cd3eb0bd 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -69,6 +69,7 @@ private slots: void initializerList(); void eraseValidIteratorOnSharedHash(); void equal_range(); + void insert_hash(); }; struct IdentityTracker { @@ -1636,5 +1637,77 @@ void tst_QHash::equal_range() } } +void tst_QHash::insert_hash() +{ + { + QHash<int, int> hash; + hash.insert(1, 1); + hash.insert(2, 2); + hash.insert(0, -1); + + QHash<int, int> hash2; + hash2.insert(0, 0); + hash2.insert(3, 3); + hash2.insert(4, 4); + + hash.insert(hash2); + + QCOMPARE(hash.count(), 5); + for (int i = 0; i < 5; ++i) + QCOMPARE(hash[i], i); + } + { + QHash<int, int> hash; + hash.insert(0, 5); + + QHash<int, int> hash2; + + hash.insert(hash2); + + QCOMPARE(hash.count(), 1); + QCOMPARE(hash[0], 5); + } + { + QHash<int, int> hash; + QHash<int, int> hash2; + hash2.insert(0, 5); + + hash.insert(hash2); + + QCOMPARE(hash.count(), 1); + QCOMPARE(hash[0], 5); + QCOMPARE(hash, hash2); + } + { + QHash<int, int> hash; + hash.insert(0, 7); + hash.insert(2, 5); + hash.insert(7, 55); + + // insert into ourself, nothing should happen + hash.insert(hash); + + QCOMPARE(hash.count(), 3); + QCOMPARE(hash[0], 7); + QCOMPARE(hash[2], 5); + QCOMPARE(hash[7], 55); + } + { + // This will use a QMultiHash and then insert that into QHash, + // the ordering is undefined so we won't test that but make + // sure this isn't adding multiple entries with the same key + // to the QHash. + QHash<int, int> hash; + QMultiHash<int, int> hash2; + hash2.insert(0, 5); + hash2.insert(0, 6); + hash2.insert(0, 7); + + hash.insert(hash2); + + QCOMPARE(hash.count(), 1); + } +} + QTEST_APPLESS_MAIN(tst_QHash) #include "tst_qhash.moc" diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index 85733639b8..1638ebc992 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -70,6 +70,7 @@ private slots: void equal_range(); void insert(); + void insertMap(); void checkMostLeftNode(); void initializerList(); void testInsertWithHint(); @@ -1202,6 +1203,101 @@ void tst_QMap::insert() } } +void tst_QMap::insertMap() +{ + { + QMap<int, int> map; + map.insert(1, 1); + map.insert(2, 2); + map.insert(0, -1); + + QMap<int, int> map2; + map2.insert(0, 0); + map2.insert(3, 3); + map2.insert(4, 4); + + map.insert(map2); + + QCOMPARE(map.count(), 5); + for (int i = 0; i < 5; ++i) + QCOMPARE(map[i], i); + } + { + QMap<int, int> map; + for (int i = 0; i < 10; ++i) + map.insert(i * 3, i); + + QMap<int, int> map2; + for (int i = 0; i < 10; ++i) + map2.insert(i * 4, i); + + map.insert(map2); + + QCOMPARE(map.count(), 17); + for (int i = 0; i < 10; ++i) { + // i * 3 == i except for i = 4, 8 + QCOMPARE(map[i * 3], (i && i % 4 == 0) ? i - (i / 4) : i); + QCOMPARE(map[i * 4], i); + } + + auto it = map.cbegin(); + int prev = it.key(); + ++it; + for (auto end = map.cend(); it != end; ++it) { + QVERIFY(prev < it.key()); + prev = it.key(); + } + } + { + QMap<int, int> map; + map.insert(1, 1); + + QMap<int, int> map2; + + map.insert(map2); + QCOMPARE(map.count(), 1); + QCOMPARE(map[1], 1); + } + { + QMap<int, int> map; + QMap<int, int> map2; + map2.insert(1, 1); + + map.insert(map2); + QCOMPARE(map.count(), 1); + QCOMPARE(map[1], 1); + } + { + QMap<int, int> map; + map.insert(0, 0); + map.insert(1, 1); + map.insert(2, 2); + + // Test inserting into self, nothing should happen + map.insert(map); + + QCOMPARE(map.count(), 3); + for (int i = 0; i < 3; ++i) + QCOMPARE(map[i], i); + } + { + // Here we use a QMultiMap and insert that into QMap, + // since it has multiple values with the same key the + // ordering is undefined so we won't test that, but + // make sure this isn't adding multiple entries with the + // same key to the QMap. + QMap<int, int> map; + QMultiMap<int, int> map2; + map2.insert(0, 0); + map2.insert(0, 1); + map2.insert(0, 2); + + map.insert(map2); + + QCOMPARE(map.count(), 1); + } +} + void tst_QMap::checkMostLeftNode() { QMap<int, int> map; diff --git a/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp index f95d48f042..01181ce20e 100644 --- a/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp +++ b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp @@ -67,7 +67,7 @@ void tst_QScopedGuard::exceptions() bool caught = false; QT_TRY { - auto cleanup = qScopeGuard([&caught] { s_globalState++; }); + auto cleanup = qScopeGuard([] { s_globalState++; }); QT_THROW(std::bad_alloc()); //if Qt compiled without exceptions this is noop s_globalState = 100; } diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 0af83c7463..7a69e844d4 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -104,7 +104,7 @@ private: static void check(const State state1, const State state2) { - QCOMPARE(state1, state2); + QCOMPARE(int(state1), int(state2)); } }; @@ -174,7 +174,7 @@ private: { // check if c object has been moved QCOMPARE(c, c->that); - QCOMPARE(c->state, Constructed); + QCOMPARE(int(c->state), int(Constructed)); } }; QAtomicInt Custom::counter = 0; @@ -307,8 +307,6 @@ private slots: void reserve(); void reserveZero(); - void reallocAfterCopy_data(); - void reallocAfterCopy(); void initializeListInt(); void initializeListMovable(); void initializeListCustom(); @@ -726,16 +724,12 @@ void tst_QVector::capacity() const myvec.remove(3); myvec.remove(3); myvec.remove(3); - // TODO: is this a safe assumption? presumably it won't release memory until shrink(), but can we asser that is true? - QVERIFY(myvec.capacity() >= 6); myvec.squeeze(); QVERIFY(myvec.capacity() >= 3); myvec.remove(0); myvec.remove(0); myvec.remove(0); - // TODO: as above note - QVERIFY(myvec.capacity() >= 3); myvec.squeeze(); QVERIFY(myvec.capacity() == 0); } @@ -2341,87 +2335,6 @@ void tst_QVector::reserveZero() QVERIFY(vec.capacity() >= 1); } -// This is a regression test for QTBUG-11763, where memory would be reallocated -// soon after copying a QVector. -void tst_QVector::reallocAfterCopy_data() -{ - QTest::addColumn<int>("capacity"); - QTest::addColumn<int>("fill_size"); - QTest::addColumn<int>("func_id"); - QTest::addColumn<int>("result1"); - QTest::addColumn<int>("result2"); - QTest::addColumn<int>("result3"); - QTest::addColumn<int>("result4"); - - int result1, result2, result3, result4; - int fill_size; - for (int i = 70; i <= 100; i += 10) { - const QByteArray prefix = "reallocAfterCopy:" + QByteArray::number(i) + ','; - fill_size = i - 20; - for (int j = 0; j <= 3; j++) { - if (j == 0) { // append - result1 = i; - result2 = i; - result3 = i - 19; - result4 = i - 20; - } else if (j == 1) { // insert(0) - result1 = i; - result2 = i; - result3 = i - 19; - result4 = i - 20; - } else if (j == 2) { // insert(20) - result1 = i; - result2 = i; - result3 = i - 19; - result4 = i - 20; - } else if (j == 3) { // insert(0, 10) - result1 = i; - result2 = i; - result3 = i - 10; - result4 = i - 20; - } - QTest::newRow((prefix + QByteArray::number(j)).constData()) - << i << fill_size << j << result1 << result2 << result3 << result4; - } - } -} - -void tst_QVector::reallocAfterCopy() -{ - QFETCH(int, capacity); - QFETCH(int, fill_size); - QFETCH(int, func_id); - QFETCH(int, result1); - QFETCH(int, result2); - QFETCH(int, result3); - QFETCH(int, result4); - - QVector<qreal> v1; - QVector<qreal> v2; - - v1.reserve(capacity); - v1.resize(0); - v1.fill(qreal(1.0), fill_size); - - v2 = v1; - - // no need to test begin() and end(), there is a detach() in them - if (func_id == 0) { - v1.append(qreal(1.0)); //push_back is same as append - } else if (func_id == 1) { - v1.insert(0, qreal(1.0)); //push_front is same as prepend, insert(0) - } else if (func_id == 2) { - v1.insert(20, qreal(1.0)); - } else if (func_id == 3) { - v1.insert(0, 10, qreal(1.0)); - } - - QCOMPARE(v1.capacity(), result1); - QCOMPARE(v2.capacity(), result2); - QCOMPARE(v1.size(), result3); - QCOMPARE(v2.size(), result4); -} - template<typename T> void tst_QVector::initializeList() { diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro index 5a7c8478f1..be195ea037 100644 --- a/tests/auto/corelib/tools/tools.pro +++ b/tests/auto/corelib/tools/tools.pro @@ -11,6 +11,7 @@ SUBDIRS=\ qcryptographichash \ qeasingcurve \ qexplicitlyshareddatapointer \ + qflatmap \ qfreelist \ qhash \ qhashfunctions \ |