diff options
author | Liang Qi <liang.qi@qt.io> | 2016-10-13 09:49:38 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-10-13 09:49:38 +0200 |
commit | dfc177e3a99dd593db4b1e9445d6243ce75ebf07 (patch) | |
tree | 4e33c7be90a44642e672fff22ea163b500ff3aef /tests/auto/corelib/io/qsettings/tst_qsettings.cpp | |
parent | 72efb2e6f4af2fd909daaf9104f09fd1425acfb0 (diff) | |
parent | 1d6eb70dcec105af28d6a5e9b59d56c895c70389 (diff) |
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts:
qmake/library/qmakeevaluator.cpp
(cherry picked from commit 1af6dc2c8fb4d91400fddc5050166f972ae57c9a in qttools)
src/corelib/kernel/qcore_mac_objc.mm
src/gui/painting/qcolor.h
src/plugins/platforms/cocoa/qcocoawindow.mm
Change-Id: I5b3ec468a5a9a73911b528d3d24ff8e19f339f31
Diffstat (limited to 'tests/auto/corelib/io/qsettings/tst_qsettings.cpp')
-rw-r--r-- | tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 196 |
1 files changed, 178 insertions, 18 deletions
diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index 0e8a784423..fcff13b416 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -41,6 +41,10 @@ #include <QtCore/QSysInfo> #include <QtGui/QKeySequence> +#include <QtCore> +#include <QtGui> +#include "tst_qmetatype.h" + #include <cctype> #include <stdlib.h> #if defined(Q_OS_WIN) && defined(Q_CC_GNU) @@ -54,6 +58,10 @@ #include <unistd.h> #endif +#if defined(Q_OS_DARWIN) +#include <CoreFoundation/CoreFoundation.h> +#endif + Q_DECLARE_METATYPE(QSettings::Format) #ifndef QSETTINGS_P_H_VERSION @@ -72,7 +80,19 @@ static inline bool canWriteNativeSystemSettings() else qErrnoWarning(result, "RegOpenKeyEx failed"); return result == ERROR_SUCCESS; -#else // Q_OS_WIN && !Q_OS_WINRT +#elif defined(Q_OS_DARWIN) + CFStringRef key = CFSTR("canWriteNativeSystemSettings"); + #define ANY_APP_USER_AND_HOST kCFPreferencesAnyApplication, kCFPreferencesAnyUser, kCFPreferencesAnyHost + CFPreferencesSetValue(key, CFSTR("true"), ANY_APP_USER_AND_HOST); + if (CFPreferencesSynchronize(ANY_APP_USER_AND_HOST)) { + // Cleanup + CFPreferencesSetValue(key, 0, ANY_APP_USER_AND_HOST); + CFPreferencesSynchronize(ANY_APP_USER_AND_HOST); + return true; + } else { + return false; + } +#else return true; #endif } @@ -149,6 +169,8 @@ private slots: void testNormalizedKey(); void testVariantTypes_data(); void testVariantTypes(); + void testMetaTypes_data(); + void testMetaTypes(); #endif void rainersSyncBugOnMac_data(); void rainersSyncBugOnMac(); @@ -158,6 +180,8 @@ private slots: void testByteArray(); void iniCodec(); void bom(); + void embeddedZeroByte_data(); + void embeddedZeroByte(); void testXdg(); private: @@ -628,7 +652,6 @@ void tst_QSettings::testByteArray_data() #ifndef QT_NO_COMPRESS QTest::newRow("compressed") << qCompress(bytes); #endif - QTest::newRow("with \\0") << bytes + '\0' + bytes; } void tst_QSettings::testByteArray() @@ -679,6 +702,53 @@ void tst_QSettings::bom() QVERIFY(allkeys.contains("section2/foo2")); } +void tst_QSettings::embeddedZeroByte_data() +{ + QTest::addColumn<QVariant>("value"); + + QByteArray bytes("hello\0world", 11); + + QTest::newRow("bytearray\\0") << QVariant(bytes); + QTest::newRow("string\\0") << QVariant(QString::fromLatin1(bytes.data(), bytes.size())); + + bytes = QByteArray("@String("); + + QTest::newRow("@bytearray") << QVariant(bytes); + QTest::newRow("@string") << QVariant(QString(bytes)); + + bytes = QByteArray("@String(\0test", 13); + + QTest::newRow("@bytearray\\0") << QVariant(bytes); + QTest::newRow("@string\\0") << QVariant(QString::fromLatin1(bytes.data(), bytes.size())); +} + +void tst_QSettings::embeddedZeroByte() +{ + QFETCH(QVariant, value); + { + QSettings settings("QtProject", "tst_qsettings"); + settings.setValue(QTest::currentDataTag(), value); + } + { + QSettings settings("QtProject", "tst_qsettings"); + QVariant outValue = settings.value(QTest::currentDataTag()); + + switch (value.type()) { + case QVariant::ByteArray: + QCOMPARE(outValue.toByteArray(), value.toByteArray()); + break; + case QVariant::String: + QCOMPARE(outValue.toString(), value.toString()); + break; + default: + Q_UNREACHABLE(); + } + + if (value.toByteArray().contains(QChar::Null)) + QVERIFY(outValue.toByteArray().contains(QChar::Null)); + } +} + void tst_QSettings::testErrorHandling_data() { QTest::addColumn<int>("filePerms"); // -1 means file should not exist @@ -1058,6 +1128,102 @@ void tst_QSettings::setValue() } #ifdef QT_BUILD_INTERNAL + +template<int MetaTypeId> +static void testMetaTypesHelper(QSettings::Format format) +{ + typedef typename MetaEnumToType<MetaTypeId>::Type Type; + const char *key = QMetaType::typeName(MetaTypeId); + Type *value = TestValueFactory<MetaTypeId>::create(); + QVariant inputVariant = QVariant::fromValue(*value); + + static const QSettings::Scope scope = QSettings::UserScope; + static const QString organization("example.org"); + static const QString applicationName("FooApp"); + + { + QSettings settings(format, scope, organization, applicationName); + settings.setValue(key, inputVariant); + } + + QConfFile::clearCache(); + + { + QSettings settings(format, scope, organization, applicationName); + QVariant outputVariant = settings.value(key); + if (MetaTypeId != QMetaType::QVariant) + QVERIFY(outputVariant.canConvert(MetaTypeId)); + if (outputVariant.type() != inputVariant.type()) + qWarning() << "type mismatch between" << inputVariant << "and" << outputVariant; + QCOMPARE(qvariant_cast<Type >(outputVariant), *value); + } + + delete value; +} + +#define FOR_EACH_NONSUPPORTED_METATYPE(F)\ + F(Void) \ + F(Nullptr) \ + F(QObjectStar) \ + F(QModelIndex) \ + F(QJsonObject) \ + F(QJsonValue) \ + F(QJsonArray) \ + F(QJsonDocument) \ + F(QPersistentModelIndex) \ + +#define EXCLUDE_NON_SUPPORTED_METATYPES(MetaTypeName) \ +template<> void testMetaTypesHelper<QMetaType::MetaTypeName>(QSettings::Format) \ +{ \ + QSKIP("This metatype is not supported by QSettings."); \ +} +FOR_EACH_NONSUPPORTED_METATYPE(EXCLUDE_NON_SUPPORTED_METATYPES) +#undef EXCLUDE_NON_SUPPORTED_METATYPES + +void tst_QSettings::testMetaTypes_data() +{ + QTest::addColumn<QSettings::Format>("format"); + QTest::addColumn<int>("type"); + +#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ + { \ + const char *formatName = QMetaEnum::fromType<QSettings::Format>().valueToKey(formats[i]); \ + const char *typeName = QMetaType::typeName(QMetaType::MetaTypeName); \ + QTest::newRow(QString("%1:%2").arg(formatName).arg(typeName).toLatin1().constData()) \ + << QSettings::Format(formats[i]) << int(QMetaType::MetaTypeName); \ + } + int formats[] = { QSettings::NativeFormat, QSettings::IniFormat }; + for (int i = 0; i < int(sizeof(formats) / sizeof(int)); ++i) { + FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW) + } +#undef ADD_METATYPE_TEST_ROW +} + +typedef void (*TypeTestFunction)(QSettings::Format); + +void tst_QSettings::testMetaTypes() +{ + struct TypeTestFunctionGetter + { + static TypeTestFunction get(int type) + { + switch (type) { +#define RETURN_CREATE_FUNCTION(MetaTypeName, MetaTypeId, RealType) \ + case QMetaType::MetaTypeName: \ + return testMetaTypesHelper<QMetaType::MetaTypeName>; +FOR_EACH_CORE_METATYPE(RETURN_CREATE_FUNCTION) +#undef RETURN_CREATE_FUNCTION + } + return 0; + } + }; + + QFETCH(QSettings::Format, format); + QFETCH(int, type); + + TypeTestFunctionGetter::get(type)(format); +} + void tst_QSettings::testVariantTypes_data() { populateWithFormats(); @@ -1731,10 +1897,10 @@ void tst_QSettings::testChildKeysAndGroups() void tst_QSettings::testUpdateRequestEvent() { -#ifdef Q_OS_WINRT const QString oldCur = QDir::currentPath(); - QDir::setCurrent(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); -#endif + QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); + QVERIFY(QDir::root().mkpath(dataLocation)); + QDir::setCurrent(dataLocation); QFile::remove("foo"); QVERIFY(!QFile::exists("foo")); @@ -1762,9 +1928,7 @@ void tst_QSettings::testUpdateRequestEvent() QTRY_COMPARE(QFileInfo("foo").size(), qint64(0)); -#ifdef Q_OS_WINRT QDir::setCurrent(oldCur); -#endif } const int NumIterations = 5; @@ -2063,13 +2227,10 @@ void tst_QSettings::fromFile() { QFETCH(QSettings::Format, format); - // Sandboxed WinRT applications cannot write into the - // application directory. Hence reset the current - // directory -#ifdef Q_OS_WINRT const QString oldCur = QDir::currentPath(); - QDir::setCurrent(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); -#endif + QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); + QVERIFY(QDir::root().mkpath(dataLocation)); + QDir::setCurrent(dataLocation); QFile::remove("foo"); QVERIFY(!QFile::exists("foo")); @@ -2118,9 +2279,8 @@ void tst_QSettings::fromFile() QCOMPARE(settings1.value("gamma/foo.bar").toInt(), 4); QCOMPARE(settings1.allKeys().size(), 3); } -#ifdef Q_OS_WINRT + QDir::setCurrent(oldCur); -#endif } #ifdef QT_BUILD_INTERNAL @@ -2855,7 +3015,7 @@ void tst_QSettings::isWritable() QSettings s2(format, QSettings::SystemScope, "software.org", "Something Different"); QSettings s3(format, QSettings::SystemScope, "foo.org", "Something Different"); - if (s1.contains("foo")) { + if (s1.status() == QSettings::NoError && s1.contains("foo")) { #if defined(Q_OS_MACX) QVERIFY(s1.isWritable()); if (format == QSettings::NativeFormat) { @@ -3304,9 +3464,9 @@ void tst_QSettings::rainersSyncBugOnMac() { QFETCH(QSettings::Format, format); -#if defined(Q_OS_OSX) || defined(Q_OS_WINRT) +#if defined(Q_OS_DARWIN) || defined(Q_OS_WINRT) if (format == QSettings::NativeFormat) - QSKIP("OSX does 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 QString fileName; |