summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/io')
-rw-r--r--tests/auto/corelib/io/io.pro1
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp54
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp134
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp1
-rw-r--r--tests/auto/corelib/io/qsavefile/qsavefile.pro5
-rw-r--r--tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp272
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp21
7 files changed, 424 insertions, 64 deletions
diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro
index 03b42a2cbb..948e9dec5f 100644
--- a/tests/auto/corelib/io/io.pro
+++ b/tests/auto/corelib/io/io.pro
@@ -20,6 +20,7 @@ SUBDIRS=\
qprocessenvironment \
qresourceengine \
qsettings \
+ qsavefile \
qstandardpaths \
qtemporarydir \
qtemporaryfile \
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
index 333ccc8e49..f452efc1b3 100644
--- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -52,7 +52,8 @@ private slots:
void warningWithoutDebug() const;
void criticalWithoutDebug() const;
void debugWithBool() const;
- void debugNoSpaces() const;
+ void debugSpaceHandling() const;
+ void stateSaver() const;
void veryLongWarningMessage() const;
void qDebugQStringRef() const;
void qDebugQLatin1String() const;
@@ -150,7 +151,36 @@ void tst_QDebug::debugWithBool() const
QCOMPARE(QString::fromLatin1(s_function), function);
}
-void tst_QDebug::debugNoSpaces() const
+class MyPoint
+{
+public:
+ MyPoint(int val1, int val2)
+ : v1(val1), v2(val2) {}
+ int v1;
+ int v2;
+};
+QDebug operator<< (QDebug s, const MyPoint& point)
+{
+ const QDebugStateSaver saver(s);
+ return s.nospace() << "MyPoint(" << point.v1 << ", " << point.v2 << ")";
+}
+
+class MyLine
+{
+public:
+ MyLine(const MyPoint& point1, const MyPoint& point2)
+ : p1(point1), p2(point2) {}
+ MyPoint p1;
+ MyPoint p2;
+};
+QDebug operator<< (QDebug s, const MyLine& line)
+{
+ const QDebugStateSaver saver(s);
+ s.nospace() << "MyLine(" << line.p1 << ", " << line.p2 << ")";
+ return s;
+}
+
+void tst_QDebug::debugSpaceHandling() const
{
MessageHandlerSetter mhs(myMessageHandler);
{
@@ -166,8 +196,26 @@ void tst_QDebug::debugNoSpaces() const
d << "key=" << "value";
d.space();
d << 1 << 2;
+ MyLine line(MyPoint(10, 11), MyPoint (12, 13));
+ d << line;
+ // With the old implementation of MyPoint doing dbg.nospace() << ...; dbg.space() we ended up with
+ // MyLine(MyPoint(10, 11) , MyPoint(12, 13) )
+ }
+ QCOMPARE(s_msg, QString::fromLatin1(" foo key=value 1 2 MyLine(MyPoint(10, 11), MyPoint(12, 13))"));
+}
+
+void tst_QDebug::stateSaver() const
+{
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ {
+ QDebugStateSaver saver(d);
+ d.nospace() << hex << right << qSetFieldWidth(3) << qSetPadChar('0') << 42;
+ }
+ d.space() << 42;
}
- QCOMPARE(s_msg, QString::fromLatin1(" foo key=value 1 2 "));
+ QCOMPARE(s_msg, QString::fromLatin1("02a 42 "));
}
void tst_QDebug::veryLongWarningMessage() const
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
index ded77c649f..c2d578d4c0 100644
--- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -46,6 +46,7 @@
#include <qcoreapplication.h>
#include <qlibrary.h>
#include <qtemporaryfile.h>
+#include <qtemporarydir.h>
#include <qdir.h>
#include <qfileinfo.h>
#ifdef Q_OS_UNIX
@@ -80,7 +81,11 @@ class tst_QFileInfo : public QObject
{
Q_OBJECT
+public:
+ tst_QFileInfo() : m_currentDir(QDir::currentPath()) {}
+
private slots:
+ void initTestCase();
void cleanupTestCase();
void getSetCheck();
@@ -190,32 +195,27 @@ private slots:
void invalidState();
void nonExistingFileDates();
+
+private:
+ const QString m_currentDir;
+ QString m_sourceFile;
+ QString m_resourcesDir;
+ QTemporaryDir m_dir;
};
-void tst_QFileInfo::cleanupTestCase()
+void tst_QFileInfo::initTestCase()
{
- QFile::remove("brokenlink.lnk");
- QFile::remove("link.lnk");
- QFile::remove("file1");
- QFile::remove("dummyfile");
- QFile::remove("simplefile.txt");
- QFile::remove("longFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileName.txt");
- QFile::remove("tempfile.txt");
+ m_sourceFile = QFINDTESTDATA("tst_qfileinfo.cpp");
+ QVERIFY(!m_sourceFile.isEmpty());
+ m_resourcesDir = QFINDTESTDATA("resources");
+ QVERIFY(!m_resourcesDir.isEmpty());
+ QVERIFY(m_dir.isValid());
+ QVERIFY(QDir::setCurrent(m_dir.path()));
+}
-#if defined(Q_OS_UNIX)
- QDir().rmdir("./.hidden-directory");
- QFile::remove("link_to_tst_qfileinfo");
-#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- QDir().rmdir("./hidden-directory");
- QDir().rmdir("abs_symlink");
- QDir().rmdir("rel_symlink");
- QDir().rmdir("junction_pwd");
- QDir().rmdir("junction_root");
- QDir().rmdir("mountpoint");
- QFile::remove("abs_symlink.cpp");
- QFile::remove("rel_symlink.cpp");
-#endif
+void tst_QFileInfo::cleanupTestCase()
+{
+ QDir::setCurrent(m_currentDir); // Release temporary directory so that it can be deleted on Windows
}
// Testing get/set functions
@@ -237,10 +237,9 @@ static QFileInfoPrivate* getPrivate(QFileInfo &info)
void tst_QFileInfo::copy()
{
- QTemporaryFile *t;
- t = new QTemporaryFile;
- t->open();
- QFileInfo info(t->fileName());
+ QTemporaryFile t;
+ t.open();
+ QFileInfo info(t.fileName());
QVERIFY(info.exists());
//copy constructor
@@ -287,7 +286,7 @@ void tst_QFileInfo::isFile_data()
QTest::addColumn<bool>("expected");
QTest::newRow("data0") << QDir::currentPath() << false;
- QTest::newRow("data1") << QFINDTESTDATA("tst_qfileinfo.cpp") << true;
+ QTest::newRow("data1") << m_sourceFile << true;
QTest::newRow("data2") << ":/tst_qfileinfo/resources/" << false;
QTest::newRow("data3") << ":/tst_qfileinfo/resources/file1" << true;
QTest::newRow("data4") << ":/tst_qfileinfo/resources/afilethatshouldnotexist" << false;
@@ -320,13 +319,13 @@ void tst_QFileInfo::isDir_data()
QTest::addColumn<bool>("expected");
QTest::newRow("data0") << QDir::currentPath() << true;
- QTest::newRow("data1") << QFINDTESTDATA("tst_qfileinfo.cpp") << false;
+ QTest::newRow("data1") << m_sourceFile << false;
QTest::newRow("data2") << ":/tst_qfileinfo/resources/" << true;
QTest::newRow("data3") << ":/tst_qfileinfo/resources/file1" << false;
QTest::newRow("data4") << ":/tst_qfileinfo/resources/afilethatshouldnotexist" << false;
- QTest::newRow("simple dir") << QFINDTESTDATA("resources") << true;
- QTest::newRow("simple dir with slash") << QFINDTESTDATA("resources/") << true;
+ QTest::newRow("simple dir") << m_resourcesDir << true;
+ QTest::newRow("simple dir with slash") << (m_resourcesDir + QLatin1Char('/')) << true;
QTest::newRow("broken link") << "brokenlink.lnk" << false;
@@ -366,8 +365,8 @@ void tst_QFileInfo::isRoot_data()
QTest::newRow("data4") << ":/tst_qfileinfo/resources/" << false;
QTest::newRow("data5") << ":/" << true;
- QTest::newRow("simple dir") << QFINDTESTDATA("resources") << false;
- QTest::newRow("simple dir with slash") << QFINDTESTDATA("resources/") << false;
+ QTest::newRow("simple dir") << m_resourcesDir << false;
+ QTest::newRow("simple dir with slash") << (m_resourcesDir + QLatin1Char('/')) << false;
#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE))
QTest::newRow("drive 1") << "c:" << false;
QTest::newRow("drive 2") << "c:/" << true;
@@ -398,21 +397,21 @@ void tst_QFileInfo::exists_data()
QTest::addColumn<bool>("expected");
QTest::newRow("data0") << QDir::currentPath() << true;
- QTest::newRow("data1") << QFINDTESTDATA("tst_qfileinfo.cpp") << true;
+ QTest::newRow("data1") << m_sourceFile << true;
QTest::newRow("data2") << "/I/do_not_expect_this_path_to_exist/" << false;
QTest::newRow("data3") << ":/tst_qfileinfo/resources/" << true;
QTest::newRow("data4") << ":/tst_qfileinfo/resources/file1" << true;
QTest::newRow("data5") << ":/I/do_not_expect_this_path_to_exist/" << false;
- QTest::newRow("data6") << (QFINDTESTDATA("resources/") + "*") << false;
- QTest::newRow("data7") << (QFINDTESTDATA("resources/") + "*.foo") << false;
- QTest::newRow("data8") << (QFINDTESTDATA("resources/") + "*.ext1") << false;
- QTest::newRow("data9") << (QFINDTESTDATA("resources/") + "file?.ext1") << false;
+ QTest::newRow("data6") << (m_resourcesDir + "/*") << false;
+ QTest::newRow("data7") << (m_resourcesDir + "/*.foo") << false;
+ QTest::newRow("data8") << (m_resourcesDir + "/*.ext1") << false;
+ QTest::newRow("data9") << (m_resourcesDir + "/file?.ext1") << false;
QTest::newRow("data10") << "." << true;
QTest::newRow("data11") << ". " << false;
QTest::newRow("empty") << "" << false;
- QTest::newRow("simple dir") << QFINDTESTDATA("resources") << true;
- QTest::newRow("simple dir with slash") << QFINDTESTDATA("resources/") << true;
+ QTest::newRow("simple dir") << m_resourcesDir << true;
+ QTest::newRow("simple dir with slash") << (m_resourcesDir + QLatin1Char('/')) << true;
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
QTest::newRow("unc 1") << "//" + QtNetworkSettings::winServerName() << true;
@@ -561,7 +560,7 @@ void tst_QFileInfo::canonicalFilePath()
// test symlinks
QFile::remove("link.lnk");
{
- QFile file(QFINDTESTDATA("tst_qfileinfo.cpp"));
+ QFile file(m_sourceFile);
if (file.link("link.lnk")) {
QFileInfo info1(file);
QFileInfo info2("link.lnk");
@@ -587,7 +586,7 @@ void tst_QFileInfo::canonicalFilePath()
QCOMPARE(info1.canonicalFilePath(), info2.canonicalFilePath());
QFileInfo info3(link + QDir::separator() + "link.lnk");
- QFileInfo info4(QFINDTESTDATA("tst_qfileinfo.cpp"));
+ QFileInfo info4(m_sourceFile);
QVERIFY(!info3.canonicalFilePath().isEmpty());
QCOMPARE(info4.canonicalFilePath(), info3.canonicalFilePath());
@@ -621,20 +620,21 @@ void tst_QFileInfo::canonicalFilePath()
// CreateSymbolicLink can return TRUE & still fail to create the link,
// the error code in that case is ERROR_PRIVILEGE_NOT_HELD (1314)
SetLastError(0);
- BOOL ret = ptrCreateSymbolicLink((wchar_t*)QString("res").utf16(), (wchar_t*)QString("resources").utf16(), 1);
+ const QString linkTarget = QStringLiteral("res");
+ BOOL ret = ptrCreateSymbolicLink((wchar_t*)linkTarget.utf16(), (wchar_t*)m_resourcesDir.utf16(), 1);
DWORD dwErr = GetLastError();
if (!ret)
QSKIP("Symbolic links aren't supported by FS");
QString currentPath = QDir::currentPath();
- bool is_res_Current = QDir::setCurrent("res");
+ bool is_res_Current = QDir::setCurrent(linkTarget);
if (!is_res_Current && dwErr == 1314)
QSKIP("Not enough privilages to create Symbolic links");
QCOMPARE(is_res_Current, true);
+ const QString actualCanonicalPath = QFileInfo("file1").canonicalFilePath();
+ QVERIFY(QDir::setCurrent(currentPath));
+ QCOMPARE(actualCanonicalPath, m_resourcesDir + QStringLiteral("/file1"));
- QCOMPARE(QFileInfo("file1").canonicalFilePath(), currentPath + "/resources/file1");
-
- QCOMPARE(QDir::setCurrent(currentPath), true);
- QDir::current().rmdir("res");
+ QDir::current().rmdir(linkTarget);
}
#endif
}
@@ -855,7 +855,7 @@ void tst_QFileInfo::permission_data()
QTest::addColumn<bool>("expected");
QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << int(QFile::ExeUser) << true;
- QTest::newRow("data1") << QFINDTESTDATA("tst_qfileinfo.cpp") << int(QFile::ReadUser) << true;
+ QTest::newRow("data1") << m_sourceFile << int(QFile::ReadUser) << true;
QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::ReadUser) << true;
QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::WriteUser) << false;
QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::ExeUser) << false;
@@ -921,13 +921,15 @@ void tst_QFileInfo::compare_data()
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6)
caseSensitiveOnMac = false;
#endif
+ QString caseChangedSource = m_sourceFile;
+ caseChangedSource.replace("info", "Info");
QTest::newRow("data0")
- << QFINDTESTDATA("tst_qfileinfo.cpp")
- << QFINDTESTDATA("tst_qfileinfo.cpp")
+ << m_sourceFile
+ << m_sourceFile
<< true;
QTest::newRow("data1")
- << QFINDTESTDATA("tst_qfileinfo.cpp")
+ << m_sourceFile
<< QString::fromLatin1("/tst_qfileinfo.cpp")
<< false;
QTest::newRow("data2")
@@ -935,8 +937,8 @@ void tst_QFileInfo::compare_data()
<< QDir::currentPath() + QString::fromLatin1("/tst_qfileinfo.cpp")
<< true;
QTest::newRow("casesense1")
- << QFINDTESTDATA("tst_qfileinfo.cpp").replace("info", "Info")
- << QFINDTESTDATA("tst_qfileinfo.cpp")
+ << caseChangedSource
+ << m_sourceFile
#if defined(Q_OS_WIN)
<< true;
#elif defined(Q_OS_MAC)
@@ -1140,7 +1142,7 @@ void tst_QFileInfo::isSymLink_data()
QFile::remove("brokenlink.lnk");
QFile::remove("dummyfile");
- QFile file1(QFINDTESTDATA("tst_qfileinfo.cpp"));
+ QFile file1(m_sourceFile);
QVERIFY(file1.link("link.lnk"));
QFile file2("dummyfile");
@@ -1152,8 +1154,8 @@ void tst_QFileInfo::isSymLink_data()
QTest::addColumn<bool>("isSymLink");
QTest::addColumn<QString>("linkTarget");
- QTest::newRow("existent file") << QFINDTESTDATA("tst_qfileinfo.cpp") << false << "";
- QTest::newRow("link") << "link.lnk" << true << QFileInfo(QFINDTESTDATA("tst_qfileinfo.cpp")).absoluteFilePath();
+ QTest::newRow("existent file") << m_sourceFile << false << "";
+ QTest::newRow("link") << "link.lnk" << true << QFileInfo(m_sourceFile).absoluteFilePath();
QTest::newRow("broken link") << "brokenlink.lnk" << true << QFileInfo("dummyfile").absoluteFilePath();
}
@@ -1390,7 +1392,7 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
}
{
//File symlinks
- QFileInfo target(QFINDTESTDATA("tst_qfileinfo.cpp"));
+ QFileInfo target(m_sourceFile);
QString absTarget = QDir::toNativeSeparators(target.absoluteFilePath());
QString absSymlink = QDir::toNativeSeparators(pwd.absolutePath()).append("\\abs_symlink.cpp");
QString relTarget = QDir::toNativeSeparators(pwd.relativeFilePath(target.absoluteFilePath()));
@@ -1447,10 +1449,22 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks()
QFETCH(QString, canonicalFilePath);
QFileInfo fi(path);
- QCOMPARE(fi.isSymLink(), isSymLink);
+ const bool actualIsSymLink = fi.isSymLink();
+ const QString actualSymLinkTarget = isSymLink ? fi.symLinkTarget() : QString();
+ const QString actualCanonicalFilePath = isSymLink ? fi.canonicalFilePath() : QString();
+ // Ensure that junctions, mountpoints are removed. If this fails, do not remove
+ // temporary directory to prevent it from trashing the system.
+ if (fi.isDir()) {
+ if (!QDir().rmdir(fi.fileName())) {
+ qWarning("Unable to remove NTFS junction '%s'', keeping '%s'.",
+ qPrintable(fi.fileName()), qPrintable(QDir::toNativeSeparators(m_dir.path())));
+ m_dir.setAutoRemove(false);
+ }
+ }
+ QCOMPARE(actualIsSymLink, isSymLink);
if (isSymLink) {
- QCOMPARE(fi.symLinkTarget(), linkTarget);
- QCOMPARE(fi.canonicalFilePath(), canonicalFilePath);
+ QCOMPARE(actualSymLinkTarget, linkTarget);
+ QCOMPARE(actualCanonicalFilePath, canonicalFilePath);
}
}
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index 7965d1d431..11824f4ab6 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -1256,7 +1256,6 @@ void tst_QProcess::waitForBytesWrittenInABytesWrittenSlot()
process->start("testProcessEcho/testProcessEcho");
QVERIFY(process->waitForStarted(5000));
- qRegisterMetaType<qint64>("qint64");
QSignalSpy spy(process, SIGNAL(bytesWritten(qint64)));
QVERIFY(spy.isValid());
process->write("f");
diff --git a/tests/auto/corelib/io/qsavefile/qsavefile.pro b/tests/auto/corelib/io/qsavefile/qsavefile.pro
new file mode 100644
index 0000000000..36db000fa7
--- /dev/null
+++ b/tests/auto/corelib/io/qsavefile/qsavefile.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase parallel_test
+TARGET = tst_qsavefile
+QT = core testlib
+SOURCES = tst_qsavefile.cpp
+TESTDATA += tst_qsavefile.cpp
diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
new file mode 100644
index 0000000000..5ef4b11e8a
--- /dev/null
+++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 David Faure <faure@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module 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 <qcoreapplication.h>
+#include <qstring.h>
+#include <qtemporaryfile.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qset.h>
+
+#if defined(Q_OS_UNIX)
+# include <unistd.h> // for geteuid
+# include <sys/types.h>
+#endif
+
+#if defined(Q_OS_WIN)
+# include <windows.h>
+#endif
+
+class tst_QSaveFile : public QObject
+{
+ Q_OBJECT
+public slots:
+
+private slots:
+ void transactionalWrite();
+ void textStreamManualFlush();
+ void textStreamAutoFlush();
+ void saveTwice();
+ void transactionalWriteNoPermissionsOnDir();
+ void transactionalWriteNoPermissionsOnFile();
+ void transactionalWriteCanceled();
+ void transactionalWriteErrorRenaming();
+};
+
+void tst_QSaveFile::transactionalWrite()
+{
+ QTemporaryDir dir;
+ const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
+ QFile::remove(targetFile);
+ QSaveFile file(targetFile);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QVERIFY(file.isOpen());
+ QCOMPARE(file.fileName(), targetFile);
+ QVERIFY(!QFile::exists(targetFile));
+
+ QCOMPARE(file.write("Hello"), Q_INT64_C(5));
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(!QFile::exists(targetFile));
+
+ QVERIFY(file.commit());
+ QVERIFY(QFile::exists(targetFile));
+ QCOMPARE(file.fileName(), targetFile);
+
+ QFile reader(targetFile);
+ QVERIFY(reader.open(QIODevice::ReadOnly));
+ QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("Hello"));
+}
+
+void tst_QSaveFile::saveTwice()
+{
+ // Check that we can reuse a QSaveFile object
+ // (and test the case of an existing target file)
+ QTemporaryDir dir;
+ const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
+ QSaveFile file(targetFile);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QCOMPARE(file.write("Hello"), Q_INT64_C(5));
+ QVERIFY2(file.commit(), qPrintable(file.errorString()));
+
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QCOMPARE(file.write("World"), Q_INT64_C(5));
+ QVERIFY2(file.commit(), qPrintable(file.errorString()));
+
+ QFile reader(targetFile);
+ QVERIFY(reader.open(QIODevice::ReadOnly));
+ QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("World"));
+}
+
+void tst_QSaveFile::textStreamManualFlush()
+{
+ QTemporaryDir dir;
+ const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
+ QSaveFile file(targetFile);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+
+ QTextStream ts(&file);
+ ts << "Manual flush";
+ ts.flush();
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(!QFile::exists(targetFile));
+
+ QVERIFY(file.commit());
+ QFile reader(targetFile);
+ QVERIFY(reader.open(QIODevice::ReadOnly));
+ QCOMPARE(QString::fromLatin1(reader.readAll().constData()), QString::fromLatin1("Manual flush"));
+ QFile::remove(targetFile);
+}
+
+void tst_QSaveFile::textStreamAutoFlush()
+{
+ QTemporaryDir dir;
+ const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
+ QSaveFile file(targetFile);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+
+ QTextStream ts(&file);
+ ts << "Auto-flush.";
+ // no flush
+ QVERIFY(file.commit()); // QIODevice::close will emit aboutToClose, which will flush the stream
+ QFile reader(targetFile);
+ QVERIFY(reader.open(QIODevice::ReadOnly));
+ QCOMPARE(QString::fromLatin1(reader.readAll().constData()), QString::fromLatin1("Auto-flush."));
+ QFile::remove(targetFile);
+}
+
+void tst_QSaveFile::transactionalWriteNoPermissionsOnDir()
+{
+#ifdef Q_OS_UNIX
+ if (::geteuid() == 0)
+ QSKIP("not valid running this test as root");
+
+ // You can write into /dev/zero, but you can't create a /dev/zero.XXXXXX temp file.
+ QSaveFile file("/dev/zero");
+ if (!QDir("/dev").exists())
+ QSKIP("/dev doesn't exist on this system");
+
+ QVERIFY(!file.open(QIODevice::WriteOnly));
+ QCOMPARE((int)file.error(), (int)QFile::OpenError);
+ QVERIFY(!file.commit());
+#endif
+}
+
+void tst_QSaveFile::transactionalWriteNoPermissionsOnFile()
+{
+ // Setup an existing but readonly file
+ QTemporaryDir dir;
+ const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
+ QFile file(targetFile);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QCOMPARE(file.write("Hello"), Q_INT64_C(5));
+ file.close();
+ file.setPermissions(QFile::ReadOwner);
+ QVERIFY(!file.open(QIODevice::WriteOnly));
+
+ // Try saving into it
+ {
+ QSaveFile saveFile(targetFile);
+ QVERIFY(!saveFile.open(QIODevice::WriteOnly)); // just like QFile
+ }
+ QVERIFY(file.exists());
+}
+
+void tst_QSaveFile::transactionalWriteCanceled()
+{
+ QTemporaryDir dir;
+ const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
+ QFile::remove(targetFile);
+ QSaveFile file(targetFile);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+
+ QTextStream ts(&file);
+ ts << "This writing operation will soon be canceled.\n";
+ ts.flush();
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(!QFile::exists(targetFile));
+
+ // We change our mind, let's abort writing
+ file.cancelWriting();
+
+ QVERIFY(!file.commit());
+
+ QVERIFY(!QFile::exists(targetFile)); // temp file was discarded
+ QCOMPARE(file.fileName(), targetFile);
+}
+
+void tst_QSaveFile::transactionalWriteErrorRenaming()
+{
+ QTemporaryDir dir;
+ const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
+ QSaveFile file(targetFile);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QCOMPARE(file.write("Hello"), qint64(5));
+ QVERIFY(!QFile::exists(targetFile));
+
+ // Restore permissions so that the QTemporaryDir cleanup can happen
+ class PermissionRestorer
+ {
+ public:
+ PermissionRestorer(const QString& path)
+ : m_path(path)
+ {}
+
+ ~PermissionRestorer()
+ {
+ QFile file(m_path);
+#ifdef Q_OS_UNIX
+ file.setPermissions(QFile::Permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner));
+#else
+ file.setPermissions(QFile::WriteOwner);
+ file.remove();
+#endif
+ }
+
+ private:
+ QString m_path;
+ };
+
+#ifdef Q_OS_UNIX
+ // Make rename() fail for lack of permissions in the directory
+ QFile dirAsFile(dir.path()); // yay, I have to use QFile to change a dir's permissions...
+ QVERIFY(dirAsFile.setPermissions(QFile::Permissions(0))); // no permissions
+ PermissionRestorer permissionRestorer(dir.path());
+#else
+ // Windows: Make rename() fail for lack of permissions on an existing target file
+ QFile existingTargetFile(targetFile);
+ QVERIFY(existingTargetFile.open(QIODevice::WriteOnly));
+ QCOMPARE(file.write("Target"), qint64(6));
+ existingTargetFile.close();
+ QVERIFY(existingTargetFile.setPermissions(QFile::ReadOwner));
+ PermissionRestorer permissionRestorer(targetFile);
+#endif
+
+ // The saving should fail.
+ QVERIFY(!file.commit());
+#ifdef Q_OS_UNIX
+ QVERIFY(!QFile::exists(targetFile)); // renaming failed
+#endif
+ QCOMPARE(file.error(), QFile::RenameError);
+}
+
+QTEST_MAIN(tst_QSaveFile)
+#include "tst_qsavefile.moc"
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
index 124ccbb456..e733a8f5f8 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl.cpp
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -79,6 +79,8 @@ private slots:
void toString();
void toString_constructed_data();
void toString_constructed();
+ void toAndFromStringList_data();
+ void toAndFromStringList();
void isParentOf_data();
void isParentOf();
void toLocalFile_data();
@@ -941,6 +943,25 @@ void tst_QUrl::toString()
QCOMPARE(url.toString(QUrl::FormattingOptions(options)), string);
}
+void tst_QUrl::toAndFromStringList_data()
+{
+ QTest::addColumn<QStringList>("strings");
+
+ QTest::newRow("empty") << QStringList();
+ QTest::newRow("local") << (QStringList() << "file:///tmp" << "file:///");
+ QTest::newRow("remote") << (QStringList() << "http://qt-project.org");
+}
+
+void tst_QUrl::toAndFromStringList()
+{
+ QFETCH(QStringList, strings);
+
+ const QList<QUrl> urls = QUrl::fromStringList(strings);
+ QCOMPARE(urls.count(), strings.count());
+ const QStringList converted = QUrl::toStringList(urls);
+ QCOMPARE(converted, strings);
+}
+
//### more tests ... what do we expect ...
void tst_QUrl::isParentOf_data()
{