diff options
Diffstat (limited to 'tests/auto/corelib/io/qfileinfo')
-rw-r--r-- | tests/auto/corelib/io/qfileinfo/CMakeLists.txt | 19 | ||||
-rw-r--r-- | tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp | 282 |
2 files changed, 204 insertions, 97 deletions
diff --git a/tests/auto/corelib/io/qfileinfo/CMakeLists.txt b/tests/auto/corelib/io/qfileinfo/CMakeLists.txt index da955ff6a6..3b997e1bca 100644 --- a/tests/auto/corelib/io/qfileinfo/CMakeLists.txt +++ b/tests/auto/corelib/io/qfileinfo/CMakeLists.txt @@ -1,14 +1,22 @@ -# Generated from qfileinfo.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qfileinfo Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qfileinfo LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qfileinfo SOURCES tst_qfileinfo.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) # Resources: @@ -41,7 +49,12 @@ qt_internal_add_resource(tst_qfileinfo "testdata" ##################################################################### qt_internal_extend_target(tst_qfileinfo CONDITION WIN32 - PUBLIC_LIBRARIES + LIBRARIES advapi32 netapi32 ) + +if (APPLE) + enable_language(OBJCXX) + set_source_files_properties(tst_qfileinfo.cpp PROPERTIES LANGUAGE OBJCXX) +endif() diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 395db040b0..563e4c2a83 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -1,35 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2021 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) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QStandardPaths> #include <QScopeGuard> -#include <QScopedValueRollback> #include <qfile.h> #include <qdir.h> @@ -56,23 +31,23 @@ #endif #include <qplatformdefs.h> #include <qdebug.h> -#if defined(Q_OS_WIN) -#include "../../../network-settings.h" -#endif #include <private/qfileinfo_p.h> #include "../../../../shared/filesystem.h" +#if defined(Q_OS_MACOS) +#include <Foundation/Foundation.h> +#endif + #if defined(Q_OS_VXWORKS) #define Q_NO_SYMLINKS #endif #if defined(Q_OS_WIN) -QT_BEGIN_NAMESPACE -extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; -QT_END_NAMESPACE bool IsUserAdmin(); #endif +using namespace Qt::StringLiterals; + inline bool qIsLikelyToBeFat(const QString &path) { QByteArray name = QStorageInfo(path).fileSystemType().toLower(); @@ -198,6 +173,7 @@ private slots: void systemFiles(); + void compareCompiles(); void compare_data(); void compare(); @@ -206,6 +182,7 @@ private slots: void fileTimes_data(); void fileTimes(); + void setFileTimes(); void fakeFileTimes_data(); void fakeFileTimes(); @@ -218,12 +195,15 @@ private slots: void isShortcut_data(); void isShortcut(); + void isAlias_data(); + void isAlias(); + void link_data(); void link(); void isHidden_data(); void isHidden(); -#if defined(Q_OS_MAC) +#if defined(Q_OS_DARWIN) void isHiddenFromFinder(); #endif @@ -260,6 +240,7 @@ private slots: void nonExistingFile(); void stdfilesystem(); + void readSymLink(); private: const QString m_currentDir; @@ -372,7 +353,7 @@ void tst_QFileInfo::isDir_data() QFile::remove("brokenlink.lnk"); QFile::remove("dummyfile"); QFile file3("dummyfile"); - file3.open(QIODevice::WriteOnly); + QVERIFY(file3.open(QIODevice::WriteOnly)); if (file3.link("brokenlink.lnk")) { file3.remove(); QFileInfo info3("brokenlink.lnk"); @@ -399,7 +380,7 @@ void tst_QFileInfo::isDir_data() //QTest::newRow("drive 2") << "t:s" << false; #endif #if defined(Q_OS_WIN) - const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName(); + 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; @@ -442,7 +423,7 @@ void tst_QFileInfo::isRoot_data() #endif #if defined(Q_OS_WIN) - const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName(); + 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" << false; @@ -486,7 +467,7 @@ void tst_QFileInfo::exists_data() QTest::newRow("simple dir with slash") << (m_resourcesDir + QLatin1Char('/')) << true; #if defined(Q_OS_WIN) - const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName(); + 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; @@ -677,7 +658,7 @@ void tst_QFileInfo::canonicalFilePath() QFile file(QDir::currentPath()); if (file.link(link)) { QFile tempfile("tempfile.txt"); - tempfile.open(QIODevice::ReadWrite); + QVERIFY(tempfile.open(QIODevice::ReadWrite)); tempfile.write("This file is generated by the QFileInfo autotest."); QVERIFY(tempfile.flush()); tempfile.close(); @@ -783,7 +764,7 @@ void tst_QFileInfo::bundleName_data() QTest::newRow("root") << "/" << ""; QTest::newRow("etc") << "/etc" << ""; -#ifdef Q_OS_MAC +#ifdef Q_OS_DARWIN QTest::newRow("safari") << "/Applications/Safari.app" << "Safari"; #endif } @@ -1014,6 +995,11 @@ void tst_QFileInfo::systemFiles() QVERIFY(fi.birthTime() <= fi.lastModified()); } +void tst_QFileInfo::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QFileInfo>(); +} + void tst_QFileInfo::compare_data() { QTest::addColumn<QString>("file1"); @@ -1040,7 +1026,7 @@ void tst_QFileInfo::compare_data() << m_sourceFile #if defined(Q_OS_WIN) << true; -#elif defined(Q_OS_MAC) +#elif defined(Q_OS_DARWIN) << !pathconf(QDir::currentPath().toLatin1().constData(), _PC_CASE_SENSITIVE); #else << false; @@ -1049,7 +1035,7 @@ void tst_QFileInfo::compare_data() void tst_QFileInfo::compare() { -#if defined(Q_OS_MAC) +#if defined(Q_OS_DARWIN) if (qstrcmp(QTest::currentDataTag(), "casesense1") == 0) QSKIP("Qt thinks all UNIX filesystems are case sensitive, see QTBUG-28246"); #endif @@ -1058,7 +1044,7 @@ void tst_QFileInfo::compare() QFETCH(QString, file2); QFETCH(bool, same); QFileInfo fi1(file1), fi2(file2); - QCOMPARE(fi1 == fi2, same); + QT_TEST_EQUALITY_OPS(fi1, fi2, same); } void tst_QFileInfo::consistent_data() @@ -1126,8 +1112,8 @@ void tst_QFileInfo::fileTimes() { // try to guess if file times on this filesystem round to the second QFileInfo cwd("."); - if (cwd.lastModified().toMSecsSinceEpoch() % 1000 == 0 - && cwd.lastRead().toMSecsSinceEpoch() % 1000 == 0) { + if (cwd.lastModified(QTimeZone::UTC).toMSecsSinceEpoch() % 1000 == 0 + && cwd.lastRead(QTimeZone::UTC).toMSecsSinceEpoch() % 1000 == 0) { fsClockSkew = sleepTime = 1000; noAccessTime = qIsLikelyToBeFat(fileName); @@ -1147,46 +1133,46 @@ void tst_QFileInfo::fileTimes() QDateTime birthTime, writeTime, metadataChangeTime, readTime; // --- Create file and write to it - beforeBirth = QDateTime::currentDateTime().addMSecs(-fsClockSkew); + beforeBirth = QDateTime::currentDateTimeUtc().addMSecs(-fsClockSkew); { QFile file(fileName); QVERIFY(file.open(QFile::WriteOnly | QFile::Text)); QFileInfo fileInfo(fileName); - birthTime = fileInfo.birthTime(); + birthTime = fileInfo.birthTime(QTimeZone::UTC); QVERIFY2(!birthTime.isValid() || birthTime > beforeBirth, datePairString(birthTime, beforeBirth)); QTest::qSleep(sleepTime); - beforeWrite = QDateTime::currentDateTime().addMSecs(-fsClockSkew); + beforeWrite = QDateTime::currentDateTimeUtc().addMSecs(-fsClockSkew); QTextStream ts(&file); ts << fileName << Qt::endl; } { QFileInfo fileInfo(fileName); - writeTime = fileInfo.lastModified(); + writeTime = fileInfo.lastModified(QTimeZone::UTC); QVERIFY2(writeTime > beforeWrite, datePairString(writeTime, beforeWrite)); - QCOMPARE(fileInfo.birthTime(), birthTime); // mustn't have changed + QCOMPARE(fileInfo.birthTime(QTimeZone::UTC), birthTime); // mustn't have changed } // --- Change the file's metadata QTest::qSleep(sleepTime); - beforeMetadataChange = QDateTime::currentDateTime().addMSecs(-fsClockSkew); + beforeMetadataChange = QDateTime::currentDateTimeUtc().addMSecs(-fsClockSkew); { QFile file(fileName); file.setPermissions(file.permissions()); } { QFileInfo fileInfo(fileName); - metadataChangeTime = fileInfo.metadataChangeTime(); + metadataChangeTime = fileInfo.metadataChangeTime(QTimeZone::UTC); QVERIFY2(metadataChangeTime > beforeMetadataChange, datePairString(metadataChangeTime, beforeMetadataChange)); QVERIFY(metadataChangeTime >= writeTime); // not all filesystems can store both times - QCOMPARE(fileInfo.birthTime(), birthTime); // mustn't have changed + QCOMPARE(fileInfo.birthTime(QTimeZone::UTC), birthTime); // mustn't have changed } // --- Read the file QTest::qSleep(sleepTime); - beforeRead = QDateTime::currentDateTime().addMSecs(-fsClockSkew); + beforeRead = QDateTime::currentDateTimeUtc().addMSecs(-fsClockSkew); { QFile file(fileName); QVERIFY(file.open(QFile::ReadOnly | QFile::Text)); @@ -1196,9 +1182,9 @@ void tst_QFileInfo::fileTimes() } QFileInfo fileInfo(fileName); - readTime = fileInfo.lastRead(); - QCOMPARE(fileInfo.lastModified(), writeTime); // mustn't have changed - QCOMPARE(fileInfo.birthTime(), birthTime); // mustn't have changed + readTime = fileInfo.lastRead(QTimeZone::UTC); + QCOMPARE(fileInfo.lastModified(QTimeZone::UTC), writeTime); // mustn't have changed + QCOMPARE(fileInfo.birthTime(QTimeZone::UTC), birthTime); // mustn't have changed QVERIFY(readTime.isValid()); #if defined(Q_OS_QNX) || defined(Q_OS_ANDROID) @@ -1222,6 +1208,28 @@ void tst_QFileInfo::fileTimes() QVERIFY(writeTime < beforeRead); } +void tst_QFileInfo::setFileTimes() +{ + QByteArray data("OLE\nOLE\nOLE"); + QTemporaryFile file; + + QVERIFY(file.open()); + QCOMPARE(file.write(data), data.size()); + QCOMPARE(file.size(), data.size()); + + QDateTime before = QDateTime::currentDateTimeUtc().addMSecs(-5000); + + QVERIFY(file.setFileTime(before, QFile::FileModificationTime)); + const QDateTime mtime = file.fileTime(QFile::FileModificationTime).toUTC(); + if (mtime.time().msec() == 0) + { + const QTime beforeTime = before.time(); + const QTime beforeTimeWithMSCutOff{beforeTime.hour(), beforeTime.minute(), beforeTime.second(), 0}; + before.setTime(beforeTimeWithMSCutOff); + } + QCOMPARE(mtime, before); +} + void tst_QFileInfo::fakeFileTimes_data() { QTest::addColumn<QDateTime>("when"); @@ -1239,7 +1247,7 @@ void tst_QFileInfo::fakeFileTimes() QFETCH(QDateTime, when); QFile file("faketimefile.txt"); - file.open(QIODevice::WriteOnly); + QVERIFY(file.open(QIODevice::WriteOnly)); file.write("\n", 1); file.close(); @@ -1248,12 +1256,12 @@ void tst_QFileInfo::fakeFileTimes() the file is open at the time. Of course, when writing, close() changes modification time, so need to re-open for read in order to setFileTime(). */ - file.open(QIODevice::ReadOnly); + QVERIFY(file.open(QIODevice::ReadOnly)); bool ok = file.setFileTime(when, QFileDevice::FileModificationTime); file.close(); if (ok) - QCOMPARE(QFileInfo(file.fileName()).lastModified(), when); + QCOMPARE(QFileInfo(file.fileName()).lastModified(QTimeZone::UTC), when); else QSKIP("Unable to set file metadata to contrived values"); } @@ -1270,7 +1278,7 @@ void tst_QFileInfo::isSymLink_data() QVERIFY(file1.link("link.lnk")); QFile file2("dummyfile"); - file2.open(QIODevice::WriteOnly); + QVERIFY(file2.open(QIODevice::WriteOnly)); QVERIFY(file2.link("brokenlink.lnk")); file2.remove(); @@ -1345,6 +1353,57 @@ void tst_QFileInfo::isShortcut() QCOMPARE(fi.isShortcut(), isShortcut); } +void tst_QFileInfo::isAlias_data() +{ + QFile::remove("symlink"); + QFile::remove("file-alias"); + QFile::remove("directory-alias"); + + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("isAlias"); + + QFile regularFile(m_sourceFile); + QTest::newRow("regular-file") << regularFile.fileName() << false; + QTest::newRow("directory") << QDir::currentPath() << false; + +#if defined(Q_OS_MACOS) + auto createAlias = [](const QString &target, const QString &alias) { + NSURL *targetUrl = [NSURL fileURLWithPath:target.toNSString()]; + NSURL *aliasUrl = [NSURL fileURLWithPath:alias.toNSString()]; + NSData *bookmarkData = [targetUrl bookmarkDataWithOptions:NSURLBookmarkCreationSuitableForBookmarkFile + includingResourceValuesForKeys:nil relativeToURL:nil error:nullptr]; + Q_ASSERT(bookmarkData); + + bool success = [NSURL writeBookmarkData:bookmarkData toURL:aliasUrl + options:NSURLBookmarkCreationSuitableForBookmarkFile error:nullptr]; + Q_ASSERT(success); + }; + + regularFile.link("symlink"); + QTest::newRow("symlink") << "symlink" << false; + + createAlias(regularFile.fileName(), QDir::current().filePath("file-alias")); + QTest::newRow("file-alias") << "file-alias" << true; + + createAlias(QDir::currentPath(), QDir::current().filePath("directory-alias")); + QTest::newRow("directory-alias") << "directory-alias" << true; + + regularFile.copy("non-existing-file"); + createAlias("non-existing-file", QDir::current().filePath("non-existing-file-alias")); + QDir::current().remove("non-existing-file"); + QTest::newRow("non-existing-file-alias") << "non-existing-file-alias" << true; +#endif +} + +void tst_QFileInfo::isAlias() +{ + QFETCH(QString, path); + QFETCH(bool, isAlias); + + QFileInfo fi(path); + QCOMPARE(fi.isAlias(), isAlias); +} + void tst_QFileInfo::isSymbolicLink_data() { QTest::addColumn<QString>("path"); @@ -1405,7 +1464,7 @@ void tst_QFileInfo::link_data() QFile file1(m_sourceFile); QFile file2("dummyfile"); - file2.open(QIODevice::WriteOnly); + QVERIFY(file2.open(QIODevice::WriteOnly)); QTest::newRow("existent file") << m_sourceFile << false << false << ""; #if defined(Q_OS_WIN) @@ -1473,9 +1532,9 @@ void tst_QFileInfo::isHidden_data() { QTest::addColumn<QString>("path"); QTest::addColumn<bool>("isHidden"); - foreach (const QFileInfo& info, QDir::drives()) { + const auto drives = QDir::drives(); + for (const QFileInfo& info : drives) QTest::newRow(qPrintable("drive." + info.path())) << info.path() << false; - } #if defined(Q_OS_WIN) QVERIFY(QDir("./hidden-directory").exists() || QDir().mkdir("./hidden-directory")); @@ -1490,14 +1549,14 @@ void tst_QFileInfo::isHidden_data() QTest::newRow("/path/to/.hidden-directory/..") << QDir::currentPath() + QString("/.hidden-directory/..") << true; #endif -#if defined(Q_OS_MAC) +#if defined(Q_OS_DARWIN) // /bin has the hidden attribute on OS X QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << true; #elif !defined(Q_OS_WIN) QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << false; #endif -#ifdef Q_OS_MAC +#ifdef Q_OS_DARWIN QTest::newRow("mac_etc") << QString::fromLatin1("/etc") << true; QTest::newRow("mac_private_etc") << QString::fromLatin1("/private/etc") << false; QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications") << false; @@ -1513,7 +1572,7 @@ void tst_QFileInfo::isHidden() QCOMPARE(fi.isHidden(), isHidden); } -#if defined(Q_OS_MAC) +#if defined(Q_OS_DARWIN) void tst_QFileInfo::isHiddenFromFinder() { const char *filename = "test_foobar.txt"; @@ -1539,7 +1598,7 @@ void tst_QFileInfo::isBundle_data() QTest::addColumn<QString>("path"); QTest::addColumn<bool>("isBundle"); QTest::newRow("root") << QString::fromLatin1("/") << false; -#ifdef Q_OS_MAC +#ifdef Q_OS_DARWIN QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications") << false; QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications/Safari.app") << true; #endif @@ -1593,14 +1652,14 @@ void tst_QFileInfo::refresh() file.flush(); QFileInfo info(file); - QDateTime lastModified = info.lastModified(); + QDateTime lastModified = info.lastModified(QTimeZone::UTC); QCOMPARE(info.size(), qint64(7)); QTest::qSleep(sleepTime); QCOMPARE(file.write("JOJOJO"), qint64(6)); file.flush(); - QCOMPARE(info.lastModified(), lastModified); + QCOMPARE(info.lastModified(QTimeZone::UTC), lastModified); QCOMPARE(info.size(), qint64(7)); #if defined(Q_OS_WIN) @@ -1608,7 +1667,7 @@ void tst_QFileInfo::refresh() #endif info.refresh(); QCOMPARE(info.size(), qint64(13)); - QVERIFY(info.lastModified() > lastModified); + QVERIFY(info.lastModified(QTimeZone::UTC) > lastModified); QFileInfo info2 = info; QCOMPARE(info2.size(), info.size()); @@ -1697,7 +1756,7 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() { // Symlink to UNC share pwd.mkdir("unc"); - QString uncTarget = QStringLiteral("//") + QtNetworkSettings::winServerName() + "/testshare"; + QString uncTarget = QStringLiteral("//") + QTest::uncServerName() + "/testshare"; QString uncSymlink = QDir::toNativeSeparators(pwd.absolutePath().append("\\unc\\link_to_unc")); QTest::newRow("UNC symlink") << NtfsTestResource(NtfsTestResource::SymLink, uncSymlink, uncTarget) @@ -1795,14 +1854,14 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks() creationResult.target = creationResult.target.sliced(4); // resolve volume to drive letter - static const QRegularExpression matchVolumeRe(uR"(^Volume\{([a-z]|[0-9]|-)+\}\\)"_qs, + static const QRegularExpression matchVolumeRe(uR"(^Volume\{([a-z]|[0-9]|-)+\}\\)"_s, QRegularExpression::CaseInsensitiveOption); auto matchVolume = matchVolumeRe.match(creationResult.target); if (matchVolume.hasMatch()) { Q_ASSERT(matchVolume.capturedStart() == 0); DWORD len; wchar_t buffer[MAX_PATH]; - const QString volumeName = uR"(\\?\)"_qs + matchVolume.captured(); + const QString volumeName = uR"(\\?\)"_s + matchVolume.captured(); if (GetVolumePathNamesForVolumeName(reinterpret_cast<LPCWSTR>(volumeName.utf16()), buffer, MAX_PATH, &len) != 0) { creationResult.target.replace(0, matchVolume.capturedLength(), @@ -1842,7 +1901,7 @@ void tst_QFileInfo::brokenShortcut() void tst_QFileInfo::isWritable() { QFile tempfile("tempfile.txt"); - tempfile.open(QIODevice::WriteOnly); + QVERIFY(tempfile.open(QIODevice::WriteOnly)); tempfile.write("This file is generated by the QFileInfo autotest."); tempfile.close(); @@ -1856,8 +1915,7 @@ void tst_QFileInfo::isWritable() #endif #if defined (Q_OS_WIN) - QScopedValueRollback<int> ntfsMode(qt_ntfs_permission_lookup); - qt_ntfs_permission_lookup = 1; + QNtfsPermissionCheckGuard permissionGuard; QFileInfo fi2(QFile::decodeName(qgetenv("SystemRoot") + "/system.ini")); QVERIFY(fi2.exists()); QCOMPARE(fi2.isWritable(), IsUserAdmin()); @@ -1878,7 +1936,13 @@ void tst_QFileInfo::isExecutable() { QString appPath = QCoreApplication::applicationDirPath(); #ifdef Q_OS_ANDROID - appPath += "/libtst_qfileinfo.so"; + QDir dir(appPath); + QVERIFY(dir.exists()); + dir.setNameFilters({ "libtst_qfileinfo*.so" }); + QStringList entries = dir.entryList(); + QCOMPARE(entries.size(), 1); + + appPath += "/" + entries[0]; #else appPath += "/tst_qfileinfo"; # if defined(Q_OS_WIN) @@ -1886,6 +1950,7 @@ void tst_QFileInfo::isExecutable() # endif #endif QFileInfo fi(appPath); + QVERIFY(fi.exists()); QCOMPARE(fi.isExecutable(), true); QCOMPARE(QFileInfo(m_proFile).isExecutable(), false); @@ -1956,7 +2021,7 @@ private: void tst_QFileInfo::testDecomposedUnicodeNames() { -#ifndef Q_OS_MAC +#ifndef Q_OS_DARWIN QSKIP("This is a OS X only test (unless you know more about filesystems, then maybe you should try it ;)"); #else QFETCH(QString, filePath); @@ -2100,7 +2165,7 @@ void tst_QFileInfo::owner() NetApiBufferFree(pBuf); } } - qt_ntfs_permission_lookup = 1; + QNtfsPermissionCheckGuard permissionGuard; #endif if (userName.isEmpty()) QSKIP("Can't retrieve the user name"); @@ -2117,9 +2182,6 @@ void tst_QFileInfo::owner() QCOMPARE(fi.owner(), userName); QFile::remove(fileName); -#if defined(Q_OS_WIN) - qt_ntfs_permission_lookup = 0; -#endif } void tst_QFileInfo::group() @@ -2203,10 +2265,10 @@ static void stateCheck(const QFileInfo &info, const QString &dirname, const QStr QCOMPARE(info.permissions(), QFile::Permissions()); - QVERIFY(!info.birthTime().isValid()); - QVERIFY(!info.metadataChangeTime().isValid()); - QVERIFY(!info.lastRead().isValid()); - QVERIFY(!info.lastModified().isValid()); + QVERIFY(!info.birthTime(QTimeZone::UTC).isValid()); + QVERIFY(!info.metadataChangeTime(QTimeZone::UTC).isValid()); + QVERIFY(!info.lastRead(QTimeZone::UTC).isValid()); + QVERIFY(!info.lastModified(QTimeZone::UTC).isValid()); }; void tst_QFileInfo::invalidState_data() @@ -2255,13 +2317,15 @@ void tst_QFileInfo::stdfilesystem() // We compare using absoluteFilePath since QFileInfo::operator== ends up using // canonicalFilePath which evaluates to empty-string for non-existent paths causing // these tests to always succeed. -#define COMPARE_CONSTRUCTION(filepath) \ - QCOMPARE(QFileInfo(fs::path(filepath)).absoluteFilePath(), \ - QFileInfo(QString::fromLocal8Bit(filepath)).absoluteFilePath()); \ - QCOMPARE(QFileInfo(base, fs::path(filepath)).absoluteFilePath(), \ - QFileInfo(base, QString::fromLocal8Bit(filepath)).absoluteFilePath()) - QDir base{ "../" }; // Used for the QFileInfo(QDir, <path>) ctor + auto doCompare = [&base](const char *filepath) { + QCOMPARE(QFileInfo(fs::path(filepath)).absoluteFilePath(), + QFileInfo(QString::fromLocal8Bit(filepath)).absoluteFilePath()); + QCOMPARE(QFileInfo(base, fs::path(filepath)).absoluteFilePath(), + QFileInfo(base, QString::fromLocal8Bit(filepath)).absoluteFilePath()); + }; +#define COMPARE_CONSTRUCTION(filepath) \ + doCompare(filepath); if (QTest::currentTestFailed()) return COMPARE_CONSTRUCTION("./file"); @@ -2274,7 +2338,22 @@ void tst_QFileInfo::stdfilesystem() COMPARE_CONSTRUCTION("/path/TO/file.txt"); COMPARE_CONSTRUCTION("./path/TO/file.txt"); COMPARE_CONSTRUCTION("../file.txt"); +#if !(defined(__GLIBCXX__) && defined(Q_OS_WIN32)) + // libstdc++ bug on Windows - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111244 COMPARE_CONSTRUCTION("./filæ.txt"); +#endif + + // Test unicode strings + QCOMPARE(QFileInfo(fs::path(u"./filæ.txt")).absoluteFilePath(), + QFileInfo(u"./filæ.txt"_s).absoluteFilePath()); + QCOMPARE(QFileInfo(base, fs::path(u"./filæ.txt")).absoluteFilePath(), + QFileInfo(base, u"./filæ.txt"_s).absoluteFilePath()); +#ifdef __cpp_char8_t + QCOMPARE(QFileInfo(fs::path(u8"./filæ.txt")).absoluteFilePath(), + QFileInfo(u8"./filæ.txt").absoluteFilePath()); + QCOMPARE(QFileInfo(base, fs::path(u8"./filæ.txt")).absoluteFilePath(), + QFileInfo(base, u8"./filæ.txt").absoluteFilePath()); +#endif #undef COMPARE_CONSTRUCTION { @@ -2336,5 +2415,20 @@ void tst_QFileInfo::stdfilesystem() #endif } +void tst_QFileInfo::readSymLink() +{ + QString symLinkName("./a.link"); + const auto tidier = qScopeGuard([symLinkName]() { QFile::remove(symLinkName); }); + +#ifdef Q_OS_WIN + QVERIFY2(CreateSymbolicLink(L"a.link", L"..\\..\\a", SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) + != 0, + "Failed to create symlink for test"); +#else + QVERIFY2(QFile::link("../../a", symLinkName), "Failed to create symlink for test"); +#endif + QFileInfo info(symLinkName); + QCOMPARE(info.readSymLink(), QString("../../a")); +} QTEST_MAIN(tst_QFileInfo) #include "tst_qfileinfo.moc" |