Make more of tst_settings pass on WASM
Missing parts of local storage backend implemented: - fallback mechanism - removal of all child keys for groups - variant decoding instead of string decoding - report AccessError when organization is empty in settings' ctor Some WASM-specific adjustments to tst_qsettings have also been introduced. Task-number: QTBUG-115509 Fixes: QTBUG-115037 Change-Id: I02cde965b11d98a64fc1ecb261d74838c508afd6 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
parent
6341e0d201
commit
63b64084cd
@ -14,6 +14,7 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
#include <emscripten/val.h>
|
#include <emscripten/val.h>
|
||||||
@ -23,6 +24,16 @@ QT_BEGIN_NAMESPACE
|
|||||||
using emscripten::val;
|
using emscripten::val;
|
||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
QStringView keyNameFromPrefixedStorageName(QStringView prefix, QStringView prefixedStorageName)
|
||||||
|
{
|
||||||
|
// Return the key slice after m_keyPrefix, or an empty string view if no match
|
||||||
|
if (!prefixedStorageName.startsWith(prefix))
|
||||||
|
return QStringView();
|
||||||
|
return prefixedStorageName.sliced(prefix.length());
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
//
|
//
|
||||||
// Native settings implementation for WebAssembly using window.localStorage
|
// Native settings implementation for WebAssembly using window.localStorage
|
||||||
// as the storage backend. localStorage is a key-value store with a synchronous
|
// as the storage backend. localStorage is a key-value store with a synchronous
|
||||||
@ -33,6 +44,7 @@ class QWasmLocalStorageSettingsPrivate final : public QSettingsPrivate
|
|||||||
public:
|
public:
|
||||||
QWasmLocalStorageSettingsPrivate(QSettings::Scope scope, const QString &organization,
|
QWasmLocalStorageSettingsPrivate(QSettings::Scope scope, const QString &organization,
|
||||||
const QString &application);
|
const QString &application);
|
||||||
|
~QWasmLocalStorageSettingsPrivate() final = default;
|
||||||
|
|
||||||
void remove(const QString &key) final;
|
void remove(const QString &key) final;
|
||||||
void set(const QString &key, const QVariant &value) final;
|
void set(const QString &key, const QVariant &value) final;
|
||||||
@ -45,10 +57,8 @@ public:
|
|||||||
QString fileName() const final;
|
QString fileName() const final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString prependStoragePrefix(const QString &key) const;
|
|
||||||
QStringView removeStoragePrefix(QStringView key) const;
|
|
||||||
val m_localStorage = val::global("window")["localStorage"];
|
val m_localStorage = val::global("window")["localStorage"];
|
||||||
QString m_keyPrefix;
|
QStringList m_keyPrefixes;
|
||||||
};
|
};
|
||||||
|
|
||||||
QWasmLocalStorageSettingsPrivate::QWasmLocalStorageSettingsPrivate(QSettings::Scope scope,
|
QWasmLocalStorageSettingsPrivate::QWasmLocalStorageSettingsPrivate(QSettings::Scope scope,
|
||||||
@ -56,87 +66,129 @@ QWasmLocalStorageSettingsPrivate::QWasmLocalStorageSettingsPrivate(QSettings::Sc
|
|||||||
const QString &application)
|
const QString &application)
|
||||||
: QSettingsPrivate(QSettings::NativeFormat, scope, organization, application)
|
: QSettingsPrivate(QSettings::NativeFormat, scope, organization, application)
|
||||||
{
|
{
|
||||||
|
if (organization.isEmpty()) {
|
||||||
|
setStatus(QSettings::AccessError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// The key prefix contians "qt" to separate Qt keys from other keys on localStorage, a
|
// The key prefix contians "qt" to separate Qt keys from other keys on localStorage, a
|
||||||
// version tag to allow for making changes to the key format in the future, the org
|
// version tag to allow for making changes to the key format in the future, the org
|
||||||
// and app names.
|
// and app names.
|
||||||
//
|
//
|
||||||
// User code could could create separate settings object with different org and app names,
|
// User code could could create separate settings object with different org and app names,
|
||||||
// and would expect them to have separate settings. Also, different webassembly instanaces
|
// and would expect them to have separate settings. Also, different webassembly instances
|
||||||
// on the page could write to the same window.localStorage. Add the org and app name
|
// on the page could write to the same window.localStorage. Add the org and app name
|
||||||
// to the key prefix to differentiate, even if that leads to keys with redundant sectons
|
// to the key prefix to differentiate, even if that leads to keys with redundant sections
|
||||||
// for the common case of a single org and app name.
|
// for the common case of a single org and app name.
|
||||||
|
//
|
||||||
|
// Also, the common Qt mechanism for user/system scope and all-application settings are
|
||||||
|
// implemented, using different prefixes.
|
||||||
|
const QString allAppsSetting = QStringLiteral("all-apps");
|
||||||
|
const QString systemSetting = QStringLiteral("sys-tem");
|
||||||
|
|
||||||
const QLatin1String separator("-");
|
const QLatin1String separator("-");
|
||||||
const QLatin1String doubleSeparator("--");
|
const QLatin1String doubleSeparator("--");
|
||||||
const QString escapedOrganization = QString(organization).replace(separator, doubleSeparator);
|
const QString escapedOrganization = QString(organization).replace(separator, doubleSeparator);
|
||||||
const QString escapedApplication = QString(application).replace(separator, doubleSeparator);
|
const QString escapedApplication = QString(application).replace(separator, doubleSeparator);
|
||||||
const QLatin1String prefix("qt-v0-");
|
const QString prefix = "qt-v0-" + escapedOrganization + separator;
|
||||||
m_keyPrefix.reserve(prefix.length() + escapedOrganization.length() +
|
if (scope == QSettings::Scope::UserScope) {
|
||||||
escapedApplication.length() + separator.length() * 2);
|
if (!escapedApplication.isEmpty())
|
||||||
m_keyPrefix = prefix + escapedOrganization + separator + escapedApplication + separator;
|
m_keyPrefixes.push_back(prefix + escapedApplication + separator);
|
||||||
|
m_keyPrefixes.push_back(prefix + allAppsSetting + separator);
|
||||||
|
}
|
||||||
|
if (!escapedApplication.isEmpty()) {
|
||||||
|
m_keyPrefixes.push_back(prefix + escapedApplication + separator + systemSetting
|
||||||
|
+ separator);
|
||||||
|
}
|
||||||
|
m_keyPrefixes.push_back(prefix + allAppsSetting + separator + systemSetting + separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmLocalStorageSettingsPrivate::remove(const QString &key)
|
void QWasmLocalStorageSettingsPrivate::remove(const QString &key)
|
||||||
{
|
{
|
||||||
const std::string keyString = prependStoragePrefix(key).toStdString();
|
const std::string removed = QString(m_keyPrefixes.first() + key).toStdString();
|
||||||
m_localStorage.call<val>("removeItem", keyString);
|
|
||||||
|
std::vector<std::string> children = { removed };
|
||||||
|
const int length = m_localStorage["length"].as<int>();
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
const QString storedKeyWithPrefix =
|
||||||
|
QString::fromStdString(m_localStorage.call<val>("key", i).as<std::string>());
|
||||||
|
|
||||||
|
const QStringView storedKey = keyNameFromPrefixedStorageName(
|
||||||
|
m_keyPrefixes.first(), QStringView(storedKeyWithPrefix));
|
||||||
|
if (storedKey.isEmpty() || !storedKey.startsWith(key))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
children.push_back(storedKeyWithPrefix.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &child : children)
|
||||||
|
m_localStorage.call<val>("removeItem", child);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmLocalStorageSettingsPrivate::set(const QString &key, const QVariant &value)
|
void QWasmLocalStorageSettingsPrivate::set(const QString &key, const QVariant &value)
|
||||||
{
|
{
|
||||||
const std::string keyString = prependStoragePrefix(key).toStdString();
|
const std::string keyString = QString(m_keyPrefixes.first() + key).toStdString();
|
||||||
const std::string valueString = QSettingsPrivate::variantToString(value).toStdString();
|
const std::string valueString = QSettingsPrivate::variantToString(value).toStdString();
|
||||||
m_localStorage.call<void>("setItem", keyString, valueString);
|
m_localStorage.call<void>("setItem", keyString, valueString);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<QVariant> QWasmLocalStorageSettingsPrivate::get(const QString &key) const
|
std::optional<QVariant> QWasmLocalStorageSettingsPrivate::get(const QString &key) const
|
||||||
{
|
{
|
||||||
const std::string keyString = prependStoragePrefix(key).toStdString();
|
for (const auto &prefix : m_keyPrefixes) {
|
||||||
|
const std::string keyString = QString(prefix + key).toStdString();
|
||||||
const emscripten::val value = m_localStorage.call<val>("getItem", keyString);
|
const emscripten::val value = m_localStorage.call<val>("getItem", keyString);
|
||||||
if (value.isNull())
|
if (!value.isNull())
|
||||||
|
return QSettingsPrivate::stringToVariant(
|
||||||
|
QString::fromStdString(value.as<std::string>()));
|
||||||
|
if (!fallbacks)
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
const QString valueString = QString::fromStdString(value.as<std::string>());
|
|
||||||
return QSettingsPrivate::stringToVariant(valueString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList QWasmLocalStorageSettingsPrivate::children(const QString &prefix, ChildSpec spec) const
|
QStringList QWasmLocalStorageSettingsPrivate::children(const QString &prefix, ChildSpec spec) const
|
||||||
{
|
{
|
||||||
|
QSet<QString> nodes;
|
||||||
// Loop through all keys on window.localStorage, return Qt keys belonging to
|
// Loop through all keys on window.localStorage, return Qt keys belonging to
|
||||||
// this application, with the correct prefix, and according to ChildSpec.
|
// this application, with the correct prefix, and according to ChildSpec.
|
||||||
QStringList children;
|
QStringList children;
|
||||||
const int length = m_localStorage["length"].as<int>();
|
const int length = m_localStorage["length"].as<int>();
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
|
for (const auto &storagePrefix : m_keyPrefixes) {
|
||||||
const QString keyString =
|
const QString keyString =
|
||||||
QString::fromStdString(m_localStorage.call<val>("key", i).as<std::string>());
|
QString::fromStdString(m_localStorage.call<val>("key", i).as<std::string>());
|
||||||
|
|
||||||
const QStringView key = removeStoragePrefix(QStringView(keyString));
|
const QStringView key =
|
||||||
if (key.isEmpty())
|
keyNameFromPrefixedStorageName(storagePrefix, QStringView(keyString));
|
||||||
continue;
|
if (!key.isEmpty() && key.startsWith(prefix)) {
|
||||||
if (!key.startsWith(prefix))
|
QStringList children;
|
||||||
continue;
|
|
||||||
|
|
||||||
QSettingsPrivate::processChild(key.sliced(prefix.length()), spec, children);
|
QSettingsPrivate::processChild(key.sliced(prefix.length()), spec, children);
|
||||||
|
if (!children.isEmpty())
|
||||||
|
nodes.insert(children.first());
|
||||||
|
}
|
||||||
|
if (!fallbacks)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return children;
|
return QStringList(nodes.begin(), nodes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmLocalStorageSettingsPrivate::clear()
|
void QWasmLocalStorageSettingsPrivate::clear()
|
||||||
{
|
{
|
||||||
// Get all Qt keys from window.localStorage
|
// Get all Qt keys from window.localStorage
|
||||||
const int length = m_localStorage["length"].as<int>();
|
const int length = m_localStorage["length"].as<int>();
|
||||||
std::vector<std::string> keys;
|
QStringList keys;
|
||||||
keys.reserve(length);
|
keys.reserve(length);
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i)
|
||||||
std::string key = (m_localStorage.call<val>("key", i).as<std::string>());
|
keys.append(QString::fromStdString((m_localStorage.call<val>("key", i).as<std::string>())));
|
||||||
keys.push_back(std::move(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove all Qt keys. Note that localStorage does not guarantee a stable
|
// Remove all Qt keys. Note that localStorage does not guarantee a stable
|
||||||
// iteration order when the storage is mutated, which is why removal is done
|
// iteration order when the storage is mutated, which is why removal is done
|
||||||
// in a second step after getting all keys.
|
// in a second step after getting all keys.
|
||||||
for (std::string key: keys) {
|
for (const QString &key : keys) {
|
||||||
if (removeStoragePrefix(QString::fromStdString(key)).isEmpty() == false)
|
if (!keyNameFromPrefixedStorageName(m_keyPrefixes.first(), key).isEmpty())
|
||||||
m_localStorage.call<val>("removeItem", key);
|
m_localStorage.call<val>("removeItem", key.toStdString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,19 +206,6 @@ QString QWasmLocalStorageSettingsPrivate::fileName() const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QWasmLocalStorageSettingsPrivate::prependStoragePrefix(const QString &key) const
|
|
||||||
{
|
|
||||||
return m_keyPrefix + key;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringView QWasmLocalStorageSettingsPrivate::removeStoragePrefix(QStringView key) const
|
|
||||||
{
|
|
||||||
// Return the key slice after m_keyPrefix, or an empty string view if no match
|
|
||||||
if (!key.startsWith(m_keyPrefix))
|
|
||||||
return QStringView();
|
|
||||||
return key.sliced(m_keyPrefix.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Native settings implementation for WebAssembly using the indexed database as
|
// Native settings implementation for WebAssembly using the indexed database as
|
||||||
// the storage backend
|
// the storage backend
|
||||||
@ -385,17 +424,37 @@ QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::
|
|||||||
format = QSettings::IniFormat;
|
format = QSettings::IniFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create settings backend according to selected format
|
if (format == WebLocalStorageFormat)
|
||||||
if (format == WebLocalStorageFormat) {
|
|
||||||
return new QWasmLocalStorageSettingsPrivate(scope, organization, application);
|
return new QWasmLocalStorageSettingsPrivate(scope, organization, application);
|
||||||
} else if (format == WebIdbFormat) {
|
if (format == WebIdbFormat)
|
||||||
return new QWasmIDBSettingsPrivate(scope, organization, application);
|
return new QWasmIDBSettingsPrivate(scope, organization, application);
|
||||||
} else if (format == QSettings::IniFormat) {
|
|
||||||
return new QConfFileSettingsPrivate(format, scope, organization, application);
|
|
||||||
}
|
|
||||||
|
|
||||||
qWarning() << "Unsupported settings format" << format;
|
// Create settings backend according to selected format
|
||||||
|
switch (format) {
|
||||||
|
case QSettings::Format::IniFormat:
|
||||||
|
case QSettings::Format::CustomFormat1:
|
||||||
|
case QSettings::Format::CustomFormat2:
|
||||||
|
case QSettings::Format::CustomFormat3:
|
||||||
|
case QSettings::Format::CustomFormat4:
|
||||||
|
case QSettings::Format::CustomFormat5:
|
||||||
|
case QSettings::Format::CustomFormat6:
|
||||||
|
case QSettings::Format::CustomFormat7:
|
||||||
|
case QSettings::Format::CustomFormat8:
|
||||||
|
case QSettings::Format::CustomFormat9:
|
||||||
|
case QSettings::Format::CustomFormat10:
|
||||||
|
case QSettings::Format::CustomFormat11:
|
||||||
|
case QSettings::Format::CustomFormat12:
|
||||||
|
case QSettings::Format::CustomFormat13:
|
||||||
|
case QSettings::Format::CustomFormat14:
|
||||||
|
case QSettings::Format::CustomFormat15:
|
||||||
|
case QSettings::Format::CustomFormat16:
|
||||||
|
return new QConfFileSettingsPrivate(format, scope, organization, application);
|
||||||
|
case QSettings::Format::InvalidFormat:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
case QSettings::Format::NativeFormat:
|
||||||
|
/* NOTREACHED */ assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -41,6 +41,10 @@
|
|||||||
#include "qplatformdefs.h"
|
#include "qplatformdefs.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_OS_WASM)
|
||||||
|
#include "emscripten/val.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QSettings::Format)
|
Q_DECLARE_METATYPE(QSettings::Format)
|
||||||
|
|
||||||
#ifndef QSETTINGS_P_H_VERSION
|
#ifndef QSETTINGS_P_H_VERSION
|
||||||
@ -323,6 +327,9 @@ void tst_QSettings::cleanupTestFiles()
|
|||||||
QSettings(QSettings::UserScope, "other.software.org").clear();
|
QSettings(QSettings::UserScope, "other.software.org").clear();
|
||||||
QSettings(QSettings::SystemScope, "other.software.org").clear();
|
QSettings(QSettings::SystemScope, "other.software.org").clear();
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(Q_OS_WASM)
|
||||||
|
emscripten::val::global("window")["localStorage"].call<void>("clear");
|
||||||
|
#endif
|
||||||
|
|
||||||
const QString foo(QLatin1String("foo"));
|
const QString foo(QLatin1String("foo"));
|
||||||
|
|
||||||
@ -2050,6 +2057,10 @@ void SettingsThread::run()
|
|||||||
|
|
||||||
void tst_QSettings::testThreadSafety()
|
void tst_QSettings::testThreadSafety()
|
||||||
{
|
{
|
||||||
|
#if !QT_CONFIG(thread)
|
||||||
|
QSKIP("This test requires threads to be enabled.");
|
||||||
|
#endif // !QT_CONFIG(thread)
|
||||||
|
|
||||||
SettingsThread threads[NumThreads];
|
SettingsThread threads[NumThreads];
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -2328,6 +2339,12 @@ void tst_QSettings::fromFile()
|
|||||||
|
|
||||||
QStringList strList = QStringList() << "hope" << "destiny" << "chastity";
|
QStringList strList = QStringList() << "hope" << "destiny" << "chastity";
|
||||||
|
|
||||||
|
#if !defined(Q_OS_WIN)
|
||||||
|
auto deleteFile = QScopeGuard([path, oldCur]() {
|
||||||
|
QFile::remove(path);
|
||||||
|
QDir::setCurrent(oldCur);
|
||||||
|
});
|
||||||
|
#endif // !defined(Q_OS_WIN)
|
||||||
{
|
{
|
||||||
QSettings settings1(path, format);
|
QSettings settings1(path, format);
|
||||||
QVERIFY(settings1.allKeys().isEmpty());
|
QVERIFY(settings1.allKeys().isEmpty());
|
||||||
@ -2363,8 +2380,6 @@ void tst_QSettings::fromFile()
|
|||||||
QCOMPARE(settings1.value("gamma/foo.bar").toInt(), 4);
|
QCOMPARE(settings1.value("gamma/foo.bar").toInt(), 4);
|
||||||
QCOMPARE(settings1.allKeys().size(), 3);
|
QCOMPARE(settings1.allKeys().size(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir::setCurrent(oldCur);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool containsSubList(QStringList mom, QStringList son)
|
static bool containsSubList(QStringList mom, QStringList son)
|
||||||
@ -3310,7 +3325,7 @@ void tst_QSettings::setPath()
|
|||||||
path checks that it has no bad side effects.
|
path checks that it has no bad side effects.
|
||||||
*/
|
*/
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN)
|
#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) && !defined(Q_OS_WASM)
|
||||||
TEST_PATH(i == 0, "conf", NativeFormat, UserScope, "alpha")
|
TEST_PATH(i == 0, "conf", NativeFormat, UserScope, "alpha")
|
||||||
TEST_PATH(i == 0, "conf", NativeFormat, SystemScope, "beta")
|
TEST_PATH(i == 0, "conf", NativeFormat, SystemScope, "beta")
|
||||||
#endif
|
#endif
|
||||||
@ -3427,6 +3442,10 @@ void tst_QSettings::rainersSyncBugOnMac()
|
|||||||
if (format == QSettings::NativeFormat)
|
if (format == QSettings::NativeFormat)
|
||||||
QSKIP("Apple OSes do not support direct reads from and writes to .plist files, due to caching and background syncing. See QTBUG-34899.");
|
QSKIP("Apple OSes do not support direct reads from and writes to .plist files, due to caching and background syncing. See QTBUG-34899.");
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(Q_OS_WASM)
|
||||||
|
if (format == QSettings::NativeFormat)
|
||||||
|
QSKIP("WASM's localStorage backend recognizes no concept of file");
|
||||||
|
#endif // Q_OS_WASM
|
||||||
|
|
||||||
QString fileName;
|
QString fileName;
|
||||||
|
|
||||||
@ -3497,14 +3516,14 @@ void tst_QSettings::consistentRegistryStorage()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) && !defined(QT_NO_STANDARDPATHS)
|
#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WASM) && !defined(QT_NO_STANDARDPATHS)
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
extern void clearDefaultPaths();
|
extern void clearDefaultPaths();
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
#endif
|
#endif
|
||||||
void tst_QSettings::testXdg()
|
void tst_QSettings::testXdg()
|
||||||
{
|
{
|
||||||
#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) && !defined(QT_NO_STANDARDPATHS)
|
#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WASM) && !defined(QT_NO_STANDARDPATHS)
|
||||||
// Note: The XDG_CONFIG_DIRS test must be done before overriding the system path
|
// Note: The XDG_CONFIG_DIRS test must be done before overriding the system path
|
||||||
// by QSettings::setPath/setSystemIniPath (used in cleanupTestFiles()).
|
// by QSettings::setPath/setSystemIniPath (used in cleanupTestFiles()).
|
||||||
clearDefaultPaths();
|
clearDefaultPaths();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user