diff options
Diffstat (limited to 'tests/auto/corelib')
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" |