diff options
author | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-02-17 17:51:49 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2016-02-17 19:57:54 +0000 |
commit | 86c5a337e3b123f2e41c8b15b416f39655519acd (patch) | |
tree | efa0f720a190889b3d31ddbd07cee0495b8a15d4 /tests/auto | |
parent | 47ca3f78139ad51a5018dcdad27fa5caf817f08d (diff) | |
parent | 6620045fcaada61a2897195f32c0ee35beebc37b (diff) |
Merge "Merge dev into 5.7" into refs/staging/5.7
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp | 29 | ||||
-rw-r--r-- | tests/auto/corelib/global/qglobal/tst_qglobal.cpp | 122 | ||||
-rw-r--r-- | tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp | 11 | ||||
-rw-r--r-- | tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp | 5 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 97 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qhash/tst_qhash.cpp | 108 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qrect/tst_qrect.cpp | 38 | ||||
-rw-r--r-- | tests/auto/gui/image/qicon/tst_qicon.cpp | 4 | ||||
-rw-r--r-- | tests/auto/gui/painting/qregion/tst_qregion.cpp | 23 |
9 files changed, 435 insertions, 2 deletions
diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp index d9ea8ef71b..1b0ac7a8bc 100644 --- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -43,6 +43,7 @@ private slots: void memberFunctions(); void implicitConvertibleTypes(); void runWaitLoop(); + void pollForIsFinished(); void recursive(); #ifndef QT_NO_EXCEPTIONS void exceptions(); @@ -348,6 +349,34 @@ void tst_QtConcurrentRun::runWaitLoop() run(fn).waitForFinished(); } +static bool allFinished(const QList<QFuture<void> > &futures) +{ + auto hasNotFinished = [](const QFuture<void> &future) { return !future.isFinished(); }; + return std::find_if(futures.cbegin(), futures.cend(), hasNotFinished) + == futures.constEnd(); +} + +static void runFunction() +{ + QEventLoop loop; + QTimer::singleShot(20, &loop, &QEventLoop::quit); + loop.exec(); +} + +void tst_QtConcurrentRun::pollForIsFinished() +{ + const int numThreads = std::max(4, 2 * QThread::idealThreadCount()); + QThreadPool::globalInstance()->setMaxThreadCount(numThreads); + + QFutureSynchronizer<void> synchronizer; + for (int i = 0; i < numThreads; ++i) + synchronizer.addFuture(QtConcurrent::run(&runFunction)); + + // same as synchronizer.waitForFinished() but with a timeout + QTRY_VERIFY(allFinished(synchronizer.futures())); +} + + QAtomicInt count; void recursiveRun(int level) diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index d1a6e66203..152906287c 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -55,6 +55,7 @@ private slots: void qprintable(); void qprintable_data(); void buildAbiEndianness(); + void testqOverload(); }; void tst_QGlobal::qIsNull() @@ -652,5 +653,126 @@ void tst_QGlobal::buildAbiEndianness() QVERIFY(QSysInfo::buildAbi().contains(endian)); } +struct Overloaded +{ + void foo() {} + void foo(QByteArray) {} + void foo(QByteArray, const QString &) {} + + void constFoo() const {} + void constFoo(QByteArray) const {} + void constFoo(QByteArray, const QString &) const {} + + void mixedFoo() {} + void mixedFoo(QByteArray) const {} +}; + +void freeOverloaded() {} +void freeOverloaded(QByteArray) {} +void freeOverloaded(QByteArray, const QString &) {} + +void freeOverloadedGet(QByteArray) {} +QByteArray freeOverloadedGet() { return QByteArray(); } + + +void tst_QGlobal::testqOverload() +{ +#ifdef Q_COMPILER_VARIADIC_TEMPLATES + + // void returning free overloaded functions + QVERIFY(QOverload<>::of(&freeOverloaded) == + static_cast<void (*)()>(&freeOverloaded)); + + QVERIFY(QOverload<QByteArray>::of(&freeOverloaded) == + static_cast<void (*)(QByteArray)>(&freeOverloaded)); + + QVERIFY((QOverload<QByteArray, const QString &>::of(&freeOverloaded)) == + static_cast<void (*)(QByteArray, const QString &)>(&freeOverloaded)); + + // value returning free overloaded functions + QVERIFY(QOverload<>::of(&freeOverloadedGet) == + static_cast<QByteArray (*)()>(&freeOverloadedGet)); + + QVERIFY(QOverload<QByteArray>::of(&freeOverloadedGet) == + static_cast<void (*)(QByteArray)>(&freeOverloadedGet)); + + // void returning overloaded member functions + QVERIFY(QOverload<>::of(&Overloaded::foo) == + static_cast<void (Overloaded::*)()>(&Overloaded::foo)); + + QVERIFY(QOverload<QByteArray>::of(&Overloaded::foo) == + static_cast<void (Overloaded::*)(QByteArray)>(&Overloaded::foo)); + + QVERIFY((QOverload<QByteArray, const QString &>::of(&Overloaded::foo)) == + static_cast<void (Overloaded::*)(QByteArray, const QString &)>(&Overloaded::foo)); + + // void returning overloaded const member functions + QVERIFY(QOverload<>::of(&Overloaded::constFoo) == + static_cast<void (Overloaded::*)() const>(&Overloaded::constFoo)); + + QVERIFY(QOverload<QByteArray>::of(&Overloaded::constFoo) == + static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::constFoo)); + + QVERIFY((QOverload<QByteArray, const QString &>::of(&Overloaded::constFoo)) == + static_cast<void (Overloaded::*)(QByteArray, const QString &) const>(&Overloaded::constFoo)); + + // void returning overloaded const AND non-const member functions + QVERIFY(QNonConstOverload<>::of(&Overloaded::mixedFoo) == + static_cast<void (Overloaded::*)()>(&Overloaded::mixedFoo)); + + QVERIFY(QConstOverload<QByteArray>::of(&Overloaded::mixedFoo) == + static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo)); + +#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 // C++14 + + // void returning free overloaded functions + QVERIFY(qOverload<>(&freeOverloaded) == + static_cast<void (*)()>(&freeOverloaded)); + + QVERIFY(qOverload<QByteArray>(&freeOverloaded) == + static_cast<void (*)(QByteArray)>(&freeOverloaded)); + + QVERIFY((qOverload<QByteArray, const QString &>(&freeOverloaded)), + static_cast<void (*)(QByteArray, const QString &)>(&freeOverloaded)); + + // value returning free overloaded functions + QVERIFY(qOverload<>(&freeOverloadedGet) == + static_cast<QByteArray (*)()>(&freeOverloadedGet)); + + QVERIFY(qOverload<QByteArray>(&freeOverloadedGet) == + static_cast<void (*)(QByteArray)>(&freeOverloadedGet)); + + // void returning overloaded member functions + QVERIFY(qOverload<>(&Overloaded::foo) == + static_cast<void (Overloaded::*)()>(&Overloaded::foo)); + + QVERIFY(qOverload<QByteArray>(&Overloaded::foo) == + static_cast<void (Overloaded::*)(QByteArray)>(&Overloaded::foo)); + + QVERIFY((qOverload<QByteArray, const QString &>(&Overloaded::foo)) == + static_cast<void (Overloaded::*)(QByteArray, const QString &)>(&Overloaded::foo)); + + // void returning overloaded const member functions + QVERIFY(qOverload<>(&Overloaded::constFoo) == + static_cast<void (Overloaded::*)() const>(&Overloaded::constFoo)); + + QVERIFY(qOverload<QByteArray>(&Overloaded::constFoo) == + static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::constFoo)); + + QVERIFY((qOverload<QByteArray, const QString &>(&Overloaded::constFoo)) == + static_cast<void (Overloaded::*)(QByteArray, const QString &) const>(&Overloaded::constFoo)); + + // void returning overloaded const AND non-const member functions + QVERIFY(qNonConstOverload<>(&Overloaded::mixedFoo) == + static_cast<void (Overloaded::*)()>(&Overloaded::mixedFoo)); + + QVERIFY(qConstOverload<QByteArray>(&Overloaded::mixedFoo) == + static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo)); +#endif + +#endif +} + + QTEST_APPLESS_MAIN(tst_QGlobal) #include "tst_qglobal.moc" diff --git a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp index 4c5ca1a7bb..e5ede1ad06 100644 --- a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp +++ b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp @@ -55,6 +55,8 @@ private slots: void urlConvenience_data(); void urlConvenience(); + + void addStatics(); }; void tst_QFileSelector::basicTest_data() @@ -224,5 +226,14 @@ void tst_QFileSelector::urlConvenience() QCOMPARE(fs.select(testUrl), expectedUrl); } +void tst_QFileSelector::addStatics() +{ + QFileSelector fs; + QCOMPARE(fs.select(QStringLiteral(":/extras/test")), QStringLiteral(":/extras/test")); + + QFileSelectorPrivate::addStatics(QStringList() << QStringLiteral("custom1")); + QCOMPARE(fs.select(QStringLiteral(":/extras/test")), QStringLiteral(":/extras/+custom1/test")); +} + QTEST_MAIN(tst_QFileSelector) #include "tst_qfileselector.moc" diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index 72dedf8be7..53c64166c4 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -540,15 +540,16 @@ void tst_QTemporaryFile::keepOpenMode() { QTemporaryFile file; QVERIFY(file.open()); + QCOMPARE(file.openMode(), QIODevice::ReadWrite); QCOMPARE(file.write(data), (qint64)data.size()); QVERIFY(file.rename("temporary-file.txt")); QVERIFY(((QFile &)file).open(QIODevice::ReadOnly)); - QVERIFY(QIODevice::ReadOnly == file.openMode()); + QCOMPARE(file.openMode(), QIODevice::ReadOnly); QCOMPARE(file.readAll(), data); QVERIFY(((QFile &)file).open(QIODevice::WriteOnly)); - QVERIFY(QIODevice::WriteOnly == file.openMode()); + QCOMPARE(file.openMode(), QIODevice::WriteOnly); } } diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 0f45ba42aa..540284f0b1 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -142,6 +142,7 @@ private slots: void qmlConnect(); void exceptions(); void noDeclarativeParentChangedOnDestruction(); + void deleteLaterInAboutToBlockHandler(); }; struct QObjectCreatedOnShutdown @@ -5789,6 +5790,102 @@ void tst_QObject::connectFunctorWithContext() context->deleteLater(); } +class StatusChanger : public QObject +{ + Q_OBJECT +public: + StatusChanger(int *status) : m_status(status) + { + } + ~StatusChanger() + { + *m_status = 2; + } +private: + int *m_status; +}; + +class DispatcherWatcher : public QObject +{ + Q_OBJECT +public: + DispatcherWatcher(QEventLoop &e, int *statusAwake, int *statusAboutToBlock) : + m_statusAboutToBlock(statusAboutToBlock), + m_statusAwake(statusAwake), + m_eventLoop(&e), + m_aboutToBlocks(0), + m_awakes(0) + { + awake = new StatusChanger(statusAwake); + abouttoblock = new StatusChanger(statusAboutToBlock); + QCOMPARE(*statusAwake, 1); + QCOMPARE(*statusAboutToBlock, 1); + connect(QAbstractEventDispatcher::instance(), SIGNAL(awake()), this, SLOT(onAwake())); + connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(onAboutToBlock())); + + } + + ~DispatcherWatcher() + { + if (awake) + awake->deleteLater(); + if (abouttoblock) + abouttoblock->deleteLater(); + } + +public slots: + // The order of these 2 handlers differs on different event dispatchers + void onAboutToBlock() + { + if (abouttoblock) { + abouttoblock->deleteLater(); + abouttoblock = 0; + } + ++m_aboutToBlocks; + } + void onAwake() + { + if (awake) { + awake->deleteLater(); + awake = 0; + } + ++m_awakes; + + } + void onSignal1() + { + // Status check. At this point the event loop should have spinned enough to delete all the objects. + QCOMPARE(*m_statusAwake, 2); + QCOMPARE(*m_statusAboutToBlock, 2); + QMetaObject::invokeMethod(m_eventLoop, "quit", Qt::QueuedConnection); + } + +private: + StatusChanger *awake; + StatusChanger *abouttoblock; + QEventLoop *m_eventLoop; + int *m_statusAwake; + int *m_statusAboutToBlock; + int m_aboutToBlocks; + int m_awakes; +}; + + +void tst_QObject::deleteLaterInAboutToBlockHandler() +{ + int statusAwake = 1; + int statusAboutToBlock = 1; + QEventLoop e; + DispatcherWatcher dw(e, &statusAwake, &statusAboutToBlock); + QTimer::singleShot(2000, &dw, &DispatcherWatcher::onSignal1); + + QCOMPARE(statusAwake, 1); + QCOMPARE(statusAboutToBlock, 1); + e.exec(); + QCOMPARE(statusAwake, 2); + QCOMPARE(statusAboutToBlock, 2); +} + class MyFunctor { public: diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index c62943febc..4336d02b2c 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -32,6 +32,7 @@ #include <qmap.h> #include <algorithm> +#include <vector> class tst_QHash : public QObject { @@ -65,6 +66,7 @@ private slots: void twoArguments_qHash(); void initializerList(); void eraseValidIteratorOnSharedHash(); + void equal_range(); }; struct IdentityTracker { @@ -1355,5 +1357,111 @@ void tst_QHash::eraseValidIteratorOnSharedHash() QCOMPARE(itemsWith10, 3); } +void tst_QHash::equal_range() +{ + QHash<int, QString> hash; + + auto result = hash.equal_range(0); + QCOMPARE(result.first, hash.end()); + QCOMPARE(result.second, hash.end()); + + hash.insert(1, "one"); + + result = hash.equal_range(1); + + QCOMPARE(result.first, hash.find(1)); + QVERIFY(std::distance(result.first, result.second) == 1); + + QHash<int, int> h1; + { + auto p = h1.equal_range(0); + QVERIFY(p.first == p.second); + QVERIFY(p.first == h1.end()); + } + + h1.insert(1, 2); + { + auto p1 = h1.equal_range(9); + QVERIFY(p1.first == p1.second); + QVERIFY(p1.first == h1.end()); + } + { + auto p2 = h1.equal_range(1); + QVERIFY(p2.first != p2.second); + QVERIFY(p2.first == h1.begin()); + QVERIFY(p2.second == h1.end()); + } + + QMultiHash<int, int> m1 = h1; + m1.insert(1, 0); + QCOMPARE(m1.size(), 2); + { + auto p1 = m1.equal_range(9); + QVERIFY(p1.first == p1.second); + QVERIFY(p1.first == m1.end()); + } + { + auto p2 = m1.equal_range(1); + QVERIFY(p2.first != p2.second); + QVERIFY(p2.first == m1.begin()); + QVERIFY(p2.second == m1.end()); + QCOMPARE(std::distance(p2.first, p2.second), 2); + } + + m1.insert(0, 0); + QCOMPARE(m1.size(), 3); + { + auto p1 = m1.equal_range(9); + QVERIFY(p1.first == p1.second); + QVERIFY(p1.first == m1.end()); + } + { + const auto p2 = m1.equal_range(1); + QVERIFY(p2.first != p2.second); + QCOMPARE(p2.first.key(), 1); + QCOMPARE(std::distance(p2.first, p2.second), 2); + QVERIFY(p2.first == m1.begin() || p2.second == m1.end()); + } + + const QHash<int, int> ch1 = h1; + { + auto p1 = ch1.equal_range(9); + QVERIFY(p1.first == p1.second); + QVERIFY(p1.first == ch1.end()); + } + { + auto p2 = ch1.equal_range(1); + QVERIFY(p2.first != p2.second); + QVERIFY(p2.first == ch1.begin()); + QVERIFY(p2.second == ch1.end()); + } + + const QMultiHash<int, int> cm1 = m1; + { + auto p1 = cm1.equal_range(9); + QVERIFY(p1.first == p1.second); + QVERIFY(p1.first == cm1.end()); + } + { + auto p2 = cm1.equal_range(1); + QVERIFY(p2.first != p2.second); + QCOMPARE(std::distance(p2.first, p2.second), 2); + QVERIFY(p2.first == cm1.cbegin() || p2.second == cm1.cend()); + } + + QHash<int, int> h2; + for (int i = 0; i < 8; ++i) + for (int j = 0; j < 8; ++j) + h2.insertMulti(i, i*j); + + for (int i = 0; i < 8; ++i) { + auto pair = h2.equal_range(i); + std::vector<int> vec(pair.first, pair.second); + std::sort(vec.begin(), vec.end()); + for (int j = 0; j < 8; ++j) + QCOMPARE(i*j, vec[j]); + } +} + QTEST_APPLESS_MAIN(tst_QHash) #include "tst_qhash.moc" diff --git a/tests/auto/corelib/tools/qrect/tst_qrect.cpp b/tests/auto/corelib/tools/qrect/tst_qrect.cpp index e8b259168d..9b35cdec30 100644 --- a/tests/auto/corelib/tools/qrect/tst_qrect.cpp +++ b/tests/auto/corelib/tools/qrect/tst_qrect.cpp @@ -127,6 +127,9 @@ private slots: void translate_data(); void translate(); + void transposed_data(); + void transposed(); + void moveTop(); void moveBottom(); void moveLeft(); @@ -3562,6 +3565,41 @@ void tst_QRect::translate() } +void tst_QRect::transposed_data() +{ + QTest::addColumn<QRect>("r"); + + QTest::newRow("InvalidQRect") << getQRectCase(InvalidQRect); + QTest::newRow("SmallestQRect") << getQRectCase(SmallestQRect); + QTest::newRow("MiddleQRect") << getQRectCase(MiddleQRect); + QTest::newRow("LargestQRect") << getQRectCase(LargestQRect); + QTest::newRow("SmallestCoordQRect") << getQRectCase(SmallestCoordQRect); + QTest::newRow("LargestCoordQRect") << getQRectCase(LargestCoordQRect); + QTest::newRow("RandomQRect") << getQRectCase(RandomQRect); + QTest::newRow("NegativeSizeQRect") << getQRectCase(NegativeSizeQRect); + QTest::newRow("NegativePointQRect") << getQRectCase(NegativePointQRect); + QTest::newRow("NullQRect") << getQRectCase(NullQRect); + QTest::newRow("EmptyQRect") << getQRectCase(EmptyQRect); +} + +void tst_QRect::transposed() +{ + QFETCH(QRect, r); + + const QRect rt = r.transposed(); + QCOMPARE(rt.height(), r.width()); + QCOMPARE(rt.width(), r.height()); + QCOMPARE(rt.topLeft(), r.topLeft()); + + const QRectF rf = r; + + const QRectF rtf = rf.transposed(); + QCOMPARE(rtf.height(), rf.width()); + QCOMPARE(rtf.width(), rf.height()); + QCOMPARE(rtf.topLeft(), rf.topLeft()); + + QCOMPARE(rtf, QRectF(rt)); +} void tst_QRect::moveTop() { diff --git a/tests/auto/gui/image/qicon/tst_qicon.cpp b/tests/auto/gui/image/qicon/tst_qicon.cpp index ff88b62c32..079b14a64e 100644 --- a/tests/auto/gui/image/qicon/tst_qicon.cpp +++ b/tests/auto/gui/image/qicon/tst_qicon.cpp @@ -642,6 +642,10 @@ void tst_QIcon::fromTheme() QIcon::setThemeName(""); abIcon = QIcon::fromTheme("address-book-new"); QVERIFY(abIcon.isNull()); + + // Passing a full path to fromTheme is not very useful, but should work anyway + QIcon fullPathIcon = QIcon::fromTheme(m_pngImageFileName); + QVERIFY(!fullPathIcon.isNull()); } void tst_QIcon::fromThemeCache() diff --git a/tests/auto/gui/painting/qregion/tst_qregion.cpp b/tests/auto/gui/painting/qregion/tst_qregion.cpp index 7292841e5d..d24435198e 100644 --- a/tests/auto/gui/painting/qregion/tst_qregion.cpp +++ b/tests/auto/gui/painting/qregion/tst_qregion.cpp @@ -45,6 +45,7 @@ public: tst_QRegion(); private slots: + void moveSemantics(); void boundingRect(); void rects(); void swap(); @@ -93,6 +94,28 @@ tst_QRegion::tst_QRegion() { } +void tst_QRegion::moveSemantics() +{ + const QRegion rect(QRect(0, 0, 100, 100)); + + // move assignment + { + QRegion r1 = rect; + QRegion r2; + r2 = std::move(r1); + QVERIFY(r1.isNull()); + QCOMPARE(r2, rect); + } + + // move construction + { + QRegion r1 = rect; + QRegion r2 = std::move(r1); + QVERIFY(r1.isNull()); + QCOMPARE(r2, rect); + } +} + void tst_QRegion::boundingRect() { { |