QStandardPaths/Unix: fix writableLocation() when test mode is enabled

In commit 482a75fef9 the code was changed to return early, but that
missed appending the organization and app names while test mode is
enabled.

Issue spotted by Edward.

Pick-to: 6.5
Change-Id: Ifd220f8990874a173413dcf71d105c04b605c800
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Ahmad Samir 2023-04-20 13:22:13 +02:00
parent e320280f61
commit a7555c3306
2 changed files with 98 additions and 29 deletions

View File

@ -180,16 +180,18 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case CacheLocation:
case GenericCacheLocation:
{
if (isTestModeEnabled())
return QDir::homePath() + "/.qttest/cache"_L1;
QString xdgCacheHome;
if (isTestModeEnabled()) {
xdgCacheHome = QDir::homePath() + "/.qttest/cache"_L1;
} else {
// http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
xdgCacheHome = QFile::decodeName(qgetenv("XDG_CACHE_HOME"));
if (!xdgCacheHome.startsWith(u'/'))
xdgCacheHome.clear(); // spec says relative paths should be ignored
// http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
QString xdgCacheHome = QFile::decodeName(qgetenv("XDG_CACHE_HOME"));
if (!xdgCacheHome.startsWith(u'/'))
xdgCacheHome.clear(); // spec says relative paths should be ignored
if (xdgCacheHome.isEmpty())
xdgCacheHome = QDir::homePath() + "/.cache"_L1;
if (xdgCacheHome.isEmpty())
xdgCacheHome = QDir::homePath() + "/.cache"_L1;
}
if (type == QStandardPaths::CacheLocation)
appendOrganizationAndApp(xdgCacheHome);
return xdgCacheHome;
@ -198,15 +200,17 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case AppLocalDataLocation:
case GenericDataLocation:
{
if (isTestModeEnabled())
return QDir::homePath() + "/.qttest/share"_L1;
QString xdgDataHome;
if (isTestModeEnabled()) {
xdgDataHome = QDir::homePath() + "/.qttest/share"_L1;
} else {
xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
if (!xdgDataHome.startsWith(u'/'))
xdgDataHome.clear(); // spec says relative paths should be ignored
QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
if (!xdgDataHome.startsWith(u'/'))
xdgDataHome.clear(); // spec says relative paths should be ignored
if (xdgDataHome.isEmpty())
xdgDataHome = QDir::homePath() + "/.local/share"_L1;
if (xdgDataHome.isEmpty())
xdgDataHome = QDir::homePath() + "/.local/share"_L1;
}
if (type == AppDataLocation || type == AppLocalDataLocation)
appendOrganizationAndApp(xdgDataHome);
return xdgDataHome;
@ -215,16 +219,18 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case GenericConfigLocation:
case AppConfigLocation:
{
if (isTestModeEnabled())
return QDir::homePath() + "/.qttest/config"_L1;
QString xdgConfigHome;
if (isTestModeEnabled()) {
xdgConfigHome = QDir::homePath() + "/.qttest/config"_L1;
} else {
// http://standards.freedesktop.org/basedir-spec/latest/
xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
if (!xdgConfigHome.startsWith(u'/'))
xdgConfigHome.clear(); // spec says relative paths should be ignored
// http://standards.freedesktop.org/basedir-spec/latest/
QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
if (!xdgConfigHome.startsWith(u'/'))
xdgConfigHome.clear(); // spec says relative paths should be ignored
if (xdgConfigHome.isEmpty())
xdgConfigHome = QDir::homePath() + "/.config"_L1;
if (xdgConfigHome.isEmpty())
xdgConfigHome = QDir::homePath() + "/.config"_L1;
}
if (type == AppConfigLocation)
appendOrganizationAndApp(xdgConfigHome);
return xdgConfigHome;

View File

@ -29,6 +29,41 @@ using namespace Qt::StringLiterals;
// Update this when adding new enum values; update enumNames too
static const int MaxStandardLocation = QStandardPaths::AppConfigLocation;
static QString genericCacheLoc()
{
return QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
}
static QString cacheLoc()
{
return QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
}
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
{
Q_OBJECT
@ -221,24 +256,52 @@ 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);
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);
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);
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);
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(cacheLoc(), cacheDir + "/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);
QCoreApplication::setApplicationName("QtTest");
QCOMPARE(cacheLoc(), cacheDir + "/Qt/QtTest"_L1);
// Check these are unaffected by org/app names
QCOMPARE(genericConfigLoc(), configDir);
QCOMPARE(configLoc(), configDir);
QCOMPARE(genericDataLoc(), dataDir);
QCOMPARE(genericCacheLoc(), cacheDir);
#endif
// On all platforms, we want to ensure that the writableLocation is different in test mode and real mode.