diff options
Diffstat (limited to 'tests/auto/corelib/io/qdir')
-rw-r--r-- | tests/auto/corelib/io/qdir/CMakeLists.txt | 103 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/qdir.pro | 14 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/qdir.qrc | 5 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt | 0 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt | 0 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt | 0 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/testdir/dir/CMakeLists.txt | 12 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/testdir/dir/qdir.pro | 3 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp | 29 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp | 29 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdir/tst_qdir.cpp | 375 |
11 files changed, 360 insertions, 210 deletions
diff --git a/tests/auto/corelib/io/qdir/CMakeLists.txt b/tests/auto/corelib/io/qdir/CMakeLists.txt new file mode 100644 index 0000000000..4032d7ac19 --- /dev/null +++ b/tests/auto/corelib/io/qdir/CMakeLists.txt @@ -0,0 +1,103 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## tst_qdir Test: +##################################################################### + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qdir LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +# Collect test data +list(APPEND test_data "testdir") +list(APPEND test_data "testData") +list(APPEND test_data "searchdir") +list(APPEND test_data "resources") +list(APPEND test_data "entrylist") +list(APPEND test_data "types") +list(APPEND test_data "tst_qdir.cpp") + +qt_internal_add_test(tst_qdir + SOURCES + tst_qdir.cpp + LIBRARIES + Qt::CorePrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +# Resources: +set(qdir_resource_files + "resources/entryList/" +) + +qt_internal_add_resource(tst_qdir "qdir" + PREFIX + "/tst_qdir/" + FILES + ${qdir_resource_files} +) + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qdir CONDITION CONFIG___contains___builtin_testdata + DEFINES + BUILTIN_TESTDATA +) + +if(ANDROID) + # Resources: + set(android_testdata_resource_files + "entrylist/directory/dummy" + "entrylist/file" + "resources/entryList/file1.data" + "resources/entryList/file2.data" + "resources/entryList/file3.data" + "resources/entryList/file4.nothing" + "searchdir/subdir1/picker.png" + "searchdir/subdir2/picker.png" + "testData/empty" + "testdir/dir/qdir.pro" + "testdir/dir/qrc_qdir.cpp" + "testdir/dir/tmp/empty" + "testdir/dir/tst_qdir.cpp" + "testdir/spaces/foo. bar" + "testdir/spaces/foo.bar" + "tst_qdir.cpp" + "types/a" + "types/a.a" + "types/a.b" + "types/a.c" + "types/b" + "types/b.a" + "types/b.b" + "types/b.c" + "types/c" + "types/c.a" + "types/c.b" + "types/c.c" + "types/d.a/dummy" + "types/d.b/dummy" + "types/d.c/dummy" + "types/d/dummy" + "types/e.a/dummy" + "types/e.b/dummy" + "types/e.c/dummy" + "types/e/dummy" + "types/f.a/dummy" + "types/f.b/dummy" + "types/f.c/dummy" + "types/f/dummy" + ) + + qt_internal_add_resource(tst_qdir "android_testdata" + PREFIX + "/android_testdata" + FILES + ${android_testdata_resource_files} + ) +endif() diff --git a/tests/auto/corelib/io/qdir/qdir.pro b/tests/auto/corelib/io/qdir/qdir.pro deleted file mode 100644 index a8b106e250..0000000000 --- a/tests/auto/corelib/io/qdir/qdir.pro +++ /dev/null @@ -1,14 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdir -QT = core core-private testlib -SOURCES = tst_qdir.cpp -RESOURCES += qdir.qrc -ios: QMAKE_INFO_PLIST = Info.plist - -TESTDATA += testdir testData searchdir resources entrylist types tst_qdir.cpp - -contains(CONFIG, builtin_testdata): DEFINES += BUILTIN_TESTDATA - -android:!android-embedded { - RESOURCES += android_testdata.qrc -} diff --git a/tests/auto/corelib/io/qdir/qdir.qrc b/tests/auto/corelib/io/qdir/qdir.qrc deleted file mode 100644 index 4c5b5af3b8..0000000000 --- a/tests/auto/corelib/io/qdir/qdir.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/tst_qdir/"> - <file>resources/entryList/</file> -</qresource> -</RCC> diff --git a/tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt b/tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt diff --git a/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt diff --git a/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt diff --git a/tests/auto/corelib/io/qdir/testdir/dir/CMakeLists.txt b/tests/auto/corelib/io/qdir/testdir/dir/CMakeLists.txt new file mode 100644 index 0000000000..d0ec6dee9a --- /dev/null +++ b/tests/auto/corelib/io/qdir/testdir/dir/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## qdir Binary: +##################################################################### + +qt_internal_add_executable(qdir + GUI + LIBRARIES + Qt::Gui +) diff --git a/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro b/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro index 856d5ea2fb..e69de29bb2 100644 --- a/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro +++ b/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro @@ -1,3 +0,0 @@ - - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp b/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp index a1d5c2c9ff..b9f84b6006 100644 --- a/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp +++ b/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp @@ -1,29 +1,4 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only diff --git a/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp index a1d5c2c9ff..b9f84b6006 100644 --- a/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp @@ -1,29 +1,4 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index a6775ec2b6..7b05a88e81 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -1,33 +1,13 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Intel Corporation. -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtTest/QtTest> +// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2017 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> +#include <QTemporaryFile> +#if QT_CONFIG(process) +#include <QProcess> +#endif #include <qcoreapplication.h> #include <qdebug.h> @@ -37,11 +17,10 @@ #if defined(Q_OS_WIN) #include <QtCore/private/qfsfileengine_p.h> -#include "../../../network-settings.h" #endif #if defined(Q_OS_WIN) && !defined(_WIN32_WINNT) -#define _WIN32_WINNT 0x500 +#define _WIN32_WINNT 0x0A00 #endif #include "../../../../shared/filesystem.h" @@ -51,7 +30,11 @@ # include <sys/stat.h> #endif -#if defined(Q_OS_VXWORKS) || defined(Q_OS_WINRT) +#ifdef Q_OS_INTEGRITY +#include "qplatformdefs.h" +#endif + +#if defined(Q_OS_VXWORKS) #define Q_NO_SYMLINKS #endif @@ -65,6 +48,8 @@ #include "private/qdir_p.h" #endif +using namespace Qt::StringLiterals; + static QByteArray msgDoesNotExist(const QString &name) { return (QLatin1Char('"') + QDir::toNativeSeparators(name) @@ -106,6 +91,8 @@ private slots: void mkdirRmdir_data(); void mkdirRmdir(); void mkdirOnSymlink(); + void mkdirWithPermissions_data(); + void mkdirWithPermissions(); void makedirReturnCode(); @@ -140,6 +127,7 @@ private slots: void normalizePathSegments(); #endif + void compareCompiles(); void compare(); void QDir_default(); @@ -216,34 +204,41 @@ private slots: void emptyDir(); void nonEmptyDir(); + void stdfilesystem(); + private: -#ifdef BUILTIN_TESTDATA - QString m_dataPath; QSharedPointer<QTemporaryDir> m_dataDir; -#else - const QString m_dataPath; -#endif + QString m_dataPath; + + constexpr static const std::array m_testDirs = { + "entrylist"_L1, + "resources"_L1, + "searchdir"_L1, + "testData"_L1, + "testdir"_L1, + "types"_L1, + "tst_qdir.cpp"_L1, + }; }; Q_DECLARE_METATYPE(tst_QDir::UncHandling) tst_QDir::tst_QDir() -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) +#ifdef Q_OS_ANDROID : m_dataPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) #elif !defined(BUILTIN_TESTDATA) : m_dataPath(QFileInfo(QFINDTESTDATA("testData")).absolutePath()) #endif { -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) +#ifdef Q_OS_ANDROID QString resourceSourcePath = QStringLiteral(":/android_testdata/"); QDirIterator it(resourceSourcePath, QDirIterator::Subdirectories); while (it.hasNext()) { - it.next(); - - QFileInfo fileInfo = it.fileInfo(); + QFileInfo fileInfo = it.nextFileInfo(); if (!fileInfo.isDir()) { - QString destination = m_dataPath + QLatin1Char('/') + fileInfo.filePath().mid(resourceSourcePath.length()); + QString destination = m_dataPath + QLatin1Char('/') + + fileInfo.filePath().mid(resourceSourcePath.length()); QFileInfo destinationFileInfo(destination); if (!destinationFileInfo.exists()) { QDir().mkpath(destinationFileInfo.path()); @@ -271,6 +266,20 @@ void tst_QDir::initTestCase() m_dataDir = QEXTRACTTESTDATA("/"); QVERIFY2(!m_dataDir.isNull(), qPrintable("Did not find testdata. Is this builtin?")); m_dataPath = m_dataDir->path(); +#elif QT_CONFIG(cxx17_filesystem) // This code doesn't work in QNX on the CI + m_dataDir.reset(new QTemporaryDir); + m_dataPath = m_dataDir->path(); + + QString sourceDir = QFileInfo(QFINDTESTDATA(m_testDirs[0])).absolutePath(); + namespace fs = std::filesystem; + for (const auto &entry : m_testDirs) { + auto l1 = QLatin1StringView(entry); + const auto src = fs::path(QString(sourceDir + u'/' + l1).toStdString()); + const auto dest = fs::path(QString(m_dataPath + u'/' + l1).toStdString()); + std::error_code ec; + fs::copy(src, dest, fs::copy_options::recursive, ec); + QCOMPARE(ec.value(), 0); + } #endif QVERIFY2(!m_dataPath.isEmpty(), "test data not found"); @@ -332,6 +341,7 @@ void tst_QDir::setPath() QFETCH(QString, dir1); QFETCH(QString, dir2); + QDir::setCurrent(m_dataPath + "/entrylist"_L1); QDir shared; QDir qDir1(dir1); QStringList entries1 = qDir1.entryList(); @@ -394,7 +404,7 @@ void tst_QDir::mkdirRmdir() void tst_QDir::mkdirOnSymlink() { -#if !defined(Q_OS_UNIX) || defined(Q_NO_SYMLINKS) +#if !defined(Q_OS_UNIX) || defined(Q_NO_SYMLINKS) || defined(Q_OS_INTEGRITY) QSKIP("Test only valid on an OS that supports symlinks"); #else // Create the structure: @@ -428,7 +438,7 @@ void tst_QDir::mkdirOnSymlink() // create our structure: dir.mkpath("two/three"); - ::symlink("two/three", "symlink"); + QCOMPARE(::symlink("two/three", "symlink"), 0); // try it: QString path = "symlink/../four/five"; @@ -438,10 +448,55 @@ void tst_QDir::mkdirOnSymlink() path = "two/four/five"; fi.setFile(path); +#if defined(Q_OS_QNX) + QSKIP("Fails on QNX QTBUG-98561"); +#endif QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData()); #endif } +void tst_QDir::mkdirWithPermissions_data() +{ + QTest::addColumn<QFile::Permissions>("permissions"); + + for (int u = 0; u < 8; ++u) { + for (int g = 0; g < 8; ++g) { + for (int o = 0; o < 8; ++o) { + auto permissions = QFileDevice::Permissions::fromInt((u << 12) | (g << 4) | o); + QTest::addRow("%04x", permissions.toInt()) << permissions; + } + } + } +} + +void tst_QDir::mkdirWithPermissions() +{ + QFETCH(QFile::Permissions, permissions); + +#ifdef Q_OS_WIN + QNtfsPermissionCheckGuard permissionGuard; +#endif +#ifdef Q_OS_UNIX + auto restoreMask = qScopeGuard([oldMask = umask(0)] { umask(oldMask); }); +#endif + + const QFile::Permissions setPermissions = { + QFile::ReadOther, QFile::WriteOther, QFile::ExeOther, + QFile::ReadGroup, QFile::WriteGroup, QFile::ExeGroup, + QFile::ReadOwner, QFile::WriteOwner, QFile::ExeOwner + }; + + const QString path = u"tmpdir"_s; + QDir dir; + auto deleteDirectory = qScopeGuard([&dir, &path] { dir.rmdir(path); }); + + QVERIFY(dir.mkdir(path, permissions)); + auto actualPermissions = QFileInfo(dir.filePath(path)).permissions(); + QCOMPARE(actualPermissions & setPermissions, permissions); + QVERIFY(dir.rmdir(path)); + deleteDirectory.dismiss(); +} + void tst_QDir::makedirReturnCode() { QString dirName = QString::fromLatin1("makedirReturnCode"); @@ -457,10 +512,15 @@ void tst_QDir::makedirReturnCode() QVERIFY(!QDir::current().mkdir(dirName)); // calling mkdir on an existing dir will fail. QVERIFY(QDir::current().mkpath(dirName)); // calling mkpath on an existing dir will pass + // the next line specifically targets Windows and macOS (QTBUG-85997, QTBUG-97110) + // calling mkpath on an existing drive name (Windows) or root path (macOS) shall pass + QVERIFY(QDir().mkpath(QDir::rootPath())); + QVERIFY(!QDir().mkdir(QDir::rootPath())); + // Remove the directory and create a file with the same path QDir::current().rmdir(dirName); QVERIFY(!f.exists()); - f.open(QIODevice::WriteOnly); + QVERIFY(f.open(QIODevice::WriteOnly)); f.write("test"); f.close(); QVERIFY2(f.exists(), msgDoesNotExist(f.fileName()).constData()); @@ -481,12 +541,12 @@ void tst_QDir::removeRecursively_data() << tmpdir + "two/three" << "relative"; QDir dir; - for (int i = 0; i < dirs.count(); ++i) + for (int i = 0; i < dirs.size(); ++i) dir.mkpath(dirs.at(i)); QStringList files; files << tmpdir + "one/file"; files << tmpdir + "two/three/file"; - for (int i = 0; i < files.count(); ++i) { + for (int i = 0; i < files.size(); ++i) { QFile file(files.at(i)); QVERIFY(file.open(QIODevice::WriteOnly)); file.write("Hello"); @@ -554,7 +614,7 @@ void tst_QDir::removeRecursivelySymlink() QDir().mkpath(tmpdir); QDir currentDir; currentDir.mkdir("myDir"); - QFile("testfile").open(QIODevice::WriteOnly); + QVERIFY(QFile("testfile").open(QIODevice::WriteOnly)); const QString link = tmpdir + "linkToDir.lnk"; const QString linkToFile = tmpdir + "linkToFile.lnk"; #ifndef Q_NO_SYMLINKS_TO_DIRS @@ -585,8 +645,8 @@ void tst_QDir::exists_data() QTest::newRow("simple dir") << (m_dataPath + "/resources") << true; QTest::newRow("simple dir with slash") << (m_dataPath + "/resources/") << true; -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName(); +#if defined(Q_OS_WIN) + const QString uncRoot = QStringLiteral("//") + QTest::uncServerName(); QTest::newRow("unc 1") << uncRoot << true; QTest::newRow("unc 2") << uncRoot + QLatin1Char('/') << true; QTest::newRow("unc 3") << uncRoot + "/testshare" << true; @@ -597,7 +657,7 @@ void tst_QDir::exists_data() QTest::newRow("unc 8") << uncRoot + "/asharethatshouldnotexist" << false; QTest::newRow("unc 9") << "//ahostthatshouldnotexist" << false; #endif -#if (defined(Q_OS_WIN) && !defined(Q_OS_WINRT)) +#if defined (Q_OS_WIN) QTest::newRow("This drive should exist") << "C:/" << true; // find a non-existing drive and check if it does not exist #ifdef QT_BUILD_INTERNAL @@ -664,32 +724,29 @@ void tst_QDir::QDir_default() QCOMPARE(dir.absolutePath(), QDir::currentPath()); } -void tst_QDir::compare() +void tst_QDir::compareCompiles() { - // operator== - - // Not using QCOMPARE to test result of QDir::operator== + QTestPrivate::testEqualityOperatorsCompile<QDir>(); +} +void tst_QDir::compare() +{ QDir dir; dir.makeAbsolute(); - QVERIFY(dir == QDir::currentPath()); + QT_TEST_EQUALITY_OPS(dir, QDir::currentPath(), true); QCOMPARE(QDir(), QDir(QDir::currentPath())); - QVERIFY(QDir("../") == QDir(QDir::currentPath() + "/..")); + + QT_TEST_EQUALITY_OPS(QDir("../"), QDir(QDir::currentPath() + "/.."), true); } -static QStringList filterLinks(const QStringList &list) +static QStringList filterLinks(QStringList &&list) { -#ifndef Q_NO_SYMLINKS - return list; -#else - QStringList result; - foreach (QString str, list) { - if (!str.endsWith(QLatin1String(".lnk"))) - result.append(str); - } - return result; +#ifdef Q_NO_SYMLINKS + auto isDotLnk = [](const auto &s) { return s.endsWith(".lnk"_L1); }; + list.removeIf(isDotLnk); #endif + return std::move(list); } void tst_QDir::entryList_data() @@ -713,13 +770,16 @@ void tst_QDir::entryList_data() << QString("qdir.pro,qrc_qdir.cpp,tst_qdir.cpp").split(','); QTest::newRow("testdir1") << (m_dataPath + "/testdir") << QStringList() << (int)(QDir::AllDirs) << (int)(QDir::NoSort) - << QString(".,..,dir,spaces").split(','); + << QString(".,..,dir,dir.lnk,spaces").split(','); QTest::newRow("resources1") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data") << (int)(QDir::NoFilter) << (int)(QDir::NoSort) << QString("file1.data,file2.data,file3.data").split(','); QTest::newRow("resources2") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data") << (int)(QDir::Files) << (int)(QDir::NoSort) << QString("file1.data,file2.data,file3.data").split(','); + QTest::newRow("testdir.lnk") << (m_dataPath + "/testdir/dir.lnk") << QStringList() + << (int)(QDir::NoFilter) << (int)(QDir::NoSort) + << QString(".,..,aaaaa.txt,subdir,subdir.lnk").split(','); } void tst_QDir::entryList() @@ -753,6 +813,12 @@ void tst_QDir::entryListWithTestFiles_data() QTest::newRow("QDir::AllEntries") << (m_dataPath + "/entrylist/") << QStringList("*") << int(QDir::AllEntries) << int(QDir::Name) << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); + // Tests an assert in QDirSortItemComparator, when QDir::LocaleAware is set + // a QCollator is used + QTest::newRow("QDir::AllEntries") + << (m_dataPath + "/entrylist/") << QStringList("*") + << int(QDir::AllEntries) << int(QDir::Name | QDir::LocaleAware) + << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::Files") << (m_dataPath + "/entrylist/") << QStringList("*") << int(QDir::Files) << int(QDir::Name) << filterLinks(QString("file,linktofile.lnk,writable").split(',')); @@ -884,14 +950,14 @@ void tst_QDir::entryListWithTestFiles() #if defined(Q_OS_WIN) // ### Sadly, this is a platform difference right now. // Note we are using capital L in entryList on one side here, to test case-insensitivity - const QVector<QPair<QString, QString> > symLinks = + const QList<QPair<QString, QString> > symLinks = { {m_dataPath + "/entryList/file", entrylistPath + "linktofile.lnk"}, {m_dataPath + "/entryList/directory", entrylistPath + "linktodirectory.lnk"}, {m_dataPath + "/entryList/nothing", entrylistPath + "brokenlink.lnk"} }; #else - const QVector<QPair<QString, QString> > symLinks = + const QList<QPair<QString, QString> > symLinks = { {"file", entrylistPath + "linktofile.lnk"}, {"directory", entrylistPath + "linktodirectory.lnk"}, @@ -956,7 +1022,7 @@ void tst_QDir::entryListTimedSort() QFileInfo aFileInfo(aFile); QFileInfo bFileInfo(bFile); - QVERIFY(bFileInfo.lastModified().msecsTo(aFileInfo.lastModified()) < 0); + QVERIFY(bFileInfo.lastModified(QTimeZone::UTC).msecsTo(aFileInfo.lastModified(QTimeZone::UTC)) < 0); QCOMPARE(actual.size(), 2); QCOMPARE(actual.first(), bFileInfo.fileName()); @@ -975,8 +1041,8 @@ void tst_QDir::entryListSimple_data() QTest::newRow("simple dir") << (m_dataPath + "/resources") << 2; QTest::newRow("simple dir with slash") << (m_dataPath + "/resources/") << 2; -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName(); +#if defined(Q_OS_WIN) + const QString uncRoot = QStringLiteral("//") + QTest::uncServerName(); QTest::newRow("unc 1") << uncRoot << 2; QTest::newRow("unc 2") << uncRoot + QLatin1Char('/') << 2; QTest::newRow("unc 3") << uncRoot + "/testshare" << 2; @@ -1002,7 +1068,7 @@ void tst_QDir::entryListSimple() QDir dir(dirName); QStringList actual = dir.entryList(); - QVERIFY2(actual.count() >= countMin, msgEntryListFailed(actual.count(), countMin, dirName).constData()); + QVERIFY2(actual.size() >= countMin, msgEntryListFailed(actual.size(), countMin, dirName).constData()); } void tst_QDir::entryListWithSymLinks() @@ -1015,7 +1081,7 @@ void tst_QDir::entryListWithSymLinks() QFile::remove("testfile.cpp"); QDir dir; dir.mkdir("myDir"); - QFile("testfile.cpp").open(QIODevice::WriteOnly); + QVERIFY(QFile("testfile.cpp").open(QIODevice::WriteOnly)); # ifndef Q_NO_SYMLINKS_TO_DIRS QVERIFY(QFile::link("myDir", "myLinkToDir.lnk")); # endif @@ -1211,11 +1277,11 @@ void tst_QDir::setNameFilters() dir.setNameFilters(nameFilters); QStringList actual = dir.entryList(); - int max = qMin(actual.count(), expected.count()); + int max = qMin(actual.size(), expected.size()); for (int i=0; i<max; ++i) QCOMPARE(actual[i], expected[i]); - QCOMPARE(actual.count(), expected.count()); + QCOMPARE(actual.size(), expected.size()); } void @@ -1246,7 +1312,7 @@ tst_QDir::cleanPath_data() #else QTest::newRow("data10") << "/:/" << "/:"; #endif -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +#if defined(Q_OS_WIN) QTest::newRow("data11") << "//foo//bar" << "//foo/bar"; #endif QTest::newRow("data12") << "ab/a/" << "ab/a"; // Path item with length of 2 @@ -1258,17 +1324,26 @@ tst_QDir::cleanPath_data() QTest::newRow("data14") << "c://foo" << "c:/foo"; // Drive letters and unc path in one string -#if defined(Q_OS_WINRT) - const QString root = QDir::rootPath(); // has trailing slash - QTest::newRow("root-up") << (root + "path/..") << root; - QTest::newRow("above-root") << (root + "..") << (root + ".."); -#elif defined(Q_OS_WIN) +#if defined(Q_OS_WIN) QTest::newRow("data15") << "//c:/foo" << "//c:/foo"; QTest::newRow("drive-up") << "A:/path/.." << "A:/"; QTest::newRow("drive-above-root") << "A:/.." << "A:/.."; QTest::newRow("unc-server-up") << "//server/path/.." << "//server"; QTest::newRow("unc-server-above-root") << "//server/.." << "//server/.."; - QTest::newRow("longpath") << "\\\\?\\d:\\" << "d:/"; + + QTest::newRow("longpath") << uR"(\\?\d:\)"_s << u"d:/"_s; + QTest::newRow("longpath-slash") << u"//?/d:/"_s << u"d:/"_s; + QTest::newRow("longpath-mixed-slashes") << uR"(//?/d:\)"_s << u"d:/"_s; + QTest::newRow("longpath-mixed-slashes-2") << uR"(\\?\d:/)"_s << u"d:/"_s; + + QTest::newRow("unc-network-share") << uR"(\\?\UNC\localhost\c$\tmp.txt)"_s + << u"//localhost/c$/tmp.txt"_s; + QTest::newRow("unc-network-share-slash") << u"//?/UNC/localhost/c$/tmp.txt"_s + << u"//localhost/c$/tmp.txt"_s; + QTest::newRow("unc-network-share-mixed-slashes") << uR"(//?/UNC/localhost\c$\tmp.txt)"_s + << u"//localhost/c$/tmp.txt"_s; + QTest::newRow("unc-network-share-mixed-slashes-2") << uR"(\\?\UNC\localhost/c$/tmp.txt)"_s + << u"//localhost/c$/tmp.txt"_s; #else QTest::newRow("data15") << "//c:/foo" << "/c:/foo"; #endif // non-windows @@ -1385,7 +1460,7 @@ void tst_QDir::absoluteFilePath_data() QTest::addColumn<QString>("fileName"); QTest::addColumn<QString>("expectedFilePath"); -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +#if defined(Q_OS_WIN) QTest::newRow("UNC-rel") << "//machine/share" << "dir" << "//machine/share/dir"; QTest::newRow("UNC-abs") << "//machine/share/path/to/blah" << "/dir" << "//machine/share/dir"; QTest::newRow("UNC-UNC") << "//machine/share/path/to/blah" << "//host/share/path" << "//host/share/path"; @@ -1423,7 +1498,7 @@ void tst_QDir::absolutePath_data() QTest::addColumn<QString>("expectedPath"); QTest::newRow("0") << "/machine/share/dir1" << "/machine/share/dir1"; -#if (defined(Q_OS_WIN) && !defined(Q_OS_WINRT)) +#if defined(Q_OS_WIN) QTest::newRow("1") << "\\machine\\share\\dir1" << "/machine/share/dir1"; QTest::newRow("2") << "//machine/share/dir1" << "//machine/share/dir1"; QTest::newRow("3") << "\\\\machine\\share\\dir1" << "//machine/share/dir1"; @@ -1491,12 +1566,10 @@ void tst_QDir::relativeFilePath_data() QTest::newRow("27") << "C:" << "D:/" << "D:/"; QTest::newRow("28") << "C:/" << "D:" << "D:"; QTest::newRow("29") << "C:/" << "D:/" << "D:/"; -#ifndef Q_OS_WINRT QTest::newRow("30") << "C:/foo/bar" << "//anotherHost/foo/bar" << "//anotherHost/foo/bar"; QTest::newRow("31") << "//anotherHost/foo" << "//anotherHost/foo/bar" << "bar"; QTest::newRow("32") << "//anotherHost/foo" << "bar" << "bar"; QTest::newRow("33") << "//anotherHost/foo" << "C:/foo/bar" << "C:/foo/bar"; -#endif // !Q_OS_WINRT #endif QTest::newRow("resource0") << ":/prefix" << "foo.bar" << "foo.bar"; @@ -1550,7 +1623,7 @@ void tst_QDir::filePath() void tst_QDir::remove() { QFile f("remove-test"); - f.open(QIODevice::WriteOnly); + QVERIFY(f.open(QIODevice::WriteOnly)); f.close(); QDir dir; QVERIFY(dir.remove("remove-test")); @@ -1563,12 +1636,12 @@ void tst_QDir::remove() void tst_QDir::rename() { QFile f("rename-test"); - f.open(QIODevice::WriteOnly); + QVERIFY(f.open(QIODevice::WriteOnly)); f.close(); QDir dir; QVERIFY(dir.rename("rename-test", "rename-test-renamed")); QVERIFY(dir.rename("rename-test-renamed", "rename-test")); -#if defined(Q_OS_MAC) +#if defined(Q_OS_DARWIN) QVERIFY(!dir.rename("rename-test", "/etc/rename-test-renamed")); #elif !defined(Q_OS_WIN) // on windows this is possible - maybe make the test a bit better @@ -1657,7 +1730,10 @@ void tst_QDir::dirName() void tst_QDir::operator_eq() { QDir dir1("."); +QT_WARNING_PUSH +QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded") dir1 = dir1; +QT_WARNING_POP dir1.setPath(".."); } @@ -1666,9 +1742,9 @@ void tst_QDir::dotAndDotDot() { QDir dir(QString((m_dataPath + "/testdir/"))); QStringList entryList = dir.entryList(QDir::Dirs); - QCOMPARE(entryList, QStringList() << QString(".") << QString("..") << QString("dir") << QString("spaces")); + QCOMPARE(entryList, QStringList({ u"."_s, u".."_s, u"dir"_s, u"dir.lnk"_s, u"spaces"_s })); entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - QCOMPARE(entryList, QStringList() << QString("dir") << QString("spaces")); + QCOMPARE(entryList, QStringList({ u"dir"_s, u"dir.lnk"_s, u"spaces"_s })); } void tst_QDir::homePath() @@ -1681,7 +1757,7 @@ void tst_QDir::homePath() QVERIFY(QDir::isAbsolutePath(strHome)); #ifdef Q_OS_UNIX - if (strHome.length() > 1) // root dir = "/" + if (strHome.size() > 1) // root dir = "/" QVERIFY(!strHome.endsWith('/')); QByteArray envHome = qgetenv("HOME"); @@ -1690,16 +1766,12 @@ void tst_QDir::homePath() qputenv("HOME", envHome); #elif defined(Q_OS_WIN) - if (strHome.length() > 3 // root dir = "c:/"; "//" is not really valid... -#if defined(Q_OS_WINRT) - && strHome.length() > QDir::rootPath().length() -#endif - ) + if (strHome.length() > 3) // root dir = "c:/"; "//" is not really valid... QVERIFY(!strHome.endsWith('/')); #endif QStringList entries = homeDir.entryList(); - for (int i = 0; i < entries.count(); ++i) { + for (int i = 0; i < entries.size(); ++i) { QFileInfo fi(QDir::homePath() + "/" + entries[i]); QCOMPARE(fi.exists(), true); } @@ -1715,7 +1787,7 @@ void tst_QDir::tempPath() QVERIFY(QDir::isAbsolutePath(path)); #ifdef Q_OS_UNIX - if (path.length() > 1) // root dir = "/" + if (path.size() > 1) // root dir = "/" QVERIFY(!path.endsWith('/')); #elif defined(Q_OS_WIN) if (path.length() > 3) // root dir = "c:/"; "//" is not really valid... @@ -1747,6 +1819,10 @@ void tst_QDir::nativeSeparators() QCOMPARE(QDir::fromNativeSeparators(QLatin1String("/")), QString("/")); QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("/")); QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\\\?\\C:\\")), QString("C:/")); + QCOMPARE(QDir::fromNativeSeparators(uR"(\\?\UNC\localhost\c$\tmp.txt)"_s), + u"//localhost/c$/tmp.txt"_s); + QCOMPARE(QDir::fromNativeSeparators(uR"(//?/UNC/localhost\c$\tmp.txt)"_s), + u"//localhost/c$/tmp.txt"_s); #else QCOMPARE(QDir::toNativeSeparators(QLatin1String("/")), QString("/")); QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\")); @@ -1786,16 +1862,16 @@ void tst_QDir::searchPaths() { QFETCH(QString, filename); QFETCH(QString, searchPathPrefixes); - QStringList searchPathPrefixList = searchPathPrefixes.split(";", QString::SkipEmptyParts); + QStringList searchPathPrefixList = searchPathPrefixes.split(";", Qt::SkipEmptyParts); QFETCH(QString, searchPaths); - QStringList searchPathsList = searchPaths.split(";", QString::SkipEmptyParts); + QStringList searchPathsList = searchPaths.split(";", Qt::SkipEmptyParts); QFETCH(QString, expectedAbsolutePath); bool exists = !expectedAbsolutePath.isEmpty(); - for (int i = 0; i < searchPathPrefixList.count(); ++i) { + for (int i = 0; i < searchPathPrefixList.size(); ++i) { QDir::setSearchPaths(searchPathPrefixList.at(i), searchPathsList.at(i).split(",")); } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { + for (int i = 0; i < searchPathPrefixList.size(); ++i) { QCOMPARE(QDir::searchPaths(searchPathPrefixList.at(i)), searchPathsList.at(i).split(",")); } @@ -1806,19 +1882,19 @@ void tst_QDir::searchPaths() QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath); } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { + for (int i = 0; i < searchPathPrefixList.size(); ++i) { QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList()); } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { + for (int i = 0; i < searchPathPrefixList.size(); ++i) { QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty()); } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { - foreach (QString path, searchPathsList.at(i).split(",")) { + for (int i = 0; i < searchPathPrefixList.size(); ++i) { + const auto parts = searchPathsList.at(i).split(","); + for (const QString &path : parts) QDir::addSearchPath(searchPathPrefixList.at(i), path); - } } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { + for (int i = 0; i < searchPathPrefixList.size(); ++i) { QCOMPARE(QDir::searchPaths(searchPathPrefixList.at(i)), searchPathsList.at(i).split(",")); } @@ -1829,10 +1905,10 @@ void tst_QDir::searchPaths() QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath); } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { + for (int i = 0; i < searchPathPrefixList.size(); ++i) { QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList()); } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { + for (int i = 0; i < searchPathPrefixList.size(); ++i) { QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty()); } } @@ -2142,18 +2218,15 @@ void tst_QDir::match() void tst_QDir::drives() { - QFileInfoList list(QDir::drives()); + const QFileInfoList list(QDir::drives()); #if defined(Q_OS_WIN) QVERIFY(list.count() >= 1); //system QLatin1Char systemdrive('c'); #endif -#if defined(Q_OS_WINRT) - QSKIP("WinRT has no concept of drives"); -#endif #if defined(Q_OS_WIN) QVERIFY(list.count() <= 26); bool foundsystem = false; - foreach (QFileInfo fi, list) { + for (const QFileInfo &fi : list) { QCOMPARE(fi.absolutePath().size(), 3); //"x:/" QCOMPARE(fi.absolutePath().at(1), QChar(QLatin1Char(':'))); QCOMPARE(fi.absolutePath().at(2), QChar(QLatin1Char('/'))); @@ -2162,7 +2235,7 @@ void tst_QDir::drives() } QCOMPARE(foundsystem, true); #else - QCOMPARE(list.count(), 1); //root + QCOMPARE(list.size(), 1); //root QCOMPARE(list.at(0).absolutePath(), QLatin1String("/")); #endif } @@ -2174,7 +2247,7 @@ void tst_QDir::arrayOperator() QStringList entries(dir1.entryList()); int i = dir2.count(); - QCOMPARE(i, entries.count()); + QCOMPARE(i, entries.size()); --i; for (;i>=0;--i) { QCOMPARE(dir2[i], entries.at(i)); @@ -2206,14 +2279,14 @@ void tst_QDir::equalityOperator_data() << true; //need a path in the root directory that is unlikely to be a symbolic link. -#if defined (Q_OS_WINRT) - QString pathinroot(QDir::rootPath() + QLatin1String("assets/..")); -#elif defined (Q_OS_WIN) +#if defined (Q_OS_WIN) QString pathinroot("c:/windows/.."); -#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) +#elif defined(Q_OS_ANDROID) QString pathinroot("/system/.."); #elif defined(Q_OS_HAIKU) QString pathinroot("/boot/.."); +#elif defined(Q_OS_VXWORKS) + QString pathinroot("/tmp/.."); #else QString pathinroot("/usr/.."); #endif @@ -2279,9 +2352,9 @@ void tst_QDir::isRelative_data() QTest::newRow("homepath") << QDir::homePath() << false; QTest::newRow("temppath") << QDir::tempPath() << false; QTest::newRow("rootpath") << QDir::rootPath() << false; - foreach (QFileInfo root, QDir::drives()) { + const auto drives = QDir::drives(); + for (const QFileInfo &root : drives) QTest::newRow(root.absolutePath().toLocal8Bit()) << root.absolutePath() << false; - } QTest::newRow("resource") << ":/prefix" << false; } @@ -2339,14 +2412,12 @@ void tst_QDir::cdBelowRoot_data() QTest::newRow("android") << "/" << "system" << "/system"; #elif defined(Q_OS_UNIX) QTest::newRow("unix") << "/" << "tmp" << "/tmp"; -#elif defined(Q_OS_WINRT) - QTest::newRow("winrt") << QDir::rootPath() << QDir::rootPath() << QDir::rootPath(); #else // Windows+CE const QString systemDrive = QString::fromLocal8Bit(qgetenv("SystemDrive")) + QLatin1Char('/'); const QString systemRoot = QString::fromLocal8Bit(qgetenv("SystemRoot")); QTest::newRow("windows-drive") << systemDrive << systemRoot.mid(3) << QDir::cleanPath(systemRoot); - const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName(); + const QString uncRoot = QStringLiteral("//") + QTest::uncServerName(); const QString testDirectory = QStringLiteral("testshare"); QTest::newRow("windows-share") << uncRoot << testDirectory << QDir::cleanPath(uncRoot + QLatin1Char('/') + testDirectory); @@ -2368,9 +2439,6 @@ void tst_QDir::cdBelowRoot() if (::getuid() == 0) QSKIP("Running this test as root doesn't make sense"); #endif -#ifdef Q_OS_WINRT - QSKIP("WinRT has no concept of system root"); -#endif QDir dir(targetPath); QVERIFY2(!dir.cd("../.."), qPrintable(dir.absolutePath())); QCOMPARE(dir.path(), targetPath); @@ -2403,6 +2471,45 @@ void tst_QDir::nonEmptyDir() QVERIFY(!dir.isEmpty()); } +void tst_QDir::stdfilesystem() +{ +#if QT_CONFIG(cxx17_filesystem) + namespace fs = std::filesystem; + fs::path path("."); + QDir dir(path); + QCOMPARE(dir, QDir(QStringLiteral("."))); + + path = path / "testdir" / "dir"; + dir.setPath(path); + + QCOMPARE(dir, QDir(QStringLiteral("./testdir/dir"))); + + auto fsPath = dir.filesystemPath(); + QCOMPARE(QString::fromStdU16String(fsPath.u16string()), dir.path()); + fsPath = dir.filesystemAbsolutePath(); + QCOMPARE(QString::fromStdU16String(fsPath.u16string()), dir.absolutePath()); + fsPath = dir.filesystemCanonicalPath(); + QCOMPARE(QString::fromStdU16String(fsPath.u16string()), dir.canonicalPath()); + + QDir emptyPath(fs::path{}); + QCOMPARE(emptyPath, QDir(QStringLiteral("."))); + + { + // Test QDir ctor with filter and sorting reversed + QDir filteredDir(fs::path{"."} / "searchdir", "subdir*", + QDir::SortFlag::Reversed, QDir::Filter::Dirs); + QStringList entries = filteredDir.entryList(); + QCOMPARE(entries, QStringList() << "subdir2" << "subdir1"); + QCOMPARE(filteredDir.sorting(), QDir::SortFlag::Reversed); + QCOMPARE(filteredDir.filter(), QDir::Filter::Dirs); + QCOMPARE(filteredDir.nameFilters().size(), 1); + QCOMPARE(filteredDir.nameFilters().first(), "subdir*"); + } +#else + QSKIP("Not supported"); +#endif +} + QTEST_MAIN(tst_QDir) #include "tst_qdir.moc" |