tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 #include "../../../src/gui/dialogs/qfilesystemmodel_p.h"
       
    45 #include <QFileIconProvider>
       
    46 #include <QTreeView>
       
    47 #include <QHeaderView>
       
    48 #include "../../shared/util.h"
       
    49 #include <QTime>
       
    50 #include <QStyle>
       
    51 #include <QtGlobal>
       
    52 #if defined(Q_OS_SYMBIAN)
       
    53 # include <f32file.h>
       
    54 #endif
       
    55 //TESTED_CLASS=
       
    56 //TESTED_FILES=
       
    57 
       
    58 #define WAITTIME 1000
       
    59 
       
    60 // Will try to wait for the condition while allowing event processing
       
    61 // for a maximum of 5 seconds.
       
    62 #define TRY_WAIT(expr) \
       
    63     do { \
       
    64         const int step = 50; \
       
    65         for (int __i = 0; __i < 5000 && !(expr); __i+=step) { \
       
    66             QTest::qWait(step); \
       
    67         } \
       
    68     } while(0)
       
    69 
       
    70 #if defined(Q_OS_SYMBIAN)
       
    71 static HBufC* qt_QString2HBufCNewL(const QString& aString)
       
    72 {
       
    73     HBufC *buffer;
       
    74 #ifdef QT_NO_UNICODE
       
    75     TPtrC8 ptr(reinterpret_cast<const TUint8*>(aString.toLocal8Bit().constData()));
       
    76     buffer = HBufC8::NewL(ptr.Length());
       
    77     buffer->Des().Copy(ptr);
       
    78 #else
       
    79     TPtrC16 ptr(reinterpret_cast<const TUint16*>(aString.utf16()));
       
    80     buffer = HBufC16::NewL(ptr.Length());
       
    81     buffer->Des().Copy(ptr);
       
    82 #endif
       
    83     return buffer;
       
    84 }
       
    85 #endif
       
    86 
       
    87 class tst_QFileSystemModel : public QObject {
       
    88   Q_OBJECT
       
    89 
       
    90 public:
       
    91     tst_QFileSystemModel();
       
    92     virtual ~tst_QFileSystemModel();
       
    93 
       
    94 public Q_SLOTS:
       
    95     void init();
       
    96     void cleanup();
       
    97 
       
    98 private slots:
       
    99     void indexPath();
       
   100 
       
   101     void rootPath();
       
   102     void naturalCompare_data();
       
   103     void naturalCompare();
       
   104     void readOnly();
       
   105     void iconProvider();
       
   106 
       
   107     void rowCount();
       
   108 
       
   109     void rowsInserted_data();
       
   110     void rowsInserted();
       
   111 
       
   112     void rowsRemoved_data();
       
   113     void rowsRemoved();
       
   114 
       
   115     void dataChanged_data();
       
   116     void dataChanged();
       
   117 
       
   118     void filters_data();
       
   119     void filters();
       
   120 
       
   121     void nameFilters();
       
   122 
       
   123     void setData_data();
       
   124     void setData();
       
   125 
       
   126     void sort_data();
       
   127     void sort();
       
   128 
       
   129     void mkdir();
       
   130 
       
   131     void caseSensitivity();
       
   132 
       
   133 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   134     void Win32LongFileName();
       
   135 #endif
       
   136 
       
   137     void drives_data();
       
   138     void drives();
       
   139     void dirsBeforeFiles();
       
   140 protected:
       
   141     bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList(), const QString &baseDir = QDir::temp().absolutePath());
       
   142 
       
   143 private:
       
   144     QFileSystemModel *model;
       
   145     QString flatDirTestPath;
       
   146 #if defined(Q_OS_SYMBIAN)
       
   147     RFs rfs;
       
   148 #endif
       
   149 };
       
   150 
       
   151 tst_QFileSystemModel::tst_QFileSystemModel() : model(0)
       
   152 {
       
   153     qRegisterMetaType<QModelIndex>("QModelIndex");
       
   154 
       
   155     QTime midnight(0, 0, 0);
       
   156     qsrand(midnight.secsTo(QTime::currentTime()));
       
   157     // generating unique temporary directory name
       
   158     flatDirTestPath = QDir::temp().path() + '/' + QString("flatdirtest.") + QString::number(qrand());
       
   159 #if defined(Q_OS_SYMBIAN)
       
   160     rfs.Connect();
       
   161 #endif
       
   162 }
       
   163 
       
   164 tst_QFileSystemModel::~tst_QFileSystemModel()
       
   165 {
       
   166 #if defined(Q_OS_SYMBIAN)
       
   167     rfs.Close();
       
   168 #endif
       
   169     QString tmp = flatDirTestPath;
       
   170     QDir dir(tmp);
       
   171     if (dir.exists() && !dir.rmdir(tmp))
       
   172         qWarning("failed to remove tmp dir %s", dir.dirName().toAscii().data());
       
   173 }
       
   174 
       
   175 void tst_QFileSystemModel::init()
       
   176 {
       
   177     cleanup();
       
   178     QCOMPARE(model, (QFileSystemModel*)0);
       
   179     model = new QFileSystemModel;
       
   180 }
       
   181 
       
   182 void tst_QFileSystemModel::cleanup()
       
   183 {
       
   184     delete model;
       
   185     model = 0;
       
   186     QString tmp = flatDirTestPath;
       
   187     QDir dir(tmp);
       
   188     if (dir.exists(tmp)) {
       
   189         QStringList list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot);
       
   190         for (int i = 0; i < list.count(); ++i) {
       
   191             QFileInfo fi(dir.path() + '/' + list.at(i));
       
   192             if (fi.exists() && fi.isFile()) {
       
   193 		        QFile p(fi.absoluteFilePath());
       
   194                 p.setPermissions(QFile::ReadUser | QFile::ReadOwner | QFile::ExeOwner | QFile::ExeUser | QFile::WriteUser | QFile::WriteOwner | QFile::WriteOther);
       
   195 		        QFile dead(dir.path() + '/' + list.at(i));
       
   196 		        dead.remove();
       
   197 	        }
       
   198 	        if (fi.exists() && fi.isDir())
       
   199                 QVERIFY(dir.rmdir(list.at(i)));
       
   200         }
       
   201         list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot);
       
   202         QVERIFY(list.count() == 0);
       
   203     }
       
   204 }
       
   205 
       
   206 void tst_QFileSystemModel::indexPath()
       
   207 {
       
   208 #if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
       
   209     int depth = QDir::currentPath().count('/');
       
   210     model->setRootPath(QDir::currentPath());
       
   211     QTest::qWait(WAITTIME);
       
   212     QString backPath;
       
   213     for (int i = 0; i <= depth * 2 + 1; ++i) {
       
   214         backPath += "../";
       
   215         QModelIndex idx = model->index(backPath);
       
   216         QVERIFY(i != depth - 1 ? idx.isValid() : !idx.isValid());
       
   217     }
       
   218     QTest::qWait(WAITTIME * 3);
       
   219     qApp->processEvents();
       
   220 #endif
       
   221 }
       
   222 
       
   223 void tst_QFileSystemModel::rootPath()
       
   224 {
       
   225     QCOMPARE(model->rootPath(), QString(QDir().path()));
       
   226 
       
   227     QSignalSpy rootChanged(model, SIGNAL(rootPathChanged(const QString &)));
       
   228     QModelIndex root = model->setRootPath(model->rootPath());
       
   229     root = model->setRootPath("this directory shouldn't exist");
       
   230     QCOMPARE(rootChanged.count(), 0);
       
   231 
       
   232     QString oldRootPath = model->rootPath();
       
   233     root = model->setRootPath(QDir::homePath());
       
   234 
       
   235     QTRY_VERIFY(model->rowCount(root) >= 0);
       
   236     QCOMPARE(model->rootPath(), QString(QDir::homePath()));
       
   237     QCOMPARE(rootChanged.count(), oldRootPath == model->rootPath() ? 0 : 1);
       
   238     QCOMPARE(model->rootDirectory().absolutePath(), QDir::homePath());
       
   239 }
       
   240 
       
   241 void tst_QFileSystemModel::naturalCompare_data()
       
   242 {
       
   243     QTest::addColumn<QString>("s1");
       
   244     QTest::addColumn<QString>("s2");
       
   245     QTest::addColumn<int>("caseSensitive");
       
   246     QTest::addColumn<int>("result");
       
   247     QTest::addColumn<int>("swap");
       
   248     for (int j = 0; j < 4; ++j) { // <- set a prefix and a postfix string (not numbers)
       
   249         QString prefix = (j == 0 || j == 1) ? "b" : "";
       
   250         QString postfix = (j == 1 || j == 2) ? "y" : "";
       
   251 
       
   252         for (int k = 0; k < 3; ++k) { // <- make 0 not a special case
       
   253             QString num = QString("%1").arg(k);
       
   254             QString nump = QString("%1").arg(k + 1);
       
   255             for (int i = 10; i < 12; ++i) { // <- swap s1 and s2 and reverse the result
       
   256                 QTest::newRow("basic") << prefix + "0" + postfix << prefix + "0" + postfix << int(Qt::CaseInsensitive) << 0;
       
   257 
       
   258                 // s1 should always be less then s2
       
   259                 QTest::newRow("just text")    << prefix + "fred" + postfix     << prefix + "jane" + postfix << int(Qt::CaseInsensitive) << i;
       
   260                 QTest::newRow("just numbers") << prefix + num + postfix        << prefix + "9" + postfix << int(Qt::CaseInsensitive) << i;
       
   261                 QTest::newRow("zero")         << prefix + num + postfix        << prefix + "0" + nump + postfix << int(Qt::CaseInsensitive) << i;
       
   262                 QTest::newRow("space b")      << prefix + num + postfix        << prefix + " " + nump + postfix << int(Qt::CaseInsensitive) << i;
       
   263                 QTest::newRow("space a")      << prefix + num + postfix        << prefix + nump + " " + postfix << int(Qt::CaseInsensitive) << i;
       
   264                 QTest::newRow("tab b")        << prefix + num + postfix        << prefix + "    " + nump + postfix << int(Qt::CaseInsensitive) << i;
       
   265                 QTest::newRow("tab a")        << prefix + num + postfix        << prefix + nump + "   " + postfix << int(Qt::CaseInsensitive) << i;
       
   266                 QTest::newRow("10 vs 2")      << prefix + num + postfix        << prefix + "10" + postfix << int(Qt::CaseInsensitive) << i;
       
   267                 QTest::newRow("diff len")     << prefix + num + postfix        << prefix + nump + postfix + "x" << int(Qt::CaseInsensitive) << i;
       
   268                 QTest::newRow("01 before 1")  << prefix + "0" + num + postfix  << prefix + nump + postfix << int(Qt::CaseInsensitive) << i;
       
   269                 QTest::newRow("mul nums 2nd") << prefix + "1-" + num + postfix << prefix + "1-" + nump + postfix << int(Qt::CaseInsensitive) << i;
       
   270                 QTest::newRow("mul nums 2nd") << prefix + "10-" + num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
       
   271                 QTest::newRow("mul nums 2nd") << prefix + "10-0"+ num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
       
   272                 QTest::newRow("mul nums 2nd") << prefix + "10-" + num + postfix<< prefix + "10-010" + postfix << int(Qt::CaseInsensitive) << i;
       
   273                 QTest::newRow("mul nums big") << prefix + "10-" + num + postfix<< prefix + "20-0" + postfix << int(Qt::CaseInsensitive) << i;
       
   274                 QTest::newRow("mul nums big") << prefix + "2-" + num + postfix << prefix + "10-0" + postfix << int(Qt::CaseInsensitive) << i;
       
   275                 QTest::newRow("mul alphabet") << prefix + num + "-a" + postfix << prefix + num + "-c" + postfix << int(Qt::CaseInsensitive) << i;
       
   276                 QTest::newRow("mul alphabet2")<< prefix + num + "-a9" + postfix<< prefix + num + "-c0" + postfix << int(Qt::CaseInsensitive) << i;
       
   277                 QTest::newRow("mul nums w\\0")<< prefix + num + "-"+ num + postfix<< prefix + num+"-0"+nump + postfix << int(Qt::CaseInsensitive) << i;
       
   278                 QTest::newRow("num first")    << prefix + num + postfix  << prefix + "a" + postfix << int(Qt::CaseInsensitive) << i;
       
   279             }
       
   280         }
       
   281     }
       
   282 }
       
   283 
       
   284 void tst_QFileSystemModel::naturalCompare()
       
   285 {
       
   286 #ifdef QT_BUILD_INTERNAL
       
   287     QFETCH(QString, s1);
       
   288     QFETCH(QString, s2);
       
   289     QFETCH(int, caseSensitive);
       
   290     QFETCH(int, result);
       
   291 
       
   292     if (result == 10)
       
   293         QCOMPARE(QFileSystemModelPrivate::naturalCompare(s1, s2, Qt::CaseSensitivity(caseSensitive)), -1);
       
   294     else
       
   295         if (result == 11)
       
   296             QCOMPARE(QFileSystemModelPrivate::naturalCompare(s2, s1, Qt::CaseSensitivity(caseSensitive)), 1);
       
   297     else
       
   298         QCOMPARE(QFileSystemModelPrivate::naturalCompare(s2, s1, Qt::CaseSensitivity(caseSensitive)), result);
       
   299 #if defined(Q_OS_WINCE)
       
   300     // On Windows CE we need to wait after each test, otherwise no new threads can be
       
   301     // created. The scheduler takes its time to recognize ended threads.
       
   302     QTest::qWait(300);
       
   303 #endif
       
   304 #endif
       
   305 }
       
   306 
       
   307 void tst_QFileSystemModel::readOnly()
       
   308 {
       
   309     QCOMPARE(model->isReadOnly(), true);
       
   310     QTemporaryFile file;
       
   311     file.open();
       
   312     QModelIndex root = model->setRootPath(QDir::tempPath());
       
   313 
       
   314     QTRY_VERIFY(model->rowCount(root) > 0);
       
   315     QVERIFY(!(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable));
       
   316     model->setReadOnly(false);
       
   317     QCOMPARE(model->isReadOnly(), false);
       
   318     QVERIFY(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable);
       
   319 }
       
   320 
       
   321 class CustomFileIconProvider : public QFileIconProvider
       
   322 {
       
   323 public:
       
   324     CustomFileIconProvider() : QFileIconProvider() {
       
   325         mb = qApp->style()->standardIcon(QStyle::SP_MessageBoxCritical);
       
   326         dvd = qApp->style()->standardIcon(QStyle::SP_DriveDVDIcon);
       
   327     }
       
   328 
       
   329     virtual QIcon icon(const QFileInfo &info) const
       
   330     {
       
   331         if (info.isDir())
       
   332             return mb;
       
   333 
       
   334         return QFileIconProvider::icon(info);
       
   335     }
       
   336     virtual QIcon icon(IconType type) const
       
   337     {
       
   338         if (type == QFileIconProvider::Folder)
       
   339             return dvd;
       
   340 
       
   341         return QFileIconProvider::icon(type);
       
   342     }
       
   343 private:
       
   344     QIcon mb;
       
   345     QIcon dvd;
       
   346 };
       
   347 
       
   348 void tst_QFileSystemModel::iconProvider()
       
   349 {
       
   350     QVERIFY(model->iconProvider());
       
   351     QFileIconProvider *p = new QFileIconProvider();
       
   352     model->setIconProvider(p);
       
   353     QCOMPARE(model->iconProvider(), p);
       
   354     model->setIconProvider(0);
       
   355     delete p;
       
   356 
       
   357     QFileSystemModel *myModel = new QFileSystemModel();
       
   358     myModel->setRootPath(QDir::homePath());
       
   359     //Let's wait to populate the model
       
   360     QTest::qWait(250);
       
   361     //We change the provider, icons must me updated
       
   362     CustomFileIconProvider *custom = new CustomFileIconProvider();
       
   363     myModel->setIconProvider(custom);
       
   364 
       
   365     QPixmap mb = qApp->style()->standardIcon(QStyle::SP_MessageBoxCritical).pixmap(50, 50);
       
   366     QCOMPARE(myModel->fileIcon(myModel->index(QDir::homePath())).pixmap(50, 50), mb);
       
   367     delete myModel;
       
   368     delete custom;
       
   369 }
       
   370 
       
   371 bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs, const QString &dir)
       
   372 {
       
   373     QDir baseDir(dir);
       
   374     if (!baseDir.exists(test_path)) {
       
   375         if (!baseDir.mkdir(test_path) && false) {
       
   376             qDebug() << "failed to create dir" << test_path;
       
   377             return false;
       
   378         }
       
   379     }
       
   380     //qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files;
       
   381     TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount));
       
   382     for (int i = 0; i < initial_dirs.count(); ++i) {
       
   383         QDir dir(test_path);
       
   384         if (!dir.exists()) {
       
   385             qWarning() << "error" << test_path << "doesn't exists";
       
   386             return false;
       
   387         }
       
   388         if(!dir.mkdir(initial_dirs.at(i))) {
       
   389             qWarning() << "error" << "failed to make" << initial_dirs.at(i);
       
   390             return false;
       
   391         }
       
   392         //qDebug() << test_path + '/' + initial_dirs.at(i) << (QFile::exists(test_path + '/' + initial_dirs.at(i)));
       
   393     }
       
   394     for (int i = 0; i < initial_files.count(); ++i) {
       
   395         QFile file(test_path + '/' + initial_files.at(i));
       
   396         if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
       
   397             qDebug() << "failed to open file" << initial_files.at(i);
       
   398             return false;
       
   399         }
       
   400         if (!file.resize(1024 + file.size())) {
       
   401             qDebug() << "failed to resize file" << initial_files.at(i);
       
   402             return false;
       
   403         }
       
   404         if (!file.flush()) {
       
   405             qDebug() << "failed to flush file" << initial_files.at(i);
       
   406             return false;
       
   407         }
       
   408         file.close();
       
   409 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   410         if (initial_files.at(i)[0] == '.')
       
   411             QProcess::execute(QString("attrib +h %1").arg(file.fileName()));
       
   412 #elif defined(Q_OS_SYMBIAN)
       
   413         if (initial_files.at(i)[0] == '.') {
       
   414             HBufC* buffer = qt_QString2HBufCNewL(QDir::toNativeSeparators(file.fileName()));
       
   415             rfs.SetAtt(*buffer, KEntryAttHidden, 0);
       
   416             delete buffer;
       
   417             }
       
   418 #endif
       
   419         //qDebug() << test_path + '/' + initial_files.at(i) << (QFile::exists(test_path + '/' + initial_files.at(i)));
       
   420     }
       
   421     return true;
       
   422 }
       
   423 
       
   424 void tst_QFileSystemModel::rowCount()
       
   425 {
       
   426     QString tmp = flatDirTestPath;
       
   427     QVERIFY(createFiles(tmp, QStringList()));
       
   428 
       
   429     QSignalSpy spy2(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
       
   430     QSignalSpy spy3(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)));
       
   431 
       
   432 #if !defined(Q_OS_WINCE)
       
   433     QStringList files = QStringList() <<  "b" << "d" << "f" << "h" << "j" << ".a" << ".c" << ".e" << ".g";
       
   434     QString l = "b,d,f,h,j,.a,.c,.e,.g";
       
   435 #else
       
   436     // Cannot hide them on CE
       
   437     QStringList files = QStringList() <<  "b" << "d" << "f" << "h" << "j";
       
   438     QString l = "b,d,f,h,j";
       
   439 #endif
       
   440     QVERIFY(createFiles(tmp, files));
       
   441 
       
   442     QModelIndex root = model->setRootPath(tmp);
       
   443     QTRY_COMPARE(model->rowCount(root), 5);
       
   444     QVERIFY(spy2.count() > 0);
       
   445     QVERIFY(spy3.count() > 0);
       
   446 }
       
   447 
       
   448 void tst_QFileSystemModel::rowsInserted_data()
       
   449 {
       
   450     QTest::addColumn<int>("count");
       
   451     QTest::addColumn<int>("assending");
       
   452     for (int i = 0; i < 4; ++i) {
       
   453         QTest::newRow(QString("Qt::AscendingOrder %1").arg(i).toLocal8Bit().constData())  << i << (int)Qt::AscendingOrder;
       
   454         QTest::newRow(QString("Qt::DescendingOrder %1").arg(i).toLocal8Bit().constData()) << i << (int)Qt::DescendingOrder;
       
   455     }
       
   456 }
       
   457 
       
   458 void tst_QFileSystemModel::rowsInserted()
       
   459 {
       
   460 #if defined(Q_OS_WINCE)
       
   461     QSKIP("Watching directories does not work on CE(see #137910)", SkipAll);
       
   462 #endif
       
   463     QString tmp = flatDirTestPath;
       
   464     rowCount();
       
   465     QModelIndex root = model->index(model->rootPath());
       
   466 
       
   467     QFETCH(int, assending);
       
   468     QFETCH(int, count);
       
   469     model->sort(0, (Qt::SortOrder)assending);
       
   470 
       
   471     QSignalSpy spy0(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
       
   472     QSignalSpy spy1(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)));
       
   473     int oldCount = model->rowCount(root);
       
   474     QStringList files;
       
   475     for (int i = 0; i < count; ++i)
       
   476         files.append(QString("c%1").arg(i));
       
   477     QVERIFY(createFiles(tmp, files, 5));
       
   478     TRY_WAIT(model->rowCount(root) == oldCount + count);
       
   479     QTRY_COMPARE(model->rowCount(root), oldCount + count);
       
   480     QTest::qWait(100); // Let the sort settle.
       
   481     int totalRowsInserted = 0;
       
   482     for (int i = 0; i < spy0.count(); ++i) {
       
   483         int start = spy0[i].value(1).toInt();
       
   484         int end = spy0[i].value(2).toInt();
       
   485         totalRowsInserted += end - start + 1;
       
   486     }
       
   487     QCOMPARE(totalRowsInserted, count);
       
   488     if (assending == (Qt::SortOrder)Qt::AscendingOrder) {
       
   489         QString letter = model->index(model->rowCount(root) - 1, 0, root).data().toString();
       
   490         QCOMPARE(letter, QString("j"));
       
   491     } else {
       
   492         QCOMPARE(model->index(model->rowCount(root) - 1, 0, root).data().toString(), QString("b"));
       
   493     }
       
   494     if (spy0.count() > 0) {
       
   495         if (count == 0)
       
   496             QCOMPARE(spy0.count(), 0);
       
   497         else
       
   498             QVERIFY(spy0.count() >= 1);
       
   499     }
       
   500     if (count == 0) QCOMPARE(spy1.count(), 0); else QVERIFY(spy1.count() >= 1);
       
   501 
       
   502     QVERIFY(createFiles(tmp, QStringList(".hidden_file"), 5 + count));
       
   503 
       
   504     if (count != 0) QTRY_VERIFY(spy0.count() >= 1); else QTRY_VERIFY(spy0.count() == 0);
       
   505     if (count != 0) QTRY_VERIFY(spy1.count() >= 1); else QTRY_VERIFY(spy1.count() == 0);
       
   506 }
       
   507 
       
   508 void tst_QFileSystemModel::rowsRemoved_data()
       
   509 {
       
   510     rowsInserted_data();
       
   511 }
       
   512 
       
   513 void tst_QFileSystemModel::rowsRemoved()
       
   514 {
       
   515 #if defined(Q_OS_WINCE)
       
   516     QSKIP("Watching directories does not work on CE(see #137910)", SkipAll);
       
   517 #endif
       
   518     QString tmp = flatDirTestPath;
       
   519     rowCount();
       
   520     QModelIndex root = model->index(model->rootPath());
       
   521 
       
   522     QFETCH(int, count);
       
   523     QFETCH(int, assending);
       
   524     model->sort(0, (Qt::SortOrder)assending);
       
   525     QTest::qWait(WAITTIME);
       
   526 
       
   527     QSignalSpy spy0(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
       
   528     QSignalSpy spy1(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)));
       
   529     int oldCount = model->rowCount(root);
       
   530     for (int i = count - 1; i >= 0; --i) {
       
   531         //qDebug() << "removing" <<  model->index(i, 0, root).data().toString();
       
   532         QVERIFY(QFile::remove(tmp + '/' + model->index(i, 0, root).data().toString()));
       
   533     }
       
   534     for (int i = 0 ; i < 10; ++i) {
       
   535         QTest::qWait(WAITTIME);
       
   536         qApp->processEvents();
       
   537         if (count != 0) {
       
   538             if (i == 10 || spy0.count() != 0) {
       
   539                 QVERIFY(spy0.count() >= 1);
       
   540                 QVERIFY(spy1.count() >= 1);
       
   541             }
       
   542         } else {
       
   543             if (i == 10 || spy0.count() == 0) {
       
   544                 QVERIFY(spy0.count() == 0);
       
   545                 QVERIFY(spy1.count() == 0);
       
   546             }
       
   547         }
       
   548         QStringList lst;
       
   549         for (int i = 0; i < model->rowCount(root); ++i)
       
   550             lst.append(model->index(i, 0, root).data().toString());
       
   551         if (model->rowCount(root) == oldCount - count)
       
   552             break;
       
   553         qDebug() << "still have:" << lst << QFile::exists(tmp + '/' + QString(".a"));
       
   554         QDir tmpLister(tmp);
       
   555         qDebug() << tmpLister.entryList();
       
   556     }
       
   557     QTRY_COMPARE(model->rowCount(root), oldCount - count);
       
   558 
       
   559     QVERIFY(QFile::exists(tmp + '/' + QString(".a")));
       
   560     QVERIFY(QFile::remove(tmp + '/' + QString(".a")));
       
   561     QVERIFY(QFile::remove(tmp + '/' + QString(".c")));
       
   562     QTest::qWait(WAITTIME);
       
   563 
       
   564     if (count != 0) QVERIFY(spy0.count() >= 1); else QVERIFY(spy0.count() == 0);
       
   565     if (count != 0) QVERIFY(spy1.count() >= 1); else QVERIFY(spy1.count() == 0);
       
   566 }
       
   567 
       
   568 void tst_QFileSystemModel::dataChanged_data()
       
   569 {
       
   570     rowsInserted_data();
       
   571 }
       
   572 
       
   573 void tst_QFileSystemModel::dataChanged()
       
   574 {
       
   575     // This can't be tested right now sense we don't watch files, only directories
       
   576     return;
       
   577 
       
   578     /*
       
   579     QString tmp = flatDirTestPath;
       
   580     rowCount();
       
   581     QModelIndex root = model->index(model->rootPath());
       
   582 
       
   583     QFETCH(int, count);
       
   584     QFETCH(int, assending);
       
   585     model->sort(0, (Qt::SortOrder)assending);
       
   586 
       
   587     QSignalSpy spy(model, SIGNAL(dataChanged (const QModelIndex &, const QModelIndex &)));
       
   588     QStringList files;
       
   589     for (int i = 0; i < count; ++i)
       
   590         files.append(model->index(i, 0, root).data().toString());
       
   591     createFiles(tmp, files);
       
   592 
       
   593     QTest::qWait(WAITTIME);
       
   594 
       
   595     if (count != 0) QVERIFY(spy.count() >= 1); else QVERIFY(spy.count() == 0);
       
   596     */
       
   597 }
       
   598 
       
   599 void tst_QFileSystemModel::filters_data()
       
   600 {
       
   601     QTest::addColumn<QStringList>("files");
       
   602     QTest::addColumn<QStringList>("dirs");
       
   603     QTest::addColumn<int>("dirFilters");
       
   604     QTest::addColumn<QStringList>("nameFilters");
       
   605     QTest::addColumn<int>("rowCount");
       
   606 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
       
   607     QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 2;
       
   608     QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1;
       
   609     QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 3;
       
   610     QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 2;
       
   611     QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() <<
       
   612                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden) << QStringList() << 5;
       
   613     QTest::newRow("dir+file+hid-dot .A") << (QStringList() << "a" << "b" << "c") << (QStringList() << ".A") <<
       
   614                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << QStringList() << 4;
       
   615     QTest::newRow("dir+files+hid+dot A") << (QStringList() << "a" << "b" << "c") << (QStringList() << "AFolder") <<
       
   616                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << (QStringList() << "A*") << 2;
       
   617     QTest::newRow("dir+files+hid+dot+cas1") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
       
   618                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "Z") << 1;
       
   619     QTest::newRow("dir+files+hid+dot+cas2") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
       
   620                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "a") << 1;
       
   621     QTest::newRow("dir+files+hid+dot+cas+alldir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
       
   622                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive | QDir::AllDirs) << (QStringList() << "Z") << 1;
       
   623 #else
       
   624     QTest::qWait(3000); // We need to calm down a bit...
       
   625     QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 0;
       
   626     QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1;
       
   627     QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 1;
       
   628     QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 0;
       
   629     QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() <<
       
   630                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden) << QStringList() << 3;
       
   631 #if defined(Q_OS_SYMBIAN)
       
   632     // Some symbian envs have a bug that causes "A" and ".A" to be considered same name in file system.
       
   633     QTest::newRow("dir+file+hid-dot .D") << (QStringList() << "a" << "b" << "c") << (QStringList() << ".D") <<
       
   634 #else
       
   635     QTest::newRow("dir+file+hid-dot .A") << (QStringList() << "a" << "b" << "c") << (QStringList() << ".A") <<
       
   636 #endif
       
   637                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << QStringList() << 4;
       
   638     QTest::newRow("dir+files+hid+dot A") << (QStringList() << "a" << "b" << "c") << (QStringList() << "AFolder") <<
       
   639                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << (QStringList() << "A*") << 2;
       
   640     QTest::newRow("dir+files+hid+dot+cas1") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
       
   641                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "Z") << 1;
       
   642     QTest::newRow("dir+files+hid+dot+cas2") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
       
   643                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "a") << 1;
       
   644     QTest::newRow("dir+files+hid+dot+cas+alldir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
       
   645                          (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive | QDir::AllDirs) << (QStringList() << "Z") << 1;
       
   646 #endif
       
   647 
       
   648     QTest::newRow("case sensitive") << (QStringList() << "Antiguagdb" << "Antiguamtd"
       
   649         << "Antiguamtp" << "afghanistangdb" << "afghanistanmtd")
       
   650         << QStringList() << (int)(QDir::Files) << QStringList() << 5;
       
   651 }
       
   652 
       
   653 void tst_QFileSystemModel::filters()
       
   654 {
       
   655     QString tmp = flatDirTestPath;
       
   656     QVERIFY(createFiles(tmp, QStringList()));
       
   657     QModelIndex root = model->setRootPath(tmp);
       
   658     QFETCH(QStringList, files);
       
   659     QFETCH(QStringList, dirs);
       
   660     QFETCH(int, dirFilters);
       
   661     QFETCH(QStringList, nameFilters);
       
   662     QFETCH(int, rowCount);
       
   663 
       
   664     if (nameFilters.count() > 0)
       
   665         model->setNameFilters(nameFilters);
       
   666     model->setNameFilterDisables(false);
       
   667     model->setFilter((QDir::Filters)dirFilters);
       
   668 
       
   669     QVERIFY(createFiles(tmp, files, 0, dirs));
       
   670     QTRY_COMPARE(model->rowCount(root), rowCount);
       
   671 
       
   672     // Make sure that we do what QDir does
       
   673     QDir xFactor(tmp);
       
   674     QDir::Filters  filters = (QDir::Filters)dirFilters;
       
   675     if (nameFilters.count() > 0)
       
   676         QCOMPARE(xFactor.entryList(nameFilters, filters).count(), rowCount);
       
   677     else
       
   678         QVERIFY(xFactor.entryList(filters).count() == rowCount);
       
   679 
       
   680 #ifdef Q_OS_LINUX
       
   681     if (files.count() >= 3 && rowCount >= 3 && rowCount != 5) {
       
   682         QString fileName1 = (tmp + '/' + files.at(0));
       
   683         QString fileName2 = (tmp + '/' + files.at(1));
       
   684         QString fileName3 = (tmp + '/' + files.at(2));
       
   685         QFile::Permissions originalPermissions = QFile::permissions(fileName1);
       
   686         QVERIFY(QFile::setPermissions(fileName1, QFile::WriteOwner));
       
   687         QVERIFY(QFile::setPermissions(fileName2, QFile::ReadOwner));
       
   688         QVERIFY(QFile::setPermissions(fileName3, QFile::ExeOwner));
       
   689 
       
   690         model->setFilter((QDir::Files | QDir::Readable));
       
   691         QTRY_COMPARE(model->rowCount(root), 1);
       
   692 
       
   693         model->setFilter((QDir::Files | QDir::Writable));
       
   694         QTRY_COMPARE(model->rowCount(root), 1);
       
   695 
       
   696         model->setFilter((QDir::Files | QDir::Executable));
       
   697         QTRY_COMPARE(model->rowCount(root), 1);
       
   698 
       
   699         // reset permissions
       
   700         QVERIFY(QFile::setPermissions(fileName1, originalPermissions));
       
   701         QVERIFY(QFile::setPermissions(fileName2, originalPermissions));
       
   702         QVERIFY(QFile::setPermissions(fileName3, originalPermissions));
       
   703     }
       
   704 #endif
       
   705 }
       
   706 
       
   707 void tst_QFileSystemModel::nameFilters()
       
   708 {
       
   709     QStringList list;
       
   710     list << "a" << "b" << "c";
       
   711     model->setNameFilters(list);
       
   712     model->setNameFilterDisables(false);
       
   713     QCOMPARE(model->nameFilters(), list);
       
   714 
       
   715     QString tmp = flatDirTestPath;
       
   716     QVERIFY(createFiles(tmp, list));
       
   717     QModelIndex root = model->setRootPath(tmp);
       
   718     QTRY_COMPARE(model->rowCount(root), 3);
       
   719 
       
   720     QStringList filters;
       
   721     filters << "a" << "b";
       
   722     model->setNameFilters(filters);
       
   723     QTRY_COMPARE(model->rowCount(root), 2);
       
   724 }
       
   725 void tst_QFileSystemModel::setData_data()
       
   726 {
       
   727     QTest::addColumn<QStringList>("files");
       
   728     QTest::addColumn<QString>("oldFileName");
       
   729     QTest::addColumn<QString>("newFileName");
       
   730     QTest::addColumn<bool>("success");
       
   731     /*QTest::newRow("outside current dir") << (QStringList() << "a" << "b" << "c")
       
   732               << flatDirTestPath + '/' + "a"
       
   733               << QDir::temp().absolutePath() + '/' + "a"
       
   734               << false;
       
   735     */
       
   736     QTest::newRow("in current dir") << (QStringList() << "a" << "b" << "c")
       
   737               << "a"
       
   738               << "d"
       
   739               << true;
       
   740 }
       
   741 
       
   742 void tst_QFileSystemModel::setData()
       
   743 {
       
   744     QSignalSpy spy(model, SIGNAL(fileRenamed(const QString&, const QString&, const QString&)));
       
   745     QString tmp = flatDirTestPath;
       
   746     QFETCH(QStringList, files);
       
   747     QFETCH(QString, oldFileName);
       
   748     QFETCH(QString, newFileName);
       
   749     QFETCH(bool, success);
       
   750 
       
   751     QVERIFY(createFiles(tmp, files));
       
   752     QModelIndex root = model->setRootPath(tmp);
       
   753     QTRY_COMPARE(model->rowCount(root), files.count());
       
   754 
       
   755     QModelIndex idx = model->index(tmp + '/' + oldFileName);
       
   756     QCOMPARE(idx.isValid(), true);
       
   757     QCOMPARE(model->setData(idx, newFileName), false);
       
   758 
       
   759     model->setReadOnly(false);
       
   760     QCOMPARE(model->setData(idx, newFileName), success);
       
   761     if (success) {
       
   762         QCOMPARE(spy.count(), 1);
       
   763         QList<QVariant> arguments = spy.takeFirst();
       
   764         QCOMPARE(model->data(idx, QFileSystemModel::FileNameRole).toString(), newFileName);
       
   765         QCOMPARE(model->index(arguments.at(0).toString()), model->index(tmp));
       
   766         QCOMPARE(arguments.at(1).toString(), oldFileName);
       
   767         QCOMPARE(arguments.at(2).toString(), newFileName);
       
   768         QCOMPARE(QFile::rename(tmp + '/' + newFileName, tmp + '/' + oldFileName), true);
       
   769     }
       
   770     QTRY_COMPARE(model->rowCount(root), files.count());
       
   771 }
       
   772 
       
   773 class MyFriendFileSystemModel : public QFileSystemModel
       
   774 {
       
   775     friend class tst_QFileSystemModel;
       
   776     Q_DECLARE_PRIVATE(QFileSystemModel)
       
   777 };
       
   778 
       
   779 void tst_QFileSystemModel::sort_data()
       
   780 {
       
   781     QTest::addColumn<bool>("fileDialogMode");
       
   782     QTest::newRow("standard usage") << false;
       
   783     QTest::newRow("QFileDialog usage") << true;
       
   784 }
       
   785 
       
   786 void tst_QFileSystemModel::sort()
       
   787 {
       
   788     QTemporaryFile file;
       
   789     file.open();
       
   790     QModelIndex root = model->setRootPath(QDir::tempPath());
       
   791     QTRY_VERIFY(model->rowCount(root) > 0);
       
   792 
       
   793     QPersistentModelIndex idx = model->index(0, 1, root);
       
   794     model->sort(0, Qt::AscendingOrder);
       
   795     model->sort(0, Qt::DescendingOrder);
       
   796     QVERIFY(idx.column() != 0);
       
   797 
       
   798     model->setRootPath(QDir::homePath());
       
   799 
       
   800     QFETCH(bool, fileDialogMode);
       
   801 
       
   802     MyFriendFileSystemModel *myModel = new MyFriendFileSystemModel();
       
   803     QTreeView *tree = new QTreeView();
       
   804 
       
   805     if (fileDialogMode)
       
   806         myModel->d_func()->disableRecursiveSort = true;
       
   807 
       
   808     QDir dir(QDir::tempPath());
       
   809     //initialize the randomness
       
   810     qsrand(QDateTime::currentDateTime().toTime_t());
       
   811     QString tempName = QLatin1String("sortTemp.") + QString::number(qrand());
       
   812     dir.mkdir(tempName);
       
   813     dir.cd(tempName);
       
   814     QTRY_VERIFY(dir.exists());
       
   815 
       
   816     const QString dirPath = dir.absolutePath();
       
   817     QVERIFY(dir.exists());
       
   818 
       
   819     //Create a file that will be at the end when sorting by name (For Mac, the default)
       
   820     //but if we sort by size descending it will be the first
       
   821     QFile tempFile(dirPath + "/plop2.txt");
       
   822     tempFile.open(QIODevice::WriteOnly | QIODevice::Text);
       
   823     QTextStream out(&tempFile);
       
   824     out << "The magic number is: " << 49 << "\n";
       
   825     tempFile.close();
       
   826 
       
   827     QFile tempFile2(dirPath + "/plop.txt");
       
   828     tempFile2.open(QIODevice::WriteOnly | QIODevice::Text);
       
   829     QTextStream out2(&tempFile2);
       
   830     out2 << "The magic number is : " << 49 << " but i write some stuff in the file \n";
       
   831     tempFile2.close();
       
   832 
       
   833     myModel->setRootPath("");
       
   834     myModel->setFilter(QDir::AllEntries | QDir::System | QDir::Hidden);
       
   835     tree->setSortingEnabled(true);
       
   836     tree->setModel(myModel);
       
   837     tree->show();
       
   838     tree->resize(800, 800);
       
   839     QTest::qWait(500);
       
   840     tree->header()->setSortIndicator(1,Qt::DescendingOrder);
       
   841     tree->header()->setResizeMode(0, QHeaderView::ResizeToContents);
       
   842     QStringList dirsToOpen;
       
   843     do
       
   844     {
       
   845         dirsToOpen<<dir.absolutePath();
       
   846     } while (dir.cdUp());
       
   847 
       
   848     for (int i = dirsToOpen.size() -1 ; i > 0 ; --i) {
       
   849         QString path = dirsToOpen[i];
       
   850         QTest::qWait(500);
       
   851         tree->expand(myModel->index(path, 0));
       
   852     }
       
   853     tree->expand(myModel->index(dirPath, 0));
       
   854     QTest::qWait(500);
       
   855     QModelIndex parent = myModel->index(dirPath, 0);
       
   856     QList<QString> expectedOrder;
       
   857     expectedOrder << tempFile2.fileName() << tempFile.fileName() << dirPath + QChar('/') + "." << dirPath + QChar('/') + "..";
       
   858     //File dialog Mode means sub trees are not sorted, only the current root
       
   859     if (fileDialogMode) {
       
   860        QList<QString> actualRows;
       
   861         for(int i = 0; i < myModel->rowCount(parent); ++i)
       
   862         {
       
   863             actualRows << dirPath + QChar('/') + myModel->index(i, 1, parent).data(QFileSystemModel::FileNameRole).toString();
       
   864         }
       
   865         QVERIFY(actualRows != expectedOrder);
       
   866     } else {
       
   867         for(int i = 0; i < myModel->rowCount(parent); ++i)
       
   868         {
       
   869             QTRY_COMPARE(dirPath + QChar('/') + myModel->index(i, 1, parent).data(QFileSystemModel::FileNameRole).toString(), expectedOrder.at(i));
       
   870         }
       
   871     }
       
   872 
       
   873     delete tree;
       
   874     delete myModel;
       
   875 
       
   876     dir.setPath(QDir::tempPath());
       
   877     dir.cd(tempName);
       
   878     tempFile.remove();
       
   879     tempFile2.remove();
       
   880     dir.cdUp();
       
   881     dir.rmdir(tempName);
       
   882 
       
   883 }
       
   884 
       
   885 void tst_QFileSystemModel::mkdir()
       
   886 {
       
   887     QString tmp = QDir::tempPath();
       
   888     QString newFolderPath = QDir::toNativeSeparators(tmp + '/' + "NewFoldermkdirtest4");
       
   889     QModelIndex tmpDir = model->index(tmp);
       
   890     QVERIFY(tmpDir.isValid());
       
   891     QDir bestatic(newFolderPath);
       
   892     if (bestatic.exists()) {
       
   893         if (!bestatic.rmdir(newFolderPath))
       
   894             qWarning() << "unable to remove" << newFolderPath;
       
   895         QTest::qWait(WAITTIME);
       
   896     }
       
   897     model->mkdir(tmpDir, "NewFoldermkdirtest3");
       
   898     model->mkdir(tmpDir, "NewFoldermkdirtest5");
       
   899     QModelIndex idx = model->mkdir(tmpDir, "NewFoldermkdirtest4");
       
   900     QVERIFY(idx.isValid());
       
   901     int oldRow = idx.row();
       
   902     QTest::qWait(WAITTIME);
       
   903     idx = model->index(newFolderPath);
       
   904     QDir cleanup(tmp);
       
   905     QVERIFY(cleanup.rmdir(QLatin1String("NewFoldermkdirtest3")));
       
   906     QVERIFY(cleanup.rmdir(QLatin1String("NewFoldermkdirtest5")));
       
   907     bestatic.rmdir(newFolderPath);
       
   908     QVERIFY(0 != idx.row());
       
   909     QCOMPARE(oldRow, idx.row());
       
   910 }
       
   911 
       
   912 void tst_QFileSystemModel::caseSensitivity()
       
   913 {
       
   914     QString tmp = flatDirTestPath;
       
   915     QStringList files;
       
   916     files << "a" << "c" << "C";
       
   917     QVERIFY(createFiles(tmp, files));
       
   918     QModelIndex root = model->index(tmp);
       
   919     QCOMPARE(model->rowCount(root), 0);
       
   920     for (int i = 0; i < files.count(); ++i) {
       
   921         QVERIFY(model->index(tmp + '/' + files.at(i)).isValid());
       
   922     }
       
   923 }
       
   924 
       
   925 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   926 void tst_QFileSystemModel::Win32LongFileName()
       
   927 {
       
   928     QString tmp = flatDirTestPath;
       
   929     QStringList files;
       
   930     files << "aaaaaaaaaa" << "bbbbbbbbbb" << "cccccccccc";
       
   931     QVERIFY(createFiles(tmp, files));
       
   932     QModelIndex root = model->setRootPath(tmp);
       
   933     QTRY_VERIFY(model->index(tmp + QLatin1String("/aaaaaa~1")).isValid());
       
   934     QTRY_VERIFY(model->index(tmp + QLatin1String("/bbbbbb~1")).isValid());
       
   935     QTRY_VERIFY(model->index(tmp + QLatin1String("/cccccc~1")).isValid());
       
   936 }
       
   937 #endif
       
   938 
       
   939 void tst_QFileSystemModel::drives_data()
       
   940 {
       
   941     QTest::addColumn<QString>("path");
       
   942     QTest::newRow("current") << QDir::currentPath();
       
   943     QTest::newRow("slash") << "/";
       
   944     QTest::newRow("My Computer") << "My Computer";
       
   945 }
       
   946 
       
   947 void tst_QFileSystemModel::drives()
       
   948 {
       
   949     QFETCH(QString, path);
       
   950     QFileSystemModel model;
       
   951     model.setRootPath(path);
       
   952     model.fetchMore(QModelIndex());
       
   953     QFileInfoList drives = QDir::drives();
       
   954     QTest::qWait(5000);
       
   955     QTRY_COMPARE(model.rowCount(), drives.count());
       
   956 }
       
   957 
       
   958 void tst_QFileSystemModel::dirsBeforeFiles()
       
   959 {
       
   960     const QString dirPath = QString("%1/task221717_sortedOrder_test_dir").arg(QDir::tempPath());
       
   961     QDir dir(dirPath);
       
   962     // clean up from last time
       
   963     if (dir.exists()) {
       
   964         for (int i = 0; i < 3; ++i) {
       
   965             QLatin1Char c('a' + i);
       
   966             dir.rmdir(QString("%1-dir").arg(c));
       
   967             QFile::remove(dirPath + QString("/%1-file").arg(c));
       
   968         }
       
   969         dir.rmdir(dirPath);
       
   970     }
       
   971     dir.mkpath(dirPath);
       
   972     QVERIFY(dir.exists());
       
   973 
       
   974     for (int i = 0; i < 3; ++i) {
       
   975         QLatin1Char c('a' + i);
       
   976         dir.mkdir(QString("%1-dir").arg(c));
       
   977         QFile file(dirPath + QString("/%1-file").arg(c));
       
   978         file.open(QIODevice::ReadWrite);
       
   979         file.close();
       
   980     }
       
   981 
       
   982     QModelIndex root = model->setRootPath(dirPath);
       
   983     QTest::qWait(1000); // allow model to be notified by the file system watcher
       
   984 
       
   985     // ensure that no file occurs before a directory
       
   986     for (int i = 0; i < model->rowCount(root); ++i) {
       
   987 #ifndef Q_OS_MAC
       
   988         QVERIFY(i == 0 ||
       
   989                 !(model->fileInfo(model->index(i - 1, 0, root)).isFile()
       
   990                   && model->fileInfo(model->index(i, 0, root)).isDir()));
       
   991 #else
       
   992         QVERIFY(i == 0 ||
       
   993                 model->fileInfo(model->index(i - 1, 0, root)).fileName() <
       
   994                 model->fileInfo(model->index(i, 0, root)).fileName());
       
   995 #endif
       
   996     }
       
   997 }
       
   998 
       
   999 QTEST_MAIN(tst_QFileSystemModel)
       
  1000 #include "tst_qfilesystemmodel.moc"
       
  1001