diff options
Diffstat (limited to 'tests/auto/corelib')
19 files changed, 773 insertions, 67 deletions
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 16a30af892..350bff0652 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -279,6 +279,9 @@ private slots: void reuseQFile(); + void moveToTrash_data(); + void moveToTrash(); + private: #ifdef BUILTIN_TESTDATA QSharedPointer<QTemporaryDir> m_dataDir; @@ -3672,5 +3675,142 @@ void tst_QFile::reuseQFile() } } +void tst_QFile::moveToTrash_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("create"); + QTest::addColumn<bool>("result"); + + // success cases + { + QTemporaryFile temp; + QVERIFY(temp.open()); + QTest::newRow("temporary file") << temp.fileName() << true << true; + } + { + QTemporaryDir tempDir; + tempDir.setAutoRemove(false); + QTest::newRow("temporary dir") + << tempDir.path() + QLatin1Char('/') + << true << true; + } + { + QTemporaryDir homeDir(QDir::homePath() + QLatin1String("/XXXXXX")); + homeDir.setAutoRemove(false); + QTemporaryFile homeFile(homeDir.path() + + QLatin1String("/tst_qfile-XXXXXX")); + homeFile.open(); + QTest::newRow("home file") + << homeFile.fileName() + << true << true; + + QTest::newRow("home dir") + << homeDir.path() + QLatin1Char('/') + << true << true; + } + QTest::newRow("relative") << QStringLiteral("tst_qfile_moveToTrash.tmp") << true << true; + + // failure cases + QTest::newRow("root") << QDir::rootPath() << false << false; + QTest::newRow("no-such-file") << QString::fromLatin1("no/such/file") << false << false; +} + +void tst_QFile::moveToTrash() +{ + QFETCH(QString, source); + QFETCH(bool, create); + QFETCH(bool, result); + + /* This test makes assumptions about the file system layout + which might be wrong - moveToTrash may fail if the file lives + on a file system that is different from the home file system, and + has no .Trash directory. + */ + const bool mayFail = QStorageInfo(source) != QStorageInfo(QDir::home()); + +#if defined(Q_OS_WINRT) + QSKIP("WinRT does not have a trash", SkipAll); +#endif + + auto ensureFile = [](const QString &source, bool create) { + if (QFileInfo::exists(source) || !create) + return; + if (source.endsWith(QLatin1Char('/'))) { + QDir::root().mkdir(source); + QFile file(source + QLatin1String("test")); + if (!file.open(QIODevice::WriteOnly)) + QSKIP("Couldn't create directory with file"); + } else { + QFile sourceFile(source); + QVERIFY2(sourceFile.open(QFile::WriteOnly | QFile::Text), qPrintable(sourceFile.errorString())); + sourceFile.close(); + } + }; + auto cleanupFile = [source, create]() { + if (!QFileInfo::exists(source) || !create) + return; + if (source.endsWith(QLatin1Char('/'))) { + QDir(source).removeRecursively(); + } else { + QFile sourceFile(source); + sourceFile.remove(); + } + }; + // non-static version + { + ensureFile(source, create); + QFile sourceFile(source); + const bool success = sourceFile.moveToTrash(); + + // tolerate moveToTrash failing + if (result && !success && mayFail) + result = false; + + if (result) { + // if any of the test fails, we still want to remove the file + auto onFailure = qScopeGuard(cleanupFile); + QVERIFY2(success, qPrintable(sourceFile.errorString())); + QCOMPARE(sourceFile.error(), QFile::NoError); + QVERIFY(source != sourceFile.fileName()); + if (!sourceFile.fileName().isEmpty()) { + QVERIFY2(sourceFile.exists(), qPrintable(sourceFile.fileName())); + // remove file/dir in trash as well, don't fill disk + if (source.endsWith(QLatin1Char('/'))) + QDir(sourceFile.fileName()).removeRecursively(); + else + sourceFile.remove(); + } + } else { + QVERIFY(!success); + QVERIFY(!sourceFile.errorString().isEmpty()); + QCOMPARE(source, sourceFile.fileName()); + } + } + + // don't retry + if (mayFail) + return; + + // static version + { + ensureFile(source, create); + QString pathInTrash; + const bool success = QFile::moveToTrash(source, &pathInTrash); + QCOMPARE(success, result); + if (result) { + auto onFailure = qScopeGuard(cleanupFile); + QVERIFY(source != pathInTrash); + if (!pathInTrash.isEmpty()) { + // remove file/dir in trash as well, don't fill disk + QVERIFY2(QFile::exists(pathInTrash), qPrintable(pathInTrash)); + if (source.endsWith(QLatin1Char('/'))) + QDir(pathInTrash).removeRecursively(); + else + QFile::remove(pathInTrash); + } + } + } +} + QTEST_MAIN(tst_QFile) #include "tst_qfile.moc" diff --git a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp index 365508024b..85a2dae3b6 100644 --- a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp +++ b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp @@ -45,8 +45,10 @@ class tst_QEventDispatcher : public QObject Q_OBJECT QAbstractEventDispatcher *eventDispatcher; - int receivedEventType; - int timerIdFromEvent; + + int receivedEventType = -1; + int timerIdFromEvent = -1; + bool doubleTimer = false; protected: bool event(QEvent *e); @@ -54,9 +56,7 @@ protected: public: inline tst_QEventDispatcher() : QObject(), - eventDispatcher(QAbstractEventDispatcher::instance(thread())), - receivedEventType(-1), - timerIdFromEvent(-1) + eventDispatcher(QAbstractEventDispatcher::instance(thread())) { } private slots: @@ -75,6 +75,9 @@ bool tst_QEventDispatcher::event(QEvent *e) switch (receivedEventType = e->type()) { case QEvent::Timer: { + // sometimes, two timers fire during a single QTRY_xxx wait loop + if (timerIdFromEvent != -1) + doubleTimer = true; timerIdFromEvent = static_cast<QTimerEvent *>(e)->timerId(); return true; } @@ -206,10 +209,31 @@ void tst_QEventDispatcher::registerTimer() QVERIFY(timers.foundCoarse()); QVERIFY(timers.foundVeryCoarse()); +#ifdef Q_OS_DARWIN + /* + We frequently experience flaky failures on macOS. Assumption is that this is + due to undeterministic VM scheduling, making us process events for significantly + longer than expected and resulting in timers firing in undefined order. + To detect this condition, we use a QElapsedTimer, and skip the test. + */ + QElapsedTimer elapsedTimer; + elapsedTimer.start(); +#endif + // process events, waiting for the next event... this should only fire the precise timer receivedEventType = -1; timerIdFromEvent = -1; + doubleTimer = false; QTRY_COMPARE_WITH_TIMEOUT(receivedEventType, int(QEvent::Timer), PreciseTimerInterval * 2); + +#ifdef Q_OS_DARWIN + if (doubleTimer) + QSKIP("Double timer during a single timeout - aborting test as flaky on macOS"); + if (timerIdFromEvent != timers.preciseTimerId() + && elapsedTimer.elapsed() > PreciseTimerInterval * 3) + QSKIP("Ignore flaky test behavior due to VM scheduling on macOS"); +#endif + QCOMPARE(timerIdFromEvent, timers.preciseTimerId()); // now unregister it and make sure it's gone timers.unregister(timers.preciseTimerId()); @@ -223,7 +247,17 @@ void tst_QEventDispatcher::registerTimer() // do the same again for the coarse timer receivedEventType = -1; timerIdFromEvent = -1; + doubleTimer = false; QTRY_COMPARE_WITH_TIMEOUT(receivedEventType, int(QEvent::Timer), CoarseTimerInterval * 2); + +#ifdef Q_OS_DARWIN + if (doubleTimer) + QSKIP("Double timer during a single timeout - aborting test as flaky on macOS"); + if (timerIdFromEvent != timers.coarseTimerId() + && elapsedTimer.elapsed() > CoarseTimerInterval * 3) + QSKIP("Ignore flaky test behavior due to VM scheduling on macOS"); +#endif + QCOMPARE(timerIdFromEvent, timers.coarseTimerId()); // now unregister it and make sure it's gone timers.unregister(timers.coarseTimerId()); diff --git a/tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp b/tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp index c03e3e8e9f..78b0b5dc55 100644 --- a/tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp +++ b/tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp @@ -41,8 +41,8 @@ class QtTestObject : public QObject { Q_OBJECT public slots: - void myslot(int id); - void myslot(const QString &str); + void myIntSlot(int id); + void myStringSlot(const QString &str); signals: void mysignal(int); @@ -54,12 +54,12 @@ public: QString str; }; -void QtTestObject::myslot(int id) +void QtTestObject::myIntSlot(int id) { this->id = id; } -void QtTestObject::myslot(const QString &str) +void QtTestObject::myStringSlot(const QString &str) { this->str = str; } @@ -71,7 +71,7 @@ void QtTestObject::emit_mysignal(int value) void tst_QSignalMapper::mapped() { - QSignalMapper mapper(0); + QSignalMapper mapper; QtTestObject target; QtTestObject src1; @@ -88,8 +88,8 @@ void tst_QSignalMapper::mapped() mapper.setMapping(&src2, "two"); mapper.setMapping(&src3, "three"); - connect(&mapper, SIGNAL(mapped(int)), &target, SLOT(myslot(int))); - connect(&mapper, SIGNAL(mapped(QString)), &target, SLOT(myslot(QString))); + connect(&mapper, &QSignalMapper::mappedInt, &target, &QtTestObject::myIntSlot); + connect(&mapper, &QSignalMapper::mappedString, &target, &QtTestObject::myStringSlot); src1.emit_mysignal(20); QCOMPARE(target.id, 1); diff --git a/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm b/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm Binary files differindex cc42afe05c..25c0aad583 100644 --- a/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm +++ b/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm diff --git a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp index b3efa97dbd..9fde7da816 100644 --- a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp +++ b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp @@ -110,9 +110,10 @@ void tst_QTranslator::load_data() QTest::addColumn<QString>("filepath"); QTest::addColumn<bool>("isEmpty"); QTest::addColumn<QString>("translation"); + QTest::addColumn<QString>("language"); - QTest::newRow("hellotr_la") << "hellotr_la.qm" << false << "Hallo Welt!"; - QTest::newRow("hellotr_empty") << "hellotr_empty.qm" << true << ""; + QTest::newRow("hellotr_la") << "hellotr_la.qm" << false << "Hallo Welt!" << "de"; + QTest::newRow("hellotr_empty") << "hellotr_empty.qm" << true << "" << ""; } void tst_QTranslator::load() @@ -120,12 +121,15 @@ void tst_QTranslator::load() QFETCH(QString, filepath); QFETCH(bool, isEmpty); QFETCH(QString, translation); + QFETCH(QString, language); { QTranslator tor; QVERIFY(tor.load(QFileInfo(filepath).baseName())); QCOMPARE(tor.isEmpty(), isEmpty); QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation); + QCOMPARE(tor.filePath(), filepath); + QCOMPARE(tor.language(), language); } { @@ -136,13 +140,18 @@ void tst_QTranslator::load() QVERIFY(tor.load((const uchar *)data.constData(), data.length())); QCOMPARE(tor.isEmpty(), isEmpty); QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation); + QCOMPARE(tor.filePath(), ""); + QCOMPARE(tor.language(), language); } { QTranslator tor; - QVERIFY(tor.load(QString(":/tst_qtranslator/%1").arg(filepath))); + QString path = QString(":/tst_qtranslator/%1").arg(filepath); + QVERIFY(tor.load(path)); QCOMPARE(tor.isEmpty(), isEmpty); QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation); + QCOMPARE(tor.filePath(), path); + QCOMPARE(tor.language(), language); } } diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 91733bea90..b8baa1cde1 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -276,6 +276,8 @@ private slots: void shouldDeleteVariantDataWorksForAssociative(); void fromStdVariant(); void qt4UuidDataStream(); + void sequentialIterableEndianessSanityCheck(); + void sequentialIterableAppend(); void preferDirectConversionOverInterfaces(); @@ -4698,6 +4700,28 @@ void tst_QVariant::qt4UuidDataStream() QCOMPARE(result.value<QUuid>(), source); } +void tst_QVariant::sequentialIterableEndianessSanityCheck() +{ + namespace QMTP = QtMetaTypePrivate; + uint oldIteratorCaps = QMTP::ForwardCapability | QMTP::BiDirectionalCapability | QMTP::RandomAccessCapability; + QMTP::QSequentialIterableImpl seqImpl {}; + QCOMPARE(seqImpl.revision(), 1u); + memcpy(&seqImpl._iteratorCapabilities, &oldIteratorCaps, sizeof(oldIteratorCaps)); + QCOMPARE(seqImpl.revision(), 0u); +} + +void tst_QVariant::sequentialIterableAppend() +{ + QVector<int> container {1, 2}; + auto variant = QVariant::fromValue(container); + QVERIFY(variant.canConvert<QtMetaTypePrivate::QSequentialIterableImpl>()); + auto asIterable = variant.value<QtMetaTypePrivate::QSequentialIterableImpl>(); + const int i = 3, j = 4; + asIterable.append(&i); + asIterable.append(&j); + QCOMPARE(variant.value<QVector<int>>(), QVector<int> ({1, 2, 3, 4})); +} + void tst_QVariant::preferDirectConversionOverInterfaces() { using namespace QtMetaTypePrivate; diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index d1a77173c3..2f812a9952 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -1276,18 +1276,18 @@ void tst_QDataStream::readQCursor(QDataStream *s) QVERIFY(d5.shape() == test.shape()); //## lacks operator== QCOMPARE(d5.hotSpot(), test.hotSpot()); - QVERIFY((d5.bitmap() != 0 && test.bitmap() != 0) || (d5.bitmap() == 0 && test.bitmap() == 0)); - if (d5.bitmap() != 0) { - QPixmap actual = *(d5.bitmap()); - QPixmap expected = *(test.bitmap()); - QCOMPARE(actual, expected); - } - QVERIFY((d5.mask() != 0 && test.mask() != 0) || (d5.mask() == 0 && test.mask() == 0)); - if (d5.mask() != 0) { - QPixmap actual = *(d5.mask()); - QPixmap expected = *(test.mask()); - QCOMPARE(actual, expected); - } + + // Comparing non-null QBitmaps will fail. Upcast them first to pass. + QCOMPARE(d5.bitmap(Qt::ReturnByValue).isNull(), test.bitmap(Qt::ReturnByValue).isNull()); + QCOMPARE( + static_cast<QPixmap>(d5.bitmap(Qt::ReturnByValue)), + static_cast<QPixmap>(test.bitmap(Qt::ReturnByValue)) + ); + QCOMPARE(d5.mask(Qt::ReturnByValue).isNull(), test.mask(Qt::ReturnByValue).isNull()); + QCOMPARE( + static_cast<QPixmap>(d5.mask(Qt::ReturnByValue)), + static_cast<QPixmap>(test.mask(Qt::ReturnByValue)) + ); } #endif diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 4b13ac45cc..b1f6090585 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -253,6 +253,10 @@ private slots: void qtbug_46703(); void postEventFromBeginSelectTransitions(); void dontProcessSlotsWhenMachineIsNotRunning(); + + void cancelDelayedEventWithChrono(); + void postDelayedEventWithChronoAndStop(); + void postDelayedEventWithChronoFromThread(); }; class TestState : public QState @@ -6702,5 +6706,163 @@ void tst_QStateMachine::dontProcessSlotsWhenMachineIsNotRunning() QTRY_VERIFY(emitter.thread.isFinished()); } +void tst_QStateMachine::cancelDelayedEventWithChrono() +{ +#if __has_include(<chrono>) + QStateMachine machine; + QTest::ignoreMessage(QtWarningMsg, + "QStateMachine::cancelDelayedEvent: the machine is not running"); + QVERIFY(!machine.cancelDelayedEvent(-1)); + + QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); + QFinalState *s2 = new QFinalState(&machine); + s1->addTransition(new StringTransition("a", s2)); + machine.setInitialState(s1); + + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(startedSpy.isValid()); + QVERIFY(runningSpy.isValid()); + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); + TEST_ACTIVE_CHANGED(s1, 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + int id1 = machine.postDelayedEvent(new StringEvent("c"), std::chrono::seconds{50}); + QVERIFY(id1 != -1); + int id2 = machine.postDelayedEvent(new StringEvent("b"), std::chrono::seconds{25}); + QVERIFY(id2 != -1); + QVERIFY(id2 != id1); + int id3 = machine.postDelayedEvent(new StringEvent("a"), std::chrono::milliseconds{100}); + QVERIFY(id3 != -1); + QVERIFY(id3 != id2); + QVERIFY(machine.cancelDelayedEvent(id1)); + QVERIFY(!machine.cancelDelayedEvent(id1)); + QVERIFY(machine.cancelDelayedEvent(id2)); + QVERIFY(!machine.cancelDelayedEvent(id2)); + + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QVERIFY(finishedSpy.isValid()); + QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); + TEST_ACTIVE_CHANGED(s1, 2); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); +#endif +} + +void tst_QStateMachine::postDelayedEventWithChronoAndStop() +{ +#if __has_include(<chrono>) + QStateMachine machine; + QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); + QFinalState *s2 = new QFinalState(&machine); + s1->addTransition(new StringTransition("a", s2)); + machine.setInitialState(s1); + + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QVERIFY(startedSpy.isValid()); + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); + TEST_ACTIVE_CHANGED(s1, 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + int id1 = machine.postDelayedEvent(new StringEvent("a"), std::chrono::milliseconds{0}); + QVERIFY(id1 != -1); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QVERIFY(stoppedSpy.isValid()); + machine.stop(); + QTRY_COMPARE(stoppedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); + TEST_ACTIVE_CHANGED(s1, 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.start(); + QTRY_COMPARE(startedSpy.count(), 2); + TEST_RUNNING_CHANGED(true); + TEST_ACTIVE_CHANGED(s1, 3); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + int id2 = machine.postDelayedEvent(new StringEvent("a"), std::chrono::seconds{1}); + QVERIFY(id2 != -1); + machine.stop(); + QTRY_COMPARE(stoppedSpy.count(), 2); + TEST_RUNNING_CHANGED(false); + TEST_ACTIVE_CHANGED(s1, 3); + machine.start(); + QTRY_COMPARE(startedSpy.count(), 3); + TEST_RUNNING_CHANGED(true); + QTestEventLoop::instance().enterLoop(2); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + TEST_ACTIVE_CHANGED(s1, 5); + QVERIFY(machine.isRunning()); +#endif +} + +class DelayedEventWithChronoPosterThread : public QThread +{ + Q_OBJECT +public: + DelayedEventWithChronoPosterThread(QStateMachine *machine, QObject *parent = 0) + : QThread(parent), firstEventWasCancelled(false), m_machine(machine) + { + moveToThread(this); + QObject::connect(m_machine, SIGNAL(started()), this, SLOT(postEvent())); + } + + mutable bool firstEventWasCancelled; + +private Q_SLOTS: + void postEvent() + { +#if __has_include(<chrono>) + int id = m_machine->postDelayedEvent(new QEvent(QEvent::User), std::chrono::seconds{1}); + firstEventWasCancelled = m_machine->cancelDelayedEvent(id); + + m_machine->postDelayedEvent(new QEvent(QEvent::User), std::chrono::milliseconds{1}); + + quit(); +#endif + } + +private: + QStateMachine *m_machine; +}; + +void tst_QStateMachine::postDelayedEventWithChronoFromThread() +{ +#if __has_include(<chrono>) + QStateMachine machine; + QState *s1 = new QState(&machine); + DEFINE_ACTIVE_SPY(s1); + QFinalState *f = new QFinalState(&machine); + s1->addTransition(new EventTransition(QEvent::User, f)); + machine.setInitialState(s1); + + DelayedEventWithChronoPosterThread poster(&machine); + poster.start(); + + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QVERIFY(finishedSpy.isValid()); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + TEST_ACTIVE_CHANGED(s1, 2); + QVERIFY(poster.firstEventWasCancelled); +#endif +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" diff --git a/tests/auto/corelib/text/qcollator/tst_qcollator.cpp b/tests/auto/corelib/text/qcollator/tst_qcollator.cpp index 2ae9c6e159..6806aa09b5 100644 --- a/tests/auto/corelib/text/qcollator/tst_qcollator.cpp +++ b/tests/auto/corelib/text/qcollator/tst_qcollator.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. @@ -105,6 +105,8 @@ void tst_QCollator::compare_data() QTest::newRow("english6") << QString("en_US") << QString("test 9") << QString("test_19") << -1 << -1 << true << true << -1; QTest::newRow("english7") << QString("en_US") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1; QTest::newRow("english8") << QString("en_US") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0; + QTest::newRow("en-empty-word") << QString("en_US") << QString() << QString("non-empty") << -1 << -1 << false << true << -1; + QTest::newRow("en-empty-number") << QString("en_US") << QString() << QString("42") << -1 << -1 << true << true << -1; /* In Swedish, a with ring above (E5) comes before a with @@ -119,6 +121,8 @@ void tst_QCollator::compare_data() QTest::newRow("swedish6") << QString("sv_SE") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1; QTest::newRow("swedish7") << QString("sv_SE") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1; QTest::newRow("swedish8") << QString("sv_SE") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0; + QTest::newRow("sv-empty-word") << QString("sv_SE") << QString() << QString("mett") << -1 << -1 << false << true << -1; + QTest::newRow("sv-empty-number") << QString("sv_SE") << QString() << QString("42") << -1 << -1 << true << true << -1; /* @@ -133,6 +137,8 @@ void tst_QCollator::compare_data() QTest::newRow("norwegian6") << QString("no_NO") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1; QTest::newRow("norwegian7") << QString("no_NO") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1; QTest::newRow("norwegian8") << QString("no_NO") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0; + QTest::newRow("nb-empty-word") << QString("nb_NO") << QString() << QString("mett") << -1 << -1 << false << true << -1; + QTest::newRow("nb-empty-number") << QString("nb_NO") << QString() << QString("42") << -1 << -1 << true << true << -1; /* In German, z comes *after* a with diaresis (E4), @@ -151,6 +157,8 @@ void tst_QCollator::compare_data() QTest::newRow("german11") << QString("de_DE") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1; QTest::newRow("german12") << QString("de_DE") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1; QTest::newRow("german13") << QString("de_DE") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0; + QTest::newRow("de-empty-word") << QString("de_DE") << QString() << QString("satt") << -1 << -1 << false << true << -1; + QTest::newRow("de-empty-number") << QString("de_DE") << QString() << QString("42") << -1 << -1 << true << true << -1; /* French sorting of e and e with acute accent @@ -163,11 +171,15 @@ void tst_QCollator::compare_data() QTest::newRow("french6") << QString("fr_FR") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1; QTest::newRow("french7") << QString("fr_FR") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1; QTest::newRow("french8") << QString("fr_FR") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0; + QTest::newRow("fr-empty-word") << QString("fr_FR") << QString() << QString("plein") << -1 << -1 << false << true << -1; + QTest::newRow("fr-empty-number") << QString("fr_FR") << QString() << QString("42") << -1 << -1 << true << true << -1; // C locale: case sensitive [A-Z] < [a-z] but case insensitive [Aa] < [Bb] <...< [Zz] const QString C = QStringLiteral("C"); QTest::newRow("C:ABBA:AaaA") << C << QStringLiteral("ABBA") << QStringLiteral("AaaA") << -1 << 1 << false << false << 1; QTest::newRow("C:AZa:aAZ") << C << QStringLiteral("AZa") << QStringLiteral("aAZ") << -1 << 1 << false << false << 1; + QTest::newRow("C-empty-word") << QString(C) << QString() << QString("non-empty") << -1 << -1 << false << true << -1; + QTest::newRow("C-empty-number") << QString(C) << QString() << QString("42") << -1 << -1 << true << true << -1; } void tst_QCollator::compare() diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index f19b66be37..e4144a376e 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 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. @@ -1887,14 +1887,16 @@ void tst_QLocale::toDateTime() // Format number string according to system locale settings. // Expected in format is US "1,234.56". -QString systemLocaleFormatNumber(const QString &numberString) +QString systemLocaleFormatNumber(QString &&numberString) { QLocale locale = QLocale::system(); - QString numberStringCopy = numberString; - return numberStringCopy.replace(QChar(','), QChar('G')) - .replace(QChar('.'), QChar('D')) - .replace(QChar('G'), locale.groupSeparator()) - .replace(QChar('D'), locale.decimalPoint()); + QString numberStringMunged = + numberString.replace(QChar(','), QChar('G')).replace(QChar('.'), QChar('D')); + if (locale.numberOptions() & QLocale::OmitGroupSeparator) + numberStringMunged.remove(QLatin1Char('G')); + else + numberStringMunged.replace(QChar('G'), locale.groupSeparator()); + return numberStringMunged.replace(QChar('D'), locale.decimalPoint()); } void tst_QLocale::macDefaultLocale() @@ -1917,12 +1919,14 @@ void tst_QLocale::macDefaultLocale() // independently of the locale. Verify that they have one of the // allowed values and are not the same. QVERIFY(locale.decimalPoint() == QChar('.') || locale.decimalPoint() == QChar(',')); - QVERIFY(locale.groupSeparator() == QChar(',') - || locale.groupSeparator() == QChar('.') - || locale.groupSeparator() == QChar('\xA0') // no-breaking space - || locale.groupSeparator() == QChar('\'') - || locale.groupSeparator() == QChar()); - QVERIFY(locale.decimalPoint() != locale.groupSeparator()); + if (!(locale.numberOptions() & QLocale::OmitGroupSeparator)) { + QVERIFY(locale.groupSeparator() == QChar(',') + || locale.groupSeparator() == QChar('.') + || locale.groupSeparator() == QChar('\xA0') // no-breaking space + || locale.groupSeparator() == QChar('\'') + || locale.groupSeparator() == QChar()); + QVERIFY(locale.decimalPoint() != locale.groupSeparator()); + } // make sure we are using the system to parse them QCOMPARE(locale.toString(1234.56), systemLocaleFormatNumber(QString("1,234.56"))); @@ -2056,6 +2060,8 @@ void tst_QLocale::windowsDefaultLocale() setWinLocaleInfo(LOCALE_SLONGDATE, longDateFormat); const QString shortTimeFormat = QStringLiteral("h^m^s"); setWinLocaleInfo(LOCALE_SSHORTTIME, shortTimeFormat); + const QString longTimeFormat = QStringLiteral("HH%mm%ss"); + setWinLocaleInfo(LOCALE_STIMEFORMAT, longTimeFormat); QSystemLocale dummy; // to provoke a refresh of the system locale QLocale locale = QLocale::system(); @@ -2069,7 +2075,7 @@ void tst_QLocale::windowsDefaultLocale() QCOMPARE(locale.dateTimeFormat(QLocale::ShortFormat), shortDateFormat + QLatin1Char(' ') + shortTimeFormat); const QString expectedLongDateTimeFormat - = longDateFormat + QLatin1Char(' ') + QStringLiteral("h:mm:ss AP"); + = longDateFormat + QLatin1Char(' ') + longTimeFormat; QCOMPARE(locale.dateTimeFormat(QLocale::LongFormat), expectedLongDateTimeFormat); // make sure we are using the system to parse them @@ -2083,7 +2089,7 @@ void tst_QLocale::windowsDefaultLocale() QCOMPARE(locale.toString(QTime(1,2,3), QLocale::ShortFormat), expectedFormattedShortTime); QCOMPARE(locale.toString(QTime(1,2,3), QLocale::NarrowFormat), locale.toString(QTime(1,2,3), QLocale::ShortFormat)); - const QString expectedFormattedLongTime = QStringLiteral("1:02:03 AM"); + const QString expectedFormattedLongTime = QStringLiteral("01%02%03"); QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime); QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat), QStringLiteral("1*12*1974 ") + expectedFormattedShortTime); @@ -2091,7 +2097,6 @@ void tst_QLocale::windowsDefaultLocale() locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat)); QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::LongFormat), QStringLiteral("1@12@1974 ") + expectedFormattedLongTime); - QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime); } #endif // Q_OS_WIN but !Q_OS_WINRT diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 24382a2b61..bcf4e73108 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> +** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> ** Copyright (C) 2019 Mail.ru Group. ** Contact: https://www.qt.io/licensing/ ** @@ -80,6 +80,13 @@ MAKE_ALL(const char*, QChar) #undef MAKE_RELOP // END FIXME +static Q_DECL_CONSTEXPR int sign(int i) noexcept +{ + return i < 0 ? -1 : + i > 0 ? +1 : + /*else*/ 0 ; +} + // Return a plain ASCII row name consisting of maximum 16 chars and the // size for data static QByteArray rowName(const QByteArray &data) @@ -162,6 +169,12 @@ private Q_SLOTS: void compare_QStringView_QStringView() { compare_impl<QStringView, QStringView>(); } void compare_QStringView_QLatin1String_data() { compare_data(); } void compare_QStringView_QLatin1String() { compare_impl<QStringView, QLatin1String>(); } +#ifdef NOT_YET_IMPLMENTED + void compare_QStringView_QByteArray_data() { compare_data(); } + void compare_QStringView_QByteArray() { compare_impl<QStringView, QByteArray>(); } + void compare_QStringView_const_char_star_data() { compare_data(); } + void compare_QStringView_const_char_star() { compare_impl<QStringView, const char *>(); } +#endif void compare_QLatin1String_QChar_data() { compare_data(false); } void compare_QLatin1String_QChar() { compare_impl<QLatin1String, QChar>(); } @@ -205,6 +218,111 @@ private Q_SLOTS: //void compare_const_char_star_const_char_star() { compare_impl<const char *, const char *>(); } private: + void member_compare_data(bool hasConceptOfNullAndEmpty=true) { compare_data(hasConceptOfNullAndEmpty); } + template <typename LHS, typename RHS> + void member_compare_impl() const; + +private Q_SLOTS: + // test all combinations of {QChar, QStringRef, QString, QStringView, QLatin1String, QByteArray, const char*} +#ifdef NOT_YET_IMPLEMENTED // probably never will be - what's the point of QChar::compare(QStringView)? + void member_compare_QChar_QChar_data() { member_compare_data(false); } + void member_compare_QChar_QChar() { member_compare_impl<QChar, QChar>(); } + void member_compare_QChar_QStringRef_data() { member_compare_data(false); } + void member_compare_QChar_QStringRef() { member_compare_impl<QChar, QStringRef>(); } + void member_compare_QChar_QString_data() { member_compare_data(false); } + void member_compare_QChar_QString() { member_compare_impl<QChar, QString>(); } + void member_compare_QChar_QStringView_data() { member_compare_data(false); } + void member_compare_QChar_QStringView() { member_compare_impl<QChar, QStringView>(); } + void member_compare_QChar_QLatin1String_data() { member_compare_data(false); } + void member_compare_QChar_QLatin1String() { member_compare_impl<QChar, QLatin1String>(); } + void member_compare_QChar_QByteArray_data() { member_compare_data(false); } + void member_compare_QChar_QByteArray() { member_compare_impl<QChar, QByteArray>(); } + void member_compare_QChar_const_char_star_data() { member_compare_data(false); } + void member_compare_QChar_const_char_star() { member_compare_impl<QChar, const char *>(); } +#endif + + void member_compare_QStringRef_QChar_data() { member_compare_data(false); } + void member_compare_QStringRef_QChar() { member_compare_impl<QStringRef, QChar>(); } + void member_compare_QStringRef_QStringRef_data() { member_compare_data(); } + void member_compare_QStringRef_QStringRef() { member_compare_impl<QStringRef, QStringRef>(); } + void member_compare_QStringRef_QString_data() { member_compare_data(); } + void member_compare_QStringRef_QString() { member_compare_impl<QStringRef, QString>(); } +#ifdef NOT_YET_IMPLEMENTED + void member_compare_QStringRef_QStringView_data() { member_compare_data(); } + void member_compare_QStringRef_QStringView() { member_compare_impl<QStringRef, QStringView>(); } +#endif + void member_compare_QStringRef_QLatin1String_data() { member_compare_data(); } + void member_compare_QStringRef_QLatin1String() { member_compare_impl<QStringRef, QLatin1String>(); } + void member_compare_QStringRef_QByteArray_data() { member_compare_data(); } + void member_compare_QStringRef_QByteArray() { member_compare_impl<QStringRef, QByteArray>(); } +#ifdef NOT_YET_IMPLEMENTED + void member_compare_QStringRef_const_char_star_data() { member_compare_data(); } + void member_compare_QStringRef_const_char_star() { member_compare_impl<QStringRef, const char *>(); } +#endif + + void member_compare_QString_QChar_data() { member_compare_data(false); } + void member_compare_QString_QChar() { member_compare_impl<QString, QChar>(); } + void member_compare_QString_QStringRef_data() { member_compare_data(); } + void member_compare_QString_QStringRef() { member_compare_impl<QString, QStringRef>(); } + void member_compare_QString_QString_data() { member_compare_data(); } + void member_compare_QString_QString() { member_compare_impl<QString, QString>(); } + void member_compare_QString_QStringView_data() { member_compare_data(); } + void member_compare_QString_QStringView() { member_compare_impl<QString, QStringView>(); } + void member_compare_QString_QLatin1String_data() { member_compare_data(); } + void member_compare_QString_QLatin1String() { member_compare_impl<QString, QLatin1String>(); } + void member_compare_QString_QByteArray_data() { member_compare_data(); } + void member_compare_QString_QByteArray() { member_compare_impl<QString, QByteArray>(); } + void member_compare_QString_const_char_star_data() { member_compare_data(); } + void member_compare_QString_const_char_star() { member_compare_impl<QString, const char *>(); } + +#ifdef NOT_YET_IMPLEMENTED // QChar doesn't implicitly convert to QStringView + void member_compare_QStringView_QChar_data() { member_compare_data(false); } + void member_compare_QStringView_QChar() { member_compare_impl<QStringView, QChar>(); } +#endif + void member_compare_QStringView_QStringRef_data() { member_compare_data(); } + void member_compare_QStringView_QStringRef() { member_compare_impl<QStringView, QStringRef>(); } + void member_compare_QStringView_QString_data() { member_compare_data(); } + void member_compare_QStringView_QString() { member_compare_impl<QStringView, QString>(); } + void member_compare_QStringView_QStringView_data() { member_compare_data(); } + void member_compare_QStringView_QStringView() { member_compare_impl<QStringView, QStringView>(); } +#ifdef NOT_YET_IMPLEMENTED + void member_compare_QStringView_QLatin1String_data() { member_compare_data(); } + void member_compare_QStringView_QLatin1String() { member_compare_impl<QStringView, QLatin1String>(); } + void member_compare_QStringView_QByteArray_data() { member_compare_data(); } + void member_compare_QStringView_QByteArray() { member_compare_impl<QStringView, QByteArray>(); } + void member_compare_QStringView_const_char_star_data() { member_compare_data(); } + void member_compare_QStringView_const_char_star() { member_compare_impl<QStringView, const char *>(); } + + void member_compare_QLatin1String_QChar_data() { member_compare_data(false); } + void member_compare_QLatin1String_QChar() { member_compare_impl<QLatin1String, QChar>(); } + void member_compare_QLatin1String_QStringRef_data() { member_compare_data(); } + void member_compare_QLatin1String_QStringRef() { member_compare_impl<QLatin1String, QStringRef>(); } + void member_compare_QLatin1String_QString_data() { member_compare_data(); } + void member_compare_QLatin1String_QString() { member_compare_impl<QLatin1String, QString>(); } + void member_compare_QLatin1String_QStringView_data() { member_compare_data(); } + void member_compare_QLatin1String_QStringView() { member_compare_impl<QLatin1String, QStringView>(); } + void member_compare_QLatin1String_QLatin1String_data() { member_compare_data(); } + void member_compare_QLatin1String_QLatin1String() { member_compare_impl<QLatin1String, QLatin1String>(); } + void member_compare_QLatin1String_QByteArray_data() { member_compare_data(); } + void member_compare_QLatin1String_QByteArray() { member_compare_impl<QLatin1String, QByteArray>(); } + void member_compare_QLatin1String_const_char_star_data() { member_compare_data(); } + void member_compare_QLatin1String_const_char_star() { member_compare_impl<QLatin1String, const char *>(); } + + void member_compare_QByteArray_QChar_data() { member_compare_data(false); } + void member_compare_QByteArray_QChar() { member_compare_impl<QByteArray, QChar>(); } + void member_compare_QByteArray_QStringRef_data() { member_compare_data(); } + void member_compare_QByteArray_QStringRef() { member_compare_impl<QByteArray, QStringRef>(); } + void member_compare_QByteArray_QString_data() { member_compare_data(); } + void member_compare_QByteArray_QString() { member_compare_impl<QByteArray, QString>(); } + void member_compare_QByteArray_QLatin1String_data() { member_compare_data(); } + void member_compare_QByteArray_QLatin1String() { member_compare_impl<QByteArray, QLatin1String>(); } +#endif + void member_compare_QByteArray_QByteArray_data() { member_compare_data(); } + void member_compare_QByteArray_QByteArray() { member_compare_impl<QByteArray, QByteArray>(); } + void member_compare_QByteArray_const_char_star_data() { member_compare_data(); } + void member_compare_QByteArray_const_char_star() { member_compare_impl<QByteArray, const char *>(); } + +private: void startsWith_data(bool rhsIsQChar = false); template <typename Haystack, typename Needle> void startsWith_impl() const; @@ -601,7 +719,7 @@ void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty) QTest::newRow(qUtf8Printable(QLatin1String("'" lhs "' <> '" rhs "': "))) \ << QStringRef(&pinned[0]) << QLatin1String(lhs) \ << QStringRef(&pinned[1]) << QLatin1String(rhs) \ - << qstrcmp(lhs, rhs) << qstricmp(lhs, rhs); \ + << sign(qstrcmp(lhs, rhs)) << sign(qstricmp(lhs, rhs)); \ } while (false) ROW("", "0"); ROW("0", ""); @@ -691,6 +809,44 @@ void tst_QStringApiSymmetry::compare_impl() const #undef CHECK } +template <typename LHS, typename RHS> +void tst_QStringApiSymmetry::member_compare_impl() const +{ + QFETCH(QStringRef, lhsUnicode); + QFETCH(QLatin1String, lhsLatin1); + QFETCH(QStringRef, rhsUnicode); + QFETCH(QLatin1String, rhsLatin1); + QFETCH(const int, caseSensitiveCompareResult); + QFETCH(const int, caseInsensitiveCompareResult); + + const auto lhsU8 = lhsUnicode.toUtf8(); + const auto rhsU8 = rhsUnicode.toUtf8(); + + const auto lhs = make<LHS>(lhsUnicode, lhsLatin1, lhsU8); + const auto rhs = make<RHS>(rhsUnicode, rhsLatin1, rhsU8); + +#define QVERIFY_NOEXCEPT(expr) do { \ + if (has_nothrow_compare<LHS, RHS>::value) {} else \ + QEXPECT_FAIL("", "Qt is missing a nothrow utf8-utf16 comparator", Continue); \ + QVERIFY(noexcept(expr)); } while (0) + + if (std::is_same<LHS, QByteArray>::value || // needs to simply be marked as noexcept + ((std::is_same<LHS, QString>::value || std::is_same<LHS, QStringRef>::value) + && std::is_same<RHS, QChar>::value)) // implict QChar -> QString conversion kills noexcept + QEXPECT_FAIL("", "known issues, will be fixed before 5.14 release", Continue); + QVERIFY_NOEXCEPT(lhs.compare(rhs, Qt::CaseSensitive)); + + QCOMPARE(sign(lhs.compare(rhs)), caseSensitiveCompareResult); + QCOMPARE(sign(lhs.compare(rhs, Qt::CaseSensitive)), caseSensitiveCompareResult); + if (is_utf8_encoded<LHS>::value && is_utf8_encoded<RHS>::value && + caseSensitiveCompareResult != caseInsensitiveCompareResult && + (!QtPrivate::isAscii(lhsUnicode) || !QtPrivate::isAscii(rhsUnicode))) + { + QEXPECT_FAIL("", "Qt is missing a case-insensitive UTF-8/UTF-8 comparator", Continue); + } + QCOMPARE(sign(lhs.compare(rhs, Qt::CaseInsensitive)), caseInsensitiveCompareResult); +} + static QString empty = QLatin1String(""); static QString null; // the tests below rely on the fact that these objects' names match their contents: diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 60e8d8cba2..49ce918caf 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -64,6 +64,7 @@ public: private slots: void runFunction(); + void runFunction2(); void createThreadRunFunction(); void runMultiple(); void waitcomplete(); @@ -160,17 +161,27 @@ void tst_QThreadPool::runFunction() { QThreadPool manager; testFunctionCount = 0; - manager.start(createTask(noSleepTestFunction)); + manager.start(noSleepTestFunction); } QCOMPARE(testFunctionCount, 1); } +void tst_QThreadPool::runFunction2() +{ + int localCount = 0; + { + QThreadPool manager; + manager.start([&]() { ++localCount; }); + } + QCOMPARE(localCount, 1); +} + void tst_QThreadPool::createThreadRunFunction() { { QThreadPool manager; testFunctionCount = 0; - manager.start(createTask(noSleepTestFunction)); + manager.start(noSleepTestFunction); } QCOMPARE(testFunctionCount, 1); @@ -184,7 +195,7 @@ void tst_QThreadPool::runMultiple() QThreadPool manager; testFunctionCount = 0; for (int i = 0; i < runs; ++i) { - manager.start(createTask(sleepTestFunctionMutex)); + manager.start(sleepTestFunctionMutex); } } QCOMPARE(testFunctionCount, runs); @@ -193,7 +204,7 @@ void tst_QThreadPool::runMultiple() QThreadPool manager; testFunctionCount = 0; for (int i = 0; i < runs; ++i) { - manager.start(createTask(noSleepTestFunctionMutex)); + manager.start(noSleepTestFunctionMutex); } } QCOMPARE(testFunctionCount, runs); @@ -201,7 +212,7 @@ void tst_QThreadPool::runMultiple() { QThreadPool manager; for (int i = 0; i < 500; ++i) - manager.start(createTask(emptyFunct)); + manager.start(emptyFunct); } } @@ -211,7 +222,7 @@ void tst_QThreadPool::waitcomplete() const int runs = 500; for (int i = 0; i < 500; ++i) { QThreadPool pool; - pool.start(createTask(noSleepTestFunction)); + pool.start(noSleepTestFunction); } QCOMPARE(testFunctionCount, runs); } diff --git a/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp b/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp index 9b41014394..5da69e76a5 100644 --- a/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp +++ b/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 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. @@ -40,6 +40,8 @@ private: private slots: void basic_data(); void basic(); + void unspecified_data() { basic_data(); } + void unspecified(); void nameCase(); void specific_data(); void specific(); @@ -145,6 +147,27 @@ void tst_QCalendar::basic() NORMALYEAR(cal, year); } +void tst_QCalendar::unspecified() +{ + QFETCH(QCalendar::System, system); + QCalendar cal(system); + + const QDate today = QDate::currentDate(); + const int thisYear = today.year(); + QCOMPARE(cal.monthsInYear(QCalendar::Unspecified), cal.maximumMonthsInYear()); + for (int month = cal.maximumMonthsInYear(); month > 0; month--) { + const int days = cal.daysInMonth(month); + int count = 0; + // 19 years = one Metonic cycle (used by some lunar calendars) + for (int i = 19; i > 0; --i) { + if (cal.daysInMonth(month, thisYear - i) == days) + count++; + } + // Require a majority of the years tested: + QVERIFY2(count > 9, "Default daysInMonth() should be for a normal year"); + } +} + void tst_QCalendar::nameCase() { QVERIFY(QCalendar::availableCalendars().contains(QStringLiteral("Gregorian"))); diff --git a/tests/auto/corelib/time/qdate/tst_qdate.cpp b/tests/auto/corelib/time/qdate/tst_qdate.cpp index 567209dcf6..274bf4f6f0 100644 --- a/tests/auto/corelib/time/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/time/qdate/tst_qdate.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -1352,6 +1352,7 @@ void tst_QDate::toStringDateFormat() QFETCH(Qt::DateFormat, format); QFETCH(QString, expectedStr); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCOMPARE(date.toString(Qt::SystemLocaleShortDate), QLocale::system().toString(date, QLocale::ShortFormat)); QCOMPARE(date.toString(Qt::DefaultLocaleShortDate), QLocale().toString(date, QLocale::ShortFormat)); QCOMPARE(date.toString(Qt::SystemLocaleLongDate), QLocale::system().toString(date, QLocale::LongFormat)); @@ -1361,6 +1362,7 @@ void tst_QDate::toStringDateFormat() QCOMPARE(date.toString(Qt::DefaultLocaleShortDate), QLocale().toString(date, QLocale::ShortFormat)); QCOMPARE(date.toString(Qt::SystemLocaleLongDate), QLocale::system().toString(date, QLocale::LongFormat)); QCOMPARE(date.toString(Qt::DefaultLocaleLongDate), QLocale().toString(date, QLocale::LongFormat)); +#endif // ### Qt 6: remove QCOMPARE(date.toString(format), expectedStr); } diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index 6aae91f62f..26ad91271d 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -127,8 +127,10 @@ private slots: #ifdef Q_OS_WIN void fromString_LOCALE_ILDATE(); #endif +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) void fromStringToStringLocale_data(); void fromStringToStringLocale(); +#endif // ### Qt 6: remove void offsetFromUtc(); void setOffsetFromUtc(); @@ -295,9 +297,9 @@ void tst_QDateTime::initTestCase() void tst_QDateTime::init() { -#if defined(Q_OS_WIN32) +#if defined(Q_OS_WIN32) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); -#endif +#endif // ### Qt 6: remove } QString tst_QDateTime::str( int y, int month, int d, int h, int min, int s ) @@ -834,8 +836,10 @@ void tst_QDateTime::toString_isoDate() QFETCH(Qt::DateFormat, format); QFETCH(QString, expected); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QLocale oldLocale; QLocale::setDefault(QLocale("en_US")); +#endif // ### Qt 6: remove QString result = datetime.toString(format); QCOMPARE(result, expected); @@ -854,7 +858,9 @@ void tst_QDateTime::toString_isoDate() QCOMPARE(resultDatetime, QDateTime()); } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QLocale::setDefault(oldLocale); +#endif // ### Qt 6: remove } void tst_QDateTime::toString_isoDate_extra() @@ -1763,7 +1769,7 @@ void tst_QDateTime::daylightSavingsTimeChange() // because some functions did not reset the flag when moving in or out of DST. // WARNING: This only tests anything if there's a Daylight Savings Time change - // in the current locale between inDST and outDST. + // in the current time-zone between inDST and outDST. // This is true for Central European Time and may be elsewhere. QFETCH(QDate, inDST); @@ -2612,6 +2618,9 @@ void tst_QDateTime::fromString_LOCALE_ILDATE() } #endif +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED + void tst_QDateTime::fromStringToStringLocale_data() { QTest::addColumn<QLocale>("locale"); @@ -2643,6 +2652,8 @@ void tst_QDateTime::fromStringToStringLocale() #undef ROUNDTRIP QLocale::setDefault(def); } +QT_WARNING_POP +#endif // ### Qt 6: remove void tst_QDateTime::offsetFromUtc() { @@ -2941,19 +2952,19 @@ void tst_QDateTime::fewDigitsInYear() const void tst_QDateTime::printNegativeYear() const { { - QDateTime date(QDate(-20, 10, 11)); + QDateTime date(QDate(-20, 10, 11).startOfDay()); QVERIFY(date.isValid()); QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0020")); } { - QDateTime date(QDate(-3, 10, 11)); + QDateTime date(QDate(-3, 10, 11).startOfDay()); QVERIFY(date.isValid()); QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0003")); } { - QDateTime date(QDate(-400, 10, 11)); + QDateTime date(QDate(-400, 10, 11).startOfDay()); QVERIFY(date.isValid()); QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0400")); } diff --git a/tests/auto/corelib/time/qtime/tst_qtime.cpp b/tests/auto/corelib/time/qtime/tst_qtime.cpp index f85e0ea74e..027232f6d5 100644 --- a/tests/auto/corelib/time/qtime/tst_qtime.cpp +++ b/tests/auto/corelib/time/qtime/tst_qtime.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. @@ -77,7 +77,9 @@ private slots: void toStringDateFormat(); void toStringFormat_data(); void toStringFormat(); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) void toStringLocale(); +#endif // ### Qt 6: remove void msecsSinceStartOfDay_data(); void msecsSinceStartOfDay(); @@ -770,6 +772,7 @@ void tst_QTime::toStringFormat() QCOMPARE( t.toString( format ), str ); } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) void tst_QTime::toStringLocale() { QTime time(18, 30); @@ -791,6 +794,7 @@ void tst_QTime::toStringLocale() QCOMPARE(time.toString(Qt::DefaultLocaleLongDate), QLocale().toString(time, QLocale::LongFormat)); } +#endif // ### Qt 6: remove void tst_QTime::msecsSinceStartOfDay_data() { diff --git a/tests/auto/corelib/tools/qscopeguard/CMakeLists.txt b/tests/auto/corelib/tools/qscopeguard/CMakeLists.txt index 243efdd0b2..11b425448b 100644 --- a/tests/auto/corelib/tools/qscopeguard/CMakeLists.txt +++ b/tests/auto/corelib/tools/qscopeguard/CMakeLists.txt @@ -8,3 +8,6 @@ add_qt_test(tst_qscopeguard SOURCES tst_qscopeguard.cpp ) + +## Scopes: +##################################################################### diff --git a/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro b/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro index 070d4b077c..e3645befcf 100644 --- a/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro +++ b/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro @@ -2,3 +2,6 @@ CONFIG += testcase TARGET = tst_qscopeguard QT = core testlib SOURCES = tst_qscopeguard.cpp + +# Force C++17 if available +contains(QT_CONFIG, c++1z): CONFIG += c++1z diff --git a/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp index 01181ce20e..4bb4113845 100644 --- a/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp +++ b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com> +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -30,24 +31,130 @@ #include <QtCore/QScopeGuard> /*! - \class tst_QScopedGuard + \class tst_QScopeGuard \internal \since 5.11 - \brief Tests class QScopedCleanup and function qScopeGuard + \brief Tests class QScopeGuard and function qScopeGuard */ -class tst_QScopedGuard : public QObject +class tst_QScopeGuard : public QObject { Q_OBJECT private Q_SLOTS: + void construction(); + void constructionFromLvalue(); + void constructionFromRvalue(); void leavingScope(); void exceptions(); }; +void func() +{ +} + +int intFunc() +{ + return 0; +} + +Q_REQUIRED_RESULT int noDiscardFunc() +{ + return 0; +} + +struct Callable +{ + Callable() { } + Callable(const Callable &other) + { + Q_UNUSED(other); + ++copied; + } + Callable(Callable &&other) + { + Q_UNUSED(other); + ++moved; + } + void operator()() { } + + static int copied; + static int moved; + static void resetCounts() + { + copied = 0; + moved = 0; + } +}; + +int Callable::copied = 0; +int Callable::moved = 0; + static int s_globalState = 0; -void tst_QScopedGuard::leavingScope() +void tst_QScopeGuard::construction() +{ +#ifdef __cpp_deduction_guides + QScopeGuard fromLambda([] { }); + QScopeGuard fromFunction(func); + QScopeGuard fromFunctionPointer(&func); + QScopeGuard fromNonVoidFunction(intFunc); + QScopeGuard fromNoDiscardFunction(noDiscardFunc); +#ifndef __apple_build_version__ + QScopeGuard fromStdFunction{std::function(func)}; + std::function stdFunction(func); + QScopeGuard fromNamedStdFunction(stdFunction); +#endif +#else + QSKIP("This test requires C++17 Class Template Argument Deduction support enabled in the compiler."); +#endif +} + +void tst_QScopeGuard::constructionFromLvalue() +{ +#ifdef __cpp_deduction_guides + Callable::resetCounts(); + { + Callable callable; + QScopeGuard guard(callable); + } + QCOMPARE(Callable::copied, 1); + QCOMPARE(Callable::moved, 0); + Callable::resetCounts(); + { + Callable callable; + auto guard = qScopeGuard(callable); + } + QCOMPARE(Callable::copied, 1); + QCOMPARE(Callable::moved, 0); +#else + QSKIP("This test requires C++17 Class Template Argument Deduction support enabled in the compiler."); +#endif +} + +void tst_QScopeGuard::constructionFromRvalue() +{ +#ifdef __cpp_deduction_guides + Callable::resetCounts(); + { + Callable callable; + QScopeGuard guard(std::move(callable)); + } + QCOMPARE(Callable::copied, 0); + QCOMPARE(Callable::moved, 1); + Callable::resetCounts(); + { + Callable callable; + auto guard = qScopeGuard(std::move(callable)); + } + QCOMPARE(Callable::copied, 0); + QCOMPARE(Callable::moved, 1); +#else + QSKIP("This test requires C++17 Class Template Argument Deduction support enabled in the compiler."); +#endif +} + +void tst_QScopeGuard::leavingScope() { auto cleanup = qScopeGuard([] { s_globalState++; QCOMPARE(s_globalState, 3); }); QCOMPARE(s_globalState, 0); @@ -61,7 +168,7 @@ void tst_QScopedGuard::leavingScope() s_globalState++; } -void tst_QScopedGuard::exceptions() +void tst_QScopeGuard::exceptions() { s_globalState = 0; bool caught = false; @@ -81,5 +188,5 @@ void tst_QScopedGuard::exceptions() } -QTEST_MAIN(tst_QScopedGuard) +QTEST_MAIN(tst_QScopeGuard) #include "tst_qscopeguard.moc" |