summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp85
-rw-r--r--tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp26
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp35
3 files changed, 137 insertions, 9 deletions
diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
index 5ef4b11e8a..d9292b8460 100644
--- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
+++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
@@ -66,6 +66,7 @@ private slots:
void textStreamManualFlush();
void textStreamAutoFlush();
void saveTwice();
+ void transactionalWriteNoPermissionsOnDir_data();
void transactionalWriteNoPermissionsOnDir();
void transactionalWriteNoPermissionsOnFile();
void transactionalWriteCanceled();
@@ -153,20 +154,86 @@ void tst_QSaveFile::textStreamAutoFlush()
QFile::remove(targetFile);
}
+void tst_QSaveFile::transactionalWriteNoPermissionsOnDir_data()
+{
+ QTest::addColumn<bool>("directWriteFallback");
+
+ QTest::newRow("default") << false;
+ QTest::newRow("directWriteFallback") << true;
+}
+
void tst_QSaveFile::transactionalWriteNoPermissionsOnDir()
{
#ifdef Q_OS_UNIX
- if (::geteuid() == 0)
- QSKIP("not valid running this test as root");
+ QFETCH(bool, directWriteFallback);
+ // Restore permissions so that the QTemporaryDir cleanup can happen
+ class PermissionRestorer
+ {
+ QString m_path;
+ public:
+ PermissionRestorer(const QString& path)
+ : m_path(path)
+ {}
- // 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");
+ ~PermissionRestorer()
+ {
+ restore();
+ }
+ void restore()
+ {
+ QFile file(m_path);
+ file.setPermissions(QFile::Permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner));
+ }
+ };
- QVERIFY(!file.open(QIODevice::WriteOnly));
- QCOMPARE((int)file.error(), (int)QFile::OpenError);
- QVERIFY(!file.commit());
+
+ QTemporaryDir dir;
+ QVERIFY(QFile(dir.path()).setPermissions(QFile::ReadOwner | QFile::ExeOwner));
+ PermissionRestorer permissionRestorer(dir.path());
+
+ const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
+ QSaveFile firstTry(targetFile);
+ QVERIFY(!firstTry.open(QIODevice::WriteOnly));
+ QCOMPARE((int)firstTry.error(), (int)QFile::OpenError);
+ QVERIFY(!firstTry.commit());
+
+ // Now make an existing writable file
+ permissionRestorer.restore();
+ QFile f(targetFile);
+ QVERIFY(f.open(QIODevice::WriteOnly));
+ QCOMPARE(f.write("Hello"), Q_INT64_C(5));
+ f.close();
+
+ // Make the directory non-writable again
+ QVERIFY(QFile(dir.path()).setPermissions(QFile::ReadOwner | QFile::ExeOwner));
+
+ // And write to it again using QSaveFile; only works if directWriteFallback is enabled
+ QSaveFile file(targetFile);
+ file.setDirectWriteFallback(directWriteFallback);
+ QCOMPARE(file.directWriteFallback(), directWriteFallback);
+ if (directWriteFallback) {
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QCOMPARE((int)file.error(), (int)QFile::NoError);
+ QCOMPARE(file.write("World"), Q_INT64_C(5));
+ QVERIFY(file.commit());
+
+ QFile reader(targetFile);
+ QVERIFY(reader.open(QIODevice::ReadOnly));
+ QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("World"));
+ reader.close();
+
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QCOMPARE((int)file.error(), (int)QFile::NoError);
+ QCOMPARE(file.write("W"), Q_INT64_C(1));
+ file.cancelWriting(); // no effect, as per the documentation
+ QVERIFY(file.commit());
+
+ QVERIFY(reader.open(QIODevice::ReadOnly));
+ QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("W"));
+ } else {
+ QVERIFY(!file.open(QIODevice::WriteOnly));
+ QCOMPARE((int)file.error(), (int)QFile::OpenError);
+ }
#endif
}
diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp
index f750b7a9d4..ea0a14c18c 100644
--- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp
@@ -79,6 +79,8 @@ private slots:
void reset();
void dataChanged();
+ void itemData();
+
protected:
void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex());
@@ -364,5 +366,29 @@ void tst_QIdentityProxyModel::dataChanged()
m_proxy->setSourceModel(0);
}
+class AppendStringProxy : public QIdentityProxyModel
+{
+public:
+ QVariant data(const QModelIndex &index, int role) const
+ {
+ const QVariant result = sourceModel()->data(index, role);
+ if (role != Qt::DisplayRole)
+ return result;
+ return result.toString() + "_appended";
+ }
+};
+
+void tst_QIdentityProxyModel::itemData()
+{
+ QStringListModel model(QStringList() << "Monday" << "Tuesday" << "Wednesday");
+ AppendStringProxy proxy;
+ proxy.setSourceModel(&model);
+
+ const QModelIndex topIndex = proxy.index(0, 0);
+ QCOMPARE(topIndex.data(Qt::DisplayRole).toString(), QStringLiteral("Monday_appended"));
+ QCOMPARE(proxy.data(topIndex, Qt::DisplayRole).toString(), QStringLiteral("Monday_appended"));
+ QCOMPARE(proxy.itemData(topIndex).value(Qt::DisplayRole).toString(), QStringLiteral("Monday_appended"));
+}
+
QTEST_MAIN(tst_QIdentityProxyModel)
#include "tst_qidentityproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
index 4578bcdab6..923b9a3a07 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
@@ -148,6 +148,7 @@ private slots:
void chainedProxyModelRoleNames();
+ void noMapAfterSourceDelete();
protected:
void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
@@ -3809,5 +3810,39 @@ void tst_QSortFilterProxyModel::chainedProxyModelRoleNames()
QVERIFY(proxy2.roleNames().value(Qt::UserRole + 1) == "custom");
}
+class SourceAssertion : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ explicit SourceAssertion(QObject *parent = 0)
+ : QSortFilterProxyModel(parent)
+ {
+
+ }
+
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const
+ {
+ Q_ASSERT(sourceModel());
+ return QSortFilterProxyModel::mapToSource(proxyIndex);
+ }
+};
+
+void tst_QSortFilterProxyModel::noMapAfterSourceDelete()
+{
+ SourceAssertion proxy;
+ QStringListModel *model = new QStringListModel(QStringList() << "Foo" << "Bar");
+
+ proxy.setSourceModel(model);
+
+ // Create mappings
+ QPersistentModelIndex persistent = proxy.index(0, 0);
+
+ QVERIFY(persistent.isValid());
+
+ delete model;
+
+ QVERIFY(!persistent.isValid());
+}
+
QTEST_MAIN(tst_QSortFilterProxyModel)
#include "tst_qsortfilterproxymodel.moc"