From fd7e00aff50c9ced966004238b2f74672dbbe300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 29 Sep 2016 16:19:28 +0200 Subject: Don't truncate QDateTime milliseconds when storing QSettings on Apple platforms The fix is trivial, but the patch adds a new QSettings tests that iterates most of the QMetaTypes and verifies that storing and retrieving them again gives the same value. This is a more complete test than the testVariantTypes tests, which is limited to a subset of the QVariant types. The new tests borrows logic from the QMetaType test machinery. QSettings has been Q_ENUM'ified in the process, for improved debug output. Note that on backends such as the INI backend, the metatype of the QVariant read from the settings will be a string, so it won't match the input QVariant type, but the result of converting that to the original value type should still work. Task-number: QTBUG-56124 Change-Id: Ib03a26abf77c9fb449b94160d28bc4baeb095f25 Reviewed-by: Jake Petroules --- tests/auto/corelib/io/qsettings/qsettings.pro | 1 + tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 102 ++++++++++++++++++++++ 2 files changed, 103 insertions(+) (limited to 'tests/auto/corelib/io/qsettings') diff --git a/tests/auto/corelib/io/qsettings/qsettings.pro b/tests/auto/corelib/io/qsettings/qsettings.pro index 3aa5ea6766..7da73a549a 100644 --- a/tests/auto/corelib/io/qsettings/qsettings.pro +++ b/tests/auto/corelib/io/qsettings/qsettings.pro @@ -3,6 +3,7 @@ TARGET = tst_qsettings QT = core-private gui testlib SOURCES = tst_qsettings.cpp RESOURCES += qsettings.qrc +INCLUDEPATH += $$PWD/../../kernel/qmetatype win32-msvc*:LIBS += advapi32.lib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index 8a2c9a9bbc..3a164e8ce4 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -41,6 +41,10 @@ #include #include +#include +#include +#include "tst_qmetatype.h" + #include #include #if defined(Q_OS_WIN) && defined(Q_CC_GNU) @@ -165,6 +169,8 @@ private slots: void testNormalizedKey(); void testVariantTypes_data(); void testVariantTypes(); + void testMetaTypes_data(); + void testMetaTypes(); #endif void rainersSyncBugOnMac_data(); void rainersSyncBugOnMac(); @@ -1121,6 +1127,102 @@ void tst_QSettings::setValue() } #ifdef QT_BUILD_INTERNAL + +template +static void testMetaTypesHelper(QSettings::Format format) +{ + typedef typename MetaEnumToType::Type Type; + const char *key = QMetaType::typeName(MetaTypeId); + Type *value = TestValueFactory::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(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(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("format"); + QTest::addColumn("type"); + +#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ + { \ + const char *formatName = QMetaEnum::fromType().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; +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(); -- cgit v1.2.3