qt5base-lts/tests/auto/qdirmodel/tst_qdirmodel.cpp
Qt by Nokia 38be0d1383 Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you
want to look at revision history older than this, please refer to the
Qt Git wiki for how to use Git history grafting. At the time of
writing, this wiki is located here:

http://qt.gitorious.org/qt/pages/GitIntroductionWithQt

If you have already performed the grafting and you don't see any
history beyond this commit, try running "git log" with the "--follow"
argument.

Branched from the monolithic repo, Qt master branch, at commit
896db169ea224deb96c59ce8af800d019de63f12
2011-04-27 12:05:43 +02:00

715 lines
20 KiB
C++

/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <qdirmodel.h>
#include <qapplication.h>
#include <qtreeview.h>
#include <qdir.h>
#include <qdebug.h>
//TESTED_CLASS=
//TESTED_FILES=
#if defined(Q_OS_SYMBIAN)
# define STRINGIFY(x) #x
# define TOSTRING(x) STRINGIFY(x)
# define SRCDIR "C:/Private/" TOSTRING(SYMBIAN_SRCDIR_UID) "/"
#endif
class tst_QDirModel : public QObject
{
Q_OBJECT
public:
tst_QDirModel();
virtual ~tst_QDirModel();
public slots:
void initTestCase();
void cleanupTestCase();
void init();
void cleanup();
private slots:
void getSetCheck();
/*
void construct();
void rowCount();
void columnCount();
void t_data();
void setData();
void hasChildren();
void isEditable();
void isDragEnabled();
void isDropEnabled();
void sort();
*/
bool rowsAboutToBeRemoved_init(const QString &test_path, const QStringList &initial_files);
bool rowsAboutToBeRemoved_cleanup(const QString &test_path);
void rowsAboutToBeRemoved_data();
void rowsAboutToBeRemoved();
void mkdir_data();
void mkdir();
void rmdir_data();
void rmdir();
void filePath();
void hidden();
void fileName();
void fileName_data();
void task196768_sorting();
void filter();
void task244669_remove();
void roleNames_data();
void roleNames();
};
// Testing get/set functions
void tst_QDirModel::getSetCheck()
{
QDirModel obj1;
// QFileIconProvider * QDirModel::iconProvider()
// void QDirModel::setIconProvider(QFileIconProvider *)
QFileIconProvider *var1 = new QFileIconProvider;
obj1.setIconProvider(var1);
QCOMPARE(var1, obj1.iconProvider());
obj1.setIconProvider((QFileIconProvider *)0);
QCOMPARE((QFileIconProvider *)0, obj1.iconProvider());
delete var1;
// bool QDirModel::resolveSymlinks()
// void QDirModel::setResolveSymlinks(bool)
obj1.setResolveSymlinks(false);
QCOMPARE(false, obj1.resolveSymlinks());
obj1.setResolveSymlinks(true);
QCOMPARE(true, obj1.resolveSymlinks());
// bool QDirModel::lazyChildCount()
// void QDirModel::setLazyChildCount(bool)
obj1.setLazyChildCount(false);
QCOMPARE(false, obj1.lazyChildCount());
obj1.setLazyChildCount(true);
QCOMPARE(true, obj1.lazyChildCount());
}
Q_DECLARE_METATYPE(QModelIndex)
Q_DECLARE_METATYPE(QModelIndexList)
tst_QDirModel::tst_QDirModel()
{
}
tst_QDirModel::~tst_QDirModel()
{
}
void tst_QDirModel::initTestCase()
{
}
void tst_QDirModel::cleanupTestCase()
{
QDir current;
current.rmdir(".qtest_hidden");
}
void tst_QDirModel::init()
{
}
void tst_QDirModel::cleanup()
{
}
/*
tests
*/
/*
void tst_QDirModel::construct()
{
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/test");
index = model.index(2, 0, index);
QVERIFY(index.isValid());
QFileInfo info(QDir::currentPath() + "/test/file03.tst");
QCOMPARE(model.filePath(index), info.absoluteFilePath());
}
void tst_QDirModel::rowCount()
{
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/test");
QVERIFY(index.isValid());
QCOMPARE(model.rowCount(index), 4);
}
void tst_QDirModel::columnCount()
{
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/test");
QVERIFY(index.isValid());
QCOMPARE(model.columnCount(index), 4);
}
void tst_QDirModel::t_data()
{
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/test");
QVERIFY(index.isValid());
QCOMPARE(model.rowCount(index), 4);
index = model.index(2, 0, index);
QVERIFY(index.isValid());
QCOMPARE(model.data(index).toString(), QString::fromLatin1("file03.tst"));
QCOMPARE(model.rowCount(index), 0);
}
void tst_QDirModel::setData()
{
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/test");
QVERIFY(index.isValid());
index = model.index(2, 0, index);
QVERIFY(index.isValid());
QVERIFY(!model.setData(index, "file0X.tst", Qt::EditRole));
}
void tst_QDirModel::hasChildren()
{
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/test");
QVERIFY(index.isValid());
index = model.index(2, 0, index);
QVERIFY(index.isValid());
QVERIFY(!model.hasChildren(index));
}
void tst_QDirModel::isEditable()
{
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/test");
QVERIFY(index.isValid());
index = model.index(2, 0, index);
QVERIFY(index.isValid());
QVERIFY(!(model.flags(index) & Qt::ItemIsEditable));
}
void tst_QDirModel::isDragEnabled()
{
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/test");
QVERIFY(index.isValid());
index = model.index(2, 0, index);
QVERIFY(index.isValid());
QVERIFY(model.flags(index) & Qt::ItemIsDragEnabled);
}
void tst_QDirModel::isDropEnabled()
{
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/test");
QVERIFY(index.isValid());
index = model.index(2, 0, index);
QVERIFY(!(model.flags(index) & Qt::ItemIsDropEnabled));
}
void tst_QDirModel::sort()
{
QDirModel model;
QModelIndex parent = model.index(QDir::currentPath() + "/test");
QVERIFY(parent.isValid());
QModelIndex index = model.index(0, 0, parent);
QCOMPARE(model.data(index).toString(), QString::fromLatin1("file01.tst"));
index = model.index(3, 0, parent);
QCOMPARE(model.data(index).toString(), QString::fromLatin1("file04.tst"));
model.sort(0, Qt::DescendingOrder);
parent = model.index(QDir::currentPath() + "/test");
index = model.index(0, 0, parent);
QCOMPARE(model.data(index).toString(), QString::fromLatin1("file04.tst"));
index = model.index(3, 0, parent);
QCOMPARE(model.data(index).toString(), QString::fromLatin1("file01.tst"));
}
*/
void tst_QDirModel::mkdir_data()
{
QTest::addColumn<QString>("dirName"); // the directory to be made under <currentpath>/dirtest
QTest::addColumn<bool>("mkdirSuccess");
QTest::addColumn<int>("rowCount");
QTest::newRow("okDirName") << QString("test2") << true << 2;
QTest::newRow("existingDirName") << QString("test1") << false << 1;
QTest::newRow("nameWithSpace") << QString("ab cd") << true << 2;
QTest::newRow("emptyDirName") << QString("") << false << 1;
QTest::newRow("nullDirName") << QString() << false << 1;
/*
QTest::newRow("recursiveDirName") << QString("test2/test3") << false << false;
QTest::newRow("singleDotDirName") << QString("./test3") << true << true;
QTest::newRow("outOfTreeDirName") << QString("../test4") << false << false;
QTest::newRow("insideTreeDirName") << QString("../dirtest/test4") << true << true;
QTest::newRow("insideTreeDirName2") << QString("./././././../dirtest/./../dirtest/test4") << true << true;
QTest::newRow("absoluteDirName") << QString(QDir::currentPath() + "/dirtest/test5") << true << true;
QTest::newRow("outOfTreeDirName") << QString(QDir::currentPath() + "/test5") << false << false;
// Directory names only illegal on Windows
#ifdef Q_WS_WIN
QTest::newRow("illegalDirName") << QString("*") << false << false;
QTest::newRow("illegalDirName2") << QString("|") << false << false;
QTest::newRow("onlySpace") << QString(" ") << false << false;
#endif
*/
}
void tst_QDirModel::mkdir()
{
QFETCH(QString, dirName);
QFETCH(bool, mkdirSuccess);
QFETCH(int, rowCount);
QDirModel model;
model.setReadOnly(false);
QModelIndex parent = model.index(SRCDIR "dirtest");
QVERIFY(parent.isValid());
QCOMPARE(model.rowCount(parent), 1); // start out with only 'test1' - in's in the depot
QModelIndex index = model.mkdir(parent, dirName);
bool success = index.isValid();
int rows = model.rowCount(parent);
if (success && !model.rmdir(index))
QVERIFY(QDir(SRCDIR "dirtests").rmdir(dirName));
QCOMPARE(rows, rowCount);
QCOMPARE(success, mkdirSuccess);
}
void tst_QDirModel::rmdir_data()
{
QTest::addColumn<QString>("dirName"); // <currentpath>/dirtest/dirname
QTest::addColumn<bool>("rmdirSuccess");
QTest::addColumn<int>("rowCount");
QTest::newRow("okDirName") << QString("test2") << true << 2;
QTest::newRow("existingDirName") << QString("test1") << false << 1;
QTest::newRow("nameWithSpace") << QString("ab cd") << true << 2;
QTest::newRow("emptyDirName") << QString("") << false << 1;
QTest::newRow("nullDirName") << QString() << false << 1;
}
void tst_QDirModel::rmdir()
{
QFETCH(QString, dirName);
QFETCH(bool, rmdirSuccess);
QFETCH(int, rowCount);
QDirModel model;
model.setReadOnly(false);
QModelIndex parent = model.index(SRCDIR "/dirtest");
QVERIFY(parent.isValid());
QCOMPARE(model.rowCount(parent), 1); // start out with only 'test1' - in's in the depot
QModelIndex index;
if (rmdirSuccess) {
index = model.mkdir(parent, dirName);
QVERIFY(index.isValid());
}
int rows = model.rowCount(parent);
bool success = model.rmdir(index);
if (!success) { // cleanup
QDir dirtests(SRCDIR "/dirtests/");
dirtests.rmdir(dirName);
}
QCOMPARE(rows, rowCount);
QCOMPARE(success, rmdirSuccess);
}
void tst_QDirModel::rowsAboutToBeRemoved_data()
{
QTest::addColumn<QString>("test_path");
QTest::addColumn<QStringList>("initial_files");
QTest::addColumn<int>("remove_row");
QTest::addColumn<QStringList>("remove_files");
QTest::addColumn<QStringList>("expected_files");
QString test_path = "test2";
QStringList initial_files = (QStringList()
<< "file1.tst"
<< "file2.tst"
<< "file3.tst"
<< "file4.tst");
QTest::newRow("removeFirstRow")
<< test_path
<< initial_files
<< 0
<< (QStringList() << "file1.tst")
<< (QStringList() << "file2.tst" << "file3.tst" << "file4.tst");
QTest::newRow("removeMiddle")
<< test_path
<< initial_files
<< 1
<< (QStringList() << "file2.tst")
<< (QStringList() << "file1.tst" << "file3.tst" << "file4.tst");
QTest::newRow("removeLastRow")
<< test_path
<< initial_files
<< 3
<< (QStringList() << "file4.tst")
<< (QStringList() << "file1.tst" << "file2.tst" << "file3.tst");
}
bool tst_QDirModel::rowsAboutToBeRemoved_init(const QString &test_path, const QStringList &initial_files)
{
QString path = QDir::currentPath() + "/" + test_path;
if (!QDir::current().mkdir(test_path) && false) { // FIXME
qDebug() << "failed to create dir" << path;
return false;
}
for (int i = 0; i < initial_files.count(); ++i) {
QFile file(path + "/" + initial_files.at(i));
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "failed to open file" << initial_files.at(i);
return false;
}
if (!file.resize(1024)) {
qDebug() << "failed to resize file" << initial_files.at(i);
return false;
}
if (!file.flush()) {
qDebug() << "failed to flush file" << initial_files.at(i);
return false;
}
}
return true;
}
bool tst_QDirModel::rowsAboutToBeRemoved_cleanup(const QString &test_path)
{
QString path = QDir::currentPath() + "/" + test_path;
QDir dir(path, "*", QDir::SortFlags(QDir::Name|QDir::IgnoreCase), QDir::Files);
QStringList files = dir.entryList();
for (int i = 0; i < files.count(); ++i) {
if (!dir.remove(files.at(i))) {
qDebug() << "failed to remove file" << files.at(i);
return false;
}
}
if (!QDir::current().rmdir(test_path) && false) { // FIXME
qDebug() << "failed to remove dir" << test_path;
return false;
}
return true;
}
void tst_QDirModel::rowsAboutToBeRemoved()
{
QFETCH(QString, test_path);
QFETCH(QStringList, initial_files);
QFETCH(int, remove_row);
QFETCH(QStringList, remove_files);
QFETCH(QStringList, expected_files);
rowsAboutToBeRemoved_cleanup(test_path); // clean up first
QVERIFY(rowsAboutToBeRemoved_init(test_path, initial_files));
QDirModel model;
model.setReadOnly(false);
qRegisterMetaType<QModelIndex>("QModelIndex");
// NOTE: QDirModel will call refresh() when a file is removed. refresh() will reread the entire directory,
// and emit layoutAboutToBeChanged and layoutChange. So, instead of checking for
// rowsAboutToBeRemoved/rowsRemoved we check for layoutAboutToBeChanged/layoutChanged
QSignalSpy spy(&model, SIGNAL(layoutAboutToBeChanged()));
QModelIndex parent = model.index(test_path);
QVERIFY(parent.isValid());
// remove the file
{
QModelIndex index = model.index(remove_row, 0, parent);
QVERIFY(index.isValid());
QVERIFY(model.remove(index));
}
QCOMPARE(spy.count(), 1);
// Compare the result
for (int row = 0; row < expected_files.count(); ++row) {
QModelIndex index = model.index(row, 0, parent);
QString str = index.data().toString();
QCOMPARE(str, expected_files.at(row));
}
QVERIFY(rowsAboutToBeRemoved_cleanup(test_path));
}
void tst_QDirModel::hidden()
{
#ifdef Q_OS_UNIX
QDir current;
current.mkdir(".qtest_hidden");
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/.qtest_hidden");
//QVERIFY(!index.isValid()); // hidden items are not listed, but if you specify a valid path, it will give a valid index
current.mkdir(".qtest_hidden/qtest_visible");
QModelIndex index2 = model.index(QDir::currentPath() + "/.qtest_hidden/qtest_visible");
QVERIFY(index2.isValid());
QDirModel model2;
model2.setFilter(model2.filter() | QDir::Hidden);
index = model2.index(QDir::currentPath() + "/.qtest_hidden");
QVERIFY(index.isValid());
#else
QSKIP("Test not implemented on non-Unixes", SkipAll);
#endif
}
void tst_QDirModel::fileName_data()
{
QTest::addColumn<QString>("path");
QTest::addColumn<QString>("result");
QTest::newRow("invalid") << "" << "";
//QTest::newRow("root") << "/" << "/";
//QTest::newRow("home") << "/home" << "home";
// TODO add symlink test too
}
void tst_QDirModel::fileName()
{
QDirModel model;
QFETCH(QString, path);
QFETCH(QString, result);
QCOMPARE(model.fileName(model.index(path)), result);
}
#if 0
void tst_QDirModel::unreadable()
{
#ifdef Q_OS_UNIX
//QFile current("qtest_unreadable");
//QVERIFY(current.setPermissions(QFile::WriteOwner));
QDirModel model;
QModelIndex index = model.index(QDir::currentPath() + "/qtest_unreadable");
QVERIFY(!index.isValid());
QDirModel model2;
model2.setFilter(model2.filter() | QDir::Hidden);
index = model2.index(QDir::currentPath() + "/qtest_unreadable");
QVERIFY(index.isValid());
#else
QSKIP("Test not implemented on non-Unixes", SkipAll);
#endif
}
#endif
void tst_QDirModel::filePath()
{
#ifdef Q_OS_SYMBIAN
QSKIP("OS doesn't support symbolic links", SkipAll);
#else
QFile::remove(SRCDIR "test.lnk");
QVERIFY(QFile(SRCDIR "tst_qdirmodel.cpp").link(SRCDIR "test.lnk"));
QDirModel model;
model.setResolveSymlinks(false);
QModelIndex index = model.index(SRCDIR "test.lnk");
QVERIFY(index.isValid());
#ifndef Q_OS_WINCE
QString path = SRCDIR;
#else
QString path = QFileInfo(SRCDIR).absoluteFilePath() + "/";
#endif
QCOMPARE(model.filePath(index), path + QString( "test.lnk"));
model.setResolveSymlinks(true);
QCOMPARE(model.filePath(index), path + QString( "tst_qdirmodel.cpp"));
QFile::remove(SRCDIR "test.lnk");
#endif
}
void tst_QDirModel::task196768_sorting()
{
//this task showed that the persistent model indexes got corrupted when sorting
QString path = SRCDIR;
QDirModel model;
/* QDirModel has a bug if we show the content of the subdirectory inside a hidden directory
and we don't add QDir::Hidden. But as QDirModel is deprecated, we decided not to fix it. */
model.setFilter(QDir::AllEntries | QDir::Hidden | QDir::AllDirs);
QTreeView view;
QPersistentModelIndex index = model.index(path);
view.setModel(&model);
QModelIndex index2 = model.index(path);
QCOMPARE(index.data(), index2.data());
view.setRootIndex(index);
index2 = model.index(path);
QCOMPARE(index.data(), index2.data());
view.setCurrentIndex(index);
index2 = model.index(path);
QCOMPARE(index.data(), index2.data());
view.setSortingEnabled(true);
index2 = model.index(path);
#ifdef Q_OS_SYMBIAN
if(!RProcess().HasCapability(ECapabilityAllFiles))
QEXPECT_FAIL("", "QTBUG-9746", Continue);
#endif
QCOMPARE(index.data(), index2.data());
}
void tst_QDirModel::filter()
{
QDirModel model;
model.setNameFilters(QStringList() << "*.nada");
QModelIndex index = model.index(SRCDIR "test");
Q_ASSERT(model.rowCount(index) == 0);
QModelIndex index2 = model.index(SRCDIR "test/file01.tst");
Q_ASSERT(!index2.isValid());
Q_ASSERT(model.rowCount(index) == 0);
}
void tst_QDirModel::task244669_remove()
{
QFile f1(SRCDIR "dirtest/f1.txt");
QVERIFY(f1.open(QIODevice::WriteOnly));
f1.close();
QFile f2(SRCDIR "dirtest/f2.txt");
QVERIFY(f2.open(QIODevice::WriteOnly));
f2.close();
QDirModel model;
model.setReadOnly(false);
QPersistentModelIndex parent = model.index(SRCDIR "dirtest");
QPersistentModelIndex index2 = model.index(SRCDIR "dirtest/f2.txt");
QPersistentModelIndex index1 = model.index(SRCDIR "dirtest/f1.txt");
QVERIFY(parent.isValid());
QVERIFY(index1.isValid());
QVERIFY(index2.isValid());
QCOMPARE(parent.data() , model.index(SRCDIR "dirtest").data());
QCOMPARE(index1.data() , model.index(SRCDIR "dirtest/f1.txt").data());
QCOMPARE(index2.data() , model.index(SRCDIR "dirtest/f2.txt").data());
QVERIFY(model.remove(index1));
QVERIFY(parent.isValid());
QVERIFY(!index1.isValid());
QVERIFY(index2.isValid());
QCOMPARE(parent.data() , model.index(SRCDIR "dirtest").data());
QCOMPARE(index2.data() , model.index(SRCDIR "dirtest/f2.txt").data());
QVERIFY(model.remove(index2));
QVERIFY(parent.isValid());
QVERIFY(!index2.isValid());
QVERIFY(!index1.isValid());
QCOMPARE(parent.data() , model.index(SRCDIR "dirtest").data());
}
void tst_QDirModel::roleNames_data()
{
QTest::addColumn<int>("role");
QTest::addColumn<QByteArray>("roleName");
QTest::newRow("decoration") << int(Qt::DecorationRole) << QByteArray("decoration");
QTest::newRow("display") << int(Qt::DisplayRole) << QByteArray("display");
QTest::newRow("fileIcon") << int(QDirModel::FileIconRole) << QByteArray("fileIcon");
QTest::newRow("filePath") << int(QDirModel::FilePathRole) << QByteArray("filePath");
QTest::newRow("fileName") << int(QDirModel::FileNameRole) << QByteArray("fileName");
}
void tst_QDirModel::roleNames()
{
QDirModel model;
QHash<int, QByteArray> roles = model.roleNames();
QFETCH(int, role);
QVERIFY(roles.contains(role));
QFETCH(QByteArray, roleName);
QList<QByteArray> values = roles.values(role);
QVERIFY(values.contains(roleName));
}
QTEST_MAIN(tst_QDirModel)
#include "tst_qdirmodel.moc"