Add StateLocation & GenericStateLocation to StandardLocation

The latest XDG spec (0.8) defines XDG_STATE_HOME that does not exist
in QStandardPaths::StandardLocation.

Some Linux distributions clean XDG_CACHE_HOME on restart which makes
XDG_STATE_HOME useful as a path for saving application state.

This commit adds StateLocation and GenericStateLocation to serve as a
StandardLocation for XDG_STATE_HOME for all platforms.

This commit also updates docs and tests to fit the new changes.

[ChangeLog][QStandardPaths] Added StateLocation &
GenericStateLocation to StandardLocation

Change-Id: I470602466c37f085062cc64d15ea243711728fa5
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Jonathan Ketchker 2023-08-27 12:45:04 +03:00
parent 505ed52cd4
commit 55f0738f16
10 changed files with 130 additions and 8 deletions

View File

@ -71,11 +71,13 @@
It affects the locations into which test programs might write It affects the locations into which test programs might write
files: \c GenericDataLocation, \c AppDataLocation, \c ConfigLocation, files: \c GenericDataLocation, \c AppDataLocation, \c ConfigLocation,
\c GenericConfigLocation, \c AppConfigLocation, \c GenericConfigLocation, \c AppConfigLocation,
\c StateLocation, \c GenericStateLocation,
\c GenericCacheLocation, and \c CacheLocation. Other locations \c GenericCacheLocation, and \c CacheLocation. Other locations
are not affected. are not affected.
On Unix, \c XDG_DATA_HOME is set to \c{~/.qttest/share}, On Unix, \c XDG_DATA_HOME is set to \c{~/.qttest/share},
\c XDG_CONFIG_HOME is set to \c{~/.qttest/config}, and \c XDG_CONFIG_HOME is set to \c{~/.qttest/config},
\c XDG_STATE_HOME is set \c{~/.qttest/state} and
\c XDG_CACHE_HOME is set to \c{~/.qttest/cache}. \c XDG_CACHE_HOME is set to \c{~/.qttest/cache}.
On macOS, data goes to \c{~/.qttest/Application Support}, On macOS, data goes to \c{~/.qttest/Application Support},

View File

@ -126,6 +126,12 @@ using namespace Qt::StringLiterals;
template files can be stored. This is a generic value. Note that the returned path may be template files can be stored. This is a generic value. Note that the returned path may be
empty if the system has no concept of a templates location. empty if the system has no concept of a templates location.
This enum value was added in Qt 6.4. This enum value was added in Qt 6.4.
\value [since 6.7] StateLocation Returns a directory location where user-specific application
state data files should be written. This is an application-specific directory,
and the returned path is never empty.
\value [since 6.7] GenericStateLocation Returns a directory location where shared state data files
across applications should be written. This value might be generic or application-specific,
but the returned path is never empty.
The following table gives examples of paths on different operating systems. The following table gives examples of paths on different operating systems.
The first path is the writable path (unless noted). Other, additional The first path is the writable path (unless noted). Other, additional
@ -166,6 +172,9 @@ using namespace Qt::StringLiterals;
\row \li CacheLocation \row \li CacheLocation
\li "~/Library/Caches/<APPNAME>", "/Library/Caches/<APPNAME>" \li "~/Library/Caches/<APPNAME>", "/Library/Caches/<APPNAME>"
\li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache" \li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache"
\row \li StateLocation
\li "~/Library/Preferences/<APPNAME>/State"
\li "C:/Users/<USER>/AppData/Local/<APPNAME>/State", "C:/ProgramData/<APPNAME>/State"
\row \li GenericDataLocation \row \li GenericDataLocation
\li "~/Library/Application Support", "/Library/Application Support" \li "~/Library/Application Support", "/Library/Application Support"
\li "C:/Users/<USER>/AppData/Local", "C:/ProgramData", "<APPDIR>", "<APPDIR>/data" \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData", "<APPDIR>", "<APPDIR>/data"
@ -184,6 +193,9 @@ using namespace Qt::StringLiterals;
\row \li GenericCacheLocation \row \li GenericCacheLocation
\li "~/Library/Caches", "/Library/Caches" \li "~/Library/Caches", "/Library/Caches"
\li "C:/Users/<USER>/AppData/Local/cache" \li "C:/Users/<USER>/AppData/Local/cache"
\row \li GenericStateLocation
\li "~/Library/Preferences/State"
\li "C:/Users/<USER>/AppData/Local/State", "C:/ProgramData/State"
\row \li AppDataLocation \row \li AppDataLocation
\li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources" \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
\li "C:/Users/<USER>/AppData/Roaming/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data", "<APPDIR>/data/<APPNAME>" \li "C:/Users/<USER>/AppData/Roaming/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data", "<APPDIR>/data/<APPNAME>"
@ -222,6 +234,8 @@ using namespace Qt::StringLiterals;
\li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>" \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
\row \li CacheLocation \row \li CacheLocation
\li "~/.cache/<APPNAME>" \li "~/.cache/<APPNAME>"
\row \li StateLocation
\li "~/.local/state/<APPNAME>"
\row \li GenericDataLocation \row \li GenericDataLocation
\li "~/.local/share", "/usr/local/share", "/usr/share" \li "~/.local/share", "/usr/local/share", "/usr/share"
\row \li RuntimeLocation \row \li RuntimeLocation
@ -234,6 +248,8 @@ using namespace Qt::StringLiterals;
\li "~/Downloads" \li "~/Downloads"
\row \li GenericCacheLocation \row \li GenericCacheLocation
\li "~/.cache" \li "~/.cache"
\row \li GenericStateLocation
\li "~/.local/state"
\row \li AppDataLocation \row \li AppDataLocation
\li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>" \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
\row \li AppConfigLocation \row \li AppConfigLocation
@ -279,6 +295,10 @@ using namespace Qt::StringLiterals;
\row \li CacheLocation \row \li CacheLocation
\li "<APPROOT>/cache", "<USER>/<APPNAME>/cache" \li "<APPROOT>/cache", "<USER>/<APPNAME>/cache"
\li "<APPROOT>/Library/Caches" \li "<APPROOT>/Library/Caches"
\row \li StateLocation
\li "<APPROOT>/files/state"
\row \li GenericStateLocation (there is shared state)
\li "<APPROOT>/files/state"
\row \li GenericDataLocation \row \li GenericDataLocation
\li "<USER>" [*] or "<USER>/<APPNAME>/files" \li "<USER>" [*] or "<USER>/<APPNAME>/files"
\li "<APPROOT>/Library/Application Support" \li "<APPROOT>/Library/Application Support"
@ -549,6 +569,8 @@ QString QStandardPaths::displayName(StandardLocation type)
return QCoreApplication::translate("QStandardPaths", "Application Data"); return QCoreApplication::translate("QStandardPaths", "Application Data");
case CacheLocation: case CacheLocation:
return QCoreApplication::translate("QStandardPaths", "Cache"); return QCoreApplication::translate("QStandardPaths", "Cache");
case StateLocation:
return QCoreApplication::translate("QStandardPaths", "State");
case GenericDataLocation: case GenericDataLocation:
return QCoreApplication::translate("QStandardPaths", "Shared Data"); return QCoreApplication::translate("QStandardPaths", "Shared Data");
case RuntimeLocation: case RuntimeLocation:
@ -559,6 +581,8 @@ QString QStandardPaths::displayName(StandardLocation type)
return QCoreApplication::translate("QStandardPaths", "Shared Configuration"); return QCoreApplication::translate("QStandardPaths", "Shared Configuration");
case GenericCacheLocation: case GenericCacheLocation:
return QCoreApplication::translate("QStandardPaths", "Shared Cache"); return QCoreApplication::translate("QStandardPaths", "Shared Cache");
case GenericStateLocation:
return QCoreApplication::translate("QStandardPaths", "Shared State");
case DownloadLocation: case DownloadLocation:
return QCoreApplication::translate("QStandardPaths", "Download"); return QCoreApplication::translate("QStandardPaths", "Download");
case AppDataLocation: case AppDataLocation:

View File

@ -38,7 +38,9 @@ public:
AppDataLocation, AppDataLocation,
AppConfigLocation, AppConfigLocation,
PublicShareLocation, PublicShareLocation,
TemplatesLocation TemplatesLocation,
StateLocation,
GenericStateLocation
}; };
Q_ENUM(StandardLocation) Q_ENUM(StandardLocation)

View File

@ -195,6 +195,9 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case QStandardPaths::ConfigLocation: case QStandardPaths::ConfigLocation:
case QStandardPaths::AppConfigLocation: case QStandardPaths::AppConfigLocation:
return getFilesDir() + testDir() + "/settings"_L1; return getFilesDir() + testDir() + "/settings"_L1;
case QStandardPaths::StateLocation:
case QStandardPaths::GenericStateLocation:
return getFilesDir() + testDir() + "/state"_L1;
case QStandardPaths::GenericDataLocation: case QStandardPaths::GenericDataLocation:
{ {
return QAndroidApplication::sdkVersion() >= 30 ? return QAndroidApplication::sdkVersion() >= 30 ?

View File

@ -120,8 +120,10 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return haikuAppStandardPath(B_USER_CACHE_DIRECTORY); return haikuAppStandardPath(B_USER_CACHE_DIRECTORY);
case GenericCacheLocation: case GenericCacheLocation:
return haikuStandardPath(B_USER_CACHE_DIRECTORY); return haikuStandardPath(B_USER_CACHE_DIRECTORY);
case ConfigLocation: // fall through case ConfigLocation:
case AppConfigLocation: case AppConfigLocation:
case StateLocation:
case GenericStateLocation:
return haikuAppStandardPath(B_USER_SETTINGS_DIRECTORY); return haikuAppStandardPath(B_USER_SETTINGS_DIRECTORY);
case GenericConfigLocation: case GenericConfigLocation:
return haikuStandardPath(B_USER_SETTINGS_DIRECTORY); return haikuStandardPath(B_USER_SETTINGS_DIRECTORY);

View File

@ -120,6 +120,12 @@ static QString baseWritableLocation(QStandardPaths::StandardLocation type,
case QStandardPaths::AppConfigLocation: case QStandardPaths::AppConfigLocation:
path = pathForDirectory(NSLibraryDirectory, mask) + "/Preferences"_L1; path = pathForDirectory(NSLibraryDirectory, mask) + "/Preferences"_L1;
break; break;
case QStandardPaths::StateLocation:
if (appendOrgAndApp) { break; }
Q_FALLTHROUGH();
case QStandardPaths::GenericStateLocation:
path = pathForDirectory(NSLibraryDirectory, mask) + "/Preferences/State"_L1;
break;
default: default:
path = pathForDirectory(dir, mask); path = pathForDirectory(dir, mask);
break; break;
@ -133,6 +139,11 @@ static QString baseWritableLocation(QStandardPaths::StandardLocation type,
case QStandardPaths::CacheLocation: case QStandardPaths::CacheLocation:
appendOrganizationAndApp(path); appendOrganizationAndApp(path);
break; break;
case QStandardPaths::StateLocation:
path = pathForDirectory(NSLibraryDirectory, mask) + "/Preferences"_L1;
appendOrganizationAndApp(path);
path += "/State"_L1;
break;
default: default:
break; break;
} }

View File

@ -196,6 +196,25 @@ QString QStandardPaths::writableLocation(StandardLocation type)
appendOrganizationAndApp(xdgCacheHome); appendOrganizationAndApp(xdgCacheHome);
return xdgCacheHome; return xdgCacheHome;
} }
case StateLocation:
case GenericStateLocation:
{
QString xdgStateHome;
if (isTestModeEnabled()) {
xdgStateHome = QDir::homePath() + "/.qttest/state"_L1;
} else {
// http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
xdgStateHome = QFile::decodeName(qgetenv("XDG_STATE_HOME"));
if (!xdgStateHome.startsWith(u'/'))
xdgStateHome.clear(); // spec says relative paths should be ignored
if (xdgStateHome.isEmpty())
xdgStateHome = QDir::homePath() + "/.local/state"_L1;
}
if (type == QStandardPaths::StateLocation)
appendOrganizationAndApp(xdgStateHome);
return xdgStateHome;
}
case AppDataLocation: case AppDataLocation:
case AppLocalDataLocation: case AppLocalDataLocation:
case GenericDataLocation: case GenericDataLocation:

View File

@ -105,8 +105,10 @@ static GUID writableSpecialFolderId(QStandardPaths::StandardLocation type)
FOLDERID_LocalAppData, // AppConfigLocation ("Local" path) FOLDERID_LocalAppData, // AppConfigLocation ("Local" path)
FOLDERID_Public, // PublicShareLocation FOLDERID_Public, // PublicShareLocation
FOLDERID_Templates, // TemplatesLocation FOLDERID_Templates, // TemplatesLocation
GUID(), // StateLocation
GUID(), // GenericStateLocation
}; };
static_assert(sizeof(folderIds) / sizeof(folderIds[0]) == size_t(QStandardPaths::TemplatesLocation + 1)); static_assert(sizeof(folderIds) / sizeof(folderIds[0]) == size_t(QStandardPaths::GenericStateLocation + 1));
// folders for low integrity processes // folders for low integrity processes
static const GUID folderIds_li[] = { static const GUID folderIds_li[] = {
@ -130,6 +132,8 @@ static GUID writableSpecialFolderId(QStandardPaths::StandardLocation type)
FOLDERID_LocalAppDataLow,// AppConfigLocation ("Local" path) FOLDERID_LocalAppDataLow,// AppConfigLocation ("Local" path)
FOLDERID_Public, // PublicShareLocation FOLDERID_Public, // PublicShareLocation
FOLDERID_Templates, // TemplatesLocation FOLDERID_Templates, // TemplatesLocation
GUID(), // StateLocation
GUID(), // GenericStateLocation
}; };
static_assert(sizeof(folderIds_li) == sizeof(folderIds)); static_assert(sizeof(folderIds_li) == sizeof(folderIds));
@ -184,6 +188,23 @@ QString QStandardPaths::writableLocation(StandardLocation type)
result = QDir::tempPath(); result = QDir::tempPath();
break; break;
case StateLocation:
result = sHGetKnownFolderPath(writableSpecialFolderId(AppLocalDataLocation));
if (!result.isEmpty()) {
appendTestMode(result);
appendOrganizationAndApp(result);
result += "/State"_L1;
}
break;
case GenericStateLocation:
result = sHGetKnownFolderPath(writableSpecialFolderId(GenericDataLocation));
if (!result.isEmpty()) {
appendTestMode(result);
result += "/State"_L1;
}
break;
default: default:
result = sHGetKnownFolderPath(writableSpecialFolderId(type)); result = sHGetKnownFolderPath(writableSpecialFolderId(type));
if (!result.isEmpty() && isConfigLocation(type)) { if (!result.isEmpty() && isConfigLocation(type)) {

View File

@ -71,12 +71,14 @@ static const StringEnum lookupTableData[] = {
{ "GenericCacheLocation", QStandardPaths::GenericCacheLocation, false }, { "GenericCacheLocation", QStandardPaths::GenericCacheLocation, false },
{ "GenericConfigLocation", QStandardPaths::GenericConfigLocation, false }, { "GenericConfigLocation", QStandardPaths::GenericConfigLocation, false },
{ "GenericDataLocation", QStandardPaths::GenericDataLocation, false }, { "GenericDataLocation", QStandardPaths::GenericDataLocation, false },
{ "GenericStateLocation", QStandardPaths::GenericStateLocation, false },
{ "HomeLocation", QStandardPaths::HomeLocation, false }, { "HomeLocation", QStandardPaths::HomeLocation, false },
{ "MoviesLocation", QStandardPaths::MoviesLocation, false }, { "MoviesLocation", QStandardPaths::MoviesLocation, false },
{ "MusicLocation", QStandardPaths::MusicLocation, false }, { "MusicLocation", QStandardPaths::MusicLocation, false },
{ "PicturesLocation", QStandardPaths::PicturesLocation, false }, { "PicturesLocation", QStandardPaths::PicturesLocation, false },
{ "PublicShareLocation", QStandardPaths::PublicShareLocation, false }, { "PublicShareLocation", QStandardPaths::PublicShareLocation, false },
{ "RuntimeLocation", QStandardPaths::RuntimeLocation, false }, { "RuntimeLocation", QStandardPaths::RuntimeLocation, false },
{ "StateLocation", QStandardPaths::StateLocation, true },
{ "TemplatesLocation", QStandardPaths::TemplatesLocation, false }, { "TemplatesLocation", QStandardPaths::TemplatesLocation, false },
{ "TempLocation", QStandardPaths::TempLocation, false } { "TempLocation", QStandardPaths::TempLocation, false }
}; };

View File

@ -27,7 +27,7 @@
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
// Update this when adding new enum values; update enumNames too // 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() static QString genericCacheLoc()
{ {
@ -38,6 +38,15 @@ static QString cacheLoc()
return QStandardPaths::writableLocation(QStandardPaths::CacheLocation); return QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
} }
static QString genericStateLoc()
{
return QStandardPaths::writableLocation(QStandardPaths::GenericStateLocation);
}
static QString stateLoc()
{
return QStandardPaths::writableLocation(QStandardPaths::StateLocation);
}
static QString genericDataLoc() static QString genericDataLoc()
{ {
return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
@ -98,14 +107,17 @@ private:
qputenv("XDG_CONFIG_DIRS", QFile::encodeName(m_globalConfigDir)); qputenv("XDG_CONFIG_DIRS", QFile::encodeName(m_globalConfigDir));
m_localAppDir = m_localAppTempDir.path(); m_localAppDir = m_localAppTempDir.path();
m_globalAppDir = m_globalAppTempDir.path(); m_globalAppDir = m_globalAppTempDir.path();
m_stateDir = m_stateTempDir.path();
qputenv("XDG_DATA_HOME", QFile::encodeName(m_localAppDir)); qputenv("XDG_DATA_HOME", QFile::encodeName(m_localAppDir));
qputenv("XDG_DATA_DIRS", QFile::encodeName(m_globalAppDir)); qputenv("XDG_DATA_DIRS", QFile::encodeName(m_globalAppDir));
qputenv("XDG_STATE_HOME", QFile::encodeName(m_stateDir));
} }
void setDefaultLocations() { void setDefaultLocations() {
qputenv("XDG_CONFIG_HOME", nullptr); qputenv("XDG_CONFIG_HOME", nullptr);
qputenv("XDG_CONFIG_DIRS", nullptr); qputenv("XDG_CONFIG_DIRS", nullptr);
qputenv("XDG_DATA_HOME", nullptr); qputenv("XDG_DATA_HOME", nullptr);
qputenv("XDG_DATA_DIRS", nullptr); qputenv("XDG_DATA_DIRS", nullptr);
qputenv("XDG_STATE_HOME", nullptr);
} }
#endif #endif
@ -120,6 +132,8 @@ private:
QTemporaryDir m_localAppTempDir; QTemporaryDir m_localAppTempDir;
QString m_globalAppDir; QString m_globalAppDir;
QTemporaryDir m_globalAppTempDir; QTemporaryDir m_globalAppTempDir;
QString m_stateDir;
QTemporaryDir m_stateTempDir;
}; };
static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths::DesktopLocation)] = { static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths::DesktopLocation)] = {
@ -141,7 +155,11 @@ static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths
"GenericCacheLocation", "GenericCacheLocation",
"GenericConfigLocation", "GenericConfigLocation",
"AppDataLocation", "AppDataLocation",
"AppConfigLocation" "AppConfigLocation",
"PublicShareLocation",
"TemplatesLocation",
"StateLocation",
"GenericStateLocation"
}; };
void tst_qstandardpaths::initTestCase() void tst_qstandardpaths::initTestCase()
@ -160,6 +178,7 @@ void tst_qstandardpaths::initTestCase()
QVERIFY2(m_globalConfigTempDir.isValid(), qPrintable(m_globalConfigTempDir.errorString())); QVERIFY2(m_globalConfigTempDir.isValid(), qPrintable(m_globalConfigTempDir.errorString()));
QVERIFY2(m_localAppTempDir.isValid(), qPrintable(m_localAppTempDir.errorString())); QVERIFY2(m_localAppTempDir.isValid(), qPrintable(m_localAppTempDir.errorString()));
QVERIFY2(m_globalAppTempDir.isValid(), qPrintable(m_globalAppTempDir.errorString())); QVERIFY2(m_globalAppTempDir.isValid(), qPrintable(m_globalAppTempDir.errorString()));
QVERIFY2(m_stateTempDir.isValid(), qPrintable(m_stateTempDir.errorString()));
} }
void tst_qstandardpaths::dump() void tst_qstandardpaths::dump()
@ -205,6 +224,8 @@ void tst_qstandardpaths::testDefaultLocations()
QCOMPARE(genericDataDirs.at(0), expectedDataHome); QCOMPARE(genericDataDirs.at(0), expectedDataHome);
QCOMPARE(genericDataDirs.at(1), QString::fromLatin1("/usr/local/share")); QCOMPARE(genericDataDirs.at(1), QString::fromLatin1("/usr/local/share"));
QCOMPARE(genericDataDirs.at(2), QString::fromLatin1("/usr/share")); QCOMPARE(genericDataDirs.at(2), QString::fromLatin1("/usr/share"));
const QString expectedGenericStateLocation = QDir::homePath() + QString::fromLatin1("/.local/state");
QCOMPARE(genericStateLoc(), expectedGenericStateLocation);
#endif #endif
} }
@ -283,25 +304,34 @@ void tst_qstandardpaths::enableTestMode()
// CacheLocation should be "GenericCacheLocation/organization-name/app-name" // CacheLocation should be "GenericCacheLocation/organization-name/app-name"
QCOMPARE(cacheLoc(), cacheDir + "/tst_qstandardpaths"_L1); 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"); QCoreApplication::setOrganizationName("Qt");
QCOMPARE(appConfigLoc(), configDir + "/Qt/tst_qstandardpaths"_L1); QCOMPARE(appConfigLoc(), configDir + "/Qt/tst_qstandardpaths"_L1);
QCOMPARE(appDataLoc(), dataDir + "/Qt/tst_qstandardpaths"_L1); QCOMPARE(appDataLoc(), dataDir + "/Qt/tst_qstandardpaths"_L1);
QCOMPARE(appLocalDataLoc(), dataDir + "/Qt/tst_qstandardpaths"_L1); QCOMPARE(appLocalDataLoc(), dataDir + "/Qt/tst_qstandardpaths"_L1);
QCOMPARE(cacheLoc(), cacheDir + "/Qt/tst_qstandardpaths"_L1); QCOMPARE(cacheLoc(), cacheDir + "/Qt/tst_qstandardpaths"_L1);
QCOMPARE(cacheLoc(), cacheDir + "/Qt/tst_qstandardpaths"_L1); QCOMPARE(stateLoc(), stateDir + "/Qt/tst_qstandardpaths"_L1);
QCoreApplication::setApplicationName("QtTest"); QCoreApplication::setApplicationName("QtTest");
QCOMPARE(appConfigLoc(), configDir + "/Qt/QtTest"_L1); QCOMPARE(appConfigLoc(), configDir + "/Qt/QtTest"_L1);
QCOMPARE(appDataLoc(), dataDir + "/Qt/QtTest"_L1); QCOMPARE(appDataLoc(), dataDir + "/Qt/QtTest"_L1);
QCOMPARE(appLocalDataLoc(), dataDir + "/Qt/QtTest"_L1); QCOMPARE(appLocalDataLoc(), dataDir + "/Qt/QtTest"_L1);
QCoreApplication::setApplicationName("QtTest");
QCOMPARE(cacheLoc(), cacheDir + "/Qt/QtTest"_L1); QCOMPARE(cacheLoc(), cacheDir + "/Qt/QtTest"_L1);
QCOMPARE(stateLoc(), stateDir + "/Qt/QtTest"_L1);
// Check these are unaffected by org/app names // Check these are unaffected by org/app names
QCOMPARE(genericConfigLoc(), configDir); QCOMPARE(genericConfigLoc(), configDir);
QCOMPARE(configLoc(), configDir); QCOMPARE(configLoc(), configDir);
QCOMPARE(genericDataLoc(), dataDir); QCOMPARE(genericDataLoc(), dataDir);
QCOMPARE(genericCacheLoc(), cacheDir); QCOMPARE(genericCacheLoc(), cacheDir);
QCOMPARE(genericStateLoc(), stateDir);
#endif #endif
// On all platforms, we want to ensure that the writableLocation is different in test mode and real mode. // On all platforms, we want to ensure that the writableLocation is different in test mode and real mode.
@ -315,6 +345,8 @@ void tst_qstandardpaths::enableTestMode()
testLocations.insert(QStandardPaths::GenericConfigLocation, genericConfigLoc()); testLocations.insert(QStandardPaths::GenericConfigLocation, genericConfigLoc());
testLocations.insert(QStandardPaths::CacheLocation, cacheLoc()); testLocations.insert(QStandardPaths::CacheLocation, cacheLoc());
testLocations.insert(QStandardPaths::GenericCacheLocation, genericCacheLoc()); 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? // On Windows, what should "Program Files" become, in test mode?
//testLocations.insert(QStandardPaths::ApplicationsLocation, QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)); //testLocations.insert(QStandardPaths::ApplicationsLocation, QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation));
@ -807,6 +839,10 @@ void tst_qstandardpaths::testXdgPathCleanup()
const QString cacheDir = cacheLoc(); const QString cacheDir = cacheLoc();
QCOMPARE_NE(cacheDir, relative); QCOMPARE_NE(cacheDir, relative);
qputenv("XDG_STATE_HOME", relative.toLatin1());
const QString stateDir = stateLoc();
QCOMPARE_NE(stateDir, relative);
qputenv("XDG_DATA_HOME", relative.toLatin1()); qputenv("XDG_DATA_HOME", relative.toLatin1());
const QString localDataDir = genericDataLoc(); const QString localDataDir = genericDataLoc();
QCOMPARE_NE(localDataDir, relative); QCOMPARE_NE(localDataDir, relative);