diff options
Diffstat (limited to 'tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp')
-rw-r--r-- | tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp | 277 |
1 files changed, 213 insertions, 64 deletions
diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 2c0500eec9..84d0a505a4 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2020 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <qstandardpaths.h> #include <QTest> @@ -24,8 +24,54 @@ #define Q_XDG_PLATFORM #endif +using namespace Qt::StringLiterals; + // Update this when adding new enum values; update enumNames too -static const int MaxStandardLocation = QStandardPaths::AppConfigLocation; +static const int MaxStandardLocation = QStandardPaths::GenericStateLocation; + +static QString genericCacheLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation); +} +static QString cacheLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::CacheLocation); +} + +static QString genericStateLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::GenericStateLocation); +} +static QString stateLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::StateLocation); +} + +static QString genericDataLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); +} +static QString appDataLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); +} +static QString appLocalDataLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); +} + +static QString genericConfigLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); +} +static QString configLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); +} +static QString appConfigLoc() +{ + return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); +} class tst_qstandardpaths : public QObject { @@ -34,6 +80,7 @@ class tst_qstandardpaths : public QObject private slots: void initTestCase(); void dump(); + void init(); void testDefaultLocations(); void testCustomLocations(); void enableTestMode(); @@ -60,14 +107,17 @@ private: qputenv("XDG_CONFIG_DIRS", QFile::encodeName(m_globalConfigDir)); m_localAppDir = m_localAppTempDir.path(); m_globalAppDir = m_globalAppTempDir.path(); + m_stateDir = m_stateTempDir.path(); qputenv("XDG_DATA_HOME", QFile::encodeName(m_localAppDir)); qputenv("XDG_DATA_DIRS", QFile::encodeName(m_globalAppDir)); + qputenv("XDG_STATE_HOME", QFile::encodeName(m_stateDir)); } void setDefaultLocations() { - qputenv("XDG_CONFIG_HOME", QByteArray()); - qputenv("XDG_CONFIG_DIRS", QByteArray()); - qputenv("XDG_DATA_HOME", QByteArray()); - qputenv("XDG_DATA_DIRS", QByteArray()); + qputenv("XDG_CONFIG_HOME", nullptr); + qputenv("XDG_CONFIG_DIRS", nullptr); + qputenv("XDG_DATA_HOME", nullptr); + qputenv("XDG_DATA_DIRS", nullptr); + qputenv("XDG_STATE_HOME", nullptr); } #endif @@ -82,6 +132,8 @@ private: QTemporaryDir m_localAppTempDir; QString m_globalAppDir; QTemporaryDir m_globalAppTempDir; + QString m_stateDir; + QTemporaryDir m_stateTempDir; }; static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths::DesktopLocation)] = { @@ -103,7 +155,11 @@ static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths "GenericCacheLocation", "GenericConfigLocation", "AppDataLocation", - "AppConfigLocation" + "AppConfigLocation", + "PublicShareLocation", + "TemplatesLocation", + "StateLocation", + "GenericStateLocation" }; void tst_qstandardpaths::initTestCase() @@ -122,6 +178,7 @@ void tst_qstandardpaths::initTestCase() QVERIFY2(m_globalConfigTempDir.isValid(), qPrintable(m_globalConfigTempDir.errorString())); QVERIFY2(m_localAppTempDir.isValid(), qPrintable(m_localAppTempDir.errorString())); QVERIFY2(m_globalAppTempDir.isValid(), qPrintable(m_globalAppTempDir.errorString())); + QVERIFY2(m_stateTempDir.isValid(), qPrintable(m_stateTempDir.errorString())); } void tst_qstandardpaths::dump() @@ -138,25 +195,37 @@ void tst_qstandardpaths::dump() } } +void tst_qstandardpaths::init() +{ + // Some unittests set a custom org/app names, restore the original ones + // before each unittest is run + static const QString org = QCoreApplication::organizationName(); + static const QString app = QCoreApplication::applicationName(); + QCoreApplication::setOrganizationName(org); + QCoreApplication::setApplicationName(app); +} + void tst_qstandardpaths::testDefaultLocations() { #ifdef Q_XDG_PLATFORM setDefaultLocations(); const QString expectedConfHome = QDir::homePath() + QString::fromLatin1("/.config"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), expectedConfHome); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), expectedConfHome); + QCOMPARE(configLoc(), expectedConfHome); + QCOMPARE(genericConfigLoc(), expectedConfHome); const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation); - QCOMPARE(confDirs.count(), 2); + QCOMPARE(confDirs.size(), 2); QVERIFY(confDirs.contains(expectedConfHome)); QCOMPARE(QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation), confDirs); const QStringList genericDataDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); - QCOMPARE(genericDataDirs.count(), 3); + QCOMPARE(genericDataDirs.size(), 3); const QString expectedDataHome = QDir::homePath() + QString::fromLatin1("/.local/share"); QCOMPARE(genericDataDirs.at(0), expectedDataHome); QCOMPARE(genericDataDirs.at(1), QString::fromLatin1("/usr/local/share")); QCOMPARE(genericDataDirs.at(2), QString::fromLatin1("/usr/share")); + const QString expectedGenericStateLocation = QDir::homePath() + QString::fromLatin1("/.local/state"); + QCOMPARE(genericStateLoc(), expectedGenericStateLocation); #endif } @@ -175,8 +244,8 @@ void tst_qstandardpaths::testCustomLocations() setCustomLocations(); // test writableLocation() - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), m_localConfigDir); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), m_localConfigDir); + QCOMPARE(configLoc(), m_localConfigDir); + QCOMPARE(genericConfigLoc(), m_localConfigDir); // test locate() const QString thisFileName = QString::fromLatin1("aFile"); @@ -208,37 +277,76 @@ void tst_qstandardpaths::enableTestMode() setCustomLocations(); // for the global config dir const QString qttestDir = QDir::homePath() + QLatin1String("/.qttest"); - // ConfigLocation + // *Config*Location const QString configDir = qttestDir + QLatin1String("/config"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), configDir); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), configDir); + QCOMPARE(configLoc(), configDir); + QCOMPARE(genericConfigLoc(), configDir); const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation); QCOMPARE(confDirs, QStringList() << configDir << m_globalConfigDir); + // AppConfigLocation should be "GenericConfigLocation/organization-name/app-name" + QCOMPARE(appConfigLoc(), configDir + "/tst_qstandardpaths"_L1); - // GenericDataLocation + // *Data*Location const QString dataDir = qttestDir + QLatin1String("/share"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), dataDir); + QCOMPARE(genericDataLoc(), dataDir); const QStringList gdDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); QCOMPARE(gdDirs, QStringList() << dataDir << m_globalAppDir); + // AppDataLocation/AppLocalDataLocation should be + // "GenericDataLocation/organization-name/app-name" + QCOMPARE(appDataLoc(), dataDir + "/tst_qstandardpaths"_L1); + QCOMPARE(appLocalDataLoc(), dataDir + "/tst_qstandardpaths"_L1); - // GenericCacheLocation + // *CacheLocation const QString cacheDir = qttestDir + QLatin1String("/cache"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation), cacheDir); + QCOMPARE(genericCacheLoc(), cacheDir); const QStringList cacheDirs = QStandardPaths::standardLocations(QStandardPaths::GenericCacheLocation); QCOMPARE(cacheDirs, QStringList() << cacheDir); + // CacheLocation should be "GenericCacheLocation/organization-name/app-name" + QCOMPARE(cacheLoc(), cacheDir + "/tst_qstandardpaths"_L1); + + // *StateLocation + const QString stateDir = qttestDir + QLatin1String("/state"); + QCOMPARE(genericStateLoc(), stateDir); + const QStringList stateDirs = QStandardPaths::standardLocations(QStandardPaths::GenericStateLocation); + QCOMPARE(stateDirs, QStringList() << stateDir); + // StateLocation should be "GenericStateLocation/organization-name/app-name" + QCOMPARE(stateLoc(), stateDir + "/tst_qstandardpaths"_L1); + + QCoreApplication::setOrganizationName("Qt"); + QCOMPARE(appConfigLoc(), configDir + "/Qt/tst_qstandardpaths"_L1); + QCOMPARE(appDataLoc(), dataDir + "/Qt/tst_qstandardpaths"_L1); + QCOMPARE(appLocalDataLoc(), dataDir + "/Qt/tst_qstandardpaths"_L1); + QCOMPARE(cacheLoc(), cacheDir + "/Qt/tst_qstandardpaths"_L1); + QCOMPARE(stateLoc(), stateDir + "/Qt/tst_qstandardpaths"_L1); + + QCoreApplication::setApplicationName("QtTest"); + QCOMPARE(appConfigLoc(), configDir + "/Qt/QtTest"_L1); + QCOMPARE(appDataLoc(), dataDir + "/Qt/QtTest"_L1); + QCOMPARE(appLocalDataLoc(), dataDir + "/Qt/QtTest"_L1); + QCOMPARE(cacheLoc(), cacheDir + "/Qt/QtTest"_L1); + QCOMPARE(stateLoc(), stateDir + "/Qt/QtTest"_L1); + + // Check these are unaffected by org/app names + QCOMPARE(genericConfigLoc(), configDir); + QCOMPARE(configLoc(), configDir); + QCOMPARE(genericDataLoc(), dataDir); + QCOMPARE(genericCacheLoc(), cacheDir); + QCOMPARE(genericStateLoc(), stateDir); #endif // On all platforms, we want to ensure that the writableLocation is different in test mode and real mode. // Check this for locations where test programs typically write. Not desktop, download, music etc... typedef QHash<QStandardPaths::StandardLocation, QString> LocationHash; LocationHash testLocations; - testLocations.insert(QStandardPaths::AppDataLocation, QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - testLocations.insert(QStandardPaths::AppLocalDataLocation, QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); - testLocations.insert(QStandardPaths::GenericDataLocation, QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)); - testLocations.insert(QStandardPaths::ConfigLocation, QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); - testLocations.insert(QStandardPaths::GenericConfigLocation, QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); - testLocations.insert(QStandardPaths::CacheLocation, QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); - testLocations.insert(QStandardPaths::GenericCacheLocation, QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)); + testLocations.insert(QStandardPaths::AppDataLocation, appDataLoc()); + testLocations.insert(QStandardPaths::AppLocalDataLocation, appLocalDataLoc()); + testLocations.insert(QStandardPaths::GenericDataLocation, genericDataLoc()); + testLocations.insert(QStandardPaths::ConfigLocation, configLoc()); + testLocations.insert(QStandardPaths::GenericConfigLocation, genericConfigLoc()); + testLocations.insert(QStandardPaths::CacheLocation, cacheLoc()); + testLocations.insert(QStandardPaths::GenericCacheLocation, genericCacheLoc()); + testLocations.insert(QStandardPaths::StateLocation, stateLoc()); + testLocations.insert(QStandardPaths::GenericStateLocation, genericStateLoc()); // On Windows, what should "Program Files" become, in test mode? //testLocations.insert(QStandardPaths::ApplicationsLocation, QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)); @@ -260,7 +368,7 @@ void tst_qstandardpaths::testLocateAll() #ifdef Q_XDG_PLATFORM setCustomLocations(); const QStringList appsDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "applications", QStandardPaths::LocateDirectory); - QCOMPARE(appsDirs.count(), 0); // they don't exist yet + QCOMPARE(appsDirs.size(), 0); // they don't exist yet const QStringList expectedAppsDirs = QStringList() << m_localAppDir + QLatin1String("/applications") << m_globalAppDir + QLatin1String("/applications"); QDir().mkdir(expectedAppsDirs.at(0)); @@ -288,28 +396,24 @@ void tst_qstandardpaths::testDataLocation() // Android is an exception to this case, owing to the fact that // applications are sandboxed. #if !defined(Q_OS_ANDROID) - const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), base + "/tst_qstandardpaths"); + const QString base = genericDataLoc(); + QCOMPARE(appLocalDataLoc(), base + "/tst_qstandardpaths"); QCoreApplication::instance()->setOrganizationName("Qt"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), base + "/Qt/tst_qstandardpaths"); + QCOMPARE(appLocalDataLoc(), base + "/Qt/tst_qstandardpaths"); QCoreApplication::instance()->setApplicationName("QtTest"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), base + "/Qt/QtTest"); + QCOMPARE(appLocalDataLoc(), base + "/Qt/QtTest"); #endif #ifdef Q_XDG_PLATFORM setDefaultLocations(); const QString expectedAppDataDir = QDir::homePath() + QString::fromLatin1("/.local/share/Qt/QtTest"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), expectedAppDataDir); + QCOMPARE(appLocalDataLoc(), expectedAppDataDir); const QStringList appDataDirs = QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation); - QCOMPARE(appDataDirs.count(), 3); + QCOMPARE(appDataDirs.size(), 3); QCOMPARE(appDataDirs.at(0), expectedAppDataDir); QCOMPARE(appDataDirs.at(1), QString::fromLatin1("/usr/local/share/Qt/QtTest")); QCOMPARE(appDataDirs.at(2), QString::fromLatin1("/usr/share/Qt/QtTest")); #endif - - // reset for other tests - QCoreApplication::setOrganizationName(QString()); - QCoreApplication::setApplicationName(QString()); } void tst_qstandardpaths::testAppConfigLocation() @@ -317,19 +421,16 @@ void tst_qstandardpaths::testAppConfigLocation() // On all platforms where applications are not sandboxed, // AppConfigLocation should be GenericConfigLocation / organization name / app name #if !defined(Q_OS_ANDROID) - const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation), base + "/tst_qstandardpaths"); + const QString base = genericConfigLoc(); + QCOMPARE(appConfigLoc(), base + "/tst_qstandardpaths"); QCoreApplication::setOrganizationName("Qt"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation), base + "/Qt/tst_qstandardpaths"); + QCOMPARE(appConfigLoc(), base + "/Qt/tst_qstandardpaths"); QCoreApplication::setApplicationName("QtTest"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation), base + "/Qt/QtTest"); - // reset for other tests - QCoreApplication::setOrganizationName(QString()); - QCoreApplication::setApplicationName(QString()); + QCOMPARE(appConfigLoc(), base + "/Qt/QtTest"); #endif } -#ifndef Q_OS_WIN +#if !defined(Q_OS_WIN) && !defined(Q_OS_WASM) // Find "sh" on Unix. // It may exist twice, in /bin/sh and /usr/bin/sh, in that case use the PATH order. static inline QFileInfo findSh() @@ -338,7 +439,7 @@ static inline QFileInfo findSh() QByteArray pEnv = qgetenv("PATH"); const QLatin1Char pathSep(':'); const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, Qt::SkipEmptyParts); - foreach (const QString &path, rawPaths) { + for (const QString &path : rawPaths) { if (QFile::exists(path + sh)) return QFileInfo(path + sh); } @@ -383,6 +484,7 @@ void tst_qstandardpaths::testFindExecutable_data() << QString() << logo << logoPath; } #else +# ifndef Q_OS_WASM const QFileInfo shFi = findSh(); Q_ASSERT(shFi.exists()); const QString shPath = shFi.absoluteFilePath(); @@ -392,6 +494,7 @@ void tst_qstandardpaths::testFindExecutable_data() << QString() << shPath << shPath; QTest::newRow("unix-sh-relativepath") << QString(shFi.absolutePath()) << QString::fromLatin1("./sh") << shPath; +#endif /* !WASM */ #endif QTest::newRow("idontexist") << QString() << QString::fromLatin1("idontexist") << QString(); @@ -423,6 +526,9 @@ void tst_qstandardpaths::testFindExecutable() void tst_qstandardpaths::testFindExecutableLinkToDirectory() { +#ifdef Q_OS_WASM + QSKIP("No applicationdir on wasm"); +#else // link to directory const QString target = QDir::tempPath() + QDir::separator() + QLatin1String("link.lnk"); QFile::remove(target); @@ -430,9 +536,10 @@ void tst_qstandardpaths::testFindExecutableLinkToDirectory() QVERIFY(appFile.link(target)); QVERIFY(QStandardPaths::findExecutable(target).isEmpty()); QFile::remove(target); +#endif } -using RuntimeDirSetup = QString (*)(QDir &); +using RuntimeDirSetup = std::optional<QString> (*)(QDir &); Q_DECLARE_METATYPE(RuntimeDirSetup); void tst_qstandardpaths::testRuntimeDirectory() @@ -492,18 +599,18 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() QSKIP("Running this test as root doesn't make sense"); # endif - addRow("environment:non-existing", [](QDir &d) { + addRow("environment:non-existing", [](QDir &d) -> std::optional<QString> { return updateRuntimeDir(d.filePath("runtime")); }); - addRow("environment:existing", [](QDir &d) { + addRow("environment:existing", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("runtime"); d.mkdir("runtime"); QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner); return updateRuntimeDir(p); }); - addRow("environment-to-existing-wrong-perm", [](QDir &d) { + addRow("environment-to-existing-wrong-perm", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("runtime"); d.mkdir("runtime"); QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | @@ -516,7 +623,7 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("environment:wrong-owner", [](QDir &) { + addRow("environment:wrong-owner", [](QDir &) -> std::optional<QString> { QT_STATBUF st; QT_STAT("/", &st); @@ -531,10 +638,18 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("environment:file", [](QDir &d) { + // static so that it can be used in RuntimeDirSetup callable without capturing + static auto failedToOpen = [](const QFile &f) { + qCritical("QFile::Open: failed to open '%s': %s", + qPrintable(f.fileName()), qPrintable(f.errorString())); + return std::nullopt; + }; + + addRow("environment:file", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("file"); QFile f(p); - f.open(QIODevice::WriteOnly); + if (!f.open(QIODevice::WriteOnly)) + return failedToOpen(f); f.setPermissions(QFile::ReadOwner | QFile::WriteOwner); updateRuntimeDir(p); @@ -545,7 +660,7 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("environment:broken-symlink", [](QDir &d) { + addRow("environment:broken-symlink", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("link"); QFile::link(d.filePath("this-goes-nowhere"), p); updateRuntimeDir(p); @@ -556,7 +671,7 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("environment:symlink-to-dir", [](QDir &d) { + addRow("environment:symlink-to-dir", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("link"); d.mkdir("dir"); QFile::link(d.filePath("dir"), p); @@ -569,12 +684,12 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("no-environment:non-existing", [](QDir &) { + addRow("no-environment:non-existing", [](QDir &) -> std::optional<QString> { clearRuntimeDir(); return fallbackXdgRuntimeDir(); }); - addRow("no-environment:existing", [](QDir &d) { + addRow("no-environment:existing", [](QDir &d) -> std::optional<QString> { clearRuntimeDir(); QString p = fallbackXdgRuntimeDir(); d.mkdir(p); // probably has wrong permissions @@ -582,10 +697,11 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return p; }); - addRow("no-environment:fallback-is-file", [](QDir &) { + addRow("no-environment:fallback-is-file", [](QDir &) -> std::optional<QString> { QString p = fallbackXdgRuntimeDir(); QFile f(p); - f.open(QIODevice::WriteOnly); + if (!f.open(QIODevice::WriteOnly)) + return failedToOpen(f); f.setPermissions(QFile::ReadOwner | QFile::WriteOwner); clearRuntimeDir(); @@ -596,10 +712,11 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return QString(); }); - addRow("environment-and-fallback-are-files", [](QDir &d) { + addRow("environment-and-fallback-are-files", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("file1"); QFile f(p); - f.open(QIODevice::WriteOnly); + if (!f.open(QIODevice::WriteOnly)) + return failedToOpen(f); f.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup); updateRuntimeDir(p); QTest::ignoreMessage(QtWarningMsg, @@ -609,7 +726,8 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() f.close(); f.setFileName(fallbackXdgRuntimeDir()); - f.open(QIODevice::WriteOnly); + if (!f.open(QIODevice::WriteOnly)) + return failedToOpen(f); f.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup); QTest::ignoreMessage(QtWarningMsg, QString("QStandardPaths: runtime directory '%1' is not a directory, " @@ -649,7 +767,9 @@ void tst_qstandardpaths::testCustomRuntimeDirectory() qputenv("TMPDIR", QFile::encodeName(tempDir.path())); QFETCH(RuntimeDirSetup, setup); - QString expected = setup(d); + std::optional<QString> opt = setup(d); + QVERIFY(opt); + QString expected = *opt; QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); QCOMPARE(runtimeDir, expected); @@ -724,6 +844,35 @@ void tst_qstandardpaths::testXdgPathCleanup() QVERIFY(!appsDirs.contains("/applications")); QVERIFY(!appsDirs.contains(uncleanGlobalAppDir + "/applications")); QVERIFY(!appsDirs.contains("relative/path/applications")); + + const QString uncleanGlobalConfigDir = "/./" + QFile::encodeName(m_globalConfigDir); + qputenv("XDG_CONFIG_DIRS", QFile::encodeName(uncleanGlobalConfigDir) + "::relative/path"); + const QStringList configDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation); + QVERIFY(!configDirs.contains("relative/path"_L1)); + QVERIFY(!configDirs.contains(""_L1)); + + // Relative paths in XDG_* env vars are ignored + const QString relative("./someRelativeDir"); + + qputenv("XDG_CACHE_HOME", relative.toLatin1()); + const QString cacheDir = cacheLoc(); + QCOMPARE_NE(cacheDir, relative); + + qputenv("XDG_STATE_HOME", relative.toLatin1()); + const QString stateDir = stateLoc(); + QCOMPARE_NE(stateDir, relative); + + qputenv("XDG_DATA_HOME", relative.toLatin1()); + const QString localDataDir = genericDataLoc(); + QCOMPARE_NE(localDataDir, relative); + + qputenv("XDG_CONFIG_HOME", relative.toLatin1()); + const QString localConfig = configLoc(); + QCOMPARE_NE(localConfig, relative); + + qputenv("XDG_RUNTIME_DIR", relative.toLatin1()); + const QString runtimeDir = genericDataLoc(); + QCOMPARE_NE(runtimeDir, relative); #endif } |