diff options
Diffstat (limited to 'tests/auto/corelib')
19 files changed, 1040 insertions, 374 deletions
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 1f2d4fe4f5..fe378b2095 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -1027,14 +1027,44 @@ void tst_QFile::ungetChar() QCOMPARE(buf[2], '4'); } +#ifdef Q_OS_WIN +QString driveLetters() +{ + wchar_t volumeName[MAX_PATH]; + wchar_t path[MAX_PATH]; + const HANDLE h = FindFirstVolumeW(volumeName, MAX_PATH); + if (h == INVALID_HANDLE_VALUE) + return QString(); + QString result; + do { + if (GetVolumePathNamesForVolumeNameW(volumeName, path, MAX_PATH, NULL)) { + if (path[1] == L':') + result.append(QChar(path[0])); + } + } while (FindNextVolumeW(h, volumeName, MAX_PATH)); + FindVolumeClose(h); + return result; +} + +static inline QChar invalidDriveLetter() +{ + const QString drives = driveLetters().toLower(); + for (char c = 'a'; c <= 'z'; ++c) + if (!drives.contains(QLatin1Char(c))) + return QLatin1Char(c); + Q_ASSERT(false); // All drive letters used?! + return QChar(); +} + +#endif // Q_OS_WIN + void tst_QFile::invalidFile_data() { QTest::addColumn<QString>("fileName"); #if !defined(Q_OS_WIN) QTest::newRow( "x11" ) << QString( "qwe//" ); #else - QTest::newRow( "colon1" ) << QString( "fail:invalid" ); - QTest::newRow( "colon2" ) << QString( "f:ail:invalid" ); + QTest::newRow( "colon2" ) << invalidDriveLetter() + QString::fromLatin1(":ail:invalid"); QTest::newRow( "colon3" ) << QString( ":failinvalid" ); QTest::newRow( "forwardslash" ) << QString( "fail/invalid" ); QTest::newRow( "asterisk" ) << QString( "fail*invalid" ); @@ -1050,8 +1080,7 @@ void tst_QFile::invalidFile() { QFETCH( QString, fileName ); QFile f( fileName ); - QEXPECT_FAIL("colon1", "QTBUG-27306", Continue); - QVERIFY( !f.open( QIODevice::ReadWrite ) ); + QVERIFY2( !f.open( QIODevice::ReadWrite ), qPrintable(fileName) ); } void tst_QFile::createFile() diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 76fa6022ba..82eaa64bc2 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -183,6 +183,9 @@ void tst_QFileSystemWatcher::basicTest() // change the permissions, should get a signal from the watcher testFile.setPermissions(QFile::ReadOwner); + // IN_ATTRIB doesn't work on QNX, so skip this test +#if !defined(Q_OS_QNX) + // waiting max 5 seconds for notification for file permission modification to trigger QTRY_COMPARE(changedSpy.count(), 1); QCOMPARE(changedSpy.at(0).count(), 1); @@ -190,6 +193,8 @@ void tst_QFileSystemWatcher::basicTest() fileName = changedSpy.at(0).at(0).toString(); QCOMPARE(fileName, testFile.fileName()); +#endif + changedSpy.clear(); // remove the watch and modify file permissions, should not get a signal from the watcher diff --git a/tests/auto/corelib/io/qprocess/test/test.pro b/tests/auto/corelib/io/qprocess/test/test.pro index 458bbca738..79ea53cc6b 100644 --- a/tests/auto/corelib/io/qprocess/test/test.pro +++ b/tests/auto/corelib/io/qprocess/test/test.pro @@ -11,7 +11,6 @@ win32:TESTDATA += ../testBatFiles/* include(../qprocess.pri) -win32:CONFIG += insignificant_test # QTBUG-25342 - sometimes hangs mac:CONFIG += insignificant_test # QTBUG-25895 - sometimes hangs for(file, SUBPROGRAMS): TEST_HELPER_INSTALLS += "../$${file}/$${file}" diff --git a/tests/auto/corelib/io/qprocess/testForwarding/main.cpp b/tests/auto/corelib/io/qprocess/testForwarding/main.cpp index ca0dc3986a..126a63c19c 100644 --- a/tests/auto/corelib/io/qprocess/testForwarding/main.cpp +++ b/tests/auto/corelib/io/qprocess/testForwarding/main.cpp @@ -43,6 +43,7 @@ int main() { +#ifndef QT_NO_PROCESS QProcess process; process.setProcessChannelMode(QProcess::ForwardedChannels); if (process.processChannelMode() != QProcess::ForwardedChannels) @@ -62,6 +63,6 @@ int main() process.closeWriteChannel(); process.waitForFinished(5000); - +#endif return 0; } diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 22c88ca1fa..49188c3057 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -75,6 +75,8 @@ class tst_QProcess : public QObject public slots: void initTestCase(); + void cleanupTestCase(); + #ifndef QT_NO_PROCESS private slots: void getSetCheck(); @@ -84,27 +86,23 @@ private slots: void startDetached(); void crashTest(); void crashTest2(); +#ifndef Q_OS_WINCE void echoTest_data(); void echoTest(); void echoTest2(); -#if defined Q_OS_WIN +#ifdef Q_OS_WIN void echoTestGui(); void batFiles_data(); void batFiles(); #endif - void exitStatus_data(); - void exitStatus(); void loopBackTest(); void readTimeoutAndThenCrash(); - void waitForFinished(); void deadWhileReading(); void restartProcessDeadlock(); void closeWriteChannel(); void closeReadChannel(); void openModes(); void emitReadyReadOnlyWhenNewDataArrives(); - void hardExit(); - void softExit(); void softExitInSlots_data(); void softExitInSlots(); void mergedChannels(); @@ -112,25 +110,14 @@ private slots: void forwardedChannelsOutput(); void atEnd(); void atEnd2(); - void processInAThread(); - void processesInMultipleThreads(); void waitForFinishedWithTimeout(); void waitForReadyReadInAReadyReadSlot(); void waitForBytesWrittenInABytesWrittenSlot(); - void spaceArgsTest_data(); - void spaceArgsTest(); -#if defined(Q_OS_WIN) - void nativeArguments(); -#endif - void exitCodeTest(); void setEnvironment_data(); void setEnvironment(); void setProcessEnvironment_data(); void setProcessEnvironment(); - void systemEnvironment(); void spaceInName(); - void lockupsInStartDetached(); - void waitForReadyReadForNonexistantProcess(); void setStandardInputFile(); void setStandardOutputFile_data(); void setStandardOutputFile(); @@ -138,9 +125,29 @@ private slots: void setStandardOutputProcess(); void removeFileWhileProcessIsRunning(); void fileWriterProcess(); - void detachedWorkingDirectoryAndPid(); void switchReadChannels(); +#ifdef Q_OS_WIN void setWorkingDirectory(); +#endif // Q_OS_WIN +#endif // not Q_OS_WINCE + + void exitStatus_data(); + void exitStatus(); + void waitForFinished(); + void hardExit(); + void softExit(); + void processInAThread(); + void processesInMultipleThreads(); + void spaceArgsTest_data(); + void spaceArgsTest(); +#if defined(Q_OS_WIN) + void nativeArguments(); +#endif + void exitCodeTest(); + void systemEnvironment(); + void lockupsInStartDetached(); + void waitForReadyReadForNonexistantProcess(); + void detachedWorkingDirectoryAndPid(); void startFinishStartFinish(); void invalidProgramString_data(); void invalidProgramString(); @@ -155,14 +162,16 @@ private slots: protected slots: void readFromProcess(); void exitLoopSlot(); +#ifndef Q_OS_WINCE void restartProcess(); void waitForReadyReadInAReadyReadSlotSlot(); void waitForBytesWrittenInABytesWrittenSlotSlot(); +#endif private: QProcess *process; qint64 bytesAvailable; -#endif +#endif //QT_NO_PROCESS }; void tst_QProcess::initTestCase() @@ -176,6 +185,13 @@ void tst_QProcess::initTestCase() #endif } +void tst_QProcess::cleanupTestCase() +{ +#ifdef QT_NO_PROCESS + QSKIP("This test requires QProcess support"); +#endif +} + #ifndef QT_NO_PROCESS // Testing get/set functions @@ -299,9 +315,6 @@ void tst_QProcess::readFromProcess() void tst_QProcess::crashTest() { qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState"); -#ifdef Q_OS_WIN - QSKIP("This test opens a crash dialog on Windows"); -#endif process = new QProcess; QSignalSpy stateSpy(process, SIGNAL(stateChanged(QProcess::ProcessState))); QVERIFY(stateSpy.isValid()); @@ -339,9 +352,6 @@ void tst_QProcess::crashTest() //----------------------------------------------------------------------------- void tst_QProcess::crashTest2() { -#ifdef Q_OS_WIN - QSKIP("This test opens a crash dialog on Windows"); -#endif process = new QProcess; process->start("testProcessCrash/testProcessCrash"); QVERIFY(process->waitForStarted(5000)); @@ -373,6 +383,8 @@ void tst_QProcess::crashTest2() process = 0; } +#ifndef Q_OS_WINCE +//Reading and writing to a process is not supported on Qt/CE //----------------------------------------------------------------------------- void tst_QProcess::echoTest_data() { @@ -389,12 +401,9 @@ void tst_QProcess::echoTest_data() } //----------------------------------------------------------------------------- + void tst_QProcess::echoTest() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QFETCH(QByteArray, input); process = new QProcess; @@ -435,6 +444,7 @@ void tst_QProcess::echoTest() delete process; process = 0; } +#endif //----------------------------------------------------------------------------- void tst_QProcess::exitLoopSlot() @@ -443,11 +453,11 @@ void tst_QProcess::exitLoopSlot() } //----------------------------------------------------------------------------- + +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::echoTest2() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif process = new QProcess; connect(process, SIGNAL(readyRead()), this, SLOT(exitLoopSlot())); @@ -491,15 +501,14 @@ void tst_QProcess::echoTest2() delete process; process = 0; } +#endif -#if defined Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +//Batch files are not supported on Winfows CE +// Reading and writing to a process is not supported on Qt/CE //----------------------------------------------------------------------------- void tst_QProcess::echoTestGui() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QProcess process; process.start("testProcessEchoGui/testProcessEchoGui"); @@ -513,22 +522,22 @@ void tst_QProcess::echoTestGui() QCOMPARE(process.readAllStandardOutput(), QByteArray("Hello")); QCOMPARE(process.readAllStandardError(), QByteArray("Hello")); } +#endif // !Q_OS_WINCE && Q_OS_WIN //----------------------------------------------------------------------------- +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +//Batch files are not supported on Winfows CE void tst_QProcess::batFiles_data() { QTest::addColumn<QString>("batFile"); QTest::addColumn<QByteArray>("output"); - QTest::newRow("simple") << QString::fromLatin1("testBatFiles/simple.bat") << QByteArray("Hello"); - QTest::newRow("with space") << QString::fromLatin1("testBatFiles/with space.bat") << QByteArray("Hello"); + QTest::newRow("simple") << QFINDTESTDATA("testBatFiles/simple.bat") << QByteArray("Hello"); + QTest::newRow("with space") << QFINDTESTDATA("testBatFiles/with space.bat") << QByteArray("Hello"); } void tst_QProcess::batFiles() { -#if defined(Q_OS_WINCE) - QSKIP("Batch files are not supported on Windows CE"); -#endif QFETCH(QString, batFile); QFETCH(QByteArray, output); @@ -542,8 +551,7 @@ void tst_QProcess::batFiles() QVERIFY(proc.readAll().startsWith(output)); } - -#endif +#endif // !Q_OS_WINCE && Q_OS_WIN //----------------------------------------------------------------------------- void tst_QProcess::exitStatus_data() @@ -576,11 +584,6 @@ void tst_QProcess::exitStatus() QFETCH(QStringList, processList); QFETCH(QList<QProcess::ExitStatus>, exitStatus); -#ifdef Q_OS_WIN - if (exitStatus.contains(QProcess::CrashExit)) - QSKIP("This test opens a crash dialog on Windows"); -#endif - QCOMPARE(exitStatus.count(), processList.count()); for (int i = 0; i < processList.count(); ++i) { process->start(processList.at(i)); @@ -594,11 +597,10 @@ void tst_QProcess::exitStatus() process = 0; } //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::loopBackTest() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif process = new QProcess; process->start("testProcessEcho/testProcessEcho"); @@ -618,13 +620,13 @@ void tst_QProcess::loopBackTest() delete process; process = 0; } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::readTimeoutAndThenCrash() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif process = new QProcess; process->start("testProcessEcho/testProcessEcho"); @@ -652,6 +654,7 @@ void tst_QProcess::readTimeoutAndThenCrash() delete process; process = 0; } +#endif void tst_QProcess::waitForFinished() { @@ -677,12 +680,10 @@ void tst_QProcess::waitForFinished() QCOMPARE(process.error(), QProcess::FailedToStart); } +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::deadWhileReading() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QProcess process; process.start("testProcessDeadWhileReading/testProcessDeadWhileReading"); @@ -696,13 +697,13 @@ void tst_QProcess::deadWhileReading() QCOMPARE(output.count("\n"), 10*1024); process.waitForFinished(); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::restartProcessDeadlock() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif // The purpose of this test is to detect whether restarting a // process in the finished() connected slot causes a deadlock @@ -726,14 +727,13 @@ void tst_QProcess::restartProcess() { process->start("testProcessEcho/testProcessEcho"); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::closeWriteChannel() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QProcess more; more.start("testProcessEOF/testProcessEOF"); @@ -755,14 +755,13 @@ void tst_QProcess::closeWriteChannel() more.write("q"); QVERIFY(more.waitForFinished(5000)); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE" void tst_QProcess::closeReadChannel() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - for (int i = 0; i < 10; ++i) { QProcess::ProcessChannel channel1 = QProcess::StandardOutput; QProcess::ProcessChannel channel2 = QProcess::StandardError; @@ -788,14 +787,13 @@ void tst_QProcess::closeReadChannel() QVERIFY(proc.waitForFinished(5000)); } } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::openModes() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QProcess proc; QVERIFY(!proc.isOpen()); QVERIFY(proc.openMode() == QProcess::NotOpen); @@ -834,13 +832,13 @@ void tst_QProcess::openModes() QVERIFY(!proc.isWritable()); QCOMPARE(proc.state(), QProcess::NotRunning); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::emitReadyReadOnlyWhenNewDataArrives() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif QProcess proc; connect(&proc, SIGNAL(readyRead()), this, SLOT(exitLoopSlot())); @@ -870,6 +868,7 @@ void tst_QProcess::emitReadyReadOnlyWhenNewDataArrives() proc.write("", 1); QVERIFY(proc.waitForFinished(5000)); } +#endif //----------------------------------------------------------------------------- void tst_QProcess::hardExit() @@ -914,6 +913,8 @@ void tst_QProcess::softExit() QCOMPARE(int(proc.error()), int(QProcess::UnknownError)); } +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE class SoftExitProcess : public QProcess { Q_OBJECT @@ -1011,14 +1012,10 @@ void tst_QProcess::softExitInSlots_data() #endif QTest::newRow("console app") << "testProcessEcho2/testProcessEcho2"; } - //----------------------------------------------------------------------------- + void tst_QProcess::softExitInSlots() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QFETCH(QString, appName); for (int i = 0; i < 5; ++i) { @@ -1029,14 +1026,13 @@ void tst_QProcess::softExitInSlots() QCOMPARE(proc.state(), QProcess::NotRunning); } } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::mergedChannels() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QProcess process; process.setReadChannelMode(QProcess::MergedChannels); QCOMPARE(process.readChannelMode(), QProcess::MergedChannels); @@ -1055,14 +1051,13 @@ void tst_QProcess::mergedChannels() process.closeWriteChannel(); QVERIFY(process.waitForFinished(5000)); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::forwardedChannels() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QProcess process; process.setReadChannelMode(QProcess::ForwardedChannels); QCOMPARE(process.readChannelMode(), QProcess::ForwardedChannels); @@ -1077,13 +1072,12 @@ void tst_QProcess::forwardedChannels() process.closeWriteChannel(); QVERIFY(process.waitForFinished(5000)); } +#endif +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::forwardedChannelsOutput() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QProcess process; process.start("testForwarding/testForwarding"); QVERIFY(process.waitForStarted(5000)); @@ -1093,14 +1087,13 @@ void tst_QProcess::forwardedChannelsOutput() QVERIFY(!data.isEmpty()); QVERIFY(data.contains("forwarded")); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::atEnd() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QProcess process; process.start("testProcessEcho/testProcessEcho"); @@ -1118,6 +1111,7 @@ void tst_QProcess::atEnd() process.write("", 1); QVERIFY(process.waitForFinished(5000)); } +#endif class TestThread : public QThread { @@ -1190,12 +1184,10 @@ void tst_QProcess::processesInMultipleThreads() } //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::waitForFinishedWithTimeout() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - process = new QProcess(this); process->start("testProcessEcho/testProcessEcho"); @@ -1210,14 +1202,13 @@ void tst_QProcess::waitForFinishedWithTimeout() delete process; process = 0; } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::waitForReadyReadInAReadyReadSlot() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - process = new QProcess(this); connect(process, SIGNAL(readyRead()), this, SLOT(waitForReadyReadInAReadyReadSlotSlot())); connect(process, SIGNAL(finished(int)), this, SLOT(exitLoopSlot())); @@ -1240,27 +1231,25 @@ void tst_QProcess::waitForReadyReadInAReadyReadSlot() delete process; process = 0; } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::waitForReadyReadInAReadyReadSlotSlot() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - bytesAvailable = process->bytesAvailable(); process->write("bar", 4); QVERIFY(process->waitForReadyRead(5000)); QTestEventLoop::instance().exitLoop(); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::waitForBytesWrittenInABytesWrittenSlot() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - process = new QProcess(this); connect(process, SIGNAL(bytesWritten(qint64)), this, SLOT(waitForBytesWrittenInABytesWrittenSlotSlot())); bytesAvailable = 0; @@ -1282,19 +1271,18 @@ void tst_QProcess::waitForBytesWrittenInABytesWrittenSlot() delete process; process = 0; } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::waitForBytesWrittenInABytesWrittenSlotSlot() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - process->write("b"); QVERIFY(process->waitForBytesWritten(5000)); QTestEventLoop::instance().exitLoop(); } - +#endif //----------------------------------------------------------------------------- void tst_QProcess::spaceArgsTest_data() { @@ -1604,12 +1592,10 @@ void tst_QProcess::failToStartWithEventLoop() } //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::removeFileWhileProcessIsRunning() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QFile file("removeFile.txt"); QVERIFY(file.open(QFile::WriteOnly)); @@ -1623,8 +1609,10 @@ void tst_QProcess::removeFileWhileProcessIsRunning() process.write("", 1); QVERIFY(process.waitForFinished(5000)); } - +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// OS doesn't support environment variables void tst_QProcess::setEnvironment_data() { QTest::addColumn<QString>("name"); @@ -1644,10 +1632,6 @@ void tst_QProcess::setEnvironment_data() void tst_QProcess::setEnvironment() { -#if defined (Q_OS_WINCE) - QSKIP("OS doesn't support environment variables"); -#endif - // make sure our environment variables are correct QVERIFY(qgetenv("tst_QProcess").isEmpty()); QVERIFY(!qgetenv("PATH").isEmpty()); @@ -1703,8 +1687,10 @@ void tst_QProcess::setEnvironment() QCOMPARE(process.readAll(), value.toLocal8Bit()); } } - +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// OS doesn't support environment variables void tst_QProcess::setProcessEnvironment_data() { setEnvironment_data(); @@ -1712,10 +1698,6 @@ void tst_QProcess::setProcessEnvironment_data() void tst_QProcess::setProcessEnvironment() { -#if defined (Q_OS_WINCE) - QSKIP("OS doesn't support environment variables"); -#endif - // make sure our environment variables are correct QVERIFY(qgetenv("tst_QProcess").isEmpty()); QVERIFY(!qgetenv("PATH").isEmpty()); @@ -1746,6 +1728,7 @@ void tst_QProcess::setProcessEnvironment() QCOMPARE(process.readAll(), value.toLocal8Bit()); } } +#endif //----------------------------------------------------------------------------- void tst_QProcess::systemEnvironment() { @@ -1763,17 +1746,17 @@ void tst_QProcess::systemEnvironment() } //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::spaceInName() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif QProcess process; process.start("test Space In Name/testSpaceInName", QStringList()); QVERIFY(process.waitForStarted()); process.write("", 1); QVERIFY(process.waitForFinished()); } +#endif //----------------------------------------------------------------------------- void tst_QProcess::lockupsInStartDetached() @@ -1790,12 +1773,10 @@ void tst_QProcess::lockupsInStartDetached() } //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::atEnd2() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QProcess process; process.start("testProcessEcho/testProcessEcho"); @@ -1808,6 +1789,7 @@ void tst_QProcess::atEnd2() } QCOMPARE(lines.size(), 7); } +#endif //----------------------------------------------------------------------------- void tst_QProcess::waitForReadyReadForNonexistantProcess() @@ -1835,12 +1817,10 @@ void tst_QProcess::waitForReadyReadForNonexistantProcess() } //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::setStandardInputFile() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - static const char data[] = "A bunch\1of\2data\3\4\5\6\7..."; QProcess process; QFile file("data"); @@ -1857,8 +1837,11 @@ void tst_QProcess::setStandardInputFile() QCOMPARE(all.size(), int(sizeof data) - 1); // testProcessEcho drops the ending \0 QVERIFY(all == data); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::setStandardOutputFile_data() { QTest::addColumn<int>("channelToTest"); @@ -1889,10 +1872,6 @@ void tst_QProcess::setStandardOutputFile_data() void tst_QProcess::setStandardOutputFile() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - static const char data[] = "Original data. "; static const char testdata[] = "Test data."; @@ -1939,8 +1918,11 @@ void tst_QProcess::setStandardOutputFile() QCOMPARE(all.size(), expectedsize); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::setStandardOutputProcess_data() { QTest::addColumn<bool>("merged"); @@ -1950,9 +1932,6 @@ void tst_QProcess::setStandardOutputProcess_data() void tst_QProcess::setStandardOutputProcess() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif QProcess source; QProcess sink; @@ -1976,14 +1955,13 @@ void tst_QProcess::setStandardOutputProcess() else QCOMPARE(all, QByteArray("HHeelllloo,, WWoorrlldd")); } +#endif //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::fileWriterProcess() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif - QString stdinStr; for (int i = 0; i < 5000; ++i) stdinStr += QString::fromLatin1("%1 -- testing testing 1 2 3\n").arg(i); @@ -2005,6 +1983,7 @@ void tst_QProcess::fileWriterProcess() QCOMPARE(QFile("fileWriterProcess.txt").size(), qint64(stdinStr.size())); } while (stopWatch.elapsed() < 3000); } +#endif //----------------------------------------------------------------------------- void tst_QProcess::detachedWorkingDirectoryAndPid() @@ -2051,11 +2030,10 @@ void tst_QProcess::detachedWorkingDirectoryAndPid() } //----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +// Reading and writing to a process is not supported on Qt/CE void tst_QProcess::switchReadChannels() { -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE"); -#endif const char data[] = "ABCD"; QProcess process; @@ -2080,16 +2058,14 @@ void tst_QProcess::switchReadChannels() process.setReadChannel(QProcess::StandardOutput); QCOMPARE(process.read(1), QByteArray("D")); } +#endif //----------------------------------------------------------------------------- +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +// Q_OS_WIN - setWorkingDirectory will chdir before starting the process on unices +// Windows CE does not support working directory logic void tst_QProcess::setWorkingDirectory() { -#ifdef Q_OS_WINCE - QSKIP("Windows CE does not support working directory logic"); -#endif -#ifndef Q_OS_WIN - QSKIP("setWorkingDirectory will chdir before starting the process on unices"); -#endif process = new QProcess; process->setWorkingDirectory("test"); process->start("testSetWorkingDirectory/testSetWorkingDirectory"); @@ -2101,6 +2077,7 @@ void tst_QProcess::setWorkingDirectory() delete process; process = 0; } +#endif //----------------------------------------------------------------------------- void tst_QProcess::startFinishStartFinish() @@ -2173,7 +2150,7 @@ void tst_QProcess::onlyOneStartedSignal() QCOMPARE(spyFinished.count(), 1); } -#endif +#endif //QT_NO_PROCESS QTEST_MAIN(tst_QProcess) #include "tst_qprocess.moc" diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index 84fbfb4131..1cf15e898f 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -115,7 +115,7 @@ private slots: void setPath(); void setDefaultFormat(); void dontCreateNeedlessPaths(); -#if !defined(Q_OS_WIN) +#if !defined(Q_OS_WIN) && !defined(QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER) void dontReorderIniKeysNeedlessly(); #endif #if defined(Q_OS_WIN) @@ -3017,12 +3017,10 @@ void tst_QSettings::dontCreateNeedlessPaths() QVERIFY(!fileInfo.dir().exists()); } -#if !defined(Q_OS_WIN) +#if !defined(Q_OS_WIN) && !defined(QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER) +// This Qt build does not preserve ordering, as a code size optimization. void tst_QSettings::dontReorderIniKeysNeedlessly() { -#ifdef QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER - QSKIP("This Qt build does not preserve ordering, as a code size optimization."); -#endif /* This is a very strong test. It asserts that modifying diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp index 956a3e67aa..24649bf587 100644 --- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp +++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp @@ -183,7 +183,9 @@ private slots: // This test *must* run first. See the definition for why. void processEvents(); void exec(); +#if !defined(QT_NO_EXCEPTIONS) && !defined(Q_OS_WINCE_WM) void throwInExec(); +#endif void reexec(); void execAfterExit(); void wakeUp(); @@ -320,17 +322,15 @@ void tst_QEventLoop::exec() } } +#if !defined(QT_NO_EXCEPTIONS) && !defined(Q_OS_WINCE_WM) +// Exceptions need to be enabled for this test +// Q_OS_WINCE_WM case: this platform doesn't support propagating exceptions through the event loop +// Windows Mobile cannot handle cross library exceptions +// qobject.cpp will try to rethrow the exception after handling +// which causes gwes.exe to crash void tst_QEventLoop::throwInExec() { -#if defined(QT_NO_EXCEPTIONS) || defined(NO_EVENTLOOP_EXCEPTIONS) - QSKIP("Exceptions are disabled"); -#elif defined(Q_OS_WINCE_WM) - // Windows Mobile cannot handle cross library exceptions - // qobject.cpp will try to rethrow the exception after handling - // which causes gwes.exe to crash - QSKIP("This platform doesn't support propagating exceptions through the event loop"); -#else - // exceptions compiled in, runtime tests follow. +// exceptions compiled in, runtime tests follow. #if defined(Q_OS_LINUX) // C++ exceptions can't be passed through glib callbacks. Skip the test if // we're using the glib event loop. @@ -366,8 +366,8 @@ void tst_QEventLoop::throwInExec() } QCOMPARE(caughtExceptions, 2); } -#endif } +#endif void tst_QEventLoop::reexec() { diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro b/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro new file mode 100644 index 0000000000..f8a49254d2 --- /dev/null +++ b/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs + +SUBDIRS = systemsemaphorehelper test diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/main.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/main.cpp new file mode 100644 index 0000000000..2e85d8610e --- /dev/null +++ b/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/main.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QCoreApplication> +#include <QDebug> +#include <QStringList> +#include <QSystemSemaphore> + +int acquire(int count = 1) +{ + QSystemSemaphore sem("store"); + + for (int i = 0; i < count; ++i) { + if (!sem.acquire()) { + qWarning() << "Could not acquire" << sem.key(); + return EXIT_FAILURE; + } + } + qDebug("done aquiring"); + return EXIT_SUCCESS; +} + +int release() +{ + QSystemSemaphore sem("store"); + if (!sem.release()) { + qWarning() << "Could not release" << sem.key(); + return EXIT_FAILURE; + } + qDebug("done releasing"); + return EXIT_SUCCESS; +} + +int acquirerelease() +{ + QSystemSemaphore sem("store"); + if (!sem.acquire()) { + qWarning() << "Could not acquire" << sem.key(); + return EXIT_FAILURE; + } + if (!sem.release()) { + qWarning() << "Could not release" << sem.key(); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + QStringList arguments = app.arguments(); + // binary name is not used here + arguments.takeFirst(); + if (arguments.count() < 1) { + qWarning("Please call the helper with the function to call as argument"); + return EXIT_FAILURE; + } + QString function = arguments.takeFirst(); + if (function == QLatin1String("acquire")) { + int count = 1; + bool ok = true; + if (arguments.count()) + count = arguments.takeFirst().toInt(&ok); + if (!ok) + count = 1; + return acquire(count); + } else if (function == QLatin1String("release")) { + return release(); + } else if (function == QLatin1String("acquirerelease")) { + return acquirerelease(); + } else { + qWarning() << "Unknown function" << function; + } + return EXIT_SUCCESS; +} diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/systemsemaphorehelper.pro b/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/systemsemaphorehelper.pro new file mode 100644 index 0000000000..d1a4e04567 --- /dev/null +++ b/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/systemsemaphorehelper.pro @@ -0,0 +1,9 @@ +QT = core testlib + +DESTDIR = ./ + +win32: CONFIG += console +mac:CONFIG -= app_bundle + +SOURCES += main.cpp + diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/test/test.pro b/tests/auto/corelib/kernel/qsystemsemaphore/test/test.pro new file mode 100644 index 0000000000..cc76b2c233 --- /dev/null +++ b/tests/auto/corelib/kernel/qsystemsemaphore/test/test.pro @@ -0,0 +1,10 @@ +CONFIG += testcase +QT = core testlib + +win32: CONFIG += console +mac:CONFIG -= app_bundle + +SOURCES += tst_qsystemsemaphore.cpp +TARGET = tst_qsystemsemaphore + +DESTDIR = ../ diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp new file mode 100644 index 0000000000..85f7d2a4b2 --- /dev/null +++ b/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp @@ -0,0 +1,275 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/QSystemSemaphore> +#include <QtCore/QVector> +#include <QtCore/QTemporaryDir> + +#define EXISTING_SHARE "existing" +#define HELPERWAITTIME 10000 + +class tst_QSystemSemaphore : public QObject +{ + Q_OBJECT + +public: + tst_QSystemSemaphore(); + +public Q_SLOTS: + void initTestCase(); + void init(); + void cleanup(); + +private slots: + void key_data(); + void key(); + + void basicacquire(); + void complexacquire(); + + void basicProcesses(); + + void processes_data(); + void processes(); + +#ifndef Q_OS_WIN + void undo(); +#endif + void initialValue(); + +private: + QString helperBinary(); + QSystemSemaphore *existingLock; +}; + +tst_QSystemSemaphore::tst_QSystemSemaphore() +{ +} + +void tst_QSystemSemaphore::initTestCase() +{ + QVERIFY2(!helperBinary().isEmpty(), "Could not find helper binary"); +} + +void tst_QSystemSemaphore::init() +{ + existingLock = new QSystemSemaphore(EXISTING_SHARE, 1, QSystemSemaphore::Create); +} + +void tst_QSystemSemaphore::cleanup() +{ + delete existingLock; +} + +void tst_QSystemSemaphore::key_data() +{ + QTest::addColumn<QString>("constructorKey"); + QTest::addColumn<QString>("setKey"); + + QTest::newRow("null, null") << QString() << QString(); + QTest::newRow("null, one") << QString() << QString("one"); + QTest::newRow("one, two") << QString("one") << QString("two"); +} + +/*! + Basic key testing + */ +void tst_QSystemSemaphore::key() +{ + QFETCH(QString, constructorKey); + QFETCH(QString, setKey); + + QSystemSemaphore sem(constructorKey); + QCOMPARE(sem.key(), constructorKey); + QCOMPARE(sem.error(), QSystemSemaphore::NoError); + QCOMPARE(sem.errorString(), QString()); + + sem.setKey(setKey); + QCOMPARE(sem.key(), setKey); + QCOMPARE(sem.error(), QSystemSemaphore::NoError); + QCOMPARE(sem.errorString(), QString()); +} + +void tst_QSystemSemaphore::basicacquire() +{ + QSystemSemaphore sem("QSystemSemaphore_basicacquire", 1, QSystemSemaphore::Create); + QVERIFY(sem.acquire()); + QCOMPARE(sem.error(), QSystemSemaphore::NoError); + QVERIFY(sem.release()); + QCOMPARE(sem.error(), QSystemSemaphore::NoError); + QCOMPARE(sem.errorString(), QString()); +} + +void tst_QSystemSemaphore::complexacquire() +{ + QSystemSemaphore sem("QSystemSemaphore_complexacquire", 2, QSystemSemaphore::Create); + QVERIFY(sem.acquire()); + QVERIFY(sem.release()); + QVERIFY(sem.acquire()); + QVERIFY(sem.release()); + QVERIFY(sem.acquire()); + QVERIFY(sem.acquire()); + QVERIFY(sem.release()); + QVERIFY(sem.release()); + QCOMPARE(sem.error(), QSystemSemaphore::NoError); + QCOMPARE(sem.errorString(), QString()); +} + +void tst_QSystemSemaphore::basicProcesses() +{ + QSystemSemaphore sem("store", 0, QSystemSemaphore::Create); + + QProcess acquire; + acquire.setProcessChannelMode(QProcess::ForwardedChannels); + + QProcess release; + release.setProcessChannelMode(QProcess::ForwardedChannels); + + acquire.start(helperBinary(), QStringList("acquire")); + QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); + acquire.waitForFinished(HELPERWAITTIME); + QVERIFY(acquire.state() == QProcess::Running); + acquire.kill(); + release.start(helperBinary(), QStringList("release")); + QVERIFY2(release.waitForStarted(), "Could not start helper binary"); + acquire.waitForFinished(HELPERWAITTIME); + release.waitForFinished(HELPERWAITTIME); + QVERIFY(acquire.state() == QProcess::NotRunning); +} + +void tst_QSystemSemaphore::processes_data() +{ + QTest::addColumn<int>("processes"); + for (int i = 0; i < 5; ++i) { + QTest::newRow("1 process") << 1; + QTest::newRow("3 process") << 3; + QTest::newRow("10 process") << 10; + } +} + +void tst_QSystemSemaphore::processes() +{ + QSystemSemaphore sem("store", 1, QSystemSemaphore::Create); + + QFETCH(int, processes); + QVector<QString> scripts(processes, "acquirerelease"); + + QList<QProcess*> consumers; + for (int i = 0; i < scripts.count(); ++i) { + QProcess *p = new QProcess; + p->setProcessChannelMode(QProcess::ForwardedChannels); + consumers.append(p); + p->start(helperBinary(), QStringList(scripts.at(i))); + } + + while (!consumers.isEmpty()) { + consumers.first()->waitForFinished(); + QCOMPARE(consumers.first()->exitStatus(), QProcess::NormalExit); + QCOMPARE(consumers.first()->exitCode(), 0); + delete consumers.takeFirst(); + } +} + +// This test only checks a unix behavior. +#ifndef Q_OS_WIN +void tst_QSystemSemaphore::undo() +{ + QSystemSemaphore sem("store", 1, QSystemSemaphore::Create); + + QStringList acquireArguments = QStringList("acquire"); + QProcess acquire; + acquire.setProcessChannelMode(QProcess::ForwardedChannels); + acquire.start(helperBinary(), acquireArguments); + QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); + acquire.waitForFinished(HELPERWAITTIME); + QVERIFY(acquire.state()== QProcess::NotRunning); + + // At process exit the kernel should auto undo + + acquire.start(helperBinary(), acquireArguments); + QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); + acquire.waitForFinished(HELPERWAITTIME); + QVERIFY(acquire.state()== QProcess::NotRunning); +} +#endif + +void tst_QSystemSemaphore::initialValue() +{ + QSystemSemaphore sem("store", 1, QSystemSemaphore::Create); + + QStringList acquireArguments = QStringList("acquire"); + QStringList releaseArguments = QStringList("release"); + QProcess acquire; + acquire.setProcessChannelMode(QProcess::ForwardedChannels); + + QProcess release; + release.setProcessChannelMode(QProcess::ForwardedChannels); + + acquire.start(helperBinary(), acquireArguments); + QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); + acquire.waitForFinished(HELPERWAITTIME); + QVERIFY(acquire.state()== QProcess::NotRunning); + + acquire.start(helperBinary(), acquireArguments << QLatin1String("2")); + QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); + acquire.waitForFinished(HELPERWAITTIME); + QVERIFY(acquire.state()== QProcess::Running); + acquire.kill(); + + release.start(helperBinary(), releaseArguments); + QVERIFY2(release.waitForStarted(), "Could not start helper binary"); + acquire.waitForFinished(HELPERWAITTIME); + release.waitForFinished(HELPERWAITTIME); + QVERIFY(acquire.state()== QProcess::NotRunning); +} + +QString tst_QSystemSemaphore::helperBinary() +{ + QString binary = QStringLiteral("systemsemaphorehelper/systemsemaphorehelper"); +#ifdef Q_OS_WIN + binary += QStringLiteral(".exe"); +#endif + return binary; +} +QTEST_MAIN(tst_QSystemSemaphore) +#include "tst_qsystemsemaphore.moc" + diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index b731eaf12a..0d41328320 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -517,38 +517,6 @@ void tst_QMimeDatabase::allMimeTypes() } } -void tst_QMimeDatabase::inheritsPerformance() -{ - // Check performance of inherits(). - // This benchmark (which started in 2009 in kmimetypetest.cpp) uses 40 mimetypes. - QStringList mimeTypes; mimeTypes << QLatin1String("image/jpeg") << QLatin1String("image/png") << QLatin1String("image/tiff") << QLatin1String("text/plain") << QLatin1String("text/html"); - mimeTypes += mimeTypes; - mimeTypes += mimeTypes; - mimeTypes += mimeTypes; - QCOMPARE(mimeTypes.count(), 40); - QMimeDatabase db; - QMimeType mime = db.mimeTypeForName(QString::fromLatin1("text/x-chdr")); - QVERIFY(mime.isValid()); - QBENCHMARK { - QString match; - foreach (const QString &mt, mimeTypes) { - if (mime.inherits(mt)) { - match = mt; - // of course there would normally be a "break" here, but we're testing worse-case - // performance here - } - } - QCOMPARE(match, QString::fromLatin1("text/plain")); - } - // Numbers from 2011, in release mode: - // KDE 4.7 numbers: 0.21 msec / 494,000 ticks / 568,345 instr. loads per iteration - // QMimeBinaryProvider (with Qt 5): 0.16 msec / NA / 416,049 instr. reads per iteration - // QMimeXmlProvider (with Qt 5): 0.062 msec / NA / 172,889 instr. reads per iteration - // (but the startup time is way higher) - // And memory usage is flat at 200K with QMimeBinaryProvider, while it peaks at 6 MB when - // parsing XML, and then keeps being around 4.5 MB for all the in-memory hashes. -} - void tst_QMimeDatabase::suffixes_data() { QTest::addColumn<QString>("mimeType"); diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h index f30eb00461..ea050b5014 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h @@ -70,7 +70,6 @@ private slots: void mimeTypeForFileAndContent_data(); void mimeTypeForFileAndContent(); void allMimeTypes(); - void inheritsPerformance(); void suffixes_data(); void suffixes(); void knownSuffix(); diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 81ba1b0fd9..6d73755cfc 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -1251,18 +1251,32 @@ void tst_QFuture::throttling() void tst_QFuture::voidConversions() { - QFutureInterface<int> iface; - iface.reportStarted(); + { + QFutureInterface<int> iface; + iface.reportStarted(); - QFuture<int> intFuture(&iface); + QFuture<int> intFuture(&iface); + int value = 10; + iface.reportFinished(&value); - int value = 10; - iface.reportFinished(&value); + QFuture<void> voidFuture(intFuture); + voidFuture = intFuture; + + QVERIFY(voidFuture == intFuture); + } - QFuture<void> voidFuture(intFuture); - voidFuture = intFuture; + { + QFuture<void> voidFuture; + { + QFutureInterface<QList<int> > iface; + iface.reportStarted(); - QVERIFY(voidFuture == intFuture); + QFuture<QList<int> > listFuture(&iface); + iface.reportResult(QList<int>() << 1 << 2 << 3); + voidFuture = listFuture; + } + QCOMPARE(voidFuture.resultCount(), 0); + } } diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 331024c560..848fdb14a4 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -147,7 +147,9 @@ private slots: void reserveExtended(); void movablity_data(); void movablity(); +#if defined(Q_COMPILER_LAMBDA) void literals(); +#endif }; static const struct StaticByteArrays { @@ -1878,9 +1880,10 @@ void tst_QByteArray::movablity() QVERIFY(true); } +#if defined(Q_COMPILER_LAMBDA) +// Only tested on c++0x compliant compiler or gcc void tst_QByteArray::literals() { -#if defined(Q_COMPILER_LAMBDA) QByteArray str(QByteArrayLiteral("abcd")); QVERIFY(str.length() == 4); @@ -1897,10 +1900,8 @@ void tst_QByteArray::literals() QVERIFY(str2.constData() == s); QVERIFY(str2.data() != s); -#else - QSKIP("Only tested on c++0x compliant compiler or gcc"); -#endif } +#endif const char globalChar = '1'; diff --git a/tests/auto/corelib/tools/qdate/tst_qdate.cpp b/tests/auto/corelib/tools/qdate/tst_qdate.cpp index 01805e1271..9978a252bf 100644 --- a/tests/auto/corelib/tools/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/tools/qdate/tst_qdate.cpp @@ -117,8 +117,8 @@ void tst_QDate::isNull_data() QTest::addColumn<qint64>("jd"); QTest::addColumn<bool>("null"); - qint64 minJd = std::numeric_limits<qint64>::min() / 2; - qint64 maxJd = std::numeric_limits<qint64>::max() / 2; + qint64 minJd = Q_INT64_C(-784350574879); + qint64 maxJd = Q_INT64_C( 784354017364); QTest::newRow("qint64 min") << std::numeric_limits<qint64>::min() << true; QTest::newRow("minJd - 1") << minJd - 1 << true; @@ -448,8 +448,8 @@ void tst_QDate::julianDaysLimits() { qint64 min = std::numeric_limits<qint64>::min(); qint64 max = std::numeric_limits<qint64>::max(); - qint64 minJd = std::numeric_limits<qint64>::min() / 2; - qint64 maxJd = std::numeric_limits<qint64>::max() / 2; + qint64 minJd = Q_INT64_C(-784350574879); + qint64 maxJd = Q_INT64_C( 784354017364); QDate maxDate = QDate::fromJulianDay(maxJd); QDate minDate = QDate::fromJulianDay(minJd); @@ -492,7 +492,7 @@ void tst_QDate::julianDaysLimits() dt = minDate.addDays(min); QCOMPARE(dt.isValid(), false); dt = minDate.addDays(max); - QCOMPARE(dt.isValid(), true); + QCOMPARE(dt.isValid(), false); dt = zeroDate.addDays(-1); QCOMPARE(dt.isValid(), true); @@ -664,8 +664,8 @@ void tst_QDate::addYears_data() void tst_QDate::daysTo() { - qint64 minJd = std::numeric_limits<qint64>::min() / 2; - qint64 maxJd = std::numeric_limits<qint64>::max() / 2; + qint64 minJd = Q_INT64_C(-784350574879); + qint64 maxJd = Q_INT64_C( 784354017364); QDate dt1(2000, 1, 1); QDate dt2(2000, 1, 5); @@ -1356,9 +1356,10 @@ void tst_QDate::roundtrip() const // year(), month(), day(), julianDayFromDate(), and getDateFromJulianDay() // to ensure they are internally consistent (but doesn't guarantee correct) - // Test Julian round trip around JD 0 and current low end of valid range + // Test Julian round trip around JD 0 and the c++ integer division rounding + // problem point (eg. negative numbers) in the conversion functions. QDate testDate; - QDate loopDate = QDate::fromJulianDay(-31738); // 1 Jan 4800 BC + QDate loopDate = QDate::fromJulianDay(-50001); // 1 Jan 4850 BC while (loopDate.toJulianDay() <= 5150) { // 31 Dec 4700 BC testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day()); QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay()); @@ -1389,9 +1390,20 @@ void tst_QDate::roundtrip() const loopDate = loopDate.addDays(1); } + qint64 minJd = Q_INT64_C(-784350574879); + qint64 maxJd = Q_INT64_C( 784354017364); + // Test Gregorian round trip at top end of conversion range - loopDate = QDate::fromJulianDay(513024036); // 1 Jan 1399900 AD - while (loopDate.toJulianDay() <= 513060925) { // 31 Dec 1400000 AD + loopDate = QDate::fromJulianDay(maxJd); + while (loopDate.toJulianDay() >= maxJd - 146397) { + testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day()); + QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay()); + loopDate = loopDate.addDays(-1); + } + + // Test Gregorian round trip at low end of conversion range + loopDate = QDate::fromJulianDay(minJd); + while (loopDate.toJulianDay() <= minJd + 146397) { testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day()); QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay()); loopDate = loopDate.addDays(1); diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 9e71a32f87..8da5d2808b 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -74,11 +74,15 @@ private slots: void toTime_t(); void daylightSavingsTimeChange(); void setDate(); + void setTime_data(); void setTime(); + void setTimeSpec_data(); void setTimeSpec(); void setTime_t(); void setMSecsSinceEpoch_data(); void setMSecsSinceEpoch(); + void fromMSecsSinceEpoch_data(); + void fromMSecsSinceEpoch(); void toString_isoDate_data(); void toString_isoDate(); void toString_enumformat(); @@ -333,57 +337,59 @@ void tst_QDateTime::setDate() QCOMPARE(dt6.timeSpec(), Qt::LocalTime); } +void tst_QDateTime::setTime_data() +{ + QTest::addColumn<QDateTime>("dateTime"); + QTest::addColumn<QTime>("newTime"); + + QTest::newRow("data0") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC) << QTime(23, 11, 22); + QTest::newRow("data1") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::LocalTime) << QTime(23, 11, 22); + QTest::newRow("data2") << QDateTime(QDate(4004, 3, 25), QTime(0, 45, 57), Qt::UTC) << QTime(23, 11, 22); + QTest::newRow("data3") << QDateTime(QDate(4004, 3, 25), QTime(0, 45, 57), Qt::LocalTime) << QTime(23, 11, 22); + QTest::newRow("data4") << QDateTime(QDate(1760, 3, 25), QTime(0, 45, 57), Qt::UTC) << QTime(23, 11, 22); + QTest::newRow("data5") << QDateTime(QDate(1760, 3, 25), QTime(0, 45, 57), Qt::LocalTime) << QTime(23, 11, 22); + + QTest::newRow("set on std/dst") << QDateTime::currentDateTime() << QTime(23, 11, 22); +} + void tst_QDateTime::setTime() { - QDateTime dt1(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC); - dt1.setTime(QTime(23, 11, 22)); - QCOMPARE(dt1.date(), QDate(2004, 3, 25)); - QCOMPARE(dt1.time(), QTime(23, 11, 22)); - QCOMPARE(dt1.timeSpec(), Qt::UTC); + QFETCH(QDateTime, dateTime); + QFETCH(QTime, newTime); - QDateTime dt2(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::LocalTime); - dt2.setTime(QTime(23, 11, 22)); - QCOMPARE(dt2.date(), QDate(2004, 3, 25)); - QCOMPARE(dt2.time(), QTime(23, 11, 22)); - QCOMPARE(dt2.timeSpec(), Qt::LocalTime); + const QDate expectedDate(dateTime.date()); + const Qt::TimeSpec expectedTimeSpec(dateTime.timeSpec()); - QDateTime dt3(QDate(4004, 3, 25), QTime(0, 45, 57), Qt::UTC); - dt3.setTime(QTime(23, 11, 22)); - QCOMPARE(dt3.date(), QDate(4004, 3, 25)); - QCOMPARE(dt3.time(), QTime(23, 11, 22)); - QCOMPARE(dt3.timeSpec(), Qt::UTC); + dateTime.setTime(newTime); - QDateTime dt4(QDate(4004, 3, 25), QTime(0, 45, 57), Qt::LocalTime); - dt4.setTime(QTime(23, 11, 22)); - QCOMPARE(dt4.date(), QDate(4004, 3, 25)); - QCOMPARE(dt4.time(), QTime(23, 11, 22)); - QCOMPARE(dt4.timeSpec(), Qt::LocalTime); + QCOMPARE(dateTime.date(), expectedDate); + QCOMPARE(dateTime.time(), newTime); + QCOMPARE(dateTime.timeSpec(), expectedTimeSpec); +} - QDateTime dt5(QDate(1760, 3, 25), QTime(0, 45, 57), Qt::UTC); - dt5.setTime(QTime(23, 11, 22)); - QCOMPARE(dt5.date(), QDate(1760, 3, 25)); - QCOMPARE(dt5.time(), QTime(23, 11, 22)); - QCOMPARE(dt5.timeSpec(), Qt::UTC); +void tst_QDateTime::setTimeSpec_data() +{ + QTest::addColumn<QDateTime>("dateTime"); + QTest::addColumn<Qt::TimeSpec>("newTimeSpec"); - QDateTime dt6(QDate(1760, 3, 25), QTime(0, 45, 57), Qt::LocalTime); - dt6.setTime(QTime(23, 11, 22)); - QCOMPARE(dt6.date(), QDate(1760, 3, 25)); - QCOMPARE(dt6.time(), QTime(23, 11, 22)); - QCOMPARE(dt6.timeSpec(), Qt::LocalTime); + QTest::newRow("UTC => UTC") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC) << Qt::UTC; + QTest::newRow("UTC => LocalTime") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC) << Qt::LocalTime; + QTest::newRow("UTC => OffsetFromUTC") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC) << Qt::OffsetFromUTC; } void tst_QDateTime::setTimeSpec() { - QDateTime dt1(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC); - dt1.setTimeSpec(Qt::UTC); - QCOMPARE(dt1.date(), QDate(2004, 3, 25)); - QCOMPARE(dt1.time(), QTime(0, 45, 57)); - QCOMPARE(dt1.timeSpec(), Qt::UTC); + QFETCH(QDateTime, dateTime); + QFETCH(Qt::TimeSpec, newTimeSpec); - dt1.setTimeSpec(Qt::LocalTime); - QCOMPARE(dt1.date(), QDate(2004, 3, 25)); - QCOMPARE(dt1.time(), QTime(0, 45, 57)); - QCOMPARE(dt1.timeSpec(), Qt::LocalTime); + const QDate expectedDate(dateTime.date()); + const QTime expectedTime(dateTime.time()); + + dateTime.setTimeSpec(newTimeSpec); + + QCOMPARE(dateTime.date(), expectedDate); + QCOMPARE(dateTime.time(), expectedTime); + QCOMPARE(dateTime.timeSpec(), newTimeSpec); } void tst_QDateTime::setTime_t() @@ -482,6 +488,13 @@ void tst_QDateTime::setMSecsSinceEpoch() QCOMPARE(dt, utc); if (europeanTimeZone) { QCOMPARE(dt.toLocalTime(), european); + + // Test converting from LocalTime to UTC back to LocalTime. + QDateTime localDt; + localDt.setTimeSpec(Qt::LocalTime); + localDt.setMSecsSinceEpoch(msecs); + + QCOMPARE(localDt, utc); } QCOMPARE(dt.toMSecsSinceEpoch(), msecs); @@ -494,6 +507,33 @@ void tst_QDateTime::setMSecsSinceEpoch() QCOMPARE(dt, reference.addMSecs(msecs)); } +void tst_QDateTime::fromMSecsSinceEpoch_data() +{ + setMSecsSinceEpoch_data(); +} + +void tst_QDateTime::fromMSecsSinceEpoch() +{ + QFETCH(qint64, msecs); + QFETCH(QDateTime, utc); + QFETCH(QDateTime, european); + + QDateTime dt(QDateTime::fromMSecsSinceEpoch(msecs)); + + QCOMPARE(dt, utc); + if (europeanTimeZone) + QCOMPARE(dt.toLocalTime(), european); + + QCOMPARE(dt.toMSecsSinceEpoch(), msecs); + + if (quint64(msecs / 1000) < 0xFFFFFFFF) { + QCOMPARE(qint64(dt.toTime_t()), msecs / 1000); + } + + QDateTime reference(QDate(1970, 1, 1), QTime(), Qt::UTC); + QCOMPARE(dt, reference.addMSecs(msecs)); +} + void tst_QDateTime::toString_isoDate_data() { QTest::addColumn<QDateTime>("dt"); @@ -514,6 +554,9 @@ void tst_QDateTime::toString_isoDate_data() QTest::newRow("negative OffsetFromUTC") << dt << QString("1978-11-09T13:28:34-02:00"); + QTest::newRow("invalid") + << QDateTime(QDate(-1, 11, 9), QTime(13, 28, 34), Qt::UTC) + << QString(); } void tst_QDateTime::toString_isoDate() @@ -1209,6 +1252,9 @@ void tst_QDateTime::operator_eqeq_data() QTest::newRow("data11") << dateTime3 << dateTime3d << true << false; QTest::newRow("data12") << dateTime3c << dateTime3d << true << false; QTest::newRow("data13") << dateTime3 << dateTime3e << false << false; + QTest::newRow("invalid == invalid") << invalidDateTime() << invalidDateTime() << true << false; + QTest::newRow("invalid == valid #1") << invalidDateTime() << dateTime1 << false << false; + if (europeanTimeZone) { QTest::newRow("data14") << QDateTime(QDate(2004, 1, 2), QTime(2, 2, 3), Qt::LocalTime) << QDateTime(QDate(2004, 1, 2), QTime(1, 2, 3), Qt::UTC) << true << true; @@ -1248,11 +1294,14 @@ void tst_QDateTime::operator_eqeq() } #ifndef Q_OS_WINCE +Q_DECLARE_METATYPE(QDataStream::Version) + void tst_QDateTime::operator_insert_extract_data() { QTest::addColumn<QDateTime>("dateTime"); QTest::addColumn<QString>("serialiseAs"); QTest::addColumn<QString>("deserialiseAs"); + QTest::addColumn<QDataStream::Version>("dataStreamVersion"); const QDateTime positiveYear(QDateTime(QDate(2012, 8, 14), QTime(8, 0, 0), Qt::LocalTime)); const QDateTime negativeYear(QDateTime(QDate(-2012, 8, 14), QTime(8, 0, 0), Qt::LocalTime)); @@ -1260,14 +1309,19 @@ void tst_QDateTime::operator_insert_extract_data() const QString westernAustralia(QString::fromLatin1("AWST-8AWDT-9,M10.5.0,M3.5.0/03:00:00")); const QString hawaii(QString::fromLatin1("HAW10")); - QTest::newRow("14/08/2012 08:00 WA => HAWAII") << positiveYear << westernAustralia << hawaii; - QTest::newRow("14/08/2012 08:00 WA => HAWAII") << positiveYear << westernAustralia << hawaii; - QTest::newRow("14/08/2012 08:00 WA => HAWAII") << positiveYear << westernAustralia << hawaii; - QTest::newRow("14/08/2012 08:00 WA => WA") << positiveYear << westernAustralia << westernAustralia; - QTest::newRow("14/08/-2012 08:00 HAWAII => WA") << negativeYear << hawaii << westernAustralia; - QTest::newRow("14/08/-2012 08:00 HAWAII => WA") << negativeYear << hawaii << westernAustralia; - QTest::newRow("14/08/-2012 08:00 HAWAII => WA") << negativeYear << hawaii << westernAustralia; - QTest::newRow("14/08/2012 08:00 HAWAII => HAWAII") << positiveYear << hawaii << hawaii; + const QDataStream tmpDataStream; + const int thisVersion = tmpDataStream.version(); + for (int version = QDataStream::Qt_1_0; version <= thisVersion; ++version) { + const QDataStream::Version dataStreamVersion = static_cast<QDataStream::Version>(version); + QTest::newRow(QString::fromLatin1("v%1 WA => HAWAII %2").arg(dataStreamVersion).arg(positiveYear.toString()).toLocal8Bit().constData()) + << positiveYear << westernAustralia << hawaii << dataStreamVersion; + QTest::newRow(QString::fromLatin1("v%1 WA => WA %2").arg(dataStreamVersion).arg(positiveYear.toString()).toLocal8Bit().constData()) + << positiveYear << westernAustralia << westernAustralia << dataStreamVersion; + QTest::newRow(QString::fromLatin1("v%1 HAWAII => WA %2").arg(dataStreamVersion).arg(negativeYear.toString()).toLocal8Bit().constData()) + << negativeYear << hawaii << westernAustralia << dataStreamVersion; + QTest::newRow(QString::fromLatin1("v%1 HAWAII => HAWAII %2").arg(dataStreamVersion).arg(positiveYear.toString()).toLocal8Bit().constData()) + << positiveYear << hawaii << hawaii << dataStreamVersion; + } } void tst_QDateTime::operator_insert_extract() @@ -1275,8 +1329,11 @@ void tst_QDateTime::operator_insert_extract() QFETCH(QDateTime, dateTime); QFETCH(QString, serialiseAs); QFETCH(QString, deserialiseAs); + QFETCH(QDataStream::Version, dataStreamVersion); + // Save the previous timezone so we can restore it afterwards, just in case. QString previousTimeZone = qgetenv("TZ"); + // Start off in a certain timezone. qputenv("TZ", serialiseAs.toLocal8Bit().constData()); tzset(); QDateTime dateTimeAsUTC(dateTime.toUTC()); @@ -1284,8 +1341,15 @@ void tst_QDateTime::operator_insert_extract() QByteArray byteArray; { QDataStream dataStream(&byteArray, QIODevice::WriteOnly); - dataStream << dateTime; - dataStream << dateTime; + dataStream.setVersion(dataStreamVersion); + if (dataStreamVersion >= QDataStream::Qt_5_0) { + // Qt 5 serialises as UTC and converts back to the stored timeSpec when + // deserialising; we don't need to do it ourselves... + dataStream << dateTime << dateTime; + } else { + // ... but lower versions don't, so we have to here. + dataStream << dateTimeAsUTC << dateTimeAsUTC; + } } // Ensure that a change in timezone between serialisation and deserialisation @@ -1296,11 +1360,26 @@ void tst_QDateTime::operator_insert_extract() { // Deserialise whole QDateTime at once. QDataStream dataStream(&byteArray, QIODevice::ReadOnly); + dataStream.setVersion(dataStreamVersion); QDateTime deserialised; dataStream >> deserialised; - // Ensure local time is still correct. - QCOMPARE(deserialised, expectedLocalTime); - // Sanity check UTC times. + + if (dataStreamVersion >= QDataStream::Qt_5_0) { + // Ensure local time is still correct. Again, Qt 5 handles the timeSpec + // conversion (in this case, UTC => LocalTime) for us when deserialising. + QCOMPARE(deserialised, expectedLocalTime); + } else { + if (dataStreamVersion < QDataStream::Qt_4_0) { + // Versions lower than Qt 4 don't serialise the timeSpec, instead + // assuming that everything is LocalTime. + deserialised.setTimeSpec(Qt::UTC); + } + // Qt 4.* versions do serialise the timeSpec, so we only need to convert from UTC here. + deserialised = deserialised.toLocalTime(); + + QCOMPARE(deserialised, expectedLocalTime); + } + // Sanity check UTC times (operator== already converts its operands to UTC before comparing). QCOMPARE(deserialised.toUTC(), expectedLocalTime.toUTC()); // Deserialise each component individually. @@ -1309,9 +1388,11 @@ void tst_QDateTime::operator_insert_extract() QTime deserialisedTime; dataStream >> deserialisedTime; qint8 deserialisedSpec; - dataStream >> deserialisedSpec; + if (dataStreamVersion >= QDataStream::Qt_4_0) + dataStream >> deserialisedSpec; deserialised = QDateTime(deserialisedDate, deserialisedTime, Qt::UTC); - deserialised = deserialised.toTimeSpec(static_cast<Qt::TimeSpec>(deserialisedSpec)); + if (dataStreamVersion >= QDataStream::Qt_4_0) + deserialised = deserialised.toTimeSpec(static_cast<Qt::TimeSpec>(deserialisedSpec)); // Ensure local time is still correct. QCOMPARE(deserialised, expectedLocalTime); // Sanity check UTC times. @@ -1352,8 +1433,6 @@ void tst_QDateTime::toString_strformat_data() << QString("d'foobar'") << QString("31foobar"); QTest::newRow( "datetime9" ) << QDateTime(QDate(1999, 12, 31), QTime(3, 59, 59, 999)) << QString("hhhhh") << QString("03033"); - QTest::newRow( "datetime10" ) << QDateTime(QDate(1999, 12, 31), QTime(3, 59, 59, 999)) - << QString("hhhhhaA") << QString("03033amAM"); QTest::newRow( "datetime11" ) << QDateTime(QDate(1999, 12, 31), QTime(23, 59, 59, 999)) << QString("HHHhhhAaAPap") << QString("23231111PMpmPMpm"); QTest::newRow( "datetime12" ) << QDateTime(QDate(1999, 12, 31), QTime(3, 59, 59, 999)) @@ -1361,6 +1440,26 @@ void tst_QDateTime::toString_strformat_data() QTest::newRow( "datetime13" ) << QDateTime(QDate(1974, 12, 1), QTime(14, 14, 20)) << QString("hh''mm''ss dd''MM''yyyy") << QString("14'14'20 01'12'1974"); + QTest::newRow( "missing p and P" ) << QDateTime(QDate(1999, 12, 31), QTime(3, 59, 59, 999)) + << QString("hhhhhaA") << QString("03033aA"); + QTest::newRow( "OK A, bad P" ) << QDateTime(QDate(1999, 12, 31), QTime(0, 59, 59, 999)) + << QString("hhAX") << QString("00AX"); + QTest::newRow( "single, 0 => 12 AM" ) << QDateTime(QDate(1999, 12, 31), QTime(0, 59, 59, 999)) + << QString("hAP") << QString("12AM"); + QTest::newRow( "double, 0 => 12 AM" ) << QDateTime(QDate(1999, 12, 31), QTime(0, 59, 59, 999)) + << QString("hhAP") << QString("12AM"); + QTest::newRow( "double, garbage" ) << QDateTime(QDate(1999, 12, 31), QTime(0, 59, 59, 999)) + << QString("hhAX") << QString("00AX"); + QTest::newRow( "dddd" ) << QDateTime(QDate(1999, 12, 31), QTime(0, 59, 59, 999)) + << QString("dddd") << QString("Friday"); + QTest::newRow( "ddd" ) << QDateTime(QDate(1999, 12, 31), QTime(0, 59, 59, 999)) + << QString("ddd") << QString("Fri"); + QTest::newRow( "MMMM" ) << QDateTime(QDate(1999, 12, 31), QTime(0, 59, 59, 999)) + << QString("MMMM") << QString("December"); + QTest::newRow( "MMM" ) << QDateTime(QDate(1999, 12, 31), QTime(0, 59, 59, 999)) + << QString("MMM") << QString("Dec"); + QTest::newRow( "emtpy" ) << QDateTime(QDate(1999, 12, 31), QTime(0, 59, 59, 999)) + << QString("") << QString(""); } void tst_QDateTime::toString_strformat() @@ -1376,126 +1475,164 @@ void tst_QDateTime::fromStringDateFormat_data() QTest::addColumn<QString>("dateTimeStr"); QTest::addColumn<Qt::DateFormat>("dateFormat"); QTest::addColumn<QDateTime>("expected"); - QTest::addColumn<Qt::TimeSpec>("timeSpec"); // Test Qt::TextDate format. QTest::newRow("text date") << QString::fromLatin1("Tue Jun 17 08:00:10 2003") - << Qt::TextDate << QDateTime(QDate(2003, 6, 17), QTime(8, 0, 10, 0)) << Qt::LocalTime; + << Qt::TextDate << QDateTime(QDate(2003, 6, 17), QTime(8, 0, 10, 0), Qt::LocalTime); QTest::newRow("text date Year 0999") << QString::fromLatin1("Tue Jun 17 08:00:10 0999") - << Qt::TextDate << QDateTime(QDate(999, 6, 17), QTime(8, 0, 10, 0)) << Qt::LocalTime; + << Qt::TextDate << QDateTime(QDate(999, 6, 17), QTime(8, 0, 10, 0), Qt::LocalTime); QTest::newRow("text date Year 999") << QString::fromLatin1("Tue Jun 17 08:00:10 999") - << Qt::TextDate << QDateTime(QDate(999, 6, 17), QTime(8, 0, 10, 0)) << Qt::LocalTime; + << Qt::TextDate << QDateTime(QDate(999, 6, 17), QTime(8, 0, 10, 0), Qt::LocalTime); QTest::newRow("text date Year 12345") << QString::fromLatin1("Tue Jun 17 08:00:10 12345") - << Qt::TextDate << QDateTime(QDate(12345, 6, 17), QTime(8, 0, 10, 0)) << Qt::LocalTime; + << Qt::TextDate << QDateTime(QDate(12345, 6, 17), QTime(8, 0, 10, 0), Qt::LocalTime); QTest::newRow("text date Year -4712") << QString::fromLatin1("Tue Jan 1 00:01:02 -4712") - << Qt::TextDate << QDateTime(QDate(-4712, 1, 1), QTime(0, 1, 2, 0)) << Qt::LocalTime; - QTest::newRow("data0") << QString::fromLatin1("Thu Jan 1 00:00:00 1970") - << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0)) << Qt::LocalTime; - QTest::newRow("data1") << QString::fromLatin1("Thu Jan 2 12:34 1970") - << Qt::TextDate << QDateTime(QDate(1970, 1, 2), QTime(12, 34, 0)) << Qt::LocalTime; - QTest::newRow("data2") << QString::fromLatin1("Thu Jan 1 00 1970") - << Qt::TextDate << invalidDateTime() << Qt::LocalTime; - QTest::newRow("data3") << QString::fromLatin1("Thu Jan 1 00:00:00:00 1970") - << Qt::TextDate << invalidDateTime() << Qt::LocalTime; - QTest::newRow("data4") << QString::fromLatin1("Thu Jan 1 00:00:00:00 1970") - << Qt::TextDate << invalidDateTime() << Qt::LocalTime; - QTest::newRow("data5") << QString::fromLatin1(" Thu Jan 1 00:00:00 1970 ") - << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0)) << Qt::LocalTime; - QTest::newRow("data6") << QString::fromLatin1("Thu Jan 1 00:00:00") - << Qt::TextDate << invalidDateTime() << Qt::LocalTime; - QTest::newRow("data7") << QString::fromLatin1("Thu Jan 1 1970 00:00:00") - << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0)) << Qt::LocalTime; - QTest::newRow("data8") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT+foo") - << Qt::TextDate << invalidDateTime() << Qt::LocalTime; - QTest::newRow("data9") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT") - << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34)) << Qt::UTC; - QTest::newRow("data10") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT-0300") - << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(3, 12, 34)) << Qt::UTC; - QTest::newRow("data11") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT+0300") - << Qt::TextDate << QDateTime(QDate(1969, 12, 31), QTime(21, 12, 34)) << Qt::UTC; - QTest::newRow("data12") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 gmt") - << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34)) << Qt::UTC; - QTest::newRow("data13") << QString::fromLatin1("Thu Jan 1 1970 00:12:34 GMT+0100") - << Qt::TextDate << QDateTime(QDate(1969, 12, 31), QTime(23, 12, 34)) << Qt::UTC; + << Qt::TextDate << QDateTime(QDate(-4712, 1, 1), QTime(0, 1, 2, 0), Qt::LocalTime); + QTest::newRow("text data0") << QString::fromLatin1("Thu Jan 1 00:00:00 1970") + << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::LocalTime); + QTest::newRow("text data1") << QString::fromLatin1("Thu Jan 2 12:34 1970") + << Qt::TextDate << QDateTime(QDate(1970, 1, 2), QTime(12, 34, 0), Qt::LocalTime); + QTest::newRow("text data2") << QString::fromLatin1("Thu Jan 1 00 1970") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text data3") << QString::fromLatin1("Thu Jan 1 00:00:00:00 1970") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text data4") << QString::fromLatin1("Thu 1. Jan 00:00:00 1970") + << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0), Qt::LocalTime); + QTest::newRow("text data5") << QString::fromLatin1(" Thu Jan 1 00:00:00 1970 ") + << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::LocalTime); + QTest::newRow("text data6") << QString::fromLatin1("Thu Jan 1 00:00:00") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text data7") << QString::fromLatin1("Thu Jan 1 1970 00:00:00") + << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::LocalTime); + QTest::newRow("text data8") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT+foo") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text data9") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT") + << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + QTest::newRow("text data10") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT-0300") + << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(3, 12, 34), Qt::UTC); + QTest::newRow("text data11") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT+0300") + << Qt::TextDate << QDateTime(QDate(1969, 12, 31), QTime(21, 12, 34), Qt::UTC); + QTest::newRow("text data12") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 gmt") + << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + QTest::newRow("text data13") << QString::fromLatin1("Thu Jan 1 1970 00:12:34 GMT+0100") + << Qt::TextDate << QDateTime(QDate(1969, 12, 31), QTime(23, 12, 34), Qt::UTC); + QTest::newRow("text empty") << QString::fromLatin1("") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text too many parts") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 gmt +0100") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid month name") << QString::fromLatin1("Thu Jaz 1 1970 00:12:34") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid date") << QString::fromLatin1("Thu Jan 32 1970 00:12:34") + << Qt::TextDate << QDateTime(invalidDate(), QTime(0, 12, 34), Qt::LocalTime); + QTest::newRow("text invalid day #1") << QString::fromLatin1("Thu Jan XX 1970 00:12:34") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid day #2") << QString::fromLatin1("Thu X. Jan 00:00:00 1970") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid day #3") << QString::fromLatin1("Thu 1 Jan 00:00:00 1970") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid year #1") << QString::fromLatin1("Thu 1. Jan 00:00:00 19X0") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid year #2") << QString::fromLatin1("Thu 1. Jan 19X0 00:00:00") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid hour") << QString::fromLatin1("Thu 1. Jan 1970 0X:00:00") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid minute") << QString::fromLatin1("Thu 1. Jan 1970 00:0X:00") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid second") << QString::fromLatin1("Thu 1. Jan 1970 00:00:0X") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid gmt specifier #1") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 DMT") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid gmt specifier #2") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 GMTx0200") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid gmt hour") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 GMT+0X00") + << Qt::TextDate << invalidDateTime(); + QTest::newRow("text invalid gmt minute") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 GMT+000X") + << Qt::TextDate << invalidDateTime(); // Test Qt::ISODate format. - QTest::newRow("data14") << QString::fromLatin1("1987-02-13T13:24:51+01:00") - << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51)) << Qt::UTC; - QTest::newRow("data15") << QString::fromLatin1("1987-02-13T13:24:51-01:00") - << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51)) << Qt::UTC; + QTest::newRow("ISO +01:00") << QString::fromLatin1("1987-02-13T13:24:51+01:00") + << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); + QTest::newRow("ISO -01:00") << QString::fromLatin1("1987-02-13T13:24:51-01:00") + << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC); + // Not sure about these two... it will currently be created as LocalTime, but it + // should probably be UTC according to the ISO 8601 spec (see 4.2.5.1). + QTest::newRow("ISO +0000") << QString::fromLatin1("1970-01-01T00:12:34+0000") + << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::LocalTime); + QTest::newRow("ISO +00:00") << QString::fromLatin1("1970-01-01T00:12:34+00:00") + << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::LocalTime); // No time specified - defaults to Qt::LocalTime. - QTest::newRow("data16") << QString::fromLatin1("2002-10-01") - << Qt::ISODate << QDateTime(QDate(2002, 10, 1), QTime(0, 0, 0, 0)) << Qt::LocalTime; + QTest::newRow("ISO data3") << QString::fromLatin1("2002-10-01") + << Qt::ISODate << QDateTime(QDate(2002, 10, 1), QTime(0, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO") << QString::fromLatin1("2005-06-28T07:57:30.0010000000Z") - << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1)) << Qt::UTC; + << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), Qt::UTC); QTest::newRow("ISO with comma 1") << QString::fromLatin1("2005-06-28T07:57:30,0040000000Z") - << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 4)) << Qt::UTC; + << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 4), Qt::UTC); QTest::newRow("ISO with comma 2") << QString::fromLatin1("2005-06-28T07:57:30,0015Z") - << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2)) << Qt::UTC; + << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), Qt::UTC); QTest::newRow("ISO with comma 3") << QString::fromLatin1("2005-06-28T07:57:30,0014Z") - << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1)) << Qt::UTC; + << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), Qt::UTC); QTest::newRow("ISO with comma 4") << QString::fromLatin1("2005-06-28T07:57:30,1Z") - << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 100)) << Qt::UTC; + << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 100), Qt::UTC); QTest::newRow("ISO with comma 5") << QString::fromLatin1("2005-06-28T07:57:30,11") - << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 110)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 110), Qt::LocalTime); // 24:00:00 Should be next day according to ISO 8601 section 4.2.3. QTest::newRow("ISO 24:00") << QString::fromLatin1("2012-06-04T24:00:00") - << Qt::ISODate << QDateTime(QDate(2012, 6, 5), QTime(0, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 6, 5), QTime(0, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO 24:00 end of month") << QString::fromLatin1("2012-06-30T24:00:00") - << Qt::ISODate << QDateTime(QDate(2012, 7, 1), QTime(0, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 7, 1), QTime(0, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO 24:00 end of year") << QString::fromLatin1("2012-12-31T24:00:00") - << Qt::ISODate << QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO 24:00, fract ms") << QString::fromLatin1("2012-01-01T24:00:00.000") - << Qt::ISODate << QDateTime(QDate(2012, 1, 2), QTime(0, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 2), QTime(0, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO 24:00 end of year, fract ms") << QString::fromLatin1("2012-12-31T24:00:00.000") - << Qt::ISODate << QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0, 0), Qt::LocalTime); // Test fractional seconds. QTest::newRow("ISO .0 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.0") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO .00 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.00") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO .000 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.000") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO .1 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,1") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 100)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 100), Qt::LocalTime); QTest::newRow("ISO .99 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,99") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 990)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 990), Qt::LocalTime); QTest::newRow("ISO .998 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,998") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 998)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 998), Qt::LocalTime); QTest::newRow("ISO .999 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,999") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 999)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 999), Qt::LocalTime); QTest::newRow("ISO .3335 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,3335") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 334)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 334), Qt::LocalTime); QTest::newRow("ISO .333333 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,333333") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 333)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 333), Qt::LocalTime); QTest::newRow("ISO .00009 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.00009") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO no fract specified") << QString::fromLatin1("2012-01-01T08:00:00.") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); // Test invalid characters (should ignore invalid characters at end of string). QTest::newRow("ISO invalid character at end") << QString::fromLatin1("2012-01-01T08:00:00!") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO invalid character at front") << QString::fromLatin1("!2012-01-01T08:00:00") - << Qt::ISODate << invalidDateTime() << Qt::LocalTime; + << Qt::ISODate << invalidDateTime(); QTest::newRow("ISO invalid character both ends") << QString::fromLatin1("!2012-01-01T08:00:00!") - << Qt::ISODate << invalidDateTime() << Qt::LocalTime; + << Qt::ISODate << invalidDateTime(); QTest::newRow("ISO invalid character at front, 2 at back") << QString::fromLatin1("!2012-01-01T08:00:00..") - << Qt::ISODate << invalidDateTime() << Qt::LocalTime; + << Qt::ISODate << invalidDateTime(); QTest::newRow("ISO invalid character 2 at front") << QString::fromLatin1("!!2012-01-01T08:00:00") - << Qt::ISODate << invalidDateTime() << Qt::LocalTime; + << Qt::ISODate << invalidDateTime(); // Test fractional minutes. QTest::newRow("ISO .0 of a minute (period)") << QString::fromLatin1("2012-01-01T08:00.0") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO .8 of a minute (period)") << QString::fromLatin1("2012-01-01T08:00.8") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 48, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 48, 0), Qt::LocalTime); QTest::newRow("ISO .99999 of a minute (period)") << QString::fromLatin1("2012-01-01T08:00.99999") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999), Qt::LocalTime); QTest::newRow("ISO .0 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,0") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime); QTest::newRow("ISO .8 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,8") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 48, 0)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 48, 0), Qt::LocalTime); QTest::newRow("ISO .99999 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,99999") - << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999)) << Qt::LocalTime; + << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999), Qt::LocalTime); + QTest::newRow("ISO empty") << QString::fromLatin1("") << Qt::ISODate << invalidDateTime(); } void tst_QDateTime::fromStringDateFormat() @@ -1503,10 +1640,8 @@ void tst_QDateTime::fromStringDateFormat() QFETCH(QString, dateTimeStr); QFETCH(Qt::DateFormat, dateFormat); QFETCH(QDateTime, expected); - QFETCH(Qt::TimeSpec, timeSpec); QDateTime dateTime = QDateTime::fromString(dateTimeStr, dateFormat); - expected.setTimeSpec(timeSpec); QCOMPARE(dateTime, expected); } diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index e07b3fc81e..e64496352c 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -49,9 +49,13 @@ class tst_QMap : public QObject { Q_OBJECT +protected: + template <class KEY, class VALUE> + void sanityCheckTree(const QMap<KEY, VALUE> &m, int calledFromLine); public slots: void init(); private slots: + void ctor(); void count(); void clear(); void beginEnd(); @@ -79,6 +83,7 @@ private slots: void setSharable(); void insert(); + void checkMostLeftNode(); }; typedef QMap<QString, QString> StringMap; @@ -115,11 +120,57 @@ QDebug operator << (QDebug d, const MyClass &c) { return d; } +template <class KEY, class VALUE> +void tst_QMap::sanityCheckTree(const QMap<KEY, VALUE> &m, int calledFromLine) +{ + QString possibleFrom; + possibleFrom.setNum(calledFromLine); + possibleFrom = "Called from line: " + possibleFrom; + int count = 0; + typename QMap<KEY, VALUE>::const_iterator oldite = m.constBegin(); + for (typename QMap<KEY, VALUE>::const_iterator i = m.constBegin(); i != m.constEnd(); ++i) { + count++; + bool oldIteratorIsLarger = i.key() < oldite.key(); + QVERIFY2(!oldIteratorIsLarger, possibleFrom.toUtf8()); + oldite = i; + } + if (m.size() != count) { // Fail + qDebug() << possibleFrom; + QCOMPARE(m.size(), count); + } + if (m.size() == 0) + QVERIFY(m.constBegin() == m.constEnd()); +} + void tst_QMap::init() { MyClass::count = 0; } +void tst_QMap::ctor() +{ + std::map<int, int> map; + for (int i = 0; i < 100000; ++i) + map.insert(std::pair<int, int>(i * 3, i * 7)); + + QMap<int, int> qmap(map); // ctor. + + // Check that we have the same + std::map<int, int>::iterator j = map.begin(); + QMap<int, int>::const_iterator i = qmap.constBegin(); + + while (i != qmap.constEnd()) { + QCOMPARE( (*j).first, i.key()); + QCOMPARE( (*j).second, i.value()); + ++i; + ++j; + } + + QCOMPARE( (int) map.size(), qmap.size()); +} + + + void tst_QMap::count() { { @@ -280,6 +331,7 @@ void tst_QMap::clear() map.insert( "key0", MyClass( "value1" ) ); map.insert( "key1", MyClass( "value2" ) ); map.clear(); + sanityCheckTree(map, __LINE__); QVERIFY( map.isEmpty() ); } QCOMPARE( MyClass::count, int(0) ); @@ -400,6 +452,8 @@ void tst_QMap::swap() m1.swap(m2); QCOMPARE(m1.value(1),QLatin1String("m2[1]")); QCOMPARE(m2.value(0),QLatin1String("m1[0]")); + sanityCheckTree(m1, __LINE__); + sanityCheckTree(m2, __LINE__); } void tst_QMap::operator_eq() @@ -631,7 +685,7 @@ void tst_QMap::lowerUpperBound() void tst_QMap::mergeCompare() { - QMap<int, QString> map1, map2, map3; + QMap<int, QString> map1, map2, map3, map1b, map2b; map1.insert(1,"ett"); map1.insert(3,"tre"); @@ -641,6 +695,13 @@ void tst_QMap::mergeCompare() map2.insert(4,"fyra"); map1.unite(map2); + sanityCheckTree(map1, __LINE__); + + map1b = map1; + map2b = map2; + map2b.insert(0, "nul"); + map1b.unite(map2b); + sanityCheckTree(map1b, __LINE__); QVERIFY(map1.value(1) == "ett"); QVERIFY(map1.value(2) == "tvo"); @@ -958,9 +1019,11 @@ void tst_QMap::setSharable() QVERIFY(!map.isDetached()); QVERIFY(copy.isSharedWith(map)); + sanityCheckTree(copy, __LINE__); } map.setSharable(false); + sanityCheckTree(map, __LINE__); QVERIFY(map.isDetached()); QCOMPARE(map.size(), 4); QCOMPARE(const_(map)[4], QString("quatro")); @@ -975,6 +1038,8 @@ void tst_QMap::setSharable() QCOMPARE(const_(copy)[4], QString("quatro")); QCOMPARE(map, copy); + sanityCheckTree(map, __LINE__); + sanityCheckTree(copy, __LINE__); } map.setSharable(true); @@ -1012,5 +1077,57 @@ void tst_QMap::insert() } } +void tst_QMap::checkMostLeftNode() +{ + QMap<int, int> map; + + map.insert(100, 1); + sanityCheckTree(map, __LINE__); + + // insert + map.insert(99, 1); + sanityCheckTree(map, __LINE__); + map.insert(98, 1); + sanityCheckTree(map, __LINE__); + map.insert(97, 1); + sanityCheckTree(map, __LINE__); + map.insert(96, 1); + sanityCheckTree(map, __LINE__); + map.insert(95, 1); + + // remove + sanityCheckTree(map, __LINE__); + map.take(95); + sanityCheckTree(map, __LINE__); + map.remove(96); + sanityCheckTree(map, __LINE__); + map.erase(map.begin()); + sanityCheckTree(map, __LINE__); + map.remove(97); + sanityCheckTree(map, __LINE__); + map.remove(98); + sanityCheckTree(map, __LINE__); + map.remove(99); + sanityCheckTree(map, __LINE__); + map.remove(100); + sanityCheckTree(map, __LINE__); + map.insert(200, 1); + QCOMPARE(map.constBegin().key(), 200); + sanityCheckTree(map, __LINE__); + // remove the non left most node + map.insert(202, 2); + map.insert(203, 3); + map.insert(204, 4); + map.remove(202); + sanityCheckTree(map, __LINE__); + map.remove(203); + sanityCheckTree(map, __LINE__); + map.remove(204); + sanityCheckTree(map, __LINE__); + // erase last item + map.erase(map.begin()); + sanityCheckTree(map, __LINE__); +} + QTEST_APPLESS_MAIN(tst_QMap) #include "tst_qmap.moc" |