summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp140
-rw-r--r--tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp44
-rw-r--r--tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp14
-rw-r--r--tests/auto/corelib/kernel/qtranslator/hellotr_la.qmbin230 -> 237 bytes
-rw-r--r--tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp15
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp24
-rw-r--r--tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp24
-rw-r--r--tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp162
-rw-r--r--tests/auto/corelib/text/qcollator/tst_qcollator.cpp14
-rw-r--r--tests/auto/corelib/text/qlocale/tst_qlocale.cpp37
-rw-r--r--tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp160
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp23
-rw-r--r--tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp25
-rw-r--r--tests/auto/corelib/time/qdate/tst_qdate.cpp4
-rw-r--r--tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp23
-rw-r--r--tests/auto/corelib/time/qtime/tst_qtime.cpp6
-rw-r--r--tests/auto/corelib/tools/qscopeguard/CMakeLists.txt3
-rw-r--r--tests/auto/corelib/tools/qscopeguard/qscopeguard.pro3
-rw-r--r--tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp119
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
index cc42afe05c..25c0aad583 100644
--- a/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm
+++ b/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm
Binary files differ
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"