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 <jake.petroules@qt.io>
This commit is contained in:
parent
764f5bf48c
commit
fd7e00aff5
@ -80,6 +80,9 @@ public:
|
|||||||
AccessError,
|
AccessError,
|
||||||
FormatError
|
FormatError
|
||||||
};
|
};
|
||||||
|
#ifndef QT_NO_QOBJECT
|
||||||
|
Q_ENUM(Status)
|
||||||
|
#endif
|
||||||
|
|
||||||
enum Format {
|
enum Format {
|
||||||
NativeFormat,
|
NativeFormat,
|
||||||
@ -108,11 +111,17 @@ public:
|
|||||||
CustomFormat15,
|
CustomFormat15,
|
||||||
CustomFormat16
|
CustomFormat16
|
||||||
};
|
};
|
||||||
|
#ifndef QT_NO_QOBJECT
|
||||||
|
Q_ENUM(Format)
|
||||||
|
#endif
|
||||||
|
|
||||||
enum Scope {
|
enum Scope {
|
||||||
UserScope,
|
UserScope,
|
||||||
SystemScope
|
SystemScope
|
||||||
};
|
};
|
||||||
|
#ifndef QT_NO_QOBJECT
|
||||||
|
Q_ENUM(Scope)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef QT_NO_QOBJECT
|
#ifndef QT_NO_QOBJECT
|
||||||
explicit QSettings(const QString &organization,
|
explicit QSettings(const QString &organization,
|
||||||
|
@ -175,18 +175,13 @@ static QCFType<CFPropertyListRef> macValue(const QVariant &value)
|
|||||||
break;
|
break;
|
||||||
case QVariant::DateTime:
|
case QVariant::DateTime:
|
||||||
{
|
{
|
||||||
/*
|
QDateTime dateTime = value.toDateTime();
|
||||||
CFDate, unlike QDateTime, doesn't store timezone information.
|
// CFDate, unlike QDateTime, doesn't store timezone information
|
||||||
*/
|
if (dateTime.timeSpec() == Qt::LocalTime)
|
||||||
QDateTime dt = value.toDateTime();
|
result = dateTime.toCFDate();
|
||||||
if (dt.timeSpec() == Qt::LocalTime) {
|
else
|
||||||
QDateTime reference;
|
|
||||||
reference.setSecsSinceEpoch(qint64(kCFAbsoluteTimeIntervalSince1970));
|
|
||||||
result = CFDateCreate(kCFAllocatorDefault, CFAbsoluteTime(reference.secsTo(dt)));
|
|
||||||
} else {
|
|
||||||
goto string_case;
|
goto string_case;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case QVariant::Bool:
|
case QVariant::Bool:
|
||||||
result = value.toBool() ? kCFBooleanTrue : kCFBooleanFalse;
|
result = value.toBool() ? kCFBooleanTrue : kCFBooleanFalse;
|
||||||
@ -303,9 +298,7 @@ static QVariant qtValue(CFPropertyListRef cfvalue)
|
|||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
} else if (typeId == CFDateGetTypeID()) {
|
} else if (typeId == CFDateGetTypeID()) {
|
||||||
QDateTime dt;
|
return QDateTime::fromCFDate(static_cast<CFDateRef>(cfvalue));
|
||||||
dt.setSecsSinceEpoch(qint64(kCFAbsoluteTimeIntervalSince1970));
|
|
||||||
return dt.addSecs((int)CFDateGetAbsoluteTime(static_cast<CFDateRef>(cfvalue)));
|
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ TARGET = tst_qsettings
|
|||||||
QT = core-private gui testlib
|
QT = core-private gui testlib
|
||||||
SOURCES = tst_qsettings.cpp
|
SOURCES = tst_qsettings.cpp
|
||||||
RESOURCES += qsettings.qrc
|
RESOURCES += qsettings.qrc
|
||||||
|
INCLUDEPATH += $$PWD/../../kernel/qmetatype
|
||||||
|
|
||||||
win32-msvc*:LIBS += advapi32.lib
|
win32-msvc*:LIBS += advapi32.lib
|
||||||
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
|
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
|
||||||
|
@ -41,6 +41,10 @@
|
|||||||
#include <QtCore/QSysInfo>
|
#include <QtCore/QSysInfo>
|
||||||
#include <QtGui/QKeySequence>
|
#include <QtGui/QKeySequence>
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QtGui>
|
||||||
|
#include "tst_qmetatype.h"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#if defined(Q_OS_WIN) && defined(Q_CC_GNU)
|
#if defined(Q_OS_WIN) && defined(Q_CC_GNU)
|
||||||
@ -165,6 +169,8 @@ private slots:
|
|||||||
void testNormalizedKey();
|
void testNormalizedKey();
|
||||||
void testVariantTypes_data();
|
void testVariantTypes_data();
|
||||||
void testVariantTypes();
|
void testVariantTypes();
|
||||||
|
void testMetaTypes_data();
|
||||||
|
void testMetaTypes();
|
||||||
#endif
|
#endif
|
||||||
void rainersSyncBugOnMac_data();
|
void rainersSyncBugOnMac_data();
|
||||||
void rainersSyncBugOnMac();
|
void rainersSyncBugOnMac();
|
||||||
@ -1121,6 +1127,102 @@ void tst_QSettings::setValue()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef QT_BUILD_INTERNAL
|
#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()
|
void tst_QSettings::testVariantTypes_data()
|
||||||
{
|
{
|
||||||
populateWithFormats();
|
populateWithFormats();
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
#include "tst_qmetatype.h"
|
||||||
#include "tst_qvariant_common.h"
|
#include "tst_qvariant_common.h"
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
@ -464,18 +465,6 @@ void tst_QMetaType::type_fromSubString()
|
|||||||
QCOMPARE(QMetaType::type(ba), expectedType);
|
QCOMPARE(QMetaType::type(ba), expectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FOR_EACH_PRIMITIVE_METATYPE(F) \
|
|
||||||
QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
|
|
||||||
QT_FOR_EACH_STATIC_CORE_POINTER(F) \
|
|
||||||
|
|
||||||
#define FOR_EACH_COMPLEX_CORE_METATYPE(F) \
|
|
||||||
QT_FOR_EACH_STATIC_CORE_CLASS(F) \
|
|
||||||
QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)
|
|
||||||
|
|
||||||
#define FOR_EACH_CORE_METATYPE(F) \
|
|
||||||
FOR_EACH_PRIMITIVE_METATYPE(F) \
|
|
||||||
FOR_EACH_COMPLEX_CORE_METATYPE(F) \
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct static_assert_trigger {
|
struct static_assert_trigger {
|
||||||
@ -495,237 +484,6 @@ Q_STATIC_ASSERT((!QMetaTypeId2<QList<int> >::IsBuiltIn));
|
|||||||
Q_STATIC_ASSERT((!QMetaTypeId2<QMap<int,int> >::IsBuiltIn));
|
Q_STATIC_ASSERT((!QMetaTypeId2<QMap<int,int> >::IsBuiltIn));
|
||||||
Q_STATIC_ASSERT((!QMetaTypeId2<QMetaType::Type>::IsBuiltIn));
|
Q_STATIC_ASSERT((!QMetaTypeId2<QMetaType::Type>::IsBuiltIn));
|
||||||
|
|
||||||
template <int ID>
|
|
||||||
struct MetaEnumToType {};
|
|
||||||
|
|
||||||
#define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \
|
|
||||||
template<> \
|
|
||||||
struct MetaEnumToType<QMetaType::MetaTypeName> { \
|
|
||||||
typedef RealType Type; \
|
|
||||||
};
|
|
||||||
FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE)
|
|
||||||
#undef DEFINE_META_ENUM_TO_TYPE
|
|
||||||
|
|
||||||
template <int ID>
|
|
||||||
struct DefaultValueFactory
|
|
||||||
{
|
|
||||||
typedef typename MetaEnumToType<ID>::Type Type;
|
|
||||||
static Type *create() { return new Type; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct DefaultValueFactory<QMetaType::Void>
|
|
||||||
{
|
|
||||||
typedef MetaEnumToType<QMetaType::Void>::Type Type;
|
|
||||||
static Type *create() { return 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int ID>
|
|
||||||
struct DefaultValueTraits
|
|
||||||
{
|
|
||||||
// By default we assume that a default-constructed value (new T) is
|
|
||||||
// initialized; e.g. QCOMPARE(*(new T), *(new T)) should succeed
|
|
||||||
enum { IsInitialized = true };
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS(MetaTypeName, MetaTypeId, RealType) \
|
|
||||||
template<> struct DefaultValueTraits<QMetaType::MetaTypeName> { \
|
|
||||||
enum { IsInitialized = false }; \
|
|
||||||
};
|
|
||||||
// Primitive types (int et al) aren't initialized
|
|
||||||
FOR_EACH_PRIMITIVE_METATYPE(DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS)
|
|
||||||
#undef DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS
|
|
||||||
|
|
||||||
template <int ID>
|
|
||||||
struct TestValueFactory {};
|
|
||||||
|
|
||||||
template<> struct TestValueFactory<QMetaType::Void> {
|
|
||||||
static void *create() { return 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct TestValueFactory<QMetaType::QString> {
|
|
||||||
static QString *create() { return new QString(QString::fromLatin1("QString")); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Int> {
|
|
||||||
static int *create() { return new int(0x12345678); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::UInt> {
|
|
||||||
static uint *create() { return new uint(0x12345678); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Bool> {
|
|
||||||
static bool *create() { return new bool(true); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Double> {
|
|
||||||
static double *create() { return new double(3.14); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QByteArray> {
|
|
||||||
static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QByteArrayList> {
|
|
||||||
static QByteArrayList *create() { return new QByteArrayList(QByteArrayList() << "Q" << "Byte" << "Array" << "List"); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QVariantMap> {
|
|
||||||
static QVariantMap *create() { return new QVariantMap(); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QVariantHash> {
|
|
||||||
static QVariantHash *create() { return new QVariantHash(); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QVariantList> {
|
|
||||||
static QVariantList *create() { return new QVariantList(QVariantList() << 123 << "Q" << "Variant" << "List"); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QChar> {
|
|
||||||
static QChar *create() { return new QChar(QChar('q')); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Long> {
|
|
||||||
static long *create() { return new long(0x12345678); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Short> {
|
|
||||||
static short *create() { return new short(0x1234); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Char> {
|
|
||||||
static char *create() { return new char('c'); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::ULong> {
|
|
||||||
static ulong *create() { return new ulong(0x12345678); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::UShort> {
|
|
||||||
static ushort *create() { return new ushort(0x1234); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::SChar> {
|
|
||||||
static signed char *create() { return new signed char(-12); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::UChar> {
|
|
||||||
static uchar *create() { return new uchar('u'); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Float> {
|
|
||||||
static float *create() { return new float(3.14f); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QObjectStar> {
|
|
||||||
static QObject * *create() { return new QObject *(0); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::VoidStar> {
|
|
||||||
static void * *create() { return new void *(0); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::LongLong> {
|
|
||||||
static qlonglong *create() { return new qlonglong(0x12345678); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::ULongLong> {
|
|
||||||
static qulonglong *create() { return new qulonglong(0x12345678); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QStringList> {
|
|
||||||
static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QBitArray> {
|
|
||||||
static QBitArray *create() { return new QBitArray(QBitArray(256, true)); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QDate> {
|
|
||||||
static QDate *create() { return new QDate(QDate::currentDate()); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QTime> {
|
|
||||||
static QTime *create() { return new QTime(QTime::currentTime()); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QDateTime> {
|
|
||||||
static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QUrl> {
|
|
||||||
static QUrl *create() { return new QUrl("http://www.example.org"); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QLocale> {
|
|
||||||
static QLocale *create() { return new QLocale(QLocale::c()); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QRect> {
|
|
||||||
static QRect *create() { return new QRect(10, 20, 30, 40); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QRectF> {
|
|
||||||
static QRectF *create() { return new QRectF(10, 20, 30, 40); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QSize> {
|
|
||||||
static QSize *create() { return new QSize(10, 20); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QSizeF> {
|
|
||||||
static QSizeF *create() { return new QSizeF(10, 20); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QLine> {
|
|
||||||
static QLine *create() { return new QLine(10, 20, 30, 40); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QLineF> {
|
|
||||||
static QLineF *create() { return new QLineF(10, 20, 30, 40); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QPoint> {
|
|
||||||
static QPoint *create() { return new QPoint(10, 20); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QPointF> {
|
|
||||||
static QPointF *create() { return new QPointF(10, 20); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QEasingCurve> {
|
|
||||||
static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QUuid> {
|
|
||||||
static QUuid *create() { return new QUuid(); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QModelIndex> {
|
|
||||||
static QModelIndex *create() { return new QModelIndex(); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QPersistentModelIndex> {
|
|
||||||
static QPersistentModelIndex *create() { return new QPersistentModelIndex(); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Nullptr> {
|
|
||||||
static std::nullptr_t *create() { return new std::nullptr_t; }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QRegExp> {
|
|
||||||
static QRegExp *create()
|
|
||||||
{
|
|
||||||
#ifndef QT_NO_REGEXP
|
|
||||||
return new QRegExp("A*");
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QRegularExpression> {
|
|
||||||
static QRegularExpression *create()
|
|
||||||
{
|
|
||||||
#ifndef QT_NO_REGEXP
|
|
||||||
return new QRegularExpression("abc.*def");
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QJsonValue> {
|
|
||||||
static QJsonValue *create() { return new QJsonValue(123.); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QJsonObject> {
|
|
||||||
static QJsonObject *create() {
|
|
||||||
QJsonObject *o = new QJsonObject();
|
|
||||||
o->insert("a", 123.);
|
|
||||||
o->insert("b", true);
|
|
||||||
o->insert("c", QJsonValue::Null);
|
|
||||||
o->insert("d", QLatin1String("ciao"));
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QJsonArray> {
|
|
||||||
static QJsonArray *create() {
|
|
||||||
QJsonArray *a = new QJsonArray();
|
|
||||||
a->append(123.);
|
|
||||||
a->append(true);
|
|
||||||
a->append(QJsonValue::Null);
|
|
||||||
a->append(QLatin1String("ciao"));
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QJsonDocument> {
|
|
||||||
static QJsonDocument *create() {
|
|
||||||
return new QJsonDocument(
|
|
||||||
QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QVariant> {
|
|
||||||
static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
|
|
||||||
};
|
|
||||||
|
|
||||||
void tst_QMetaType::create_data()
|
void tst_QMetaType::create_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<int>("type");
|
QTest::addColumn<int>("type");
|
||||||
|
279
tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
Normal file
279
tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
// Used by both tst_qmetatype and tst_qsettings
|
||||||
|
|
||||||
|
#ifndef TST_QMETATYPE_H
|
||||||
|
#define TST_QMETATYPE_H
|
||||||
|
|
||||||
|
#include <qmetatype.h>
|
||||||
|
|
||||||
|
#define FOR_EACH_PRIMITIVE_METATYPE(F) \
|
||||||
|
QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
|
||||||
|
QT_FOR_EACH_STATIC_CORE_POINTER(F) \
|
||||||
|
|
||||||
|
#define FOR_EACH_COMPLEX_CORE_METATYPE(F) \
|
||||||
|
QT_FOR_EACH_STATIC_CORE_CLASS(F) \
|
||||||
|
QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)
|
||||||
|
|
||||||
|
#define FOR_EACH_CORE_METATYPE(F) \
|
||||||
|
FOR_EACH_PRIMITIVE_METATYPE(F) \
|
||||||
|
FOR_EACH_COMPLEX_CORE_METATYPE(F) \
|
||||||
|
|
||||||
|
template <int ID>
|
||||||
|
struct MetaEnumToType {};
|
||||||
|
|
||||||
|
#define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \
|
||||||
|
template<> \
|
||||||
|
struct MetaEnumToType<QMetaType::MetaTypeName> { \
|
||||||
|
typedef RealType Type; \
|
||||||
|
};
|
||||||
|
FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE)
|
||||||
|
#undef DEFINE_META_ENUM_TO_TYPE
|
||||||
|
|
||||||
|
template <int ID>
|
||||||
|
struct DefaultValueFactory
|
||||||
|
{
|
||||||
|
typedef typename MetaEnumToType<ID>::Type Type;
|
||||||
|
static Type *create() { return new Type; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct DefaultValueFactory<QMetaType::Void>
|
||||||
|
{
|
||||||
|
typedef MetaEnumToType<QMetaType::Void>::Type Type;
|
||||||
|
static Type *create() { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <int ID>
|
||||||
|
struct DefaultValueTraits
|
||||||
|
{
|
||||||
|
// By default we assume that a default-constructed value (new T) is
|
||||||
|
// initialized; e.g. QCOMPARE(*(new T), *(new T)) should succeed
|
||||||
|
enum { IsInitialized = true };
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS(MetaTypeName, MetaTypeId, RealType) \
|
||||||
|
template<> struct DefaultValueTraits<QMetaType::MetaTypeName> { \
|
||||||
|
enum { IsInitialized = false }; \
|
||||||
|
};
|
||||||
|
// Primitive types (int et al) aren't initialized
|
||||||
|
FOR_EACH_PRIMITIVE_METATYPE(DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS)
|
||||||
|
#undef DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS
|
||||||
|
|
||||||
|
template <int ID>
|
||||||
|
struct TestValueFactory {};
|
||||||
|
|
||||||
|
template<> struct TestValueFactory<QMetaType::Void> {
|
||||||
|
static void *create() { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct TestValueFactory<QMetaType::QString> {
|
||||||
|
static QString *create() { return new QString(QString::fromLatin1("QString")); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Int> {
|
||||||
|
static int *create() { return new int(0x12345678); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::UInt> {
|
||||||
|
static uint *create() { return new uint(0x12345678); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Bool> {
|
||||||
|
static bool *create() { return new bool(true); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Double> {
|
||||||
|
static double *create() { return new double(3.14); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QByteArray> {
|
||||||
|
static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QByteArrayList> {
|
||||||
|
static QByteArrayList *create() { return new QByteArrayList(QByteArrayList() << "Q" << "Byte" << "Array" << "List"); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QVariantMap> {
|
||||||
|
static QVariantMap *create() { return new QVariantMap(); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QVariantHash> {
|
||||||
|
static QVariantHash *create() { return new QVariantHash(); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QVariantList> {
|
||||||
|
static QVariantList *create() { return new QVariantList(QVariantList() << 123 << "Q" << "Variant" << "List"); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QChar> {
|
||||||
|
static QChar *create() { return new QChar(QChar('q')); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Long> {
|
||||||
|
static long *create() { return new long(0x12345678); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Short> {
|
||||||
|
static short *create() { return new short(0x1234); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Char> {
|
||||||
|
static char *create() { return new char('c'); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::ULong> {
|
||||||
|
static ulong *create() { return new ulong(0x12345678); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::UShort> {
|
||||||
|
static ushort *create() { return new ushort(0x1234); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::SChar> {
|
||||||
|
static signed char *create() { return new signed char(-12); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::UChar> {
|
||||||
|
static uchar *create() { return new uchar('u'); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Float> {
|
||||||
|
static float *create() { return new float(3.14f); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QObjectStar> {
|
||||||
|
static QObject * *create() { return new QObject *(0); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::VoidStar> {
|
||||||
|
static void * *create() { return new void *(0); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::LongLong> {
|
||||||
|
static qlonglong *create() { return new qlonglong(0x12345678); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::ULongLong> {
|
||||||
|
static qulonglong *create() { return new qulonglong(0x12345678); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QStringList> {
|
||||||
|
static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QBitArray> {
|
||||||
|
static QBitArray *create() { return new QBitArray(QBitArray(256, true)); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QDate> {
|
||||||
|
static QDate *create() { return new QDate(QDate::currentDate()); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QTime> {
|
||||||
|
static QTime *create() { return new QTime(QTime::currentTime()); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QDateTime> {
|
||||||
|
static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QUrl> {
|
||||||
|
static QUrl *create() { return new QUrl("http://www.example.org"); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QLocale> {
|
||||||
|
static QLocale *create() { return new QLocale(QLocale::c()); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QRect> {
|
||||||
|
static QRect *create() { return new QRect(10, 20, 30, 40); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QRectF> {
|
||||||
|
static QRectF *create() { return new QRectF(10, 20, 30, 40); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QSize> {
|
||||||
|
static QSize *create() { return new QSize(10, 20); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QSizeF> {
|
||||||
|
static QSizeF *create() { return new QSizeF(10, 20); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QLine> {
|
||||||
|
static QLine *create() { return new QLine(10, 20, 30, 40); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QLineF> {
|
||||||
|
static QLineF *create() { return new QLineF(10, 20, 30, 40); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QPoint> {
|
||||||
|
static QPoint *create() { return new QPoint(10, 20); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QPointF> {
|
||||||
|
static QPointF *create() { return new QPointF(10, 20); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QEasingCurve> {
|
||||||
|
static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QUuid> {
|
||||||
|
static QUuid *create() { return new QUuid(); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QModelIndex> {
|
||||||
|
static QModelIndex *create() { return new QModelIndex(); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QPersistentModelIndex> {
|
||||||
|
static QPersistentModelIndex *create() { return new QPersistentModelIndex(); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Nullptr> {
|
||||||
|
static std::nullptr_t *create() { return new std::nullptr_t; }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QRegExp> {
|
||||||
|
static QRegExp *create()
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_REGEXP
|
||||||
|
return new QRegExp("A*");
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QRegularExpression> {
|
||||||
|
static QRegularExpression *create()
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_REGEXP
|
||||||
|
return new QRegularExpression("abc.*def");
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QJsonValue> {
|
||||||
|
static QJsonValue *create() { return new QJsonValue(123.); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QJsonObject> {
|
||||||
|
static QJsonObject *create() {
|
||||||
|
QJsonObject *o = new QJsonObject();
|
||||||
|
o->insert("a", 123.);
|
||||||
|
o->insert("b", true);
|
||||||
|
o->insert("c", QJsonValue::Null);
|
||||||
|
o->insert("d", QLatin1String("ciao"));
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QJsonArray> {
|
||||||
|
static QJsonArray *create() {
|
||||||
|
QJsonArray *a = new QJsonArray();
|
||||||
|
a->append(123.);
|
||||||
|
a->append(true);
|
||||||
|
a->append(QJsonValue::Null);
|
||||||
|
a->append(QLatin1String("ciao"));
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QJsonDocument> {
|
||||||
|
static QJsonDocument *create() {
|
||||||
|
return new QJsonDocument(
|
||||||
|
QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QVariant> {
|
||||||
|
static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TST_QMETATYPE_H
|
Loading…
x
Reference in New Issue
Block a user