tests/auto/qfileinfo/tst_qfileinfo.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
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 
       
    45 
       
    46 #include <qfile.h>
       
    47 #include <qdir.h>
       
    48 #include <qcoreapplication.h>
       
    49 #include <qtemporaryfile.h>
       
    50 #include <qdir.h>
       
    51 #include <qfileinfo.h>
       
    52 #ifdef Q_OS_UNIX
       
    53 #include <fcntl.h>
       
    54 #include <unistd.h>
       
    55 #include <sys/stat.h>
       
    56 #endif
       
    57 #ifdef Q_OS_WIN
       
    58 #include <qt_windows.h>
       
    59 #endif
       
    60 #include <qplatformdefs.h>
       
    61 #include <qdebug.h>
       
    62 #ifdef Q_OS_SYMBIAN
       
    63 #include <f32file.h>
       
    64 #include <private/qcore_symbian_p.h>
       
    65 #endif
       
    66 #include "../network-settings.h"
       
    67 #include <private/qfileinfo_p.h>
       
    68 
       
    69 #if defined(Q_OS_SYMBIAN)
       
    70 # define SRCDIR ""
       
    71 #endif
       
    72 
       
    73 //TESTED_CLASS=
       
    74 //TESTED_FILES=
       
    75 
       
    76 class tst_QFileInfo : public QObject
       
    77 {
       
    78 Q_OBJECT
       
    79 
       
    80 public:
       
    81     tst_QFileInfo();
       
    82     ~tst_QFileInfo();
       
    83 
       
    84 private slots:
       
    85     void getSetCheck();
       
    86 
       
    87     void copy();
       
    88 
       
    89     void isFile_data();
       
    90     void isFile();
       
    91 
       
    92     void isDir_data();
       
    93     void isDir();
       
    94 
       
    95     void isRoot_data();
       
    96     void isRoot();
       
    97 
       
    98     void exists_data();
       
    99     void exists();
       
   100 
       
   101     void absolutePath_data();
       
   102     void absolutePath();
       
   103 
       
   104     void absFilePath_data();
       
   105     void absFilePath();
       
   106 
       
   107     void canonicalPath();
       
   108     void canonicalFilePath();
       
   109 
       
   110     void fileName_data();
       
   111     void fileName();
       
   112 
       
   113     void bundleName_data();
       
   114     void bundleName();
       
   115 
       
   116     void dir_data();
       
   117     void dir();
       
   118 
       
   119     void suffix_data();
       
   120     void suffix();
       
   121 
       
   122     void completeSuffix_data();
       
   123     void completeSuffix();
       
   124 
       
   125     void baseName_data();
       
   126     void baseName();
       
   127 
       
   128     void completeBaseName_data();
       
   129     void completeBaseName();
       
   130 
       
   131     void permission_data();
       
   132     void permission();
       
   133 
       
   134     void size_data();
       
   135     void size();
       
   136 
       
   137     void systemFiles();
       
   138 
       
   139     void compare_data();
       
   140     void compare();
       
   141 
       
   142     void consistent_data();
       
   143     void consistent();
       
   144 
       
   145     void fileTimes_data();
       
   146     void fileTimes();
       
   147     void fileTimes_oldFile();
       
   148 
       
   149     void isSymLink_data();
       
   150     void isSymLink();
       
   151 
       
   152     void isHidden_data();
       
   153     void isHidden();
       
   154 
       
   155     void isBundle_data();
       
   156     void isBundle();
       
   157 
       
   158     void isLocalFs_data();
       
   159     void isLocalFs();
       
   160 
       
   161     void refresh();
       
   162 
       
   163 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   164     void brokenShortcut();
       
   165 #endif
       
   166 
       
   167     void isWritable();
       
   168     void isExecutable();
       
   169     void testDecomposedUnicodeNames_data();
       
   170     void testDecomposedUnicodeNames();
       
   171 
       
   172     void equalOperator() const;
       
   173     void equalOperatorWithDifferentSlashes() const;
       
   174     void notEqualOperator() const;
       
   175 };
       
   176 
       
   177 tst_QFileInfo::tst_QFileInfo()
       
   178 {
       
   179 }
       
   180 
       
   181 tst_QFileInfo::~tst_QFileInfo()
       
   182 {
       
   183     QFile::remove("brokenlink.lnk");
       
   184     QFile::remove("link.lnk");
       
   185     QFile::remove("file1");
       
   186     QFile::remove("dummyfile");
       
   187 #ifdef Q_OS_SYMBIAN
       
   188     QFile::remove("hidden.txt");
       
   189     QFile::remove("nothidden.txt");
       
   190 #else
       
   191     QFile::remove("tempfile.txt");
       
   192 #endif
       
   193 
       
   194 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
       
   195     QDir().rmdir("./.hidden-directory");
       
   196 #endif
       
   197 }
       
   198 
       
   199 // Testing get/set functions
       
   200 void tst_QFileInfo::getSetCheck()
       
   201 {
       
   202     QFileInfo obj1;
       
   203     // bool QFileInfo::caching()
       
   204     // void QFileInfo::setCaching(bool)
       
   205     obj1.setCaching(false);
       
   206     QCOMPARE(false, obj1.caching());
       
   207     obj1.setCaching(true);
       
   208     QCOMPARE(true, obj1.caching());
       
   209 }
       
   210 
       
   211 static QFileInfoPrivate* getPrivate(QFileInfo &info)
       
   212 {
       
   213     return (*reinterpret_cast<QFileInfoPrivate**>(&info));
       
   214 }
       
   215 
       
   216 void tst_QFileInfo::copy()
       
   217 {
       
   218     QTemporaryFile *t;
       
   219     t = new QTemporaryFile;
       
   220     t->open();
       
   221     QFileInfo info(t->fileName());
       
   222     QVERIFY(info.exists());
       
   223 
       
   224     //copy constructor
       
   225     QFileInfo info2(info);
       
   226     QFileInfoPrivate *privateInfo = getPrivate(info);
       
   227     QFileInfoPrivate *privateInfo2 = getPrivate(info2);
       
   228     QCOMPARE(privateInfo->data, privateInfo2->data);
       
   229 
       
   230     //operator =
       
   231     QFileInfo info3 = info;
       
   232     QFileInfoPrivate *privateInfo3 = getPrivate(info3);
       
   233     QCOMPARE(privateInfo->data, privateInfo3->data);
       
   234     QCOMPARE(privateInfo2->data, privateInfo3->data);
       
   235 
       
   236     //refreshing info3 will detach it
       
   237     QFile file(info.absoluteFilePath());
       
   238     QVERIFY(file.open(QFile::WriteOnly));
       
   239     QCOMPARE(file.write("JAJAJAA"), qint64(7));
       
   240     file.flush();
       
   241 
       
   242     QTest::qWait(250);
       
   243 #if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
       
   244     if (QSysInfo::windowsVersion() & QSysInfo::WV_VISTA ||
       
   245                 QSysInfo::windowsVersion() & QSysInfo::WV_CE_based)
       
   246         file.close();
       
   247 #endif
       
   248 #if defined(Q_OS_WINCE)
       
   249     // On Windows CE we need to close the file.
       
   250     // Otherwise the content will be cached and not
       
   251     // flushed to the storage, although we flushed it
       
   252     // manually!!! CE has interim cache, we cannot influence.
       
   253     QTest::qWait(5000);
       
   254 #endif
       
   255     info3.refresh();
       
   256     QVERIFY(privateInfo->data != privateInfo3->data);
       
   257     QVERIFY(privateInfo2->data != privateInfo3->data);
       
   258     QCOMPARE(privateInfo->data, privateInfo2->data);
       
   259 }
       
   260 
       
   261 void tst_QFileInfo::isFile_data()
       
   262 {
       
   263     QTest::addColumn<QString>("path");
       
   264     QTest::addColumn<bool>("expected");
       
   265 
       
   266     QTest::newRow("data0") << QDir::currentPath() << false;
       
   267     QTest::newRow("data1") << SRCDIR "tst_qfileinfo.cpp" << true;
       
   268     QTest::newRow("data2") << ":/tst_qfileinfo/resources/" << false;
       
   269     QTest::newRow("data3") << ":/tst_qfileinfo/resources/file1" << true;
       
   270     QTest::newRow("data4") << ":/tst_qfileinfo/resources/afilethatshouldnotexist" << false;
       
   271 }
       
   272 
       
   273 void tst_QFileInfo::isFile()
       
   274 {
       
   275     QFETCH(QString, path);
       
   276     QFETCH(bool, expected);
       
   277 
       
   278     QFileInfo fi(path);
       
   279     QCOMPARE(fi.isFile(), expected);
       
   280 }
       
   281 
       
   282 
       
   283 void tst_QFileInfo::isDir_data()
       
   284 {
       
   285     // create a broken symlink
       
   286     QFile::remove("brokenlink.lnk");
       
   287     QFile::remove("dummyfile");
       
   288     QFile file3("dummyfile");
       
   289     file3.open(QIODevice::WriteOnly);
       
   290     if (file3.link("brokenlink.lnk")) {
       
   291         file3.remove();
       
   292         QFileInfo info3("brokenlink.lnk");
       
   293         QVERIFY( info3.isSymLink() );
       
   294     }
       
   295 
       
   296     QTest::addColumn<QString>("path");
       
   297     QTest::addColumn<bool>("expected");
       
   298 
       
   299     QTest::newRow("data0") << QDir::currentPath() << true;
       
   300     QTest::newRow("data1") << SRCDIR "tst_qfileinfo.cpp" << false;
       
   301     QTest::newRow("data2") << ":/tst_qfileinfo/resources/" << true;
       
   302     QTest::newRow("data3") << ":/tst_qfileinfo/resources/file1" << false;
       
   303     QTest::newRow("data4") << ":/tst_qfileinfo/resources/afilethatshouldnotexist" << false;
       
   304 
       
   305     QTest::newRow("simple dir") << SRCDIR "resources" << true;
       
   306     QTest::newRow("simple dir with slash") << SRCDIR "resources/" << true;
       
   307 
       
   308     QTest::newRow("broken link") << "brokenlink.lnk" << false;
       
   309 
       
   310 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
       
   311     QTest::newRow("drive 1") << "c:" << true;
       
   312     QTest::newRow("drive 2") << "c:/" << true;
       
   313     //QTest::newRow("drive 2") << "t:s" << false;
       
   314 #endif
       
   315 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   316     QTest::newRow("unc 1") << "//"  + QtNetworkSettings::winServerName() << true;
       
   317     QTest::newRow("unc 2") << "//"  + QtNetworkSettings::winServerName() + "/" << true;
       
   318     QTest::newRow("unc 3") << "//"  + QtNetworkSettings::winServerName() + "/testshare" << true;
       
   319     QTest::newRow("unc 4") << "//"  + QtNetworkSettings::winServerName() + "/testshare/" << true;
       
   320     QTest::newRow("unc 5") << "//"  + QtNetworkSettings::winServerName() + "/testshare/tmp" << true;
       
   321     QTest::newRow("unc 6") << "//"  + QtNetworkSettings::winServerName() + "/testshare/tmp/" << true;
       
   322     QTest::newRow("unc 7") << "//"  + QtNetworkSettings::winServerName() + "/testshare/adirthatshouldnotexist" << false;
       
   323 #endif
       
   324 }
       
   325 
       
   326 void tst_QFileInfo::isDir()
       
   327 {
       
   328     QFETCH(QString, path);
       
   329     QFETCH(bool, expected);
       
   330 
       
   331     QFileInfo fi(path);
       
   332     QCOMPARE(fi.isDir(), expected);
       
   333 }
       
   334 
       
   335 void tst_QFileInfo::isRoot_data()
       
   336 {
       
   337     QTest::addColumn<QString>("path");
       
   338     QTest::addColumn<bool>("expected");
       
   339     QTest::newRow("data0") << QDir::currentPath() << false;
       
   340     QTest::newRow("data1") << "/" << true;
       
   341     QTest::newRow("data2") << "*" << false;
       
   342     QTest::newRow("data3") << "/*" << false;
       
   343     QTest::newRow("data4") << ":/tst_qfileinfo/resources/" << false;
       
   344     QTest::newRow("data5") << ":/" << true;
       
   345 
       
   346     QTest::newRow("simple dir") << SRCDIR "resources" << false;
       
   347     QTest::newRow("simple dir with slash") << SRCDIR "resources/" << false;
       
   348 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
       
   349     QTest::newRow("drive 1") << "c:" << false;
       
   350     QTest::newRow("drive 2") << "c:/" << true;
       
   351     QTest::newRow("drive 3") << "p:/" << false;
       
   352 #endif
       
   353 
       
   354 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   355     QTest::newRow("unc 1") << "//"  + QtNetworkSettings::winServerName() << true;
       
   356     QTest::newRow("unc 2") << "//"  + QtNetworkSettings::winServerName() + "/" << true;
       
   357     QTest::newRow("unc 3") << "//"  + QtNetworkSettings::winServerName() + "/testshare" << false;
       
   358     QTest::newRow("unc 4") << "//"  + QtNetworkSettings::winServerName() + "/testshare/" << false;
       
   359     QTest::newRow("unc 7") << "//ahostthatshouldnotexist" << false;
       
   360 #endif
       
   361 }
       
   362 
       
   363 void tst_QFileInfo::isRoot()
       
   364 {
       
   365     QFETCH(QString, path);
       
   366     QFETCH(bool, expected);
       
   367 
       
   368     QFileInfo fi(path);
       
   369     QCOMPARE(fi.isRoot(), expected);
       
   370 }
       
   371 
       
   372 void tst_QFileInfo::exists_data()
       
   373 {
       
   374     QTest::addColumn<QString>("path");
       
   375     QTest::addColumn<bool>("expected");
       
   376 
       
   377     QTest::newRow("data0") << QDir::currentPath() << true;
       
   378     QTest::newRow("data1") << SRCDIR "tst_qfileinfo.cpp" << true;
       
   379     QTest::newRow("data2") << "/I/do_not_expect_this_path_to_exist/" << false;
       
   380     QTest::newRow("data3") << ":/tst_qfileinfo/resources/" << true;
       
   381     QTest::newRow("data4") << ":/tst_qfileinfo/resources/file1" << true;
       
   382     QTest::newRow("data5") << ":/I/do_not_expect_this_path_to_exist/" << false;
       
   383     QTest::newRow("data6") << SRCDIR "resources/*" << false;
       
   384     QTest::newRow("data7") << SRCDIR "resources/*.foo" << false;
       
   385     QTest::newRow("data8") << SRCDIR "resources/*.ext1" << false;
       
   386     QTest::newRow("data9") << SRCDIR "resources/file?.ext1" << false;
       
   387     QTest::newRow("data10") << "." << true;
       
   388     QTest::newRow("data11") << ". " << false;
       
   389 
       
   390     QTest::newRow("simple dir") << SRCDIR "resources" << true;
       
   391     QTest::newRow("simple dir with slash") << SRCDIR "resources/" << true;
       
   392 
       
   393 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   394     QTest::newRow("unc 1") << "//"  + QtNetworkSettings::winServerName() << true;
       
   395     QTest::newRow("unc 2") << "//"  + QtNetworkSettings::winServerName() + "/" << true;
       
   396     QTest::newRow("unc 3") << "//"  + QtNetworkSettings::winServerName() + "/testshare" << true;
       
   397     QTest::newRow("unc 4") << "//"  + QtNetworkSettings::winServerName() + "/testshare/" << true;
       
   398     QTest::newRow("unc 5") << "//"  + QtNetworkSettings::winServerName() + "/testshare/tmp" << true;
       
   399     QTest::newRow("unc 6") << "//"  + QtNetworkSettings::winServerName() + "/testshare/tmp/" << true;
       
   400     QTest::newRow("unc 7") << "//"  + QtNetworkSettings::winServerName() + "/testshare/adirthatshouldnotexist" << false;
       
   401     QTest::newRow("unc 8") << "//"  + QtNetworkSettings::winServerName() + "/asharethatshouldnotexist" << false;
       
   402     QTest::newRow("unc 9") << "//ahostthatshouldnotexist" << false;
       
   403 #endif
       
   404 }
       
   405 
       
   406 void tst_QFileInfo::exists()
       
   407 {
       
   408     QFETCH(QString, path);
       
   409     QFETCH(bool, expected);
       
   410 
       
   411     QFileInfo fi(path);
       
   412     QCOMPARE(fi.exists(), expected);
       
   413 }
       
   414 
       
   415 void tst_QFileInfo::absolutePath_data()
       
   416 {
       
   417     QTest::addColumn<QString>("file");
       
   418     QTest::addColumn<QString>("path");
       
   419     QTest::addColumn<QString>("filename");
       
   420 
       
   421     QString drivePrefix;
       
   422 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
       
   423     drivePrefix = QDir::currentPath().left(2);
       
   424     QString nonCurrentDrivePrefix =
       
   425         drivePrefix.left(1).compare("X", Qt::CaseInsensitive) == 0 ? QString("Y:") : QString("X:");
       
   426 
       
   427     // Make sure drive-relative paths return correct absolute paths (task 255326)
       
   428     QTest::newRow("<current drive>:my.dll") << drivePrefix + "my.dll" << QDir::currentPath() << "my.dll";
       
   429     QTest::newRow("<not current drive>:my.dll") << nonCurrentDrivePrefix + "my.dll"
       
   430                                                 << nonCurrentDrivePrefix + "/"
       
   431                                                 << "my.dll";
       
   432 #endif
       
   433     QTest::newRow("0") << "/machine/share/dir1/" << drivePrefix + "/machine/share/dir1" << "";
       
   434     QTest::newRow("1") << "/machine/share/dir1" << drivePrefix + "/machine/share" << "dir1";
       
   435     QTest::newRow("2") << "/usr/local/bin" << drivePrefix + "/usr/local" << "bin";
       
   436     QTest::newRow("3") << "/usr/local/bin/" << drivePrefix + "/usr/local/bin" << "";
       
   437     QTest::newRow("/test") << "/test" << drivePrefix + "/" << "test";
       
   438 
       
   439 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   440     // see task 102898
       
   441     QTest::newRow("c:\\autoexec.bat") << "c:\\autoexec.bat" << "C:/"
       
   442                                       << "autoexec.bat";
       
   443 #endif
       
   444 }
       
   445 
       
   446 void tst_QFileInfo::absolutePath()
       
   447 {
       
   448     QFETCH(QString, file);
       
   449     QFETCH(QString, path);
       
   450     QFETCH(QString, filename);
       
   451 
       
   452     QFileInfo fi(file);
       
   453 
       
   454     QCOMPARE(fi.absolutePath(), path);
       
   455     QCOMPARE(fi.fileName(), filename);
       
   456 }
       
   457 
       
   458 void tst_QFileInfo::absFilePath_data()
       
   459 {
       
   460     QTest::addColumn<QString>("file");
       
   461     QTest::addColumn<QString>("expected");
       
   462 
       
   463     QTest::newRow("relativeFile") << "tmp.txt" << QDir::currentPath() + "/tmp.txt";
       
   464     QTest::newRow("relativeFileInSubDir") << "temp/tmp.txt" << QDir::currentPath() + "/" + "temp/tmp.txt";
       
   465 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
       
   466     QString curr = QDir::currentPath();
       
   467 
       
   468     curr.remove(0, 2);   // Make it a absolute path with no drive specifier: \depot\qt-4.2\tests\auto\qfileinfo
       
   469     QTest::newRow(".")            << curr << QDir::currentPath();
       
   470     QTest::newRow("absFilePath") << "c:\\home\\andy\\tmp.txt" << "C:/home/andy/tmp.txt";
       
   471 
       
   472     // Make sure drive-relative paths return correct absolute paths (task 255326)
       
   473     QString drivePrefix = QDir::currentPath().left(2);
       
   474     QString nonCurrentDrivePrefix =
       
   475         drivePrefix.left(1).compare("X", Qt::CaseInsensitive) == 0 ? QString("Y:") : QString("X:");
       
   476 
       
   477     QTest::newRow("<current drive>:my.dll") << drivePrefix + "temp/my.dll" << QDir::currentPath() + "/temp/my.dll";
       
   478     QTest::newRow("<not current drive>:my.dll") << nonCurrentDrivePrefix + "temp/my.dll"
       
   479                                                 << nonCurrentDrivePrefix + "/temp/my.dll";
       
   480 #else
       
   481     QTest::newRow("absFilePath") << "/home/andy/tmp.txt" << "/home/andy/tmp.txt";
       
   482 #endif
       
   483 }
       
   484 
       
   485 void tst_QFileInfo::absFilePath()
       
   486 {
       
   487     QFETCH(QString, file);
       
   488     QFETCH(QString, expected);
       
   489 
       
   490     QFileInfo fi(file);
       
   491     QCOMPARE(fi.absoluteFilePath(), expected);
       
   492 }
       
   493 
       
   494 void tst_QFileInfo::canonicalPath()
       
   495 {
       
   496     QTemporaryFile tempFile;
       
   497     tempFile.setAutoRemove(true);
       
   498     tempFile.open();
       
   499     QFileInfo fi(tempFile.fileName());
       
   500     QCOMPARE(fi.canonicalPath(), QFileInfo(QDir::tempPath()).canonicalFilePath());
       
   501 }
       
   502 
       
   503 void tst_QFileInfo::canonicalFilePath()
       
   504 {
       
   505     const QString fileName("tmp.canon");
       
   506     QFile tempFile(fileName);
       
   507     QVERIFY(tempFile.open(QFile::WriteOnly));
       
   508     QFileInfo fi(tempFile.fileName());
       
   509     QCOMPARE(fi.canonicalFilePath(), QDir::currentPath() + "/" + fileName);
       
   510     tempFile.remove();
       
   511 
       
   512     // This used to crash on Mac, verify that it doesn't anymore.
       
   513     QFileInfo info("/tmp/../../../../../../../../../../../../../../../../../");
       
   514     info.canonicalFilePath();
       
   515 
       
   516 #ifndef Q_OS_WIN
       
   517     // test symlinks
       
   518     QFile::remove("link.lnk");
       
   519     {
       
   520         QFile file(SRCDIR "tst_qfileinfo.cpp");
       
   521         if (file.link("link.lnk")) {
       
   522             QFileInfo info1(file);
       
   523             QFileInfo info2("link.lnk");
       
   524             QCOMPARE(info1.canonicalFilePath(), info2.canonicalFilePath());
       
   525         }
       
   526     }
       
   527 #  if !defined(Q_OS_SYMBIAN)
       
   528     // Symbian doesn't support links to directories
       
   529     {
       
   530         const QString link(QDir::tempPath() + QDir::separator() + "tst_qfileinfo");
       
   531         QFile::remove(link);
       
   532         QFile file(QDir::currentPath());
       
   533         if (file.link(link)) {
       
   534             QFile tempfile("tempfile.txt");
       
   535             tempfile.open(QIODevice::ReadWrite);
       
   536             tempfile.write("This file is generated by the QFileInfo autotest.");
       
   537             QVERIFY(tempfile.flush());
       
   538             tempfile.close();
       
   539 
       
   540             QFileInfo info1("tempfile.txt");
       
   541             QFileInfo info2(link + QDir::separator() + "tempfile.txt");
       
   542 
       
   543             QVERIFY(info1.exists());
       
   544             QVERIFY(info2.exists());
       
   545             QCOMPARE(info1.canonicalFilePath(), info2.canonicalFilePath());
       
   546 
       
   547             QFileInfo info3(link + QDir::separator() + "link.lnk");
       
   548             QFileInfo info4(SRCDIR "tst_qfileinfo.cpp");
       
   549             QVERIFY(!info3.canonicalFilePath().isEmpty());
       
   550             QCOMPARE(info4.canonicalFilePath(), info3.canonicalFilePath());
       
   551 
       
   552             tempfile.remove();
       
   553         }
       
   554     }
       
   555     {
       
   556         QString link(QDir::tempPath() + QDir::separator() + "tst_qfileinfo"
       
   557                      + QDir::separator() + "link_to_tst_qfileinfo");
       
   558         QFile::remove(link);
       
   559 
       
   560         QFile file(QDir::tempPath() + QDir::separator() + "tst_qfileinfo"
       
   561                    + QDir::separator() + "tst_qfileinfo.cpp");
       
   562         if (file.link(link))
       
   563         {
       
   564             QFileInfo info1("tst_qfileinfo.cpp");
       
   565             QFileInfo info2(link);
       
   566             QCOMPARE(info1.canonicalFilePath(), info2.canonicalFilePath());
       
   567         }
       
   568     }
       
   569 #  endif
       
   570 #endif
       
   571 }
       
   572 
       
   573 void tst_QFileInfo::fileName_data()
       
   574 {
       
   575     QTest::addColumn<QString>("file");
       
   576     QTest::addColumn<QString>("expected");
       
   577 
       
   578     QTest::newRow("relativeFile") << "tmp.txt" << "tmp.txt";
       
   579     QTest::newRow("relativeFileInSubDir") << "temp/tmp.txt" << "tmp.txt";
       
   580 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
       
   581     QTest::newRow("absFilePath") << "c:\\home\\andy\\tmp.txt" << "tmp.txt";
       
   582 #else
       
   583     QTest::newRow("absFilePath") << "/home/andy/tmp.txt" << "tmp.txt";
       
   584 #endif
       
   585     QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "file1.ext1";
       
   586     QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "file1.ext1.ext2";
       
   587 
       
   588     QTest::newRow("ending slash [small]") << QString::fromLatin1("/a/") << QString::fromLatin1("");
       
   589     QTest::newRow("no ending slash [small]") << QString::fromLatin1("/a") << QString::fromLatin1("a");
       
   590 
       
   591     QTest::newRow("ending slash") << QString::fromLatin1("/somedir/") << QString::fromLatin1("");
       
   592     QTest::newRow("no ending slash") << QString::fromLatin1("/somedir") << QString::fromLatin1("somedir");
       
   593 }
       
   594 
       
   595 void tst_QFileInfo::fileName()
       
   596 {
       
   597     QFETCH(QString, file);
       
   598     QFETCH(QString, expected);
       
   599 
       
   600     QFileInfo fi(file);
       
   601     QCOMPARE(fi.fileName(), expected);
       
   602 }
       
   603 
       
   604 void tst_QFileInfo::bundleName_data()
       
   605 {
       
   606     QTest::addColumn<QString>("file");
       
   607     QTest::addColumn<QString>("expected");
       
   608 
       
   609     QTest::newRow("root") << "/" << "";
       
   610     QTest::newRow("etc") << "/etc" << "";
       
   611 #ifdef Q_OS_MAC
       
   612     QTest::newRow("safari") << "/Applications/Safari.app" << "Safari";
       
   613 #endif
       
   614 }
       
   615 
       
   616 void tst_QFileInfo::bundleName()
       
   617 {
       
   618     QFETCH(QString, file);
       
   619     QFETCH(QString, expected);
       
   620 
       
   621     QFileInfo fi(file);
       
   622     QCOMPARE(fi.bundleName(), expected);
       
   623 }
       
   624 
       
   625 void tst_QFileInfo::dir_data()
       
   626 {
       
   627     QTest::addColumn<QString>("file");
       
   628     QTest::addColumn<bool>("absPath");
       
   629     QTest::addColumn<QString>("expected");
       
   630 
       
   631     QTest::newRow("relativeFile") << "tmp.txt" << false << ".";
       
   632     QTest::newRow("relativeFileAbsPath") << "tmp.txt" << true << QDir::currentPath();
       
   633     QTest::newRow("relativeFileInSubDir") << "temp/tmp.txt" << false << "temp";
       
   634     QTest::newRow("relativeFileInSubDirAbsPath") << "temp/tmp.txt" << true << QDir::currentPath() + "/temp";
       
   635     QTest::newRow("absFilePath") << QDir::currentPath() + "/tmp.txt" << false << QDir::currentPath();
       
   636     QTest::newRow("absFilePathAbsPath") << QDir::currentPath() + "/tmp.txt" << true << QDir::currentPath();
       
   637     QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << true << ":/tst_qfileinfo/resources";
       
   638 }
       
   639 
       
   640 void tst_QFileInfo::dir()
       
   641 {
       
   642     QFETCH(QString, file);
       
   643     QFETCH(bool, absPath);
       
   644     QFETCH(QString, expected);
       
   645 
       
   646     QFileInfo fi(file);
       
   647     if (absPath)
       
   648         QCOMPARE(fi.absolutePath(), expected);
       
   649     else
       
   650         QCOMPARE(fi.path(), expected);
       
   651 }
       
   652 
       
   653 
       
   654 void tst_QFileInfo::suffix_data()
       
   655 {
       
   656     QTest::addColumn<QString>("file");
       
   657     QTest::addColumn<QString>("expected");
       
   658 
       
   659     QTest::newRow("noextension0") << "file" << "";
       
   660     QTest::newRow("noextension1") << "/path/to/file" << "";
       
   661     QTest::newRow("data0") << "file.tar" << "tar";
       
   662     QTest::newRow("data1") << "file.tar.gz" << "gz";
       
   663     QTest::newRow("data2") << "/path/file/file.tar.gz" << "gz";
       
   664     QTest::newRow("data3") << "/path/file.tar" << "tar";
       
   665     QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "ext1";
       
   666     QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "ext2";
       
   667     QTest::newRow("hidden1") << ".ext1" << "ext1";
       
   668     QTest::newRow("hidden1") << ".ext" << "ext";
       
   669     QTest::newRow("hidden1") << ".ex" << "ex";
       
   670     QTest::newRow("hidden1") << ".e" << "e";
       
   671     QTest::newRow("hidden2") << ".ext1.ext2" << "ext2";
       
   672     QTest::newRow("hidden2") << ".ext.ext2" << "ext2";
       
   673     QTest::newRow("hidden2") << ".ex.ext2" << "ext2";
       
   674     QTest::newRow("hidden2") << ".e.ext2" << "ext2";
       
   675     QTest::newRow("hidden2") << "..ext2" << "ext2";
       
   676 }
       
   677 
       
   678 void tst_QFileInfo::suffix()
       
   679 {
       
   680     QFETCH(QString, file);
       
   681     QFETCH(QString, expected);
       
   682 
       
   683     QFileInfo fi(file);
       
   684     QCOMPARE(fi.suffix(), expected);
       
   685 }
       
   686 
       
   687 
       
   688 void tst_QFileInfo::completeSuffix_data()
       
   689 {
       
   690     QTest::addColumn<QString>("file");
       
   691     QTest::addColumn<QString>("expected");
       
   692 
       
   693     QTest::newRow("noextension0") << "file" << "";
       
   694     QTest::newRow("noextension1") << "/path/to/file" << "";
       
   695     QTest::newRow("data0") << "file.tar" << "tar";
       
   696     QTest::newRow("data1") << "file.tar.gz" << "tar.gz";
       
   697     QTest::newRow("data2") << "/path/file/file.tar.gz" << "tar.gz";
       
   698     QTest::newRow("data3") << "/path/file.tar" << "tar";
       
   699     QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "ext1";
       
   700     QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "ext1.ext2";
       
   701 }
       
   702 
       
   703 void tst_QFileInfo::completeSuffix()
       
   704 {
       
   705     QFETCH(QString, file);
       
   706     QFETCH(QString, expected);
       
   707 
       
   708     QFileInfo fi(file);
       
   709     QCOMPARE(fi.completeSuffix(), expected);
       
   710 }
       
   711 
       
   712 void tst_QFileInfo::baseName_data()
       
   713 {
       
   714     QTest::addColumn<QString>("file");
       
   715     QTest::addColumn<QString>("expected");
       
   716 
       
   717     QTest::newRow("data0") << "file.tar" << "file";
       
   718     QTest::newRow("data1") << "file.tar.gz" << "file";
       
   719     QTest::newRow("data2") << "/path/file/file.tar.gz" << "file";
       
   720     QTest::newRow("data3") << "/path/file.tar" << "file";
       
   721     QTest::newRow("data4") << "/path/file" << "file";
       
   722     QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "file1";
       
   723     QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "file1";
       
   724 }
       
   725 
       
   726 void tst_QFileInfo::baseName()
       
   727 {
       
   728     QFETCH(QString, file);
       
   729     QFETCH(QString, expected);
       
   730 
       
   731     QFileInfo fi(file);
       
   732     QCOMPARE(fi.baseName(), expected);
       
   733 }
       
   734 
       
   735 void tst_QFileInfo::completeBaseName_data()
       
   736 {
       
   737     QTest::addColumn<QString>("file");
       
   738     QTest::addColumn<QString>("expected");
       
   739 
       
   740     QTest::newRow("data0") << "file.tar" << "file";
       
   741     QTest::newRow("data1") << "file.tar.gz" << "file.tar";
       
   742     QTest::newRow("data2") << "/path/file/file.tar.gz" << "file.tar";
       
   743     QTest::newRow("data3") << "/path/file.tar" << "file";
       
   744     QTest::newRow("data4") << "/path/file" << "file";
       
   745     QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << "file1";
       
   746     QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << "file1.ext1";
       
   747 }
       
   748 
       
   749 void tst_QFileInfo::completeBaseName()
       
   750 {
       
   751     QFETCH(QString, file);
       
   752     QFETCH(QString, expected);
       
   753 
       
   754     QFileInfo fi(file);
       
   755     QCOMPARE(fi.completeBaseName(), expected);
       
   756 }
       
   757 
       
   758 void tst_QFileInfo::permission_data()
       
   759 {
       
   760     QTest::addColumn<QString>("file");
       
   761     QTest::addColumn<int>("perms");
       
   762     QTest::addColumn<bool>("expected");
       
   763 
       
   764     QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << int(QFile::ExeUser) << true;
       
   765     QTest::newRow("data1") << SRCDIR "tst_qfileinfo.cpp" << int(QFile::ReadUser) << true;
       
   766 //    QTest::newRow("data2") << "tst_qfileinfo.cpp" << int(QFile::WriteUser) << false;
       
   767     QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::ReadUser) << true;
       
   768     QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::WriteUser) << false;
       
   769     QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << int(QFile::ExeUser) << false;
       
   770 }
       
   771 
       
   772 void tst_QFileInfo::permission()
       
   773 {
       
   774     QFETCH(QString, file);
       
   775     QFETCH(int, perms);
       
   776     QFETCH(bool, expected);
       
   777 #ifdef Q_OS_SYMBIAN
       
   778     QSKIP("No user based rights in Symbian OS - SOS needs platform security tests instead", SkipAll);
       
   779 #endif
       
   780     QFileInfo fi(file);
       
   781     QCOMPARE(fi.permission(QFile::Permissions(perms)), expected);
       
   782 }
       
   783 
       
   784 void tst_QFileInfo::size_data()
       
   785 {
       
   786     QTest::addColumn<QString>("file");
       
   787     QTest::addColumn<int>("size");
       
   788 
       
   789     QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << 0;
       
   790     QFile::remove("file1");
       
   791     QFile file("file1");
       
   792     QVERIFY(file.open(QFile::WriteOnly));
       
   793     QCOMPARE(file.write("JAJAJAA"), qint64(7));
       
   794     QTest::newRow("created-file") << "file1" << 7;
       
   795 
       
   796     QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1.ext2" << 0;
       
   797 }
       
   798 
       
   799 void tst_QFileInfo::size()
       
   800 {
       
   801     QFETCH(QString, file);
       
   802 
       
   803     QFileInfo fi(file);
       
   804     (void)fi.permissions();     // see task 104198
       
   805     QTEST(int(fi.size()), "size");
       
   806 }
       
   807 
       
   808 void tst_QFileInfo::systemFiles()
       
   809 {
       
   810 #if !defined(Q_OS_WIN) || defined(Q_OS_WINCE)
       
   811     QSKIP("This is a Windows only test", SkipAll);
       
   812 #endif
       
   813     QFileInfo fi("c:\\pagefile.sys");
       
   814     QVERIFY(fi.exists());      // task 167099
       
   815     QVERIFY(fi.size() > 0);    // task 189202
       
   816     QVERIFY(fi.lastModified().isValid());
       
   817 }
       
   818 
       
   819 void tst_QFileInfo::compare_data()
       
   820 {
       
   821     QTest::addColumn<QString>("file1");
       
   822     QTest::addColumn<QString>("file2");
       
   823     QTest::addColumn<bool>("same");
       
   824 
       
   825     QTest::newRow("data0")
       
   826         << QString::fromLatin1(SRCDIR "tst_qfileinfo.cpp")
       
   827         << QString::fromLatin1(SRCDIR "tst_qfileinfo.cpp")
       
   828         << true;
       
   829     QTest::newRow("data1")
       
   830         << QString::fromLatin1(SRCDIR "tst_qfileinfo.cpp")
       
   831         << QString::fromLatin1("/tst_qfileinfo.cpp")
       
   832         << false;
       
   833     QTest::newRow("data2")
       
   834         << QString::fromLatin1("tst_qfileinfo.cpp")
       
   835         << QDir::currentPath() + QString::fromLatin1("/tst_qfileinfo.cpp")
       
   836         << true;
       
   837     QTest::newRow("casesense1")
       
   838         << QString::fromLatin1(SRCDIR "tst_qfileInfo.cpp")
       
   839         << QString::fromLatin1(SRCDIR "tst_qfileinfo.cpp")
       
   840 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
       
   841         << true;
       
   842 #else
       
   843         << false;
       
   844 #endif
       
   845 }
       
   846 
       
   847 void tst_QFileInfo::compare()
       
   848 {
       
   849     QFETCH(QString, file1);
       
   850     QFETCH(QString, file2);
       
   851     QFETCH(bool, same);
       
   852     QFileInfo fi1(file1), fi2(file2);
       
   853     QCOMPARE(same, fi1 == fi2);
       
   854 }
       
   855 
       
   856 void tst_QFileInfo::consistent_data()
       
   857 {
       
   858     QTest::addColumn<QString>("file");
       
   859     QTest::addColumn<QString>("expected");
       
   860 
       
   861 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
       
   862     QTest::newRow("slashes") << QString::fromLatin1("\\a\\a\\a\\a") << QString::fromLatin1("/a/a/a/a");
       
   863 #endif
       
   864     QTest::newRow("ending slash") << QString::fromLatin1("/a/somedir/") << QString::fromLatin1("/a/somedir/");
       
   865     QTest::newRow("no ending slash") << QString::fromLatin1("/a/somedir") << QString::fromLatin1("/a/somedir");
       
   866 }
       
   867 
       
   868 void tst_QFileInfo::consistent()
       
   869 {
       
   870     QFETCH(QString, file);
       
   871     QFETCH(QString, expected);
       
   872 
       
   873     QFileInfo fi(file);
       
   874     QCOMPARE(fi.filePath(), expected);
       
   875     QCOMPARE(fi.dir().path() + "/" + fi.fileName(), expected);
       
   876 }
       
   877 
       
   878 
       
   879 void tst_QFileInfo::fileTimes_data()
       
   880 {
       
   881     QTest::addColumn<QString>("fileName");
       
   882     QTest::newRow("simple") << QString::fromLatin1("simplefile.txt");
       
   883     QTest::newRow( "longfile" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
       
   884                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
   885                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
   886                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
   887                                                      "longFileNamelongFileNamelongFileNamelongFileName.txt");
       
   888     QTest::newRow( "longfile absolutepath" ) << QFileInfo(QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
       
   889                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
   890                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
   891                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
   892                                                      "longFileNamelongFileNamelongFileNamelongFileName.txt")).absoluteFilePath();
       
   893 }
       
   894 
       
   895 void tst_QFileInfo::fileTimes()
       
   896 {
       
   897 #if defined(Q_OS_WINCE)
       
   898     int sleepTime = 3000;
       
   899 #else
       
   900     int sleepTime = 2000;
       
   901 #endif
       
   902     QFETCH(QString, fileName);
       
   903     if (QFile::exists(fileName)) {
       
   904         QVERIFY(QFile::remove(fileName));
       
   905     }
       
   906     QTest::qSleep(sleepTime);
       
   907     {
       
   908         QFile file(fileName);
       
   909 #if defined(Q_OS_WINCE)
       
   910         QEXPECT_FAIL("longfile", "No long filenames on WinCE", Abort);
       
   911         QEXPECT_FAIL("longfile absolutepath", "No long filenames on WinCE", Abort);
       
   912 #elif defined(Q_OS_SYMBIAN)
       
   913         QEXPECT_FAIL("longfile", "Maximum total filepath cannot exceed 256 characters in Symbian", Abort);
       
   914         QEXPECT_FAIL("longfile absolutepath", "Maximum total filepath cannot exceed 256 characters in Symbian", Abort);
       
   915 #endif
       
   916         QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
       
   917         QTextStream ts(&file);
       
   918         ts << fileName << endl;
       
   919     }
       
   920     QTest::qSleep(sleepTime);
       
   921     QDateTime beforeWrite = QDateTime::currentDateTime();
       
   922     QTest::qSleep(sleepTime);
       
   923     {
       
   924         QFileInfo fileInfo(fileName);
       
   925         QVERIFY(fileInfo.created() < beforeWrite);
       
   926         QFile file(fileName);
       
   927         QVERIFY(file.open(QFile::ReadWrite | QFile::Text));
       
   928         QTextStream ts(&file);
       
   929         ts << fileName << endl;
       
   930     }
       
   931     QTest::qSleep(sleepTime);
       
   932     QDateTime beforeRead = QDateTime::currentDateTime();
       
   933     QTest::qSleep(sleepTime);
       
   934     {
       
   935         QFileInfo fileInfo(fileName);
       
   936 // On unix created() returns the same as lastModified().
       
   937 #if !defined(Q_OS_UNIX) && !defined(Q_OS_WINCE)
       
   938         QVERIFY(fileInfo.created() < beforeWrite);
       
   939 #endif
       
   940         QVERIFY(fileInfo.lastModified() > beforeWrite);
       
   941         QFile file(fileName);
       
   942         QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
       
   943         QTextStream ts(&file);
       
   944         QString line = ts.readLine();
       
   945         QCOMPARE(line, fileName);
       
   946     }
       
   947 
       
   948     QFileInfo fileInfo(fileName);
       
   949 #if !defined(Q_OS_UNIX) && !defined(Q_OS_WINCE)
       
   950     QVERIFY(fileInfo.created() < beforeWrite);
       
   951 #endif
       
   952     //In Vista the last-access timestamp is not updated when the file is accessed/touched (by default).
       
   953     //To enable this the HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate
       
   954     //is set to 0, in the test machine.
       
   955 #ifdef Q_OS_WINCE
       
   956     QEXPECT_FAIL("simple", "WinCE only stores date of access data, not the time", Continue);
       
   957 #endif
       
   958 #ifdef Q_OS_SYMBIAN
       
   959         QEXPECT_FAIL("simple", "Symbian implementation of stat doesn't return read time right", Abort);
       
   960 #endif
       
   961     QVERIFY(fileInfo.lastRead() > beforeRead);
       
   962     QVERIFY(fileInfo.lastModified() > beforeWrite);
       
   963     QVERIFY(fileInfo.lastModified() < beforeRead);
       
   964 }
       
   965 
       
   966 void tst_QFileInfo::fileTimes_oldFile()
       
   967 {
       
   968     // This is not supported on WinCE
       
   969 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   970     // All files are opened in share mode (both read and write).
       
   971     DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
       
   972 
       
   973     // All files on Windows can be read; there's no such thing as an
       
   974     // unreadable file. Add GENERIC_WRITE if WriteOnly is passed.
       
   975     int accessRights = GENERIC_READ | GENERIC_WRITE;
       
   976 
       
   977     SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
       
   978 
       
   979     // Regular file mode. In Unbuffered mode, pass the no-buffering flag.
       
   980     DWORD flagsAndAtts = FILE_ATTRIBUTE_NORMAL;
       
   981 
       
   982     // WriteOnly can create files, ReadOnly cannot.
       
   983     DWORD creationDisp = OPEN_ALWAYS;
       
   984 
       
   985     // Create the file handle.
       
   986     HANDLE fileHandle = CreateFile(L"oldfile.txt",
       
   987         accessRights,
       
   988         shareMode,
       
   989         &securityAtts,
       
   990         creationDisp,
       
   991         flagsAndAtts,
       
   992         NULL);
       
   993 
       
   994     // Set file times back to 1601.
       
   995     SYSTEMTIME stime;
       
   996     stime.wYear = 1601;
       
   997     stime.wMonth = 1;
       
   998     stime.wDayOfWeek = 1;
       
   999     stime.wDay = 1;
       
  1000     stime.wHour = 1;
       
  1001     stime.wMinute = 0;
       
  1002     stime.wSecond = 0;
       
  1003     stime.wMilliseconds = 0;
       
  1004 
       
  1005     FILETIME ctime;
       
  1006     QVERIFY(SystemTimeToFileTime(&stime, &ctime));
       
  1007     FILETIME atime = ctime;
       
  1008     FILETIME mtime = atime;
       
  1009     QVERIFY(fileHandle);
       
  1010     QVERIFY(SetFileTime(fileHandle, &ctime, &atime, &mtime) != 0);
       
  1011 
       
  1012     CloseHandle(fileHandle);
       
  1013 
       
  1014     QFileInfo info("oldfile.txt");
       
  1015     QCOMPARE(info.lastModified(), QDateTime(QDate(1601, 1, 1), QTime(1, 0), Qt::UTC).toLocalTime());
       
  1016 #endif
       
  1017 }
       
  1018 
       
  1019 void tst_QFileInfo::isSymLink_data()
       
  1020 {
       
  1021     QFile::remove("link.lnk");
       
  1022     QFile::remove("brokenlink.lnk");
       
  1023     QFile::remove("dummyfile");
       
  1024 
       
  1025     QFile file1(SRCDIR "tst_qfileinfo.cpp");
       
  1026     QVERIFY(file1.link("link.lnk"));
       
  1027 
       
  1028     QFile file2("dummyfile");
       
  1029     file2.open(QIODevice::WriteOnly);
       
  1030     QVERIFY(file2.link("brokenlink.lnk"));
       
  1031     file2.remove();
       
  1032 
       
  1033     QTest::addColumn<QString>("path");
       
  1034     QTest::addColumn<bool>("isSymLink");
       
  1035     QTest::addColumn<QString>("linkTarget");
       
  1036 
       
  1037     QTest::newRow("existent file") << SRCDIR "tst_qfileinfo.cpp" << false << "";
       
  1038     QTest::newRow("link") << "link.lnk" << true << QFileInfo(SRCDIR "tst_qfileinfo.cpp").absoluteFilePath();
       
  1039     QTest::newRow("broken link") << "brokenlink.lnk" << true << QFileInfo("dummyfile").absoluteFilePath();
       
  1040 
       
  1041 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  1042     if (QSysInfo::WindowsVersion & QSysInfo::WV_VISTA) {
       
  1043         QTest::newRow("Documents and Settings") << "C:/Documents and Settings" << true << "C:/Users";
       
  1044         QTest::newRow("All Users") << "C:/Users/All Users" << true << "C:/ProgramData";
       
  1045         QTest::newRow("Default User") << "C:/Users/Default User" << true << "C:/Users/Default";
       
  1046     }
       
  1047 #endif
       
  1048 }
       
  1049 
       
  1050 void tst_QFileInfo::isSymLink()
       
  1051 {
       
  1052     QFETCH(QString, path);
       
  1053     QFETCH(bool, isSymLink);
       
  1054     QFETCH(QString, linkTarget);
       
  1055 
       
  1056     QFileInfo fi(path);
       
  1057     QCOMPARE(fi.isSymLink(), isSymLink);
       
  1058     QCOMPARE(fi.symLinkTarget(), linkTarget);
       
  1059 }
       
  1060 
       
  1061 void tst_QFileInfo::isHidden_data()
       
  1062 {
       
  1063     QTest::addColumn<QString>("path");
       
  1064     QTest::addColumn<bool>("isHidden");
       
  1065     foreach (const QFileInfo& info, QDir::drives()) {
       
  1066         QTest::newRow(qPrintable("drive." + info.path())) << info.path() << false;
       
  1067     }
       
  1068 
       
  1069 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  1070     QTest::newRow("C:/RECYCLER") << QString::fromLatin1("C:/RECYCLER") << true;
       
  1071     QTest::newRow("C:/RECYCLER/.") << QString::fromLatin1("C:/RECYCLER/.") << false;
       
  1072     QTest::newRow("C:/RECYCLER/..") << QString::fromLatin1("C:/RECYCLER/..") << false;
       
  1073 #endif
       
  1074 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
       
  1075 
       
  1076     if (!QDir("./.hidden-directory").exists()
       
  1077             && !QDir().mkdir("./.hidden-directory"))
       
  1078         qWarning("Unable to create directory './.hidden-directory'. Some tests will fail.");
       
  1079 
       
  1080     QTest::newRow("./.hidden-directory") << QString("./.hidden-directory") << true;
       
  1081     QTest::newRow("./.hidden-directory/.") << QString("./.hidden-directory/.") << false;
       
  1082     QTest::newRow("./.hidden-directory/..") << QString("./.hidden-directory/..") << false;
       
  1083 
       
  1084     QTest::newRow("/path/to/.hidden-directory") << QDir::currentPath() + QString("/.hidden-directory") << true;
       
  1085     QTest::newRow("/path/to/.hidden-directory/.") << QDir::currentPath() + QString("/.hidden-directory/.") << false;
       
  1086     QTest::newRow("/path/to/.hidden-directory/..") << QDir::currentPath() + QString("/.hidden-directory/..") << false;
       
  1087 #endif
       
  1088 
       
  1089 #if defined(Q_OS_MAC)
       
  1090     // /bin has the hidden attribute on Mac OS X
       
  1091     QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << true;
       
  1092 #elif !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
       
  1093     QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << false;
       
  1094 #endif
       
  1095 
       
  1096 #ifdef Q_OS_MAC
       
  1097     QTest::newRow("mac_etc") << QString::fromLatin1("/etc") << true;
       
  1098     QTest::newRow("mac_private_etc") << QString::fromLatin1("/private/etc") << false;
       
  1099     QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications") << false;
       
  1100 #endif
       
  1101 
       
  1102 #ifdef Q_OS_SYMBIAN
       
  1103     // No guaranteed hidden file knows to exist in Symbian filesystem, so make one.
       
  1104     QString hiddenFileName("hidden.txt");
       
  1105     QString notHiddenFileName("nothidden.txt");
       
  1106     QTest::newRow("hidden file") << hiddenFileName << true;
       
  1107     QTest::newRow("non-hidden file") << notHiddenFileName << false;
       
  1108 
       
  1109     {
       
  1110         QFile file(hiddenFileName);
       
  1111         if (file.open(QIODevice::WriteOnly)) {
       
  1112             QTextStream t(&file);
       
  1113             t << "foobar";
       
  1114         } else {
       
  1115             qWarning("Failed to create hidden file");
       
  1116         }
       
  1117         QFile file2(notHiddenFileName);
       
  1118         if (file2.open(QIODevice::WriteOnly)) {
       
  1119             QTextStream t(&file);
       
  1120             t << "foobar";
       
  1121         } else {
       
  1122             qWarning("Failed to create non-hidden file");
       
  1123         }
       
  1124     }
       
  1125 
       
  1126     RFs rfs;
       
  1127     TInt err = rfs.Connect();
       
  1128     if (err == KErrNone) {
       
  1129         HBufC* symFile = qt_QString2HBufC(hiddenFileName);
       
  1130         err = rfs.SetAtt(*symFile, KEntryAttHidden, 0);
       
  1131         rfs.Close();
       
  1132         delete symFile;
       
  1133         if (err != KErrNone) {
       
  1134             qWarning("Failed to set hidden attribute for test file");
       
  1135         }
       
  1136     } else {
       
  1137         qWarning("Failed to open RFs session");
       
  1138     }
       
  1139 #endif
       
  1140 }
       
  1141 
       
  1142 void tst_QFileInfo::isHidden()
       
  1143 {
       
  1144     QFETCH(QString, path);
       
  1145     QFETCH(bool, isHidden);
       
  1146     QFileInfo fi(path);
       
  1147 
       
  1148     QCOMPARE(fi.isHidden(), isHidden);
       
  1149 }
       
  1150 
       
  1151 void tst_QFileInfo::isBundle_data()
       
  1152 {
       
  1153     QTest::addColumn<QString>("path");
       
  1154     QTest::addColumn<bool>("isBundle");
       
  1155     QTest::newRow("root") << QString::fromLatin1("/") << false;
       
  1156 #ifdef Q_OS_MAC
       
  1157     QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications") << false;
       
  1158     QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications/Safari.app") << true;
       
  1159 #endif
       
  1160 }
       
  1161 
       
  1162 void tst_QFileInfo::isBundle()
       
  1163 {
       
  1164     QFETCH(QString, path);
       
  1165     QFETCH(bool, isBundle);
       
  1166     QFileInfo fi(path);
       
  1167     QCOMPARE(fi.isBundle(), isBundle);
       
  1168 }
       
  1169 
       
  1170 void tst_QFileInfo::isLocalFs_data()
       
  1171 {
       
  1172     QTest::addColumn<QString>("path");
       
  1173     QTest::addColumn<bool>("isLocalFs");
       
  1174 
       
  1175     QTest::newRow("local root") << QString::fromLatin1("/") << true;
       
  1176     QTest::newRow("local non-existent file") << QString::fromLatin1("/abrakadabra.boo") << true;
       
  1177 
       
  1178     QTest::newRow("qresource root") << QString::fromLatin1(":/") << false;
       
  1179 }
       
  1180 
       
  1181 void tst_QFileInfo::isLocalFs()
       
  1182 {
       
  1183     QFETCH(QString, path);
       
  1184     QFETCH(bool, isLocalFs);
       
  1185 
       
  1186     QFileInfo info(path);
       
  1187     QFileInfoPrivate *privateInfo = getPrivate(info);
       
  1188     QVERIFY(privateInfo->data->fileEngine);
       
  1189     QCOMPARE(bool(privateInfo->data->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag)
       
  1190                   & QAbstractFileEngine::LocalDiskFlag), isLocalFs);
       
  1191 }
       
  1192 
       
  1193 void tst_QFileInfo::refresh()
       
  1194 {
       
  1195 #if defined(Q_OS_WINCE)
       
  1196     int sleepTime = 3000;
       
  1197 #else
       
  1198     int sleepTime = 2000;
       
  1199 #endif
       
  1200 
       
  1201     QFile::remove("file1");
       
  1202     QFile file("file1");
       
  1203     QVERIFY(file.open(QFile::WriteOnly));
       
  1204     QCOMPARE(file.write("JAJAJAA"), qint64(7));
       
  1205     file.flush();
       
  1206 
       
  1207     QFileInfo info(file);
       
  1208     QDateTime lastModified = info.lastModified();
       
  1209     QCOMPARE(info.size(), qint64(7));
       
  1210 
       
  1211     QTest::qSleep(sleepTime);
       
  1212 
       
  1213     QCOMPARE(file.write("JOJOJO"), qint64(6));
       
  1214     file.flush();
       
  1215     QVERIFY(info.lastModified() == lastModified);
       
  1216 
       
  1217     QCOMPARE(info.size(), qint64(7));
       
  1218 #if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
       
  1219     if (QSysInfo::windowsVersion() & QSysInfo::WV_VISTA ||
       
  1220                 QSysInfo::windowsVersion() & QSysInfo::WV_CE_based)
       
  1221         file.close();
       
  1222 #endif
       
  1223 #if defined(Q_OS_WINCE)
       
  1224     // On Windows CE we need to close the file.
       
  1225     // Otherwise the content will be cached and not
       
  1226     // flushed to the storage, although we flushed it
       
  1227     // manually!!! CE has interim cache, we cannot influence.
       
  1228     QTest::qWait(5000);
       
  1229 #endif
       
  1230     info.refresh();
       
  1231     QCOMPARE(info.size(), qint64(13));
       
  1232     QVERIFY(info.lastModified() > lastModified);
       
  1233 
       
  1234     QFileInfo info2 = info;
       
  1235     QCOMPARE(info2.size(), info.size());
       
  1236 
       
  1237     info2.refresh();
       
  1238     QCOMPARE(info2.size(), info.size());
       
  1239 }
       
  1240 
       
  1241 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  1242 void tst_QFileInfo::brokenShortcut()
       
  1243 {
       
  1244     QString linkName("borkenlink.lnk");
       
  1245     QFile::remove(linkName);
       
  1246     QFile file(linkName);
       
  1247     file.open(QFile::WriteOnly);
       
  1248     file.write("b0rk");
       
  1249     file.close();
       
  1250 
       
  1251     QFileInfo info(linkName);
       
  1252     QVERIFY(info.isSymLink());
       
  1253     QVERIFY(!info.exists());
       
  1254     QFile::remove(linkName);
       
  1255 }
       
  1256 #endif
       
  1257 
       
  1258 void tst_QFileInfo::isWritable()
       
  1259 {
       
  1260 #ifdef Q_OS_SYMBIAN
       
  1261     QSKIP("Currently skipped on Symbian OS, but surely there is a writeable file somewhere???", SkipAll);
       
  1262 #endif
       
  1263 
       
  1264     QFile tempfile("tempfile.txt");
       
  1265     tempfile.open(QIODevice::WriteOnly);
       
  1266     tempfile.write("This file is generated by the QFileInfo autotest.");
       
  1267     tempfile.close();
       
  1268 
       
  1269     QVERIFY(QFileInfo("tempfile.txt").isWritable());
       
  1270     tempfile.remove();
       
  1271 
       
  1272 #ifdef Q_OS_WIN
       
  1273 #ifdef Q_OS_WINCE
       
  1274     QFileInfo fi("\\Windows\\wince.nls");
       
  1275 #else
       
  1276     QFileInfo fi("c:\\pagefile.sys");
       
  1277 #endif
       
  1278     QVERIFY(fi.exists());
       
  1279     QVERIFY(!fi.isWritable());
       
  1280 #endif
       
  1281 #ifdef Q_OS_UNIX
       
  1282     if (::getuid() == 0)
       
  1283         QVERIFY(QFileInfo("/etc/passwd").isWritable());
       
  1284     else
       
  1285         QVERIFY(!QFileInfo("/etc/passwd").isWritable());
       
  1286 #endif
       
  1287 }
       
  1288 
       
  1289 void tst_QFileInfo::isExecutable()
       
  1290 {
       
  1291 #ifdef Q_OS_SYMBIAN
       
  1292 # if defined(Q_CC_NOKIAX86)
       
  1293     QSKIP("Impossible to implement reading/touching of application binaries in Symbian emulator", SkipAll);
       
  1294 # endif
       
  1295     QString appPath = "c:/sys/bin/tst_qfileinfo.exe";
       
  1296 #else
       
  1297     QString appPath = QCoreApplication::applicationDirPath();
       
  1298     appPath += "/tst_qfileinfo";
       
  1299 # if defined(Q_OS_WIN)
       
  1300     appPath += ".exe";
       
  1301 # endif
       
  1302 #endif
       
  1303     QFileInfo fi(appPath);
       
  1304     QCOMPARE(fi.isExecutable(), true);
       
  1305 
       
  1306     QCOMPARE(QFileInfo("qfileinfo.pro").isExecutable(), false);
       
  1307 }
       
  1308 
       
  1309 
       
  1310 void tst_QFileInfo::testDecomposedUnicodeNames_data()
       
  1311 {
       
  1312     QTest::addColumn<QString>("filePath");
       
  1313     QTest::addColumn<QString>("fileName");
       
  1314     QTest::addColumn<bool>("exists");
       
  1315     QString currPath = QDir::currentPath();
       
  1316     QTest::newRow("latin-only") << currPath + "/4.pdf" << "4.pdf" << true;
       
  1317     QTest::newRow("one-decomposed uni") << currPath + QString::fromUtf8("/4 ä.pdf") << QString::fromUtf8("4 ä.pdf") << true;
       
  1318     QTest::newRow("many-decomposed uni") << currPath + QString::fromUtf8("/4 äääcopy.pdf") << QString::fromUtf8("4 äääcopy.pdf") << true;
       
  1319     QTest::newRow("no decomposed") << currPath + QString::fromUtf8("/4 øøøcopy.pdf") << QString::fromUtf8("4 øøøcopy.pdf") << true;
       
  1320 }
       
  1321 
       
  1322 static void createFileNative(const QString &filePath)
       
  1323 {
       
  1324 #ifdef Q_OS_UNIX
       
  1325     int fd = open(filePath.normalized(QString::NormalizationForm_D).toUtf8().constData(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
       
  1326     if (fd < 0) {
       
  1327         QFAIL("couldn't create file");
       
  1328     } else {
       
  1329         close(fd);
       
  1330     }
       
  1331 #else
       
  1332     Q_UNUSED(filePath);
       
  1333 #endif
       
  1334 }
       
  1335 
       
  1336 static void removeFileNative(const QString &filePath)
       
  1337 {
       
  1338 #ifdef Q_OS_UNIX
       
  1339     unlink(filePath.normalized(QString::NormalizationForm_D).toUtf8().constData());
       
  1340 #else
       
  1341     Q_UNUSED(filePath);
       
  1342 #endif
       
  1343 }
       
  1344 
       
  1345 void tst_QFileInfo::testDecomposedUnicodeNames()
       
  1346 {
       
  1347 #ifndef Q_OS_MAC
       
  1348     QSKIP("This is a OS X only test (unless you know more about filesystems, then maybe you should try it ;)", SkipAll);
       
  1349 #endif
       
  1350     QFETCH(QString, filePath);
       
  1351     createFileNative(filePath);
       
  1352 
       
  1353     QFileInfo file(filePath);
       
  1354     QTEST(file.fileName(), "fileName");
       
  1355     QTEST(file.exists(), "exists");
       
  1356     removeFileNative(filePath);
       
  1357 }
       
  1358 
       
  1359 void tst_QFileInfo::equalOperator() const
       
  1360 {
       
  1361     /* Compare two default constructed values. Yes, to me it seems it should be the opposite too, but
       
  1362      * this is how the code was written. */
       
  1363     QVERIFY(!(QFileInfo() == QFileInfo()));
       
  1364 }
       
  1365 
       
  1366 
       
  1367 void tst_QFileInfo::equalOperatorWithDifferentSlashes() const
       
  1368 {
       
  1369     const QFileInfo fi1("/usr");
       
  1370     const QFileInfo fi2("/usr/");
       
  1371 
       
  1372     QCOMPARE(fi1, fi2);
       
  1373 }
       
  1374 
       
  1375 void tst_QFileInfo::notEqualOperator() const
       
  1376 {
       
  1377     /* Compare two default constructed values. Yes, to me it seems it should be the opposite too, but
       
  1378      * this is how the code was written. */
       
  1379     QVERIFY(QFileInfo() != QFileInfo());
       
  1380 }
       
  1381 
       
  1382 QTEST_MAIN(tst_QFileInfo)
       
  1383 #include "tst_qfileinfo.moc"