1/****************************************************************************
2**
3** Copyright (C) 2017 Intel Corporation.
4** Copyright (C) 2016 The Qt Company Ltd.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the test suite of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3 as published by the Free Software
21** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include <QtTest/QtTest>
31
32#include <qcoreapplication.h>
33#include <qdebug.h>
34#include <qdir.h>
35#include <qfileinfo.h>
36#include <qstringlist.h>
37
38#if defined(Q_OS_WIN)
39#include <QtCore/private/qfsfileengine_p.h>
40#include "../../../network-settings.h"
41#endif
42
43#if defined(Q_OS_WIN) && !defined(_WIN32_WINNT)
44#define _WIN32_WINNT 0x500
45#endif
46
47#include "../../../../shared/filesystem.h"
48
49#if defined(Q_OS_UNIX)
50# include <unistd.h>
51# include <sys/stat.h>
52#endif
53
54#if defined(Q_OS_VXWORKS) || defined(Q_OS_WINRT)
55#define Q_NO_SYMLINKS
56#endif
57
58#ifdef Q_OS_WIN
59#define DRIVE "Q:"
60#else
61#define DRIVE
62#endif
63
64#ifdef QT_BUILD_INTERNAL
65#include "private/qdir_p.h"
66#endif
67
68static QByteArray msgDoesNotExist(const QString &name)
69{
70 return (QLatin1Char('"') + QDir::toNativeSeparators(pathName: name)
71 + QLatin1String("\" does not exist.")).toLocal8Bit();
72}
73
74class tst_QDir : public QObject
75{
76Q_OBJECT
77
78public:
79 enum UncHandling { HandleUnc, IgnoreUnc };
80 tst_QDir();
81
82private slots:
83 void init();
84 void initTestCase();
85 void cleanupTestCase();
86
87 void getSetCheck();
88 void construction();
89
90 void setPath_data();
91 void setPath();
92
93 void entryList_data();
94 void entryList();
95
96 void entryListWithTestFiles_data();
97 void entryListWithTestFiles();
98
99 void entryListTimedSort();
100
101 void entryListSimple_data();
102 void entryListSimple();
103
104 void entryListWithSymLinks();
105
106 void mkdirRmdir_data();
107 void mkdirRmdir();
108 void mkdirOnSymlink();
109
110 void makedirReturnCode();
111
112 void removeRecursively_data();
113 void removeRecursively();
114 void removeRecursivelyFailure();
115 void removeRecursivelySymlink();
116
117 void exists_data();
118 void exists();
119
120 void isRelativePath_data();
121 void isRelativePath();
122
123 void canonicalPath_data();
124 void canonicalPath();
125
126 void current_data();
127 void current();
128
129 void cd_data();
130 void cd();
131
132 void setNameFilters_data();
133 void setNameFilters();
134
135 void cleanPath_data();
136 void cleanPath();
137
138#ifdef QT_BUILD_INTERNAL
139 void normalizePathSegments_data();
140 void normalizePathSegments();
141#endif
142
143 void compare();
144 void QDir_default();
145
146 void filePath_data();
147 void filePath();
148
149 void absoluteFilePath_data();
150 void absoluteFilePath();
151
152 void absolutePath_data();
153 void absolutePath();
154
155 void relativeFilePath_data();
156 void relativeFilePath();
157
158 void remove();
159 void rename();
160
161 void exists2_data();
162 void exists2();
163
164 void dirName_data();
165 void dirName();
166
167 void operator_eq();
168
169 void dotAndDotDot();
170
171 void homePath();
172 void tempPath();
173 void rootPath();
174
175 void nativeSeparators();
176
177 void searchPaths();
178 void searchPaths_data();
179
180 void entryListWithSearchPaths();
181
182 void longFileName_data();
183 void longFileName();
184
185 void updateFileLists();
186
187 void detachingOperations();
188
189 void testCaching();
190
191 void isRoot_data();
192 void isRoot();
193
194#ifndef QT_NO_REGEXP
195 void match_data();
196 void match();
197#endif
198
199 void drives();
200
201 void arrayOperator();
202
203 void equalityOperator_data();
204 void equalityOperator();
205
206 void isRelative_data();
207 void isRelative();
208
209 void isReadable();
210
211 void cdNonreadable();
212
213 void cdBelowRoot_data();
214 void cdBelowRoot();
215
216 void emptyDir();
217 void nonEmptyDir();
218
219private:
220#ifdef BUILTIN_TESTDATA
221 QString m_dataPath;
222 QSharedPointer<QTemporaryDir> m_dataDir;
223#else
224 const QString m_dataPath;
225#endif
226};
227
228Q_DECLARE_METATYPE(tst_QDir::UncHandling)
229
230tst_QDir::tst_QDir()
231#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
232 : m_dataPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
233#elif !defined(BUILTIN_TESTDATA)
234 : m_dataPath(QFileInfo(QFINDTESTDATA("testData")).absolutePath())
235#endif
236{
237#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
238 QString resourceSourcePath = QStringLiteral(":/android_testdata/");
239 QDirIterator it(resourceSourcePath, QDirIterator::Subdirectories);
240 while (it.hasNext()) {
241 it.next();
242
243 QFileInfo fileInfo = it.fileInfo();
244
245 if (!fileInfo.isDir()) {
246 QString destination = m_dataPath + QLatin1Char('/') + fileInfo.filePath().mid(resourceSourcePath.length());
247 QFileInfo destinationFileInfo(destination);
248 if (!destinationFileInfo.exists()) {
249 QDir().mkpath(destinationFileInfo.path());
250 if (!QFile::copy(fileInfo.filePath(), destination))
251 qWarning("Failed to copy %s", qPrintable(fileInfo.filePath()));
252 }
253 }
254
255 }
256
257 if (!QDir::setCurrent(m_dataPath))
258 qWarning("Couldn't set current path to %s", qPrintable(m_dataPath));
259#endif
260}
261
262void tst_QDir::init()
263{
264 // Some tests want to use "." as relative path to data.
265 QVERIFY2(QDir::setCurrent(m_dataPath), qPrintable("Could not chdir to " + m_dataPath));
266}
267
268void tst_QDir::initTestCase()
269{
270#ifdef BUILTIN_TESTDATA
271 m_dataDir = QEXTRACTTESTDATA("/");
272 QVERIFY2(!m_dataDir.isNull(), qPrintable("Did not find testdata. Is this builtin?"));
273 m_dataPath = m_dataDir->path();
274#endif
275
276 QVERIFY2(!m_dataPath.isEmpty(), "test data not found");
277}
278
279void tst_QDir::cleanupTestCase()
280{
281#ifdef BUILTIN_TESTDATA
282 // We need to reset the current directory outside of QTemporaryDir for successful deletion
283 QDir::setCurrent(QCoreApplication::applicationDirPath());
284#else
285 QDir(QDir::currentPath() + "/tmpdir").removeRecursively();
286#endif
287}
288
289// Testing get/set functions
290void tst_QDir::getSetCheck()
291{
292 QDir obj1;
293 // Filters QDir::filter()
294 // void QDir::setFilter(Filters)
295 obj1.setFilter(QDir::Filters(QDir::Dirs));
296 QCOMPARE(QDir::Filters(QDir::Dirs), obj1.filter());
297 obj1.setFilter(QDir::Filters(QDir::Dirs | QDir::Files));
298 QCOMPARE(QDir::Filters(QDir::Dirs | QDir::Files), obj1.filter());
299 obj1.setFilter(QDir::Filters(QDir::NoFilter));
300 QCOMPARE(QDir::Filters(QDir::NoFilter), obj1.filter());
301
302 // SortFlags QDir::sorting()
303 // void QDir::setSorting(SortFlags)
304 obj1.setSorting(QDir::SortFlags(QDir::Name));
305 QCOMPARE(QDir::SortFlags(QDir::Name), obj1.sorting());
306 obj1.setSorting(QDir::SortFlags(QDir::Name | QDir::IgnoreCase));
307 QCOMPARE(QDir::SortFlags(QDir::Name | QDir::IgnoreCase), obj1.sorting());
308 obj1.setSorting(QDir::SortFlags(QDir::NoSort));
309 QCOMPARE(QDir::SortFlags(QDir::NoSort), obj1.sorting());
310}
311
312void tst_QDir::construction()
313{
314 QFileInfo myFileInfo("/machine/share/dir1/file1");
315 QDir myDir(myFileInfo.absoluteDir()); // this asserted
316 QCOMPARE(myFileInfo.absoluteDir().absolutePath(), myDir.absolutePath());
317}
318
319void tst_QDir::setPath_data()
320{
321 QTest::addColumn<QString>(name: "dir1");
322 QTest::addColumn<QString>(name: "dir2");
323
324 QTest::newRow(dataTag: "data0") << QString(".") << QString("..");
325#if defined(Q_OS_WIN)
326 QTest::newRow("data1") << QString("c:/") << QDir::currentPath();
327#endif
328}
329
330void tst_QDir::setPath()
331{
332 QFETCH(QString, dir1);
333 QFETCH(QString, dir2);
334
335 QDir shared;
336 QDir qDir1(dir1);
337 QStringList entries1 = qDir1.entryList();
338 shared.setPath(dir1);
339 QCOMPARE(shared.entryList(), entries1);
340
341 QDir qDir2(dir2);
342 QStringList entries2 = qDir2.entryList();
343 shared.setPath(dir2);
344 QCOMPARE(shared.entryList(), entries2);
345}
346
347void tst_QDir::mkdirRmdir_data()
348{
349 QTest::addColumn<QString>(name: "path");
350 QTest::addColumn<bool>(name: "recurse");
351
352 const struct {
353 const char *name; // shall have a prefix added
354 const char *path; // relative
355 bool recurse;
356 } cases[] = {
357 { .name: "plain", .path: "testdir/one", .recurse: false },
358 { .name: "recursive", .path: "testdir/two/three/four", .recurse: true },
359 { .name: "with-..", .path: "testdir/../testdir/three", .recurse: false },
360 };
361
362 for (const auto &it : cases) {
363 QVERIFY(!QFile::exists(it.path));
364 QTest::addRow(format: "absolute-%s", it.name) << (QDir::currentPath() + "/") + it.path << it.recurse;
365 QTest::addRow(format: "relative-%s", it.name) << QString::fromLatin1(str: it.path) << it.recurse;
366 }
367}
368
369void tst_QDir::mkdirRmdir()
370{
371 QFETCH(QString, path);
372 QFETCH(bool, recurse);
373
374 QDir dir;
375 dir.rmdir(dirName: path);
376 if (recurse)
377 QVERIFY(dir.mkpath(path));
378 else
379 QVERIFY(dir.mkdir(path));
380
381 //make sure it really exists (ie that mkdir returns the right value)
382 QFileInfo fi(path);
383 QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData());
384
385 if (recurse)
386 QVERIFY(dir.rmpath(path));
387 else
388 QVERIFY(dir.rmdir(path));
389
390 //make sure it really doesn't exist (ie that rmdir returns the right value)
391 fi.refresh();
392 QVERIFY(!fi.exists());
393}
394
395void tst_QDir::mkdirOnSymlink()
396{
397#if !defined(Q_OS_UNIX) || defined(Q_NO_SYMLINKS)
398 QSKIP("Test only valid on an OS that supports symlinks");
399#else
400 // Create the structure:
401 // .
402 // ├── symlink -> two/three
403 // └── two
404 // └── three
405 // so when we mkdir("symlink/../four/five"), we end up with:
406 // .
407 // ├── symlink -> two/three
408 // └── two
409 // ├── four
410 // │ └── five
411 // └── three
412
413 QDir dir;
414 struct Clean {
415 QDir &dir;
416 Clean(QDir &dir) : dir(dir) {}
417 ~Clean() { doClean(); }
418 void doClean() {
419 dir.rmpath(dirPath: "two/three");
420 dir.rmpath(dirPath: "two/four/five");
421 // in case the test fails, don't leave junk behind
422 dir.rmpath(dirPath: "four/five");
423 QFile::remove(fileName: "symlink");
424 }
425 };
426 Clean clean(dir);
427 clean.doClean();
428
429 // create our structure:
430 dir.mkpath(dirPath: "two/three");
431 ::symlink(from: "two/three", to: "symlink");
432
433 // try it:
434 QString path = "symlink/../four/five";
435 QVERIFY(dir.mkpath(path));
436 QFileInfo fi(path);
437 QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData());
438
439 path = "two/four/five";
440 fi.setFile(path);
441 QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData());
442#endif
443}
444
445void tst_QDir::makedirReturnCode()
446{
447 QString dirName = QString::fromLatin1(str: "makedirReturnCode");
448 QFile f(QDir::current().filePath(fileName: dirName));
449
450 // cleanup a previous run.
451 f.remove();
452 QDir::current().rmdir(dirName);
453
454 QDir dir(dirName);
455 QVERIFY(!dir.exists());
456 QVERIFY(QDir::current().mkdir(dirName));
457 QVERIFY(!QDir::current().mkdir(dirName)); // calling mkdir on an existing dir will fail.
458 QVERIFY(QDir::current().mkpath(dirName)); // calling mkpath on an existing dir will pass
459
460 // Remove the directory and create a file with the same path
461 QDir::current().rmdir(dirName);
462 QVERIFY(!f.exists());
463 f.open(flags: QIODevice::WriteOnly);
464 f.write(data: "test");
465 f.close();
466 QVERIFY2(f.exists(), msgDoesNotExist(f.fileName()).constData());
467 QVERIFY(!QDir::current().mkdir(dirName)); // calling mkdir on an existing file will fail.
468 QVERIFY(!QDir::current().mkpath(dirName)); // calling mkpath on an existing file will fail.
469 f.remove();
470}
471
472void tst_QDir::removeRecursively_data()
473{
474 QTest::addColumn<QString>(name: "path");
475
476 // Create dirs and files
477 const QString tmpdir = QDir::currentPath() + "/tmpdir/";
478 QStringList dirs;
479 dirs << tmpdir + "empty"
480 << tmpdir + "one"
481 << tmpdir + "two/three"
482 << "relative";
483 QDir dir;
484 for (int i = 0; i < dirs.count(); ++i)
485 dir.mkpath(dirPath: dirs.at(i));
486 QStringList files;
487 files << tmpdir + "one/file";
488 files << tmpdir + "two/three/file";
489 for (int i = 0; i < files.count(); ++i) {
490 QFile file(files.at(i));
491 QVERIFY(file.open(QIODevice::WriteOnly));
492 file.write(data: "Hello");
493 }
494
495 QTest::newRow(dataTag: "empty") << tmpdir + "empty";
496 QTest::newRow(dataTag: "one") << tmpdir + "one";
497 QTest::newRow(dataTag: "two") << tmpdir + "two";
498 QTest::newRow(dataTag: "does not exist") << tmpdir + "doesnotexist";
499 QTest::newRow(dataTag: "relative") << "relative";
500}
501
502void tst_QDir::removeRecursively()
503{
504 QFETCH(QString, path);
505
506 QDir dir(path);
507 QVERIFY(dir.removeRecursively());
508
509 //make sure it really doesn't exist (ie that remove worked)
510 QVERIFY(!dir.exists());
511}
512
513void tst_QDir::removeRecursivelyFailure()
514{
515#ifdef Q_OS_UNIX
516 if (::getuid() == 0)
517 QSKIP("Running this test as root doesn't make sense");
518#endif
519 const QString tmpdir = QDir::currentPath() + "/tmpdir/";
520 const QString path = tmpdir + "undeletable";
521 QDir().mkpath(dirPath: path);
522
523 // Need a file in there, otherwise rmdir works even w/o permissions
524 QFile file(path + "/file");
525 QVERIFY(file.open(QIODevice::WriteOnly));
526 file.write(data: "Hello");
527 file.close();
528
529#ifdef Q_OS_UNIX
530 QFile dirAsFile(path); // yay, I have to use QFile to change a dir's permissions...
531 QVERIFY(dirAsFile.setPermissions({})); // no permissions
532
533 QVERIFY(!QDir().rmdir(path));
534 QDir dir(path);
535 QVERIFY(!dir.removeRecursively()); // didn't work
536 QVERIFY2(dir.exists(), msgDoesNotExist(dir.absolutePath()).constData()); // still exists
537
538 QVERIFY(dirAsFile.setPermissions(QFile::Permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner)));
539 QVERIFY(dir.removeRecursively());
540 QVERIFY(!dir.exists());
541#else // Q_OS_UNIX
542 QVERIFY(file.setPermissions(QFile::ReadOwner));
543 QVERIFY(!QDir().rmdir(path));
544 QDir dir(path);
545 QVERIFY(dir.removeRecursively());
546 QVERIFY(!dir.exists());
547#endif // !Q_OS_UNIX
548}
549
550void tst_QDir::removeRecursivelySymlink()
551{
552#ifndef Q_NO_SYMLINKS
553 const QString tmpdir = QDir::currentPath() + "/tmpdir/";
554 QDir().mkpath(dirPath: tmpdir);
555 QDir currentDir;
556 currentDir.mkdir(dirName: "myDir");
557 QFile("testfile").open(flags: QIODevice::WriteOnly);
558 const QString link = tmpdir + "linkToDir.lnk";
559 const QString linkToFile = tmpdir + "linkToFile.lnk";
560#ifndef Q_NO_SYMLINKS_TO_DIRS
561 QVERIFY(QFile::link("../myDir", link));
562 QVERIFY(QFile::link("../testfile", linkToFile));
563#endif
564
565 QDir dir(tmpdir);
566 QVERIFY(dir.removeRecursively());
567 QVERIFY(QDir("myDir").exists()); // it didn't follow the symlink, good.
568 QVERIFY(QFile::exists("testfile"));
569
570 currentDir.rmdir(dirName: "myDir");
571 QFile::remove(fileName: "testfile");
572#endif
573}
574
575void tst_QDir::exists_data()
576{
577 QTest::addColumn<QString>(name: "path");
578 QTest::addColumn<bool>(name: "expected");
579
580 QTest::newRow(dataTag: "data0") << QDir::currentPath() << true;
581 QTest::newRow(dataTag: "data0.1") << QDir::currentPath() + "/" << true;
582 QTest::newRow(dataTag: "data1") << QString("/I/Do_not_expect_this_path_to_exist/") << false;
583 QTest::newRow(dataTag: "resource0") << QString(":/tst_qdir/") << true;
584 QTest::newRow(dataTag: "resource1") << QString(":/I/Do_not_expect_this_resource_to_exist/") << false;
585
586 QTest::newRow(dataTag: "simple dir") << (m_dataPath + "/resources") << true;
587 QTest::newRow(dataTag: "simple dir with slash") << (m_dataPath + "/resources/") << true;
588#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
589 const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName();
590 QTest::newRow("unc 1") << uncRoot << true;
591 QTest::newRow("unc 2") << uncRoot + QLatin1Char('/') << true;
592 QTest::newRow("unc 3") << uncRoot + "/testshare" << true;
593 QTest::newRow("unc 4") << uncRoot + "/testshare/" << true;
594 QTest::newRow("unc 5") << uncRoot + "/testshare/tmp" << true;
595 QTest::newRow("unc 6") << uncRoot + "/testshare/tmp/" << true;
596 QTest::newRow("unc 7") << uncRoot + "/testshare/adirthatshouldnotexist" << false;
597 QTest::newRow("unc 8") << uncRoot + "/asharethatshouldnotexist" << false;
598 QTest::newRow("unc 9") << "//ahostthatshouldnotexist" << false;
599#endif
600#if (defined(Q_OS_WIN) && !defined(Q_OS_WINRT))
601 QTest::newRow("This drive should exist") << "C:/" << true;
602 // find a non-existing drive and check if it does not exist
603#ifdef QT_BUILD_INTERNAL
604 QFileInfoList drives = QFSFileEngine::drives();
605 QStringList driveLetters;
606 for (int i = 0; i < drives.count(); ++i) {
607 driveLetters+=drives.at(i).absoluteFilePath();
608 }
609 char drive = 'Z';
610 QString driv;
611 do {
612 driv = drive + QLatin1String(":/");
613 if (!driveLetters.contains(driv)) break;
614 --drive;
615 } while (drive >= 'A');
616 if (drive >= 'A') {
617 QTest::newRow("This drive should not exist") << driv << false;
618 }
619#endif
620#endif
621}
622
623void tst_QDir::exists()
624{
625 QFETCH(QString, path);
626 QFETCH(bool, expected);
627
628 QDir dir(path);
629 if (expected)
630 QVERIFY2(dir.exists(), msgDoesNotExist(path).constData());
631 else
632 QVERIFY(!dir.exists());
633}
634
635void tst_QDir::isRelativePath_data()
636{
637 QTest::addColumn<QString>(name: "path");
638 QTest::addColumn<bool>(name: "relative");
639
640 QTest::newRow(dataTag: "data0") << "../somedir" << true;
641#if defined(Q_OS_WIN)
642 QTest::newRow("data1") << "C:/sOmedir" << false;
643#endif
644 QTest::newRow(dataTag: "data2") << "somedir" << true;
645 QTest::newRow(dataTag: "data3") << "/somedir" << false;
646
647 QTest::newRow(dataTag: "resource0") << ":/prefix" << false;
648 QTest::newRow(dataTag: "resource1") << ":/prefix/foo.bar" << false;
649}
650
651void tst_QDir::isRelativePath()
652{
653 QFETCH(QString, path);
654 QFETCH(bool, relative);
655
656 QCOMPARE(QDir::isRelativePath(path),relative);
657}
658
659
660void tst_QDir::QDir_default()
661{
662 //default constructor QDir();
663 QDir dir; // according to documentation should be currentDirPath
664 QCOMPARE(dir.absolutePath(), QDir::currentPath());
665}
666
667void tst_QDir::compare()
668{
669 // operator==
670
671 // Not using QCOMPARE to test result of QDir::operator==
672
673 QDir dir;
674 dir.makeAbsolute();
675 QVERIFY(dir == QDir::currentPath());
676
677 QCOMPARE(QDir(), QDir(QDir::currentPath()));
678 QVERIFY(QDir("../") == QDir(QDir::currentPath() + "/.."));
679}
680
681static QStringList filterLinks(const QStringList &list)
682{
683#ifndef Q_NO_SYMLINKS
684 return list;
685#else
686 QStringList result;
687 foreach (QString str, list) {
688 if (!str.endsWith(QLatin1String(".lnk")))
689 result.append(str);
690 }
691 return result;
692#endif
693}
694
695void tst_QDir::entryList_data()
696{
697 QTest::addColumn<QString>(name: "dirName"); // relative from current path or abs
698 QTest::addColumn<QStringList>(name: "nameFilters");
699 QTest::addColumn<int>(name: "filterspec");
700 QTest::addColumn<int>(name: "sortspec");
701 QTest::addColumn<QStringList>(name: "expected");
702 QTest::newRow(dataTag: "spaces1") << (m_dataPath + "/testdir/spaces") << QStringList("*. bar")
703 << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
704 << QStringList("foo. bar"); // notice how spaces5 works
705 QTest::newRow(dataTag: "spaces2") << (m_dataPath + "/testdir/spaces") << QStringList("*.bar")
706 << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
707 << QStringList("foo.bar");
708 QTest::newRow(dataTag: "spaces3") << (m_dataPath + "/testdir/spaces") << QStringList("foo.*")
709 << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
710 << QString("foo. bar,foo.bar").split(sep: ',');
711 QTest::newRow(dataTag: "files1") << (m_dataPath + "/testdir/dir") << QString("*r.cpp *.pro").split(sep: " ")
712 << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
713 << QString("qdir.pro,qrc_qdir.cpp,tst_qdir.cpp").split(sep: ',');
714 QTest::newRow(dataTag: "testdir1") << (m_dataPath + "/testdir") << QStringList()
715 << (int)(QDir::AllDirs) << (int)(QDir::NoSort)
716 << QString(".,..,dir,spaces").split(sep: ',');
717 QTest::newRow(dataTag: "resources1") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data")
718 << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
719 << QString("file1.data,file2.data,file3.data").split(sep: ',');
720 QTest::newRow(dataTag: "resources2") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data")
721 << (int)(QDir::Files) << (int)(QDir::NoSort)
722 << QString("file1.data,file2.data,file3.data").split(sep: ',');
723}
724
725void tst_QDir::entryList()
726{
727 QFETCH(QString, dirName);
728 QFETCH(QStringList, nameFilters);
729 QFETCH(int, filterspec);
730 QFETCH(int, sortspec);
731 QFETCH(QStringList, expected);
732
733 QDir dir(dirName);
734 QVERIFY2(dir.exists(), msgDoesNotExist(dirName).constData());
735
736 QStringList actual = dir.entryList(nameFilters, filters: (QDir::Filters)filterspec,
737 sort: (QDir::SortFlags)sortspec);
738
739 QCOMPARE(actual, expected);
740}
741
742void tst_QDir::entryListWithTestFiles_data()
743{
744 QTest::addColumn<QString>(name: "dirName"); // relative from current path or abs
745 QTest::addColumn<QStringList>(name: "nameFilters");
746 QTest::addColumn<int>(name: "filterspec");
747 QTest::addColumn<int>(name: "sortspec");
748 QTest::addColumn<QStringList>(name: "expected");
749
750 QTest::newRow(dataTag: "nofilter") << (m_dataPath + "/entrylist/") << QStringList("*")
751 << int(QDir::NoFilter) << int(QDir::Name)
752 << filterLinks(list: QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(sep: ','));
753 QTest::newRow(dataTag: "QDir::AllEntries") << (m_dataPath + "/entrylist/") << QStringList("*")
754 << int(QDir::AllEntries) << int(QDir::Name)
755 << filterLinks(list: QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(sep: ','));
756 QTest::newRow(dataTag: "QDir::Files") << (m_dataPath + "/entrylist/") << QStringList("*")
757 << int(QDir::Files) << int(QDir::Name)
758 << filterLinks(list: QString("file,linktofile.lnk,writable").split(sep: ','));
759 QTest::newRow(dataTag: "QDir::Dirs") << (m_dataPath + "/entrylist/") << QStringList("*")
760 << int(QDir::Dirs) << int(QDir::Name)
761 << filterLinks(list: QString(".,..,directory,linktodirectory.lnk").split(sep: ','));
762 QTest::newRow(dataTag: "QDir::Dirs | QDir::NoDotAndDotDot") << (m_dataPath + "/entrylist/") << QStringList("*")
763 << int(QDir::Dirs | QDir::NoDotAndDotDot) << int(QDir::Name)
764 << filterLinks(list: QString("directory,linktodirectory.lnk").split(sep: ','));
765 QTest::newRow(dataTag: "QDir::AllDirs") << (m_dataPath + "/entrylist/") << QStringList("*")
766 << int(QDir::AllDirs) << int(QDir::Name)
767 << filterLinks(list: QString(".,..,directory,linktodirectory.lnk").split(sep: ','));
768 QTest::newRow(dataTag: "QDir::AllDirs | QDir::Dirs") << (m_dataPath + "/entrylist/") << QStringList("*")
769 << int(QDir::AllDirs | QDir::Dirs) << int(QDir::Name)
770 << filterLinks(list: QString(".,..,directory,linktodirectory.lnk").split(sep: ','));
771 QTest::newRow(dataTag: "QDir::AllDirs | QDir::Files") << (m_dataPath + "/entrylist/") << QStringList("*")
772 << int(QDir::AllDirs | QDir::Files) << int(QDir::Name)
773 << filterLinks(list: QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(sep: ','));
774 QTest::newRow(dataTag: "QDir::AllEntries | QDir::NoSymLinks") << (m_dataPath + "/entrylist/") << QStringList("*")
775 << int(QDir::AllEntries | QDir::NoSymLinks) << int(QDir::Name)
776 << filterLinks(list: QString(".,..,directory,file,writable").split(sep: ','));
777 QTest::newRow(dataTag: "QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot") << (m_dataPath + "/entrylist/") << QStringList("*")
778 << int(QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot) << int(QDir::Name)
779 << filterLinks(list: QString("directory,file,writable").split(sep: ','));
780 QTest::newRow(dataTag: "QDir::Files | QDir::NoSymLinks") << (m_dataPath + "/entrylist/") << QStringList("*")
781 << int(QDir::Files | QDir::NoSymLinks) << int(QDir::Name)
782 << filterLinks(list: QString("file,writable").split(sep: ','));
783 QTest::newRow(dataTag: "QDir::Dirs | QDir::NoSymLinks") << (m_dataPath + "/entrylist/") << QStringList("*")
784 << int(QDir::Dirs | QDir::NoSymLinks) << int(QDir::Name)
785 << filterLinks(list: QString(".,..,directory").split(sep: ','));
786 QTest::newRow(dataTag: "QDir::Drives | QDir::Files | QDir::NoDotAndDotDot") << (m_dataPath + "/entrylist/") << QStringList("*")
787 << int(QDir::Drives | QDir::Files | QDir::NoDotAndDotDot) << int(QDir::Name)
788 << filterLinks(list: QString("file,linktofile.lnk,writable").split(sep: ','));
789 QTest::newRow(dataTag: "QDir::System") << (m_dataPath + "/entrylist/") << QStringList("*")
790 << int(QDir::System) << int(QDir::Name)
791 << filterLinks(list: QStringList("brokenlink.lnk"));
792 QTest::newRow(dataTag: "QDir::Hidden") << (m_dataPath + "/entrylist/") << QStringList("*")
793 << int(QDir::Hidden) << int(QDir::Name)
794 << QStringList();
795 QTest::newRow(dataTag: "QDir::System | QDir::Hidden") << (m_dataPath + "/entrylist/") << QStringList("*")
796 << int(QDir::System | QDir::Hidden) << int(QDir::Name)
797 << filterLinks(list: QStringList("brokenlink.lnk"));
798 QTest::newRow(dataTag: "QDir::AllDirs | QDir::NoSymLinks") << (m_dataPath + "/entrylist/") << QStringList("*")
799 << int(QDir::AllDirs | QDir::NoSymLinks) << int(QDir::Name)
800 << filterLinks(list: QString(".,..,directory").split(sep: ','));
801 QTest::newRow(dataTag: "QDir::AllEntries | QDir::Hidden | QDir::System") << (m_dataPath + "/entrylist/") << QStringList("*")
802 << int(QDir::AllEntries | QDir::Hidden | QDir::System) << int(QDir::Name)
803 << filterLinks(list: QString(".,..,brokenlink.lnk,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(sep: ','));
804 QTest::newRow(dataTag: "QDir::AllEntries | QDir::Readable") << (m_dataPath + "/entrylist/") << QStringList("*")
805 << int(QDir::AllEntries | QDir::Readable) << int(QDir::Name)
806 << filterLinks(list: QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(sep: ','));
807 QTest::newRow(dataTag: "QDir::AllEntries | QDir::Writable") << (m_dataPath + "/entrylist/") << QStringList("*")
808 << int(QDir::AllEntries | QDir::Writable) << int(QDir::Name)
809 << filterLinks(list: QString(".,..,directory,linktodirectory.lnk,writable").split(sep: ','));
810 QTest::newRow(dataTag: "QDir::Files | QDir::Readable") << (m_dataPath + "/entrylist/") << QStringList("*")
811 << int(QDir::Files | QDir::Readable) << int(QDir::Name)
812 << filterLinks(list: QString("file,linktofile.lnk,writable").split(sep: ','));
813 QTest::newRow(dataTag: "QDir::Dirs | QDir::Readable") << (m_dataPath + "/entrylist/") << QStringList("*")
814 << int(QDir::Dirs | QDir::Readable) << int(QDir::Name)
815 << filterLinks(list: QString(".,..,directory,linktodirectory.lnk").split(sep: ','));
816 QTest::newRow(dataTag: "Namefilters b*") << (m_dataPath + "/entrylist/") << QStringList("d*")
817 << int(QDir::NoFilter) << int(QDir::Name)
818 << filterLinks(list: QString("directory").split(sep: ','));
819 QTest::newRow(dataTag: "Namefilters f*") << (m_dataPath + "/entrylist/") << QStringList("f*")
820 << int(QDir::NoFilter) << int(QDir::Name)
821 << filterLinks(list: QString("file").split(sep: ','));
822 QTest::newRow(dataTag: "Namefilters link*") << (m_dataPath + "/entrylist/") << QStringList("link*")
823 << int(QDir::NoFilter) << int(QDir::Name)
824 << filterLinks(list: QString("linktodirectory.lnk,linktofile.lnk").split(sep: ','));
825 QTest::newRow(dataTag: "Namefilters *to*") << (m_dataPath + "/entrylist/") << QStringList("*to*")
826 << int(QDir::NoFilter) << int(QDir::Name)
827 << filterLinks(list: QString("directory,linktodirectory.lnk,linktofile.lnk").split(sep: ','));
828 QTest::newRow(dataTag: "Sorting QDir::Name") << (m_dataPath + "/entrylist/") << QStringList("*")
829 << int(QDir::NoFilter) << int(QDir::Name)
830 << filterLinks(list: QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(sep: ','));
831 QTest::newRow(dataTag: "Sorting QDir::Name | QDir::Reversed") << (m_dataPath + "/entrylist/") << QStringList("*")
832 << int(QDir::NoFilter) << int(QDir::Name | QDir::Reversed)
833 << filterLinks(list: QString("writable,linktofile.lnk,linktodirectory.lnk,file,directory,..,.").split(sep: ','));
834
835 QTest::newRow(dataTag: "Sorting QDir::Type") << (m_dataPath + "/types/") << QStringList("*")
836 << int(QDir::NoFilter) << int(QDir::Type)
837 << QString(".,..,a,b,c,d,e,f,a.a,b.a,c.a,d.a,e.a,f.a,a.b,b.b,c.b,d.b,e.b,f.b,a.c,b.c,c.c,d.c,e.c,f.c").split(sep: ',');
838 QTest::newRow(dataTag: "Sorting QDir::Type | QDir::Reversed") << (m_dataPath + "/types/") << QStringList("*")
839 << int(QDir::NoFilter) << int(QDir::Type | QDir::Reversed)
840 << QString("f.c,e.c,d.c,c.c,b.c,a.c,f.b,e.b,d.b,c.b,b.b,a.b,f.a,e.a,d.a,c.a,b.a,a.a,f,e,d,c,b,a,..,.").split(sep: ',');
841 QTest::newRow(dataTag: "Sorting QDir::Type | QDir::DirsLast") << (m_dataPath + "/types/") << QStringList("*")
842 << int(QDir::NoFilter) << int(QDir::Type | QDir::DirsLast)
843 << QString("a,b,c,a.a,b.a,c.a,a.b,b.b,c.b,a.c,b.c,c.c,.,..,d,e,f,d.a,e.a,f.a,d.b,e.b,f.b,d.c,e.c,f.c").split(sep: ',');
844 QTest::newRow(dataTag: "Sorting QDir::Type | QDir::DirsFirst") << (m_dataPath + "/types/") << QStringList("*")
845 << int(QDir::NoFilter) << int(QDir::Type | QDir::DirsFirst)
846 << QString(".,..,d,e,f,d.a,e.a,f.a,d.b,e.b,f.b,d.c,e.c,f.c,a,b,c,a.a,b.a,c.a,a.b,b.b,c.b,a.c,b.c,c.c").split(sep: ',');
847 QTest::newRow(dataTag: "Sorting QDir::Size") << (m_dataPath + "/types/") << QStringList("*")
848 << int(QDir::AllEntries|QDir::NoDotAndDotDot) << int(QDir::Size | QDir::DirsFirst)
849 << QString("d,d.a,d.b,d.c,e,e.a,e.b,e.c,f,f.a,f.b,f.c,c.a,c.b,c.c,b.a,b.c,b.b,a.c,a.b,a.a,a,b,c").split(sep: ',');
850 QTest::newRow(dataTag: "Sorting QDir::Size | QDir::Reversed") << (m_dataPath + "/types/") << QStringList("*")
851 << int(QDir::AllEntries|QDir::NoDotAndDotDot) << int(QDir::Size | QDir::Reversed | QDir::DirsLast)
852 << QString("c,b,a,a.a,a.b,a.c,b.b,b.c,b.a,c.c,c.b,c.a,f.c,f.b,f.a,f,e.c,e.b,e.a,e,d.c,d.b,d.a,d").split(sep: ',');
853}
854
855void tst_QDir::entryListWithTestFiles()
856{
857 QFETCH(QString, dirName);
858 QFETCH(QStringList, nameFilters);
859 QFETCH(int, filterspec);
860 QFETCH(int, sortspec);
861 QFETCH(QStringList, expected);
862
863 QStringList testFiles;
864
865 QString entrylistPath = (m_dataPath + "/entrylist/");
866
867 {
868 const QString writableFileName = entrylistPath + "writable";
869 QFile writableFile(writableFileName);
870 testFiles.append(t: writableFileName);
871
872 QVERIFY2(writableFile.open(QIODevice::ReadWrite),
873 qPrintable(writableFile.errorString()));
874 }
875
876 {
877 QFile readOnlyFile(entrylistPath + "file");
878 QVERIFY2(readOnlyFile.setPermissions(QFile::ReadOwner | QFile::ReadUser),
879 qPrintable(readOnlyFile.errorString()));
880 }
881
882
883#ifndef Q_NO_SYMLINKS
884#if defined(Q_OS_WIN)
885 // ### Sadly, this is a platform difference right now.
886 // Note we are using capital L in entryList on one side here, to test case-insensitivity
887 const QVector<QPair<QString, QString> > symLinks =
888 {
889 {m_dataPath + "/entryList/file", entrylistPath + "linktofile.lnk"},
890 {m_dataPath + "/entryList/directory", entrylistPath + "linktodirectory.lnk"},
891 {m_dataPath + "/entryList/nothing", entrylistPath + "brokenlink.lnk"}
892 };
893#else
894 const QVector<QPair<QString, QString> > symLinks =
895 {
896 {"file", entrylistPath + "linktofile.lnk"},
897 {"directory", entrylistPath + "linktodirectory.lnk"},
898 {"nothing", entrylistPath + "brokenlink.lnk"}
899 };
900#endif
901 for (const auto &symLink : symLinks) {
902 QVERIFY2(QFile::link(symLink.first, symLink.second),
903 qPrintable(symLink.first + "->" + symLink.second));
904 testFiles.append(t: symLink.second);
905 }
906#endif //Q_NO_SYMLINKS
907
908 QDir dir(dirName);
909 QVERIFY2(dir.exists(), msgDoesNotExist(dirName).constData());
910
911 QStringList actual = dir.entryList(nameFilters, filters: (QDir::Filters)filterspec,
912 sort: (QDir::SortFlags)sortspec);
913
914 bool doContentCheck = true;
915#if defined(Q_OS_UNIX)
916 if (qstrcmp(str1: QTest::currentDataTag(), str2: "QDir::AllEntries | QDir::Writable") == 0) {
917 // for root, everything is writeable
918 if (::getuid() == 0)
919 doContentCheck = false;
920 }
921#endif
922
923 for (int i = testFiles.size() - 1; i >= 0; --i)
924 QVERIFY2(QFile::remove(testFiles.at(i)), qPrintable(testFiles.at(i)));
925
926 if (doContentCheck)
927 QCOMPARE(actual, expected);
928}
929
930void tst_QDir::entryListTimedSort()
931{
932#if QT_CONFIG(process)
933 const QString touchBinary = "/bin/touch";
934 if (!QFile::exists(fileName: touchBinary))
935 QSKIP("/bin/touch not found");
936
937 const QString entrylistPath = m_dataPath + "/entrylist/";
938 QTemporaryFile aFile(entrylistPath + "A-XXXXXX.qws");
939 QTemporaryFile bFile(entrylistPath + "B-XXXXXX.qws");
940
941 QVERIFY2(aFile.open(), qPrintable(aFile.errorString()));
942 QVERIFY2(bFile.open(), qPrintable(bFile.errorString()));
943 {
944 QProcess p;
945 p.start(program: touchBinary, arguments: QStringList() << "-t" << "201306021513" << aFile.fileName());
946 QVERIFY(p.waitForFinished(1000));
947 }
948 {
949 QProcess p;
950 p.start(program: touchBinary, arguments: QStringList() << "-t" << "201504131513" << bFile.fileName());
951 QVERIFY(p.waitForFinished(1000));
952 }
953
954 QStringList actual = QDir(entrylistPath).entryList(nameFilters: QStringList() << "*.qws", filters: QDir::NoFilter,
955 sort: QDir::Time);
956
957 QFileInfo aFileInfo(aFile);
958 QFileInfo bFileInfo(bFile);
959 QVERIFY(bFileInfo.lastModified().msecsTo(aFileInfo.lastModified()) < 0);
960
961 QCOMPARE(actual.size(), 2);
962 QCOMPARE(actual.first(), bFileInfo.fileName());
963 QCOMPARE(actual.last(), aFileInfo.fileName());
964#else
965 QSKIP("This test requires QProcess support.");
966#endif // QT_CONFIG(process)
967}
968
969void tst_QDir::entryListSimple_data()
970{
971 QTest::addColumn<QString>(name: "dirName");
972 QTest::addColumn<int>(name: "countMin");
973
974 QTest::newRow(dataTag: "data2") << "do_not_expect_this_path_to_exist/" << 0;
975 QTest::newRow(dataTag: "simple dir") << (m_dataPath + "/resources") << 2;
976 QTest::newRow(dataTag: "simple dir with slash") << (m_dataPath + "/resources/") << 2;
977
978#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
979 const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName();
980 QTest::newRow("unc 1") << uncRoot << 2;
981 QTest::newRow("unc 2") << uncRoot + QLatin1Char('/') << 2;
982 QTest::newRow("unc 3") << uncRoot + "/testshare" << 2;
983 QTest::newRow("unc 4") << uncRoot + "/testshare/" << 2;
984 QTest::newRow("unc 5") << uncRoot + "/testshare/tmp" << 2;
985 QTest::newRow("unc 6") << uncRoot + "/testshare/tmp/" << 2;
986 QTest::newRow("unc 7") << uncRoot + "/testshare/adirthatshouldnotexist" << 0;
987 QTest::newRow("unc 8") << uncRoot + "/asharethatshouldnotexist" << 0;
988 QTest::newRow("unc 9") << "//ahostthatshouldnotexist" << 0;
989#endif
990}
991
992static QByteArray msgEntryListFailed(int actual, int expectedMin, const QString &name)
993{
994 return QByteArray::number(actual) + " < " + QByteArray::number(expectedMin) + " in \""
995 + QFile::encodeName(fileName: QDir::toNativeSeparators(pathName: name)) + '"';
996}
997
998void tst_QDir::entryListSimple()
999{
1000 QFETCH(QString, dirName);
1001 QFETCH(int, countMin);
1002
1003 QDir dir(dirName);
1004 QStringList actual = dir.entryList();
1005 QVERIFY2(actual.count() >= countMin, msgEntryListFailed(actual.count(), countMin, dirName).constData());
1006}
1007
1008void tst_QDir::entryListWithSymLinks()
1009{
1010#ifndef Q_NO_SYMLINKS
1011# ifndef Q_NO_SYMLINKS_TO_DIRS
1012 QFile::remove(fileName: "myLinkToDir.lnk");
1013# endif
1014 QFile::remove(fileName: "myLinkToFile.lnk");
1015 QFile::remove(fileName: "testfile.cpp");
1016 QDir dir;
1017 dir.mkdir(dirName: "myDir");
1018 QFile("testfile.cpp").open(flags: QIODevice::WriteOnly);
1019# ifndef Q_NO_SYMLINKS_TO_DIRS
1020 QVERIFY(QFile::link("myDir", "myLinkToDir.lnk"));
1021# endif
1022 QVERIFY(QFile::link("testfile.cpp", "myLinkToFile.lnk"));
1023
1024 {
1025 QStringList entryList = QDir().entryList();
1026 QVERIFY(entryList.contains("myDir"));
1027# ifndef Q_NO_SYMLINKS_TO_DIRS
1028 QVERIFY(entryList.contains("myLinkToDir.lnk"));
1029#endif
1030 QVERIFY(entryList.contains("myLinkToFile.lnk"));
1031 }
1032 {
1033 QStringList entryList = QDir().entryList(filters: QDir::Dirs);
1034 QVERIFY(entryList.contains("myDir"));
1035# ifndef Q_NO_SYMLINKS_TO_DIRS
1036 QVERIFY(entryList.contains("myLinkToDir.lnk"));
1037#endif
1038 QVERIFY(!entryList.contains("myLinkToFile.lnk"));
1039 }
1040 {
1041 QStringList entryList = QDir().entryList(filters: QDir::Dirs | QDir::NoSymLinks);
1042 QVERIFY(entryList.contains("myDir"));
1043 QVERIFY(!entryList.contains("myLinkToDir.lnk"));
1044 QVERIFY(!entryList.contains("myLinkToFile.lnk"));
1045 }
1046
1047 QFile::remove(fileName: "myLinkToDir.lnk");
1048 QFile::remove(fileName: "myLinkToFile.lnk");
1049 QFile::remove(fileName: "testfile.cpp");
1050 dir.rmdir(dirName: "myDir");
1051#endif
1052}
1053
1054void tst_QDir::canonicalPath_data()
1055{
1056 QTest::addColumn<QString>(name: "path");
1057 QTest::addColumn<QString>(name: "canonicalPath");
1058
1059 QTest::newRow(dataTag: "relative") << "." << m_dataPath;
1060 QTest::newRow(dataTag: "relativeSubDir") << "./testData/../testData" << m_dataPath + "/testData";
1061#ifndef Q_OS_WIN
1062 QTest::newRow(dataTag: "absPath") << m_dataPath + "/testData/../testData" << m_dataPath + "/testData";
1063#else
1064 QTest::newRow("absPath") << m_dataPath + "\\testData\\..\\testData" << m_dataPath + "/testData";
1065#endif
1066 QTest::newRow(dataTag: "nonexistant") << "testd" << QString();
1067
1068 QTest::newRow(dataTag: "rootPath") << QDir::rootPath() << QDir::rootPath();
1069 QTest::newRow(dataTag: "rootPath + ./") << QDir::rootPath().append(s: "./") << QDir::rootPath();
1070 QTest::newRow(dataTag: "rootPath + ../.. ") << QDir::rootPath().append(s: "../..") << QDir::rootPath();
1071#if defined(Q_OS_WIN)
1072 QTest::newRow("drive:\\") << QDir::toNativeSeparators(QDir::rootPath()) << QDir::rootPath();
1073 QTest::newRow("drive:\\.\\") << QDir::toNativeSeparators(QDir::rootPath().append("./")) << QDir::rootPath();
1074 QTest::newRow("drive:\\..\\..") << QDir::toNativeSeparators(QDir::rootPath().append("../..")) << QDir::rootPath();
1075 QTest::newRow("drive:") << QDir().canonicalPath().left(2) << QDir().canonicalPath();
1076#endif
1077
1078 QTest::newRow(dataTag: "resource") << ":/tst_qdir/resources/entryList" << ":/tst_qdir/resources/entryList";
1079}
1080
1081void tst_QDir::canonicalPath()
1082{
1083 QDir dataDir(m_dataPath);
1084 if (dataDir.absolutePath() != dataDir.canonicalPath())
1085 QSKIP("This test does not work if this directory path consists of symlinks.");
1086
1087 QString oldpwd = QDir::currentPath();
1088 QDir::setCurrent(dataDir.absolutePath());
1089
1090 QFETCH(QString, path);
1091 QFETCH(QString, canonicalPath);
1092
1093 QDir dir(path);
1094#if defined(Q_OS_WIN)
1095 QCOMPARE(dir.canonicalPath().toLower(), canonicalPath.toLower());
1096#else
1097 QCOMPARE(dir.canonicalPath(), canonicalPath);
1098#endif
1099
1100 QDir::setCurrent(oldpwd);
1101}
1102
1103void tst_QDir::current_data()
1104{
1105 QTest::addColumn<QString>(name: "path");
1106 QTest::addColumn<QString>(name: "currentDir");
1107
1108 QTest::newRow(dataTag: "startup") << QString() << m_dataPath;
1109 QTest::newRow(dataTag: "relPath") << "testData" << m_dataPath + "/testData";
1110#ifndef Q_OS_WIN
1111 QTest::newRow(dataTag: "absPath") << m_dataPath + "/testData" << m_dataPath + "/testData";
1112#else
1113 QTest::newRow("absPath") << m_dataPath + "\\testData" << m_dataPath + "/testData";
1114#endif
1115 QTest::newRow(dataTag: "nonexistant") << "testd" << QString();
1116
1117 QTest::newRow(dataTag: "parent") << ".." << m_dataPath.left(n: m_dataPath.lastIndexOf(c: '/'));
1118}
1119
1120void tst_QDir::current()
1121{
1122 QString oldDir = QDir::currentPath();
1123 QDir::setCurrent(m_dataPath);
1124 QFETCH(QString, path);
1125 QFETCH(QString, currentDir);
1126
1127 if (!path.isEmpty()) {
1128 bool b = QDir::setCurrent(path);
1129 // If path is non existent, then setCurrent should be false (currentDir is empty in testData)
1130 QCOMPARE(b, !currentDir.isEmpty());
1131 }
1132 if (!currentDir.isEmpty()) {
1133 QDir newCurrent = QDir::current();
1134 QDir::setCurrent(oldDir);
1135#if defined(Q_OS_WIN)
1136 QCOMPARE(newCurrent.absolutePath().toLower(), currentDir.toLower());
1137#else
1138 QCOMPARE(newCurrent.absolutePath(), currentDir);
1139#endif
1140 }
1141
1142 QDir::setCurrent(oldDir);
1143}
1144
1145void tst_QDir::cd_data()
1146{
1147 QTest::addColumn<QString>(name: "startDir");
1148 QTest::addColumn<QString>(name: "cdDir");
1149 QTest::addColumn<bool>(name: "successExpected");
1150 QTest::addColumn<QString>(name: "newDir");
1151
1152 int index = m_dataPath.lastIndexOf(c: QLatin1Char('/'));
1153 QTest::newRow(dataTag: "cdUp") << m_dataPath << ".." << true << m_dataPath.left(n: index==0?1:index);
1154 QTest::newRow(dataTag: "cdUp non existent (relative dir)") << "anonexistingDir" << ".."
1155 << true << m_dataPath;
1156 QTest::newRow(dataTag: "cdUp non existent (absolute dir)") << m_dataPath + "/anonexistingDir" << ".."
1157 << true << m_dataPath;
1158 QTest::newRow(dataTag: "noChange") << m_dataPath << "." << true << m_dataPath;
1159#if defined(Q_OS_WIN) // on windows QDir::root() is usually c:/ but cd "/" will not force it to be root
1160 QTest::newRow("absolute") << m_dataPath << "/" << true << "/";
1161#else
1162 QTest::newRow(dataTag: "absolute") << m_dataPath << "/" << true << QDir::root().absolutePath();
1163#endif
1164 QTest::newRow(dataTag: "non existant") << "." << "../anonexistingdir" << false << m_dataPath;
1165 QTest::newRow(dataTag: "self") << "." << (QString("../") + QFileInfo(m_dataPath).fileName()) << true << m_dataPath;
1166 QTest::newRow(dataTag: "file") << "." << "qdir.pro" << false << m_dataPath;
1167}
1168
1169void tst_QDir::cd()
1170{
1171 QFETCH(QString, startDir);
1172 QFETCH(QString, cdDir);
1173 QFETCH(bool, successExpected);
1174 QFETCH(QString, newDir);
1175
1176 QDir d = startDir;
1177 bool notUsed = d.exists(); // make sure we cache this before so we can see if 'cd' fails to flush this
1178 Q_UNUSED(notUsed);
1179 QCOMPARE(d.cd(cdDir), successExpected);
1180 QCOMPARE(d.absolutePath(), newDir);
1181}
1182
1183void tst_QDir::setNameFilters_data()
1184{
1185 // Effectively copied from entryList2() test
1186
1187 QTest::addColumn<QString>(name: "dirName"); // relative from current path or abs
1188 QTest::addColumn<QStringList>(name: "nameFilters");
1189 QTest::addColumn<QStringList>(name: "expected");
1190
1191 QTest::newRow(dataTag: "spaces1") << m_dataPath + "/testdir/spaces" << QStringList("*. bar")
1192 << QStringList("foo. bar");
1193 QTest::newRow(dataTag: "spaces2") << m_dataPath + "/testdir/spaces" << QStringList("*.bar")
1194 << QStringList("foo.bar");
1195 QTest::newRow(dataTag: "spaces3") << m_dataPath + "/testdir/spaces" << QStringList("foo.*")
1196 << QString("foo. bar,foo.bar").split(sep: QLatin1Char(','));
1197 QTest::newRow(dataTag: "files1") << m_dataPath + "/testdir/dir" << QString("*r.cpp *.pro").split(sep: QLatin1Char(' '))
1198 << QString("qdir.pro,qrc_qdir.cpp,tst_qdir.cpp").split(sep: QLatin1Char(','));
1199 QTest::newRow(dataTag: "resources1") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data")
1200 << QString("file1.data,file2.data,file3.data").split(sep: QLatin1Char(','));
1201}
1202
1203void tst_QDir::setNameFilters()
1204{
1205 QFETCH(QString, dirName);
1206 QFETCH(QStringList, nameFilters);
1207 QFETCH(QStringList, expected);
1208
1209 QDir dir(dirName);
1210 QVERIFY2(dir.exists(), msgDoesNotExist(dirName).constData());
1211
1212 dir.setNameFilters(nameFilters);
1213 QStringList actual = dir.entryList();
1214 int max = qMin(a: actual.count(), b: expected.count());
1215
1216 for (int i=0; i<max; ++i)
1217 QCOMPARE(actual[i], expected[i]);
1218 QCOMPARE(actual.count(), expected.count());
1219}
1220
1221void
1222tst_QDir::cleanPath_data()
1223{
1224 QTest::addColumn<QString>(name: "path");
1225 QTest::addColumn<QString>(name: "expected");
1226
1227 QTest::newRow(dataTag: "data0") << "/Users/sam/troll/qt4.0//.." << "/Users/sam/troll";
1228 QTest::newRow(dataTag: "data1") << "/Users/sam////troll/qt4.0//.." << "/Users/sam/troll";
1229 QTest::newRow(dataTag: "data2") << "/" << "/";
1230 QTest::newRow(dataTag: "data2-up") << "/path/.." << "/";
1231 QTest::newRow(dataTag: "data2-above-root") << "/.." << "/..";
1232 QTest::newRow(dataTag: "data3") << QDir::cleanPath(path: "../.") << "..";
1233 QTest::newRow(dataTag: "data4") << QDir::cleanPath(path: "../..") << "../..";
1234#if defined(Q_OS_WIN)
1235 QTest::newRow("data5") << "d:\\a\\bc\\def\\.." << "d:/a/bc";
1236 QTest::newRow("data6") << "d:\\a\\bc\\def\\../../.." << "d:/";
1237#else
1238 QTest::newRow(dataTag: "data5") << "d:\\a\\bc\\def\\.." << "d:\\a\\bc\\def\\..";
1239 QTest::newRow(dataTag: "data6") << "d:\\a\\bc\\def\\../../.." << "..";
1240#endif
1241 QTest::newRow(dataTag: "data7") << ".//file1.txt" << "file1.txt";
1242 QTest::newRow(dataTag: "data8") << "/foo/bar/..//file1.txt" << "/foo/file1.txt";
1243 QTest::newRow(dataTag: "data9") << "//" << "/";
1244#if defined Q_OS_WIN
1245 QTest::newRow("data10") << "c:\\" << "c:/";
1246#else
1247 QTest::newRow(dataTag: "data10") << "/:/" << "/:";
1248#endif
1249#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
1250 QTest::newRow("data11") << "//foo//bar" << "//foo/bar";
1251#endif
1252 QTest::newRow(dataTag: "data12") << "ab/a/" << "ab/a"; // Path item with length of 2
1253#ifdef Q_OS_WIN
1254 QTest::newRow("data13") << "c://" << "c:/";
1255#else
1256 QTest::newRow(dataTag: "data13") << "c://" << "c:";
1257#endif
1258
1259 QTest::newRow(dataTag: "data14") << "c://foo" << "c:/foo";
1260 // Drive letters and unc path in one string
1261#if defined(Q_OS_WINRT)
1262 const QString root = QDir::rootPath(); // has trailing slash
1263 QTest::newRow("root-up") << (root + "path/..") << root;
1264 QTest::newRow("above-root") << (root + "..") << (root + "..");
1265#elif defined(Q_OS_WIN)
1266 QTest::newRow("data15") << "//c:/foo" << "//c:/foo";
1267 QTest::newRow("drive-up") << "A:/path/.." << "A:/";
1268 QTest::newRow("drive-above-root") << "A:/.." << "A:/..";
1269 QTest::newRow("unc-server-up") << "//server/path/.." << "//server";
1270 QTest::newRow("unc-server-above-root") << "//server/.." << "//server/..";
1271 QTest::newRow("longpath") << "\\\\?\\d:\\" << "d:/";
1272#else
1273 QTest::newRow(dataTag: "data15") << "//c:/foo" << "/c:/foo";
1274#endif // non-windows
1275
1276 QTest::newRow(dataTag: "QTBUG-23892_0") << "foo/.." << ".";
1277 QTest::newRow(dataTag: "QTBUG-23892_1") << "foo/../" << ".";
1278
1279 QTest::newRow(dataTag: "QTBUG-3472_0") << "/foo/./bar" << "/foo/bar";
1280 QTest::newRow(dataTag: "QTBUG-3472_1") << "./foo/.." << ".";
1281 QTest::newRow(dataTag: "QTBUG-3472_2") << "./foo/../" << ".";
1282
1283 QTest::newRow(dataTag: "resource0") << ":/prefix/foo.bar" << ":/prefix/foo.bar";
1284 QTest::newRow(dataTag: "resource1") << "://prefix/..//prefix/foo.bar" << ":/prefix/foo.bar";
1285}
1286
1287
1288void
1289tst_QDir::cleanPath()
1290{
1291 QFETCH(QString, path);
1292 QFETCH(QString, expected);
1293 QString cleaned = QDir::cleanPath(path);
1294 QCOMPARE(cleaned, expected);
1295}
1296
1297#ifdef QT_BUILD_INTERNAL
1298void tst_QDir::normalizePathSegments_data()
1299{
1300 QTest::addColumn<QString>(name: "path");
1301 QTest::addColumn<UncHandling>(name: "uncHandling");
1302 QTest::addColumn<QString>(name: "expected");
1303
1304 QTest::newRow(dataTag: "data0") << "/Users/sam/troll/qt4.0//.." << HandleUnc << "/Users/sam/troll";
1305 QTest::newRow(dataTag: "data1") << "/Users/sam////troll/qt4.0//.." << HandleUnc << "/Users/sam/troll";
1306 QTest::newRow(dataTag: "data2") << "/" << HandleUnc << "/";
1307 QTest::newRow(dataTag: "data3") << "//" << HandleUnc << "//";
1308 QTest::newRow(dataTag: "data4") << "//" << IgnoreUnc << "/";
1309 QTest::newRow(dataTag: "data5") << "/." << HandleUnc << "/";
1310 QTest::newRow(dataTag: "data6") << "/./" << HandleUnc << "/";
1311 QTest::newRow(dataTag: "data7") << "/.." << HandleUnc << "/..";
1312 QTest::newRow(dataTag: "data8") << "/../" << HandleUnc << "/../";
1313 QTest::newRow(dataTag: "data9") << "." << HandleUnc << ".";
1314 QTest::newRow(dataTag: "data10") << "./" << HandleUnc << "./";
1315 QTest::newRow(dataTag: "data11") << "./." << HandleUnc << ".";
1316 QTest::newRow(dataTag: "data12") << "././" << HandleUnc << "./";
1317 QTest::newRow(dataTag: "data13") << ".." << HandleUnc << "..";
1318 QTest::newRow(dataTag: "data14") << "../" << HandleUnc << "../";
1319 QTest::newRow(dataTag: "data15") << "../." << HandleUnc << "..";
1320 QTest::newRow(dataTag: "data16") << ".././" << HandleUnc << "../";
1321 QTest::newRow(dataTag: "data17") << "../.." << HandleUnc << "../..";
1322 QTest::newRow(dataTag: "data18") << "../../" << HandleUnc << "../../";
1323 QTest::newRow(dataTag: "data19") << ".//file1.txt" << HandleUnc << "file1.txt";
1324 QTest::newRow(dataTag: "data20") << "/foo/bar/..//file1.txt" << HandleUnc << "/foo/file1.txt";
1325 QTest::newRow(dataTag: "data21") << "foo/.." << HandleUnc << ".";
1326 QTest::newRow(dataTag: "data22") << "./foo/.." << HandleUnc << ".";
1327 QTest::newRow(dataTag: "data23") << ".foo/.." << HandleUnc << ".";
1328 QTest::newRow(dataTag: "data24") << "foo/bar/../.." << HandleUnc << ".";
1329 QTest::newRow(dataTag: "data25") << "./foo/bar/../.." << HandleUnc << ".";
1330 QTest::newRow(dataTag: "data26") << "../foo/bar" << HandleUnc << "../foo/bar";
1331 QTest::newRow(dataTag: "data27") << "./../foo/bar" << HandleUnc << "../foo/bar";
1332 QTest::newRow(dataTag: "data28") << "../../foo/../bar" << HandleUnc << "../../bar";
1333 QTest::newRow(dataTag: "data29") << "./foo/bar/.././.." << HandleUnc << ".";
1334 QTest::newRow(dataTag: "data30") << "/./foo" << HandleUnc << "/foo";
1335 QTest::newRow(dataTag: "data31") << "/../foo/" << HandleUnc << "/../foo/";
1336 QTest::newRow(dataTag: "data32") << "c:/" << HandleUnc << "c:/";
1337 QTest::newRow(dataTag: "data33") << "c://" << HandleUnc << "c:/";
1338 QTest::newRow(dataTag: "data34") << "c://foo" << HandleUnc << "c:/foo";
1339 QTest::newRow(dataTag: "data35") << "c:" << HandleUnc << "c:";
1340 QTest::newRow(dataTag: "data36") << "c:foo/bar" << IgnoreUnc << "c:foo/bar";
1341#if defined Q_OS_WIN
1342 QTest::newRow("data37") << "c:/." << HandleUnc << "c:/";
1343 QTest::newRow("data38") << "c:/.." << HandleUnc << "c:/..";
1344 QTest::newRow("data39") << "c:/../" << HandleUnc << "c:/../";
1345#else
1346 QTest::newRow(dataTag: "data37") << "c:/." << HandleUnc << "c:";
1347 QTest::newRow(dataTag: "data38") << "c:/.." << HandleUnc << ".";
1348 QTest::newRow(dataTag: "data39") << "c:/../" << HandleUnc << "./";
1349#endif
1350 QTest::newRow(dataTag: "data40") << "c:/./" << HandleUnc << "c:/";
1351 QTest::newRow(dataTag: "data41") << "foo/../foo/.." << HandleUnc << ".";
1352 QTest::newRow(dataTag: "data42") << "foo/../foo/../.." << HandleUnc << "..";
1353 QTest::newRow(dataTag: "data43") << "..foo.bar/foo" << HandleUnc << "..foo.bar/foo";
1354 QTest::newRow(dataTag: "data44") << ".foo./bar/.." << HandleUnc << ".foo.";
1355 QTest::newRow(dataTag: "data45") << "foo/..bar.." << HandleUnc << "foo/..bar..";
1356 QTest::newRow(dataTag: "data46") << "foo/.bar./.." << HandleUnc << "foo";
1357 QTest::newRow(dataTag: "data47") << "//foo//bar" << HandleUnc << "//foo/bar";
1358 QTest::newRow(dataTag: "data48") << "..." << HandleUnc << "...";
1359 QTest::newRow(dataTag: "data49") << "foo/.../bar" << HandleUnc << "foo/.../bar";
1360 QTest::newRow(dataTag: "data50") << "ab/a/" << HandleUnc << "ab/a/"; // Path item with length of 2
1361 // Drive letters and unc path in one string. The drive letter isn't handled as a drive letter
1362 // but as a host name in this case (even though Windows host names can't contain a ':')
1363 QTest::newRow(dataTag: "data51") << "//c:/foo" << HandleUnc << "//c:/foo";
1364 QTest::newRow(dataTag: "data52") << "//c:/foo" << IgnoreUnc << "/c:/foo";
1365
1366 QTest::newRow(dataTag: "resource0") << ":/prefix/foo.bar" << HandleUnc << ":/prefix/foo.bar";
1367 QTest::newRow(dataTag: "resource1") << "://prefix/..//prefix/foo.bar" << HandleUnc << ":/prefix/foo.bar";
1368}
1369
1370void tst_QDir::normalizePathSegments()
1371{
1372 QFETCH(QString, path);
1373 QFETCH(UncHandling, uncHandling);
1374 QFETCH(QString, expected);
1375 QString cleaned = qt_normalizePathSegments(name: path, flags: uncHandling == HandleUnc ? QDirPrivate::AllowUncPaths : QDirPrivate::DefaultNormalization);
1376 QCOMPARE(cleaned, expected);
1377 if (path == expected)
1378 QVERIFY2(path.isSharedWith(cleaned), "Strings are same but data is not shared");
1379}
1380# endif //QT_BUILD_INTERNAL
1381
1382void tst_QDir::absoluteFilePath_data()
1383{
1384 QTest::addColumn<QString>(name: "path");
1385 QTest::addColumn<QString>(name: "fileName");
1386 QTest::addColumn<QString>(name: "expectedFilePath");
1387
1388#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
1389 QTest::newRow("UNC-rel") << "//machine/share" << "dir" << "//machine/share/dir";
1390 QTest::newRow("UNC-abs") << "//machine/share/path/to/blah" << "/dir" << "//machine/share/dir";
1391 QTest::newRow("UNC-UNC") << "//machine/share/path/to/blah" << "//host/share/path" << "//host/share/path";
1392 QTest::newRow("Drive-UNC") << "c:/side/town" << "//host/share/path" << "//host/share/path";
1393 QTest::newRow("Drive-LTUNC") << "c:/side/town" << "\\/leaning\\toothpick/path" << "\\/leaning\\toothpick/path";
1394 QTest::newRow("Drive-abs") << "c:/side/town" << "/my/way/home" << "c:/my/way/home";
1395#endif
1396
1397 QTest::newRow(dataTag: "0") << DRIVE "/etc" << "/passwd" << DRIVE "/passwd";
1398 QTest::newRow(dataTag: "1") << DRIVE "/etc" << "passwd" << DRIVE "/etc/passwd";
1399 QTest::newRow(dataTag: "2") << DRIVE "/" << "passwd" << DRIVE "/passwd";
1400 QTest::newRow(dataTag: "3") << "relative" << "path" << QDir::currentPath() + "/relative/path";
1401 QTest::newRow(dataTag: "4") << "" << "" << QDir::currentPath();
1402
1403 // Resource paths are absolute:
1404 QTest::newRow(dataTag: "resource-rel") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar";
1405 QTest::newRow(dataTag: "abs-res-res") << ":/prefix" << ":/abc.txt" << ":/abc.txt";
1406 QTest::newRow(dataTag: "abs-res-path") << DRIVE "/etc" << ":/abc.txt" << ":/abc.txt";
1407}
1408
1409void tst_QDir::absoluteFilePath()
1410{
1411 QFETCH(QString, path);
1412 QFETCH(QString, fileName);
1413 QFETCH(QString, expectedFilePath);
1414
1415 QDir dir(path);
1416 QString absFilePath = dir.absoluteFilePath(fileName);
1417 QCOMPARE(absFilePath, expectedFilePath);
1418}
1419
1420void tst_QDir::absolutePath_data()
1421{
1422 QTest::addColumn<QString>(name: "path");
1423 QTest::addColumn<QString>(name: "expectedPath");
1424
1425 QTest::newRow(dataTag: "0") << "/machine/share/dir1" << "/machine/share/dir1";
1426#if (defined(Q_OS_WIN) && !defined(Q_OS_WINRT))
1427 QTest::newRow("1") << "\\machine\\share\\dir1" << "/machine/share/dir1";
1428 QTest::newRow("2") << "//machine/share/dir1" << "//machine/share/dir1";
1429 QTest::newRow("3") << "\\\\machine\\share\\dir1" << "//machine/share/dir1";
1430 QTest::newRow("4") << "c:/machine/share/dir1" << "c:/machine/share/dir1";
1431 QTest::newRow("5") << "c:\\machine\\share\\dir1" << "c:/machine/share/dir1";
1432#endif
1433 //test dirty paths are cleaned (QTBUG-19995)
1434 QTest::newRow(dataTag: "/home/qt/.") << QDir::rootPath() + "home/qt/." << QDir::rootPath() + "home/qt";
1435 QTest::newRow(dataTag: "/system/data/../config") << QDir::rootPath() + "system/data/../config" << QDir::rootPath() + "system/config";
1436 QTest::newRow(dataTag: "//home//qt/") << QDir::rootPath() + "/home//qt/" << QDir::rootPath() + "home/qt";
1437 QTest::newRow(dataTag: "foo/../bar") << "foo/../bar" << QDir::currentPath() + "/bar";
1438 QTest::newRow(dataTag: "resource") << ":/prefix/foo.bar" << ":/prefix/foo.bar";
1439}
1440
1441void tst_QDir::absolutePath()
1442{
1443 QFETCH(QString, path);
1444 QFETCH(QString, expectedPath);
1445
1446 QDir dir(path);
1447 QCOMPARE(dir.absolutePath(), expectedPath);
1448}
1449
1450void tst_QDir::relativeFilePath_data()
1451{
1452 QTest::addColumn<QString>(name: "dir");
1453 QTest::addColumn<QString>(name: "path");
1454 QTest::addColumn<QString>(name: "expected");
1455
1456 QTest::newRow(dataTag: "0") << "/foo/bar" << "ding.txt" << "ding.txt";
1457 QTest::newRow(dataTag: "1") << "/foo/bar" << "ding/dong.txt" << "ding/dong.txt";
1458 QTest::newRow(dataTag: "2") << "/foo/bar" << "../ding/dong.txt" << "../ding/dong.txt";
1459
1460 QTest::newRow(dataTag: "3") << "/foo/bar" << "/foo/bar/ding.txt" << "ding.txt";
1461 QTest::newRow(dataTag: "4") << "/foo/bar/" << "/foo/bar/ding/dong.txt" << "ding/dong.txt";
1462 QTest::newRow(dataTag: "5") << "/foo/bar/" << "/ding/dong.txt" << "../../ding/dong.txt";
1463
1464 QTest::newRow(dataTag: "6") << "/" << "/ding/dong.txt" << "ding/dong.txt";
1465 QTest::newRow(dataTag: "7") << "/" << "/ding/" << "ding";
1466 QTest::newRow(dataTag: "8") << "/" << "/ding//" << "ding";
1467 QTest::newRow(dataTag: "9") << "/" << "/ding/../dong" << "dong";
1468 QTest::newRow(dataTag: "10") << "/" << "/ding/../../../../dong" << "../../../dong";
1469
1470 QTest::newRow(dataTag: "11") << "" << "" << "";
1471
1472 QTest::newRow(dataTag: "same path 1") << "/tmp" << "/tmp" << ".";
1473 QTest::newRow(dataTag: "same path 2") << "//tmp" << "/tmp/" << ".";
1474
1475#if defined(Q_OS_WIN)
1476 QTest::newRow("12") << "C:/foo/bar" << "ding" << "ding";
1477 QTest::newRow("13") << "C:/foo/bar" << "C:/ding/dong" << "../../ding/dong";
1478 QTest::newRow("14") << "C:/foo/bar" << "/ding/dong" << "../../ding/dong";
1479 QTest::newRow("15") << "C:/foo/bar" << "D:/ding/dong" << "D:/ding/dong";
1480 QTest::newRow("16") << "C:" << "C:/ding/dong" << "ding/dong";
1481 QTest::newRow("17") << "C:/" << "C:/ding/dong" << "ding/dong";
1482 QTest::newRow("18") << "C:" << "C:" << ".";
1483 QTest::newRow("19") << "C:/" << "C:" << ".";
1484 QTest::newRow("20") << "C:" << "C:/" << ".";
1485 QTest::newRow("21") << "C:/" << "C:/" << ".";
1486 QTest::newRow("22") << "C:" << "C:file.txt" << "file.txt";
1487 QTest::newRow("23") << "C:/" << "C:file.txt" << "file.txt";
1488 QTest::newRow("24") << "C:" << "C:/file.txt" << "file.txt";
1489 QTest::newRow("25") << "C:/" << "C:/file.txt" << "file.txt";
1490 QTest::newRow("26") << "C:" << "D:" << "D:";
1491 QTest::newRow("27") << "C:" << "D:/" << "D:/";
1492 QTest::newRow("28") << "C:/" << "D:" << "D:";
1493 QTest::newRow("29") << "C:/" << "D:/" << "D:/";
1494#ifndef Q_OS_WINRT
1495 QTest::newRow("30") << "C:/foo/bar" << "//anotherHost/foo/bar" << "//anotherHost/foo/bar";
1496 QTest::newRow("31") << "//anotherHost/foo" << "//anotherHost/foo/bar" << "bar";
1497 QTest::newRow("32") << "//anotherHost/foo" << "bar" << "bar";
1498 QTest::newRow("33") << "//anotherHost/foo" << "C:/foo/bar" << "C:/foo/bar";
1499#endif // !Q_OS_WINRT
1500#endif
1501
1502 QTest::newRow(dataTag: "resource0") << ":/prefix" << "foo.bar" << "foo.bar";
1503 QTest::newRow(dataTag: "resource1") << ":/prefix" << ":/prefix/foo.bar" << "foo.bar";
1504}
1505
1506void tst_QDir::relativeFilePath()
1507{
1508 QFETCH(QString, dir);
1509 QFETCH(QString, path);
1510 QFETCH(QString, expected);
1511
1512 QCOMPARE(QDir(dir).relativeFilePath(path), expected);
1513}
1514
1515void tst_QDir::filePath_data()
1516{
1517 QTest::addColumn<QString>(name: "path");
1518 QTest::addColumn<QString>(name: "fileName");
1519 QTest::addColumn<QString>(name: "expectedFilePath");
1520
1521 QTest::newRow(dataTag: "abs-abs") << DRIVE "/etc" << DRIVE "/passwd" << DRIVE "/passwd";
1522 QTest::newRow(dataTag: "abs-rel") << DRIVE "/etc" << "passwd" << DRIVE "/etc/passwd";
1523 QTest::newRow(dataTag: "root-rel") << DRIVE "/" << "passwd" << DRIVE "/passwd";
1524 QTest::newRow(dataTag: "rel-rel") << "relative" << "path" << "relative/path";
1525 QTest::newRow(dataTag: "empty-empty") << "" << "" << ".";
1526 QTest::newRow(dataTag: "resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar";
1527#ifdef Q_OS_IOS
1528 QTest::newRow("assets-rel") << "assets-library:/" << "foo/bar.baz" << "assets-library:/foo/bar.baz";
1529 QTest::newRow("assets-abs") << "assets-library:/" << "/foo/bar.baz" << "/foo/bar.baz";
1530 QTest::newRow("abs-assets") << "/some/path" << "assets-library:/foo/bar.baz" << "assets-library:/foo/bar.baz";
1531#endif
1532#ifdef Q_OS_WIN
1533 QTest::newRow("abs-LTUNC") << "Q:/path" << "\\/leaning\\tooth/pick" << "\\/leaning\\tooth/pick";
1534 QTest::newRow("LTUNC-slash") << "\\/leaning\\tooth/pick" << "/path" << "//leaning/tooth/path";
1535 QTest::newRow("LTUNC-abs") << "\\/leaning\\tooth/pick" << "Q:/path" << "Q:/path";
1536#endif
1537}
1538
1539void tst_QDir::filePath()
1540{
1541 QFETCH(QString, path);
1542 QFETCH(QString, fileName);
1543 QFETCH(QString, expectedFilePath);
1544
1545 QDir dir(path);
1546 QString absFilePath = dir.filePath(fileName);
1547 QCOMPARE(absFilePath, expectedFilePath);
1548}
1549
1550void tst_QDir::remove()
1551{
1552 QFile f("remove-test");
1553 f.open(flags: QIODevice::WriteOnly);
1554 f.close();
1555 QDir dir;
1556 QVERIFY(dir.remove("remove-test"));
1557 // Test that the file just removed is gone
1558 QVERIFY(!dir.remove("remove-test"));
1559 QTest::ignoreMessage(type: QtWarningMsg, message: "QDir::remove: Empty or null file name");
1560 QVERIFY(!dir.remove(""));
1561}
1562
1563void tst_QDir::rename()
1564{
1565 QFile f("rename-test");
1566 f.open(flags: QIODevice::WriteOnly);
1567 f.close();
1568 QDir dir;
1569 QVERIFY(dir.rename("rename-test", "rename-test-renamed"));
1570 QVERIFY(dir.rename("rename-test-renamed", "rename-test"));
1571#if defined(Q_OS_MAC)
1572 QVERIFY(!dir.rename("rename-test", "/etc/rename-test-renamed"));
1573#elif !defined(Q_OS_WIN)
1574 // on windows this is possible - maybe make the test a bit better
1575#ifdef Q_OS_UNIX
1576 // not valid if run as root so skip if needed
1577 if (::getuid() != 0)
1578 QVERIFY(!dir.rename("rename-test", "/rename-test-renamed"));
1579#else
1580 QVERIFY(!dir.rename("rename-test", "/rename-test-renamed"));
1581#endif
1582#endif
1583 QTest::ignoreMessage(type: QtWarningMsg, message: "QDir::rename: Empty or null file name(s)");
1584 QVERIFY(!dir.rename("rename-test", ""));
1585 QTest::ignoreMessage(type: QtWarningMsg, message: "QDir::rename: Empty or null file name(s)");
1586 QVERIFY(!dir.rename("", "rename-test-renamed"));
1587 QVERIFY(!dir.rename("some-file-that-does-not-exist", "rename-test-renamed"));
1588
1589 QVERIFY(dir.remove("rename-test"));
1590}
1591
1592void tst_QDir::exists2_data()
1593{
1594 QTest::addColumn<QString>(name: "path");
1595 QTest::addColumn<bool>(name: "exists");
1596
1597 QTest::newRow(dataTag: "0") << "." << true;
1598 QTest::newRow(dataTag: "1") << "/" << true;
1599 QTest::newRow(dataTag: "2") << "" << false;
1600 QTest::newRow(dataTag: "3") << "testData" << true;
1601 QTest::newRow(dataTag: "4") << "/testData" << false;
1602#ifdef Q_OS_WIN
1603 QTest::newRow("abs") << "Q:/testData" << false;
1604#endif
1605 QTest::newRow(dataTag: "5") << "tst_qdir.cpp" << true;
1606 QTest::newRow(dataTag: "6") << "/resources.cpp" << false;
1607 QTest::newRow(dataTag: "resource0") << ":/prefix/foo.bar" << false;
1608 QTest::newRow(dataTag: "resource1") << ":/tst_qdir/resources/entryList/file1.data" << true;
1609}
1610
1611void tst_QDir::exists2()
1612{
1613 QFETCH(QString, path);
1614 QFETCH(bool, exists);
1615
1616 QString oldpwd = QDir::currentPath();
1617 QDir::setCurrent((m_dataPath + "/."));
1618
1619 if (path.isEmpty())
1620 QTest::ignoreMessage(type: QtWarningMsg, message: "QDir::exists: Empty or null file name");
1621
1622 QDir dir;
1623 if (exists)
1624 QVERIFY2(dir.exists(path), msgDoesNotExist(path).constData());
1625 else
1626 QVERIFY(!dir.exists(path));
1627
1628 QDir::setCurrent(oldpwd);
1629}
1630
1631void tst_QDir::dirName_data()
1632{
1633 QTest::addColumn<QString>(name: "path");
1634 QTest::addColumn<QString>(name: "dirName");
1635
1636 QTest::newRow(dataTag: "slash0") << "c:/winnt/system32" << "system32";
1637 QTest::newRow(dataTag: "slash1") << "/winnt/system32" << "system32";
1638 QTest::newRow(dataTag: "slash2") << "c:/winnt/system32/kernel32.dll" << "kernel32.dll";
1639#if defined(Q_OS_WIN)
1640 QTest::newRow("bslash0") << "c:\\winnt\\system32" << "system32";
1641 QTest::newRow("bslash1") << "\\winnt\\system32" << "system32";
1642 QTest::newRow("bslash2") << "c:\\winnt\\system32\\kernel32.dll" << "kernel32.dll";
1643#endif
1644
1645 QTest::newRow(dataTag: "resource") << ":/prefix" << "prefix";
1646}
1647
1648void tst_QDir::dirName()
1649{
1650 QFETCH(QString, path);
1651 QFETCH(QString, dirName);
1652
1653 QDir dir(path);
1654 QCOMPARE(dir.dirName(), dirName);
1655}
1656
1657void tst_QDir::operator_eq()
1658{
1659 QDir dir1(".");
1660 dir1 = dir1;
1661 dir1.setPath("..");
1662}
1663
1664// WinCE does not have . nor ..
1665void tst_QDir::dotAndDotDot()
1666{
1667 QDir dir(QString((m_dataPath + "/testdir/")));
1668 QStringList entryList = dir.entryList(filters: QDir::Dirs);
1669 QCOMPARE(entryList, QStringList() << QString(".") << QString("..") << QString("dir") << QString("spaces"));
1670 entryList = dir.entryList(filters: QDir::Dirs | QDir::NoDotAndDotDot);
1671 QCOMPARE(entryList, QStringList() << QString("dir") << QString("spaces"));
1672}
1673
1674void tst_QDir::homePath()
1675{
1676 QDir homeDir = QDir::home();
1677 QString strHome = QDir::homePath();
1678
1679 // docs say that homePath() is an absolute path
1680 QCOMPARE(strHome, homeDir.absolutePath());
1681 QVERIFY(QDir::isAbsolutePath(strHome));
1682
1683#ifdef Q_OS_UNIX
1684 if (strHome.length() > 1) // root dir = "/"
1685 QVERIFY(!strHome.endsWith('/'));
1686
1687 QByteArray envHome = qgetenv(varName: "HOME");
1688 unsetenv(name: "HOME");
1689 QCOMPARE(QDir::homePath(), QDir::rootPath());
1690 qputenv(varName: "HOME", value: envHome);
1691
1692#elif defined(Q_OS_WIN)
1693 if (strHome.length() > 3 // root dir = "c:/"; "//" is not really valid...
1694#if defined(Q_OS_WINRT)
1695 && strHome.length() > QDir::rootPath().length()
1696#endif
1697 )
1698 QVERIFY(!strHome.endsWith('/'));
1699#endif
1700
1701 QStringList entries = homeDir.entryList();
1702 for (int i = 0; i < entries.count(); ++i) {
1703 QFileInfo fi(QDir::homePath() + "/" + entries[i]);
1704 QCOMPARE(fi.exists(), true);
1705 }
1706}
1707
1708void tst_QDir::tempPath()
1709{
1710 QDir dir = QDir::temp();
1711 QString path = QDir::tempPath();
1712
1713 // docs say that tempPath() is an absolute path
1714 QCOMPARE(path, dir.absolutePath());
1715 QVERIFY(QDir::isAbsolutePath(path));
1716
1717#ifdef Q_OS_UNIX
1718 if (path.length() > 1) // root dir = "/"
1719 QVERIFY(!path.endsWith('/'));
1720#elif defined(Q_OS_WIN)
1721 if (path.length() > 3) // root dir = "c:/"; "//" is not really valid...
1722 QVERIFY(!path.endsWith('/'));
1723 QVERIFY2(!path.contains(QLatin1Char('~')),
1724 qPrintable(QString::fromLatin1("Temp path (%1) must not be a short name.").arg(path)));
1725#endif
1726}
1727
1728void tst_QDir::rootPath()
1729{
1730 QDir dir = QDir::root();
1731 QString path = QDir::rootPath();
1732
1733 // docs say that tempPath() is an absolute path
1734 QCOMPARE(path, dir.absolutePath());
1735 QVERIFY(QDir::isAbsolutePath(path));
1736
1737#if defined(Q_OS_UNIX)
1738 QCOMPARE(path, QString("/"));
1739#endif
1740}
1741
1742void tst_QDir::nativeSeparators()
1743{
1744#if defined(Q_OS_WIN)
1745 QCOMPARE(QDir::toNativeSeparators(QLatin1String("/")), QString("\\"));
1746 QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\"));
1747 QCOMPARE(QDir::fromNativeSeparators(QLatin1String("/")), QString("/"));
1748 QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("/"));
1749 QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\\\?\\C:\\")), QString("C:/"));
1750#else
1751 QCOMPARE(QDir::toNativeSeparators(QLatin1String("/")), QString("/"));
1752 QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\"));
1753 QCOMPARE(QDir::fromNativeSeparators(QLatin1String("/")), QString("/"));
1754 QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("\\"));
1755#endif
1756}
1757
1758void tst_QDir::searchPaths_data()
1759{
1760 QTest::addColumn<QString>(name: "filename");
1761 QTest::addColumn<QString>(name: "searchPathPrefixes");
1762 QTest::addColumn<QString>(name: "searchPaths");
1763 QTest::addColumn<QString>(name: "expectedAbsolutePath");
1764
1765 QString searchDir = (m_dataPath + "/searchdir");
1766 QString srcdir = QFileInfo(searchDir).absolutePath();
1767
1768 // sanity
1769 QTest::newRow(dataTag: "nopath") << "picker.png" << QString() << QString() << QString();
1770 QTest::newRow(dataTag: "emptysearchpath") << "subdir1/picker.png" << QString() << QString() << QString();
1771 QTest::newRow(dataTag: "searchpathwithoutprefix") << (m_dataPath + "/searchdir/subdir1/picker.png") << QString("searchpath") << QString("searchdir") << (searchDir+"/subdir1/picker.png");
1772
1773 // new
1774 QTest::newRow(dataTag: "novalidsearchpath") << "searchpath:subdir1/picker.png" << QString() << QString() << QString();
1775 QTest::newRow(dataTag: "invalidsearchpath") << "searchpath:subdir1/picker.png" << QString("invalid") << QString("invalid") << QString();
1776 QTest::newRow(dataTag: "onlyvalidsearchpath") << "searchpath:subdir1/picker.png" << QString("searchpath") << QString((m_dataPath + "/searchdir")) << (searchDir+"/subdir1/picker.png");
1777 QTest::newRow(dataTag: "validandinvalidsearchpath") << "searchpath:subdir1/picker.png" << QString("invalid;searchpath") << ("invalid;" + (m_dataPath + "/searchdir")) << (searchDir+"/subdir1/picker.png");
1778 QTest::newRow(dataTag: "precedence1") << "searchpath:picker.png" << QString("invalid;searchpath") << ("invalid;" + (m_dataPath + "/searchdir/subdir1") + "," + (m_dataPath + "/searchdir/subdir2")) << (searchDir+"/subdir1/picker.png");
1779 QTest::newRow(dataTag: "precedence2") << "searchpath:picker.png" << QString("invalid;searchpath") << ("invalid;" + (m_dataPath + "/searchdir/subdir2") + "," + (m_dataPath + "/searchdir/subdir1")) << (searchDir+"/subdir2/picker.png");
1780 QTest::newRow(dataTag: "precedence3") << "searchpath2:picker.png" << QString("searchpath1;searchpath2") << ((m_dataPath + "/searchdir/subdir1") + ";" + (m_dataPath + "/searchdir/subdir2")) << (searchDir+"/subdir2/picker.png");
1781
1782 // re
1783}
1784
1785void tst_QDir::searchPaths()
1786{
1787 QFETCH(QString, filename);
1788 QFETCH(QString, searchPathPrefixes);
1789 QStringList searchPathPrefixList = searchPathPrefixes.split(sep: ";", behavior: Qt::SkipEmptyParts);
1790 QFETCH(QString, searchPaths);
1791 QStringList searchPathsList = searchPaths.split(sep: ";", behavior: Qt::SkipEmptyParts);
1792 QFETCH(QString, expectedAbsolutePath);
1793 bool exists = !expectedAbsolutePath.isEmpty();
1794
1795 for (int i = 0; i < searchPathPrefixList.count(); ++i) {
1796 QDir::setSearchPaths(prefix: searchPathPrefixList.at(i), searchPaths: searchPathsList.at(i).split(sep: ","));
1797 }
1798 for (int i = 0; i < searchPathPrefixList.count(); ++i) {
1799 QCOMPARE(QDir::searchPaths(searchPathPrefixList.at(i)), searchPathsList.at(i).split(","));
1800 }
1801
1802 QCOMPARE(QFile(filename).exists(), exists);
1803 QCOMPARE(QFileInfo(filename).exists(), exists);
1804
1805 if (exists) {
1806 QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath);
1807 }
1808
1809 for (int i = 0; i < searchPathPrefixList.count(); ++i) {
1810 QDir::setSearchPaths(prefix: searchPathPrefixList.at(i), searchPaths: QStringList());
1811 }
1812 for (int i = 0; i < searchPathPrefixList.count(); ++i) {
1813 QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty());
1814 }
1815
1816 for (int i = 0; i < searchPathPrefixList.count(); ++i) {
1817 foreach (QString path, searchPathsList.at(i).split(",")) {
1818 QDir::addSearchPath(prefix: searchPathPrefixList.at(i), path);
1819 }
1820 }
1821 for (int i = 0; i < searchPathPrefixList.count(); ++i) {
1822 QCOMPARE(QDir::searchPaths(searchPathPrefixList.at(i)), searchPathsList.at(i).split(","));
1823 }
1824
1825 QCOMPARE(QFile(filename).exists(), exists);
1826 QCOMPARE(QFileInfo(filename).exists(), exists);
1827
1828 if (exists) {
1829 QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath);
1830 }
1831
1832 for (int i = 0; i < searchPathPrefixList.count(); ++i) {
1833 QDir::setSearchPaths(prefix: searchPathPrefixList.at(i), searchPaths: QStringList());
1834 }
1835 for (int i = 0; i < searchPathPrefixList.count(); ++i) {
1836 QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty());
1837 }
1838}
1839
1840void tst_QDir::entryListWithSearchPaths()
1841{
1842 QDir realDir(":/tst_qdir/resources/entryList");
1843 QVERIFY(realDir.exists());
1844 QVERIFY(!realDir.entryList().isEmpty());
1845 QVERIFY(realDir.entryList().contains("file3.data"));
1846
1847 QDir::setSearchPaths(prefix: "searchpath", searchPaths: QStringList(":/tst_qdir/resources"));
1848 QDir dir("searchpath:entryList/");
1849 QCOMPARE(dir.path(), QString(":/tst_qdir/resources/entryList"));
1850 QVERIFY(dir.exists());
1851 QStringList entryList = dir.entryList();
1852 QVERIFY(entryList.contains("file3.data"));
1853}
1854
1855void tst_QDir::longFileName_data()
1856{
1857 QTest::addColumn<int>(name: "length");
1858
1859 QTest::newRow(dataTag: "128") << 128;
1860 QTest::newRow(dataTag: "256") << 256;
1861 QTest::newRow(dataTag: "512") << 512;
1862 QTest::newRow(dataTag: "1024") << 1024;
1863 QTest::newRow(dataTag: "2048") << 2048;
1864 QTest::newRow(dataTag: "4096") << 4096;
1865}
1866
1867void tst_QDir::longFileName()
1868{
1869 QFETCH(int, length);
1870
1871 QString fileName(length, QLatin1Char('a'));
1872 fileName += QLatin1String(".txt");
1873
1874 QFile file(fileName);
1875 if (!file.open(flags: QFile::WriteOnly))
1876 QSKIP("Cannot create long file names");
1877
1878 QFile file2(fileName);
1879 QVERIFY(file2.open(QFile::ReadOnly));
1880
1881 QVERIFY(QDir().entryList().contains(fileName));
1882
1883 file.close();
1884 file2.close();
1885
1886 QFile::remove(fileName);
1887}
1888
1889void tst_QDir::updateFileLists()
1890{
1891 // Test setup
1892
1893 FileSystem fs;
1894 const QString dirName = QStringLiteral("update-file-lists");
1895
1896 QVERIFY( fs.createDirectory(dirName));
1897 QVERIFY( fs.createFile(dirName + QStringLiteral("/file1.txt")) );
1898 QVERIFY( fs.createFile(dirName + QStringLiteral("/file2.doc")) );
1899
1900 QVERIFY( fs.createDirectory(dirName + QStringLiteral("/sub-dir1")) );
1901 QVERIFY( fs.createFile(dirName + QStringLiteral("/sub-dir1/file3.txt")) );
1902 QVERIFY( fs.createFile(dirName + QStringLiteral("/sub-dir1/file4.doc")) );
1903 QVERIFY( fs.createFile(dirName + QStringLiteral("/sub-dir1/file5.txt")) );
1904
1905 QVERIFY( fs.createDirectory(dirName + QStringLiteral("/sub-dir2")) );
1906 QVERIFY( fs.createFile(dirName + QStringLiteral("/sub-dir2/file6.txt")) );
1907 QVERIFY( fs.createFile(dirName + QStringLiteral("/sub-dir2/file7.txt")) );
1908 QVERIFY( fs.createFile(dirName + QStringLiteral("/sub-dir2/file8.doc")) );
1909 QVERIFY( fs.createFile(dirName + QStringLiteral("/sub-dir2/file9.doc")) );
1910
1911 // Actual test
1912
1913 QDir dir(fs.absoluteFilePath(fileName: dirName));
1914
1915 QCOMPARE(dir.count(), uint(6));
1916 QCOMPARE(dir.entryList().size(), 6);
1917 QCOMPARE(dir.entryInfoList().size(), 6);
1918
1919 dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
1920
1921 QCOMPARE(dir.entryList().size(), 4);
1922 QCOMPARE(dir.count(), uint(4));
1923 QCOMPARE(dir.entryInfoList().size(), 4);
1924
1925 dir.setPath(fs.absoluteFilePath(fileName: dirName + QStringLiteral("/sub-dir1")));
1926
1927 QCOMPARE(dir.entryInfoList().size(), 3);
1928 QCOMPARE(dir.count(), uint(3));
1929 QCOMPARE(dir.entryList().size(), 3);
1930
1931 dir.setNameFilters(QStringList("*.txt"));
1932
1933 QCOMPARE(dir.entryInfoList().size(), 2);
1934 QCOMPARE(dir.entryList().size(), 2);
1935 QCOMPARE(dir.count(), uint(2));
1936
1937 dir.setPath(fs.absoluteFilePath(fileName: dirName));
1938 dir = QDir(dir.path(),
1939 "*.txt",
1940 QDir::Name | QDir::DirsLast,
1941 QDir::AllEntries | QDir::AllDirs | QDir::NoDotAndDotDot);
1942
1943 QCOMPARE(dir.count(), uint(3));
1944 QCOMPARE(dir.entryList().size(), 3);
1945 QCOMPARE(dir.entryInfoList().size(), 3);
1946 QCOMPARE(dir.entryList(), QStringList() << "file1.txt" << "sub-dir1" << "sub-dir2");
1947
1948 dir.setSorting(QDir::Name | QDir::DirsFirst);
1949
1950 QCOMPARE(dir.count(), uint(3));
1951 QCOMPARE(dir.entryList().size(), 3);
1952 QCOMPARE(dir.entryInfoList().size(), 3);
1953 QCOMPARE(dir.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt");
1954
1955 {
1956 QVERIFY( fs.createFile(dirName + QStringLiteral("/extra-file.txt")) );
1957
1958 QDir dir2(dir);
1959
1960 QCOMPARE(dir2.count(), uint(3));
1961 QCOMPARE(dir2.entryList().size(), 3);
1962 QCOMPARE(dir2.entryInfoList().size(), 3);
1963 QCOMPARE(dir2.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt");
1964
1965 dir2.refresh();
1966
1967 QCOMPARE(dir2.count(), uint(4));
1968 QCOMPARE(dir2.entryList().size(), 4);
1969 QCOMPARE(dir2.entryInfoList().size(), 4);
1970 QCOMPARE(dir2.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "extra-file.txt" << "file1.txt");
1971 }
1972
1973 QCOMPARE(dir.count(), uint(3));
1974 QCOMPARE(dir.entryList().size(), 3);
1975 QCOMPARE(dir.entryInfoList().size(), 3);
1976 QCOMPARE(dir.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt");
1977}
1978
1979void tst_QDir::detachingOperations()
1980{
1981 QString const defaultPath(".");
1982 QStringList const defaultNameFilters = QStringList("*");
1983 QDir::SortFlags const defaultSorting = QDir::Name | QDir::IgnoreCase;
1984 QDir::Filters const defaultFilter = QDir::AllEntries;
1985
1986 QString const path1("..");
1987 QString const path2("./foo");
1988 QStringList const nameFilters = QStringList(QString("*.txt"));
1989 QDir::SortFlags const sorting = QDir::Name | QDir::DirsLast | QDir::Reversed;
1990 QDir::Filters const filter = QDir::Writable;
1991
1992 QDir dir1;
1993
1994 QCOMPARE(dir1.path(), defaultPath);
1995 QCOMPARE(dir1.filter(), defaultFilter);
1996 QCOMPARE(dir1.nameFilters(), defaultNameFilters);
1997 QCOMPARE(dir1.sorting(), defaultSorting);
1998
1999 dir1.setPath(path1);
2000 QCOMPARE(dir1.path(), path1);
2001 QCOMPARE(dir1.filter(), defaultFilter);
2002 QCOMPARE(dir1.nameFilters(), defaultNameFilters);
2003 QCOMPARE(dir1.sorting(), defaultSorting);
2004
2005 dir1.setFilter(filter);
2006 QCOMPARE(dir1.path(), path1);
2007 QCOMPARE(dir1.filter(), filter);
2008 QCOMPARE(dir1.nameFilters(), defaultNameFilters);
2009 QCOMPARE(dir1.sorting(), defaultSorting);
2010
2011 dir1.setNameFilters(nameFilters);
2012 QCOMPARE(dir1.path(), path1);
2013 QCOMPARE(dir1.filter(), filter);
2014 QCOMPARE(dir1.nameFilters(), nameFilters);
2015 QCOMPARE(dir1.sorting(), defaultSorting);
2016
2017 dir1.setSorting(sorting);
2018 QCOMPARE(dir1.path(), path1);
2019 QCOMPARE(dir1.filter(), filter);
2020 QCOMPARE(dir1.nameFilters(), nameFilters);
2021 QCOMPARE(dir1.sorting(), sorting);
2022
2023 dir1.setPath(path2);
2024 QCOMPARE(dir1.path(), path2);
2025 QCOMPARE(dir1.filter(), filter);
2026 QCOMPARE(dir1.nameFilters(), nameFilters);
2027 QCOMPARE(dir1.sorting(), sorting);
2028
2029 {
2030 QDir dir2(dir1);
2031 QCOMPARE(dir2.path(), path2);
2032 QCOMPARE(dir2.filter(), filter);
2033 QCOMPARE(dir2.nameFilters(), nameFilters);
2034 QCOMPARE(dir2.sorting(), sorting);
2035 }
2036
2037 {
2038 QDir dir2;
2039 QCOMPARE(dir2.path(), defaultPath);
2040 QCOMPARE(dir2.filter(), defaultFilter);
2041 QCOMPARE(dir2.nameFilters(), defaultNameFilters);
2042 QCOMPARE(dir2.sorting(), defaultSorting);
2043
2044 dir2 = dir1;
2045 QCOMPARE(dir2.path(), path2);
2046 QCOMPARE(dir2.filter(), filter);
2047 QCOMPARE(dir2.nameFilters(), nameFilters);
2048 QCOMPARE(dir2.sorting(), sorting);
2049
2050 dir2.setPath(path1);
2051 QCOMPARE(dir2.path(), path1);
2052 QCOMPARE(dir2.filter(), filter);
2053 QCOMPARE(dir2.nameFilters(), nameFilters);
2054 QCOMPARE(dir2.sorting(), sorting);
2055 }
2056
2057 dir1.refresh();
2058 QCOMPARE(dir1.path(), path2);
2059 QCOMPARE(dir1.filter(), filter);
2060 QCOMPARE(dir1.nameFilters(), nameFilters);
2061 QCOMPARE(dir1.sorting(), sorting);
2062
2063 QString const currentPath = QDir::currentPath();
2064 QVERIFY(dir1.cd(currentPath));
2065 QCOMPARE(dir1.path(), currentPath);
2066 QCOMPARE(dir1.filter(), filter);
2067 QCOMPARE(dir1.nameFilters(), nameFilters);
2068 QCOMPARE(dir1.sorting(), sorting);
2069
2070 QVERIFY(dir1.cdUp());
2071 QCOMPARE(dir1.filter(), filter);
2072 QCOMPARE(dir1.nameFilters(), nameFilters);
2073 QCOMPARE(dir1.sorting(), sorting);
2074}
2075
2076void tst_QDir::testCaching()
2077{
2078 QString dirName = QString::fromLatin1(str: "testCaching");
2079 QDir::current().rmdir(dirName); // cleanup a previous run.
2080 QDir dir(dirName);
2081 QVERIFY(!dir.exists());
2082 QDir::current().mkdir(dirName);
2083 QVERIFY(QDir(dirName).exists()); // dir exists
2084 QVERIFY(dir.exists()); // QDir doesn't cache the 'exist' between calls.
2085}
2086
2087void tst_QDir::isRoot_data()
2088{
2089 QTest::addColumn<QString>(name: "path");
2090 QTest::addColumn<bool>(name: "isRoot");
2091
2092 QString test = QDir::rootPath();
2093 QTest::newRow(dataTag: QString("rootPath " + test).toLatin1()) << test << true;
2094 test = QDir::rootPath().append(s: "./");
2095 QTest::newRow(dataTag: QString("./ appended " + test).toLatin1()) << test << false;
2096
2097 test = QDir(QDir::rootPath().append(s: "./")).canonicalPath();
2098 QTest::newRow(dataTag: QString("canonicalPath " + test).toLatin1()) << test << true;
2099
2100#if defined(Q_OS_WIN)
2101 test = QDir::rootPath().left(2);
2102 QTest::newRow(QString("drive relative " + test).toLatin1()) << test << false;
2103#endif
2104
2105 QTest::newRow(dataTag: "resources root") << ":/" << true;
2106 QTest::newRow(dataTag: "resources nonroot") << ":/entrylist" << false;
2107}
2108
2109void tst_QDir::isRoot()
2110{
2111 QFETCH(QString, path);
2112 QFETCH(bool, isRoot);
2113
2114 QDir dir(path);
2115 QCOMPARE(dir.isRoot(),isRoot);
2116}
2117
2118#ifndef QT_NO_REGEXP
2119void tst_QDir::match_data()
2120{
2121 QTest::addColumn<QString>(name: "filter");
2122 QTest::addColumn<QString>(name: "filename");
2123 QTest::addColumn<bool>(name: "match");
2124
2125 QTest::newRow(dataTag: "single, matching") << "*.cpp" << "tst_qdir.cpp" << true;
2126 QTest::newRow(dataTag: "single, not matching") << "*.cpp" << "tst_qdir.h" << false;
2127 QTest::newRow(dataTag: "multi, matching") << "*.cpp;*.h" << "tst_qdir.cpp" << true;
2128 QTest::newRow(dataTag: "multi, matching2") << "*.cpp;*.h" << "tst_qdir.h" << true;
2129 QTest::newRow(dataTag: "multi, not matching") << "*.cpp;*.h" << "readme.txt" << false;
2130}
2131
2132void tst_QDir::match()
2133{
2134 QFETCH(QString, filter);
2135 QFETCH(QString, filename);
2136 QFETCH(bool, match);
2137
2138 QCOMPARE(QDir::match(filter, filename), match);
2139 QCOMPARE(QDir::match(filter.split(QLatin1Char(';')), filename), match);
2140}
2141#endif
2142
2143void tst_QDir::drives()
2144{
2145 QFileInfoList list(QDir::drives());
2146#if defined(Q_OS_WIN)
2147 QVERIFY(list.count() >= 1); //system
2148 QLatin1Char systemdrive('c');
2149#endif
2150#if defined(Q_OS_WINRT)
2151 QSKIP("WinRT has no concept of drives");
2152#endif
2153#if defined(Q_OS_WIN)
2154 QVERIFY(list.count() <= 26);
2155 bool foundsystem = false;
2156 foreach (QFileInfo fi, list) {
2157 QCOMPARE(fi.absolutePath().size(), 3); //"x:/"
2158 QCOMPARE(fi.absolutePath().at(1), QChar(QLatin1Char(':')));
2159 QCOMPARE(fi.absolutePath().at(2), QChar(QLatin1Char('/')));
2160 if (fi.absolutePath().at(0).toLower() == systemdrive)
2161 foundsystem = true;
2162 }
2163 QCOMPARE(foundsystem, true);
2164#else
2165 QCOMPARE(list.count(), 1); //root
2166 QCOMPARE(list.at(0).absolutePath(), QLatin1String("/"));
2167#endif
2168}
2169
2170void tst_QDir::arrayOperator()
2171{
2172 QDir dir1((m_dataPath + "/entrylist/"));
2173 QDir dir2((m_dataPath + "/entrylist/"));
2174
2175 QStringList entries(dir1.entryList());
2176 int i = dir2.count();
2177 QCOMPARE(i, entries.count());
2178 --i;
2179 for (;i>=0;--i) {
2180 QCOMPARE(dir2[i], entries.at(i));
2181 }
2182}
2183
2184void tst_QDir::equalityOperator_data()
2185{
2186 QTest::addColumn<QString>(name: "leftPath");
2187 QTest::addColumn<QString>(name: "leftNameFilters");
2188 QTest::addColumn<int>(name: "leftSort");
2189 QTest::addColumn<int>(name: "leftFilters");
2190 QTest::addColumn<QString>(name: "rightPath");
2191 QTest::addColumn<QString>(name: "rightNameFilters");
2192 QTest::addColumn<int>(name: "rightSort");
2193 QTest::addColumn<int>(name: "rightFilters");
2194 QTest::addColumn<bool>(name: "expected");
2195
2196 QTest::newRow(dataTag: "same") << (m_dataPath + "/.") << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2197 << (m_dataPath + "/.") << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2198 << true;
2199
2200 QTest::newRow(dataTag: "relativepaths") << "entrylist/" << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2201 << "./entrylist" << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2202 << true;
2203
2204 QTest::newRow(dataTag: "QTBUG-20495") << QDir::currentPath() + "/entrylist/.." << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2205 << "." << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2206 << true;
2207
2208 //need a path in the root directory that is unlikely to be a symbolic link.
2209#if defined (Q_OS_WINRT)
2210 QString pathinroot(QDir::rootPath() + QLatin1String("assets/.."));
2211#elif defined (Q_OS_WIN)
2212 QString pathinroot("c:/windows/..");
2213#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
2214 QString pathinroot("/system/..");
2215#elif defined(Q_OS_HAIKU)
2216 QString pathinroot("/boot/..");
2217#else
2218 QString pathinroot("/usr/..");
2219#endif
2220 QTest::newRow(dataTag: "QTBUG-20495-root") << pathinroot << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2221 << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2222 << true;
2223
2224 QTest::newRow(dataTag: "slashdot") << QDir::rootPath() + "." << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2225 << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2226 << true;
2227
2228 QTest::newRow(dataTag: "slashdotslash") << QDir::rootPath() + "./" << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2229 << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2230 << true;
2231
2232 QTest::newRow(dataTag: "nonexistantpaths") << "dir-that-dont-exist" << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2233 << "another-dir-that-dont-exist" << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2234 << false;
2235
2236 QTest::newRow(dataTag: "diff-filters") << (m_dataPath + "/.") << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2237 << m_dataPath << "*.cpp" << int(QDir::Name) << int(QDir::Dirs)
2238 << false;
2239
2240 QTest::newRow(dataTag: "diff-sort") << (m_dataPath + "/.") << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2241 << m_dataPath << "*.cpp" << int(QDir::Time) << int(QDir::Files)
2242 << false;
2243
2244 QTest::newRow(dataTag: "diff-namefilters") << (m_dataPath + "/.") << "*.cpp" << int(QDir::Name) << int(QDir::Files)
2245 << m_dataPath << "*.jpg" << int(QDir::Name) << int(QDir::Files)
2246 << false;
2247}
2248
2249void tst_QDir::equalityOperator()
2250{
2251 QFETCH(QString, leftPath);
2252 QFETCH(QString, leftNameFilters);
2253 QFETCH(int, leftSort);
2254 QFETCH(int, leftFilters);
2255 QFETCH(QString, rightPath);
2256 QFETCH(QString, rightNameFilters);
2257 QFETCH(int, rightSort);
2258 QFETCH(int, rightFilters);
2259 QFETCH(bool, expected);
2260
2261 QDir dir1(leftPath, leftNameFilters, QDir::SortFlags(leftSort), QDir::Filters(leftFilters));
2262 QDir dir2(rightPath, rightNameFilters, QDir::SortFlags(rightSort), QDir::Filters(rightFilters));
2263
2264 QCOMPARE((dir1 == dir2), expected);
2265 QCOMPARE((dir2 == dir1), expected);
2266 QCOMPARE((dir1 != dir2), !expected);
2267 QCOMPARE((dir2 != dir1), !expected);
2268}
2269
2270void tst_QDir::isRelative_data()
2271{
2272 QTest::addColumn<QString>(name: "path");
2273 QTest::addColumn<bool>(name: "relative");
2274
2275 QTest::newRow(dataTag: ".") << "./" << true;
2276 QTest::newRow(dataTag: "..") << "../" << true;
2277 QTest::newRow(dataTag: "content") << "entrylist/" << true;
2278 QTest::newRow(dataTag: "current") << QDir::currentPath() << false;
2279 QTest::newRow(dataTag: "homepath") << QDir::homePath() << false;
2280 QTest::newRow(dataTag: "temppath") << QDir::tempPath() << false;
2281 QTest::newRow(dataTag: "rootpath") << QDir::rootPath() << false;
2282 foreach (QFileInfo root, QDir::drives()) {
2283 QTest::newRow(dataTag: root.absolutePath().toLocal8Bit()) << root.absolutePath() << false;
2284 }
2285
2286 QTest::newRow(dataTag: "resource") << ":/prefix" << false;
2287}
2288
2289void tst_QDir::isRelative()
2290{
2291 QFETCH(QString, path);
2292 QFETCH(bool, relative);
2293
2294 QCOMPARE(QDir(path).isRelative(), relative);
2295}
2296
2297void tst_QDir::isReadable()
2298{
2299#ifdef Q_OS_UNIX
2300 if (::getuid() == 0)
2301 QSKIP("Running this test as root doesn't make sense");
2302#endif
2303 QDir dir;
2304
2305 QVERIFY(dir.isReadable());
2306#if defined (Q_OS_UNIX)
2307 QVERIFY(dir.mkdir("nonreadabledir"));
2308 QVERIFY(0 == ::chmod("nonreadabledir", 0));
2309 QVERIFY(!QDir("nonreadabledir").isReadable());
2310 QVERIFY(0 == ::chmod("nonreadabledir", S_IRUSR | S_IWUSR | S_IXUSR));
2311 QVERIFY(dir.rmdir("nonreadabledir"));
2312#endif
2313}
2314
2315void tst_QDir::cdNonreadable()
2316{
2317#ifdef Q_OS_UNIX
2318 if (::getuid() == 0)
2319 QSKIP("Running this test as root doesn't make sense");
2320
2321 QDir dir;
2322 QVERIFY(dir.mkdir("nonreadabledir2"));
2323 QVERIFY(0 == ::chmod("nonreadabledir2", S_IWUSR | S_IXUSR));
2324 QVERIFY(dir.cd("nonreadabledir2"));
2325 QVERIFY(!dir.isReadable());
2326 QVERIFY(dir.cd(".."));
2327 QVERIFY(0 == ::chmod("nonreadabledir2", S_IRUSR | S_IWUSR | S_IXUSR));
2328 QVERIFY(dir.rmdir("nonreadabledir2"));
2329#endif
2330}
2331
2332void tst_QDir::cdBelowRoot_data()
2333{
2334 QTest::addColumn<QString>(name: "rootPath");
2335 QTest::addColumn<QString>(name: "cdInto");
2336 QTest::addColumn<QString>(name: "targetPath");
2337
2338#if defined(Q_OS_ANDROID)
2339 QTest::newRow("android") << "/" << "system" << "/system";
2340#elif defined(Q_OS_UNIX)
2341 QTest::newRow(dataTag: "unix") << "/" << "tmp" << "/tmp";
2342#elif defined(Q_OS_WINRT)
2343 QTest::newRow("winrt") << QDir::rootPath() << QDir::rootPath() << QDir::rootPath();
2344#else // Windows+CE
2345 const QString systemDrive = QString::fromLocal8Bit(qgetenv("SystemDrive")) + QLatin1Char('/');
2346 const QString systemRoot = QString::fromLocal8Bit(qgetenv("SystemRoot"));
2347 QTest::newRow("windows-drive")
2348 << systemDrive << systemRoot.mid(3) << QDir::cleanPath(systemRoot);
2349 const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName();
2350 const QString testDirectory = QStringLiteral("testshare");
2351 QTest::newRow("windows-share")
2352 << uncRoot << testDirectory << QDir::cleanPath(uncRoot + QLatin1Char('/') + testDirectory);
2353#endif // Windows
2354}
2355
2356void tst_QDir::cdBelowRoot()
2357{
2358 QFETCH(QString, rootPath);
2359 QFETCH(QString, cdInto);
2360 QFETCH(QString, targetPath);
2361
2362 QDir root(rootPath);
2363 QVERIFY2(!root.cd(".."), qPrintable(root.absolutePath()));
2364 QCOMPARE(root.path(), rootPath);
2365 QVERIFY(root.cd(cdInto));
2366 QCOMPARE(root.path(), targetPath);
2367#ifdef Q_OS_UNIX
2368 if (::getuid() == 0)
2369 QSKIP("Running this test as root doesn't make sense");
2370#endif
2371#ifdef Q_OS_WINRT
2372 QSKIP("WinRT has no concept of system root");
2373#endif
2374 QDir dir(targetPath);
2375 QVERIFY2(!dir.cd("../.."), qPrintable(dir.absolutePath()));
2376 QCOMPARE(dir.path(), targetPath);
2377 QVERIFY2(!dir.cd("../abs/../.."), qPrintable(dir.absolutePath()));
2378 QCOMPARE(dir.path(), targetPath);
2379 QVERIFY(dir.cd(".."));
2380 QCOMPARE(dir.path(), rootPath);
2381}
2382
2383void tst_QDir::emptyDir()
2384{
2385 const QString tempDir = QDir::currentPath() + "/tmpdir/";
2386 QDir temp(tempDir);
2387 if (!temp.exists()) {
2388 QVERIFY(QDir().mkdir(tempDir));
2389 }
2390 QVERIFY(temp.mkdir("emptyDirectory"));
2391
2392 QDir testDir(tempDir + "emptyDirectory");
2393 QVERIFY(testDir.isEmpty());
2394 QVERIFY(!testDir.isEmpty(QDir::AllEntries));
2395 QVERIFY(!testDir.isEmpty(QDir::AllEntries | QDir::NoDot));
2396 QVERIFY(!testDir.isEmpty(QDir::AllEntries | QDir::NoDotDot));
2397 QVERIFY(QDir(tempDir).removeRecursively());
2398}
2399
2400void tst_QDir::nonEmptyDir()
2401{
2402 const QDir dir(m_dataPath);
2403 QVERIFY(!dir.isEmpty());
2404}
2405
2406QTEST_MAIN(tst_QDir)
2407#include "tst_qdir.moc"
2408
2409

source code of qtbase/tests/auto/corelib/io/qdir/tst_qdir.cpp