From 85416ae6fd9da00540e471e5b0864a3e1678f423 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Sun, 7 Feb 2021 11:45:06 +0100 Subject: Split up the QMetaType unit test gcc 9 consumed enourmous amounts of memory building the test, regularly dying on a VM with 4GB RAM. Splitting it up helps. As a drive-by, use inline static variables, and rename the header used by other tests to tst_qmetatype_common.h. Change-Id: Ib716d8e3506aac6c87845e57b04cb1a4f6c68387 Reviewed-by: Fabian Kosmale --- tests/auto/corelib/kernel/qmetatype/CMakeLists.txt | 2 +- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 663 +-------------------- .../auto/corelib/kernel/qmetatype/tst_qmetatype.h | 430 ++++++------- .../corelib/kernel/qmetatype/tst_qmetatype2.cpp | 483 +++++++++++++++ .../kernel/qmetatype/tst_qmetatype_common.h | 298 +++++++++ 5 files changed, 966 insertions(+), 910 deletions(-) create mode 100644 tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp create mode 100644 tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h (limited to 'tests/auto/corelib/kernel/qmetatype') diff --git a/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt index d3e576127f..49fcecebc3 100644 --- a/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt @@ -9,7 +9,7 @@ list(APPEND test_data "./typeFlags.bin") qt_internal_add_test(tst_qmetatype SOURCES - tst_qmetatype.cpp + tst_qmetatype.h tst_qmetatype.cpp tst_qmetatype2.cpp DEFINES QT_DISABLE_DEPRECATED_BEFORE=0 INCLUDE_DIRECTORIES diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 1978e9e1b7..81a67f1b78 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -26,14 +26,10 @@ ** ****************************************************************************/ +#include "tst_qmetatype.h" -#include -#include #include -#include "tst_qmetatype.h" -#include "tst_qvariant_common.h" - #ifdef Q_OS_LINUX # include #endif @@ -153,91 +149,6 @@ static_assert(!QTypeTraits::has_operator_less_than_v>); } - -class tst_QMetaType: public QObject -{ - Q_OBJECT - Q_PROPERTY(QList prop READ prop WRITE setProp) - -public: - struct GadgetPropertyType { - QByteArray type; - QByteArray name; - QVariant testData; - }; - - tst_QMetaType() { propList << 42 << "Hello"; } - - QList prop() const { return propList; } - void setProp(const QList &list) { propList = list; } - -private: - void registerGadget(const char * name, const QList &gadgetProperties); - QList propList; - -private slots: - void defined(); - void threadSafety(); - void namespaces(); - void id(); - void qMetaTypeId(); - void properties(); - void normalizedTypes(); - void typeName_data(); - void typeName(); - void type_data(); - void type(); - void type_fromSubString_data(); - void type_fromSubString(); - void create_data(); - void create(); - void createCopy_data(); - void createCopy(); - void sizeOf_data(); - void sizeOf(); - void sizeOfStaticLess_data(); - void sizeOfStaticLess(); - void alignOf_data(); - void alignOf(); - void flags_data(); - void flags(); - void flagsStaticLess_data(); - void flagsStaticLess(); - void flagsBinaryCompatibility6_0_data(); - void flagsBinaryCompatibility6_0(); - void construct_data(); - void construct(); - void typedConstruct(); - void constructCopy_data(); - void constructCopy(); - void typedefs(); - void registerType(); - void isRegistered_data(); - void isRegistered(); - void isRegisteredStaticLess_data(); - void isRegisteredStaticLess(); - void isEnum(); - void automaticTemplateRegistration(); - void saveAndLoadBuiltin_data(); - void saveAndLoadBuiltin(); - void saveAndLoadCustom(); - void metaObject_data(); - void metaObject(); - void constexprMetaTypeIds(); - void constRefs(); - void convertCustomType_data(); - void convertCustomType(); - void compareCustomEqualOnlyType(); - void customDebugStream(); - void unknownType(); - void fromType(); - void operatorEq_data(); - void operatorEq(); - void typesWithInaccessibleDTors(); - void voidIsNotUnknown(); - void typeNameNormalization(); -}; - struct BaseGenericType { int m_typeId = -1; @@ -647,18 +558,6 @@ void tst_QMetaType::properties() QCOMPARE(v.toList().count(), 4); } -template -struct Whity { T t; Whity() {} }; - -Q_DECLARE_METATYPE( Whity < int > ) -Q_DECLARE_METATYPE(Whity) - -#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501 -QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(Whity, Q_RELOCATABLE_TYPE); -QT_END_NAMESPACE -#endif - void tst_QMetaType::normalizedTypes() { int WhityIntId = ::qMetaTypeId >(); @@ -1011,20 +910,6 @@ void tst_QMetaType::alignOf() QCOMPARE(size_t(QMetaType(type).alignOf()), size); } -struct CustomMovable { CustomMovable() {} }; - -// needed for QSet. We actually check that it makes sense. -bool operator==(const CustomMovable &, const CustomMovable &) { return true; } -qsizetype qHash(const CustomMovable &, qsizetype seed = 0) { return seed; } - -#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501 -QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(CustomMovable, Q_RELOCATABLE_TYPE); -QT_END_NAMESPACE -#endif - -Q_DECLARE_METATYPE(CustomMovable); - class CustomObject : public QObject { Q_OBJECT @@ -2234,549 +2119,5 @@ void tst_QMetaType::constexprMetaTypeIds() Q_UNUSED(metaType); } -void tst_QMetaType::constRefs() -{ - QCOMPARE(::qMetaTypeId(), ::qMetaTypeId()); - QCOMPARE(::qMetaTypeId(), ::qMetaTypeId()); - QCOMPARE(::qMetaTypeId(), ::qMetaTypeId()); - QCOMPARE(::qMetaTypeId &>(), ::qMetaTypeId >()); - static_assert(::qMetaTypeId() == ::qMetaTypeId()); -} - -struct CustomConvertibleType -{ - explicit CustomConvertibleType(const QVariant &foo = QVariant()) : m_foo(foo) {} - virtual ~CustomConvertibleType() {} - QString toString() const { return m_foo.toString(); } - operator QPoint() const { return QPoint(12, 34); } - template - To convert() const { return s_value.value();} - template - To convertOk(bool *ok) const { *ok = s_ok; return s_value.value();} - - QVariant m_foo; - static QVariant s_value; - static bool s_ok; -}; - -bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) -{ return lhs.m_foo.toString() < rhs.m_foo.toString(); } -bool operator==(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) -{ return lhs.m_foo == rhs.m_foo; } -bool operator!=(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) -{ return !operator==(lhs, rhs); } - -QVariant CustomConvertibleType::s_value; -bool CustomConvertibleType::s_ok = true; - -struct CustomConvertibleType2 -{ - // implicit - CustomConvertibleType2(const CustomConvertibleType &t = CustomConvertibleType()) - : m_foo(t.m_foo) {} - virtual ~CustomConvertibleType2() {} - - QVariant m_foo; -}; - -struct CustomDebugStreamableType -{ - QString toString() const { return "test"; } -}; - -struct CustomDebugStreamableType2 -{ - QString toString() const { return "test"; } -}; - -QDebug operator<<(QDebug dbg, const CustomDebugStreamableType&) -{ - return dbg << "string-content"; -} - -bool operator==(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs) -{ return lhs.m_foo == rhs.m_foo; } -bool operator!=(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs) -{ return !operator==(lhs, rhs); } - - -struct CustomEqualsOnlyType -{ - explicit CustomEqualsOnlyType(int value = 0) : val(value) {} - virtual ~CustomEqualsOnlyType() {} - - int val; -}; -bool operator==(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs) -{ return lhs.val == rhs.val;} -bool operator!=(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs) -{ return !operator==(lhs, rhs); } - -static_assert(QTypeTraits::has_operator_equal_v); -static_assert(!QTypeTraits::has_operator_less_than_v); - -Q_DECLARE_METATYPE(CustomConvertibleType); -Q_DECLARE_METATYPE(CustomConvertibleType2); -Q_DECLARE_METATYPE(CustomDebugStreamableType); -Q_DECLARE_METATYPE(CustomEqualsOnlyType); - -template -U convert(const T &t) -{ - return t; -} - -template -struct ConvertFunctor -{ - CustomConvertibleType operator()(const From& f) const - { - return CustomConvertibleType(QVariant::fromValue(f)); - } -}; - -template -bool hasRegisteredConverterFunction() -{ - return QMetaType::hasRegisteredConverterFunction(); -} - -template -void testCustomTypeNotYetConvertible() -{ - QVERIFY((!hasRegisteredConverterFunction())); - QVERIFY((!QVariant::fromValue(From()).template canConvert())); -} - -template -void testCustomTypeConvertible() -{ - QVERIFY((hasRegisteredConverterFunction())); - QVERIFY((QVariant::fromValue(From()).template canConvert())); -} - -void customTypeNotYetConvertible() -{ - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); - testCustomTypeNotYetConvertible(); -} - -void registerCustomTypeConversions() -{ - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); - QVERIFY((QMetaType::registerConverter(convert))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); - QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); - QVERIFY((QMetaType::registerConverter())); - QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2"); - QVERIFY((!QMetaType::registerConverter())); -} - -void tst_QMetaType::convertCustomType_data() -{ - customTypeNotYetConvertible(); - registerCustomTypeConversions(); - - QTest::addColumn("ok"); - QTest::addColumn("testQString"); - QTest::addColumn("testBool"); - QTest::addColumn("testInt"); - QTest::addColumn("testDouble"); - QTest::addColumn("testFloat"); - QTest::addColumn("testQRect"); - QTest::addColumn("testQRectF"); - QTest::addColumn("testQPoint"); - QTest::addColumn("testQPointF"); - QTest::addColumn("testQSize"); - QTest::addColumn("testQSizeF"); - QTest::addColumn("testQLine"); - QTest::addColumn("testQLineF"); - QTest::addColumn("testQChar"); - QTest::addColumn("testCustom"); - - QTest::newRow("default") << true - << QString::fromLatin1("string") << true << 15 - << double(3.14) << float(3.6) << QRect(1, 2, 3, 4) - << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34) - << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8) - << QLine(3, 9, 29, 4) << QLineF(38.9, 28.9, 102.3, 0.0) - << QChar('Q') << CustomConvertibleType(QString::fromLatin1("test")); - QTest::newRow("not ok") << false - << QString::fromLatin1("string") << true << 15 - << double(3.14) << float(3.6) << QRect(1, 2, 3, 4) - << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34) - << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8) - << QLine(3, 9, 29, 4) << QLineF() - << QChar('Q') << CustomConvertibleType(42); -} - -void tst_QMetaType::convertCustomType() -{ - QFETCH(bool, ok); - CustomConvertibleType::s_ok = ok; - - CustomConvertibleType t; - QVariant v = QVariant::fromValue(t); - QFETCH(QString, testQString); - CustomConvertibleType::s_value = testQString; - QCOMPARE(v.toString(), ok ? testQString : QString()); - QCOMPARE(v.value(), ok ? testQString : QString()); - QVERIFY(CustomConvertibleType::s_value.canConvert()); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toString()), testQString); - - QFETCH(bool, testBool); - CustomConvertibleType::s_value = testBool; - QCOMPARE(v.toBool(), testBool); - QCOMPARE(v.value(), testBool); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toBool()), testBool); - - QFETCH(int, testInt); - CustomConvertibleType::s_value = testInt; - QCOMPARE(v.toInt(), ok ? testInt : 0); - QCOMPARE(v.value(), ok ? testInt : 0); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toInt()), testInt); - - QFETCH(double, testDouble); - CustomConvertibleType::s_value = testDouble; - QCOMPARE(v.toDouble(), testDouble); - QCOMPARE(v.value(), testDouble); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toDouble()), testDouble); - - QFETCH(float, testFloat); - CustomConvertibleType::s_value = testFloat; - QCOMPARE(v.toFloat(), ok ? testFloat : 0.0); - QCOMPARE(v.value(), ok ? testFloat : 0.0); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toFloat()), testFloat); - - QFETCH(QRect, testQRect); - CustomConvertibleType::s_value = testQRect; - QCOMPARE(v.toRect(), testQRect); - QCOMPARE(v.value(), testQRect); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toRect()), testQRect); - - QFETCH(QRectF, testQRectF); - CustomConvertibleType::s_value = testQRectF; - QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF()); - QCOMPARE(v.value(), ok ? testQRectF : QRectF()); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toRectF()), testQRectF); - - QFETCH(QPoint, testQPoint); - CustomConvertibleType::s_value = testQPoint; - QCOMPARE(v.toPoint(), testQPoint); - QCOMPARE(v.value(), testQPoint); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toPoint()), testQPoint); - - QFETCH(QPointF, testQPointF); - CustomConvertibleType::s_value = testQPointF; - QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF()); - QCOMPARE(v.value(), ok ? testQPointF : QPointF()); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toPointF()), testQPointF); - - QFETCH(QSize, testQSize); - CustomConvertibleType::s_value = testQSize; - QCOMPARE(v.toSize(), testQSize); - QCOMPARE(v.value(), testQSize); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toSize()), testQSize); - - QFETCH(QSizeF, testQSizeF); - CustomConvertibleType::s_value = testQSizeF; - QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF()); - QCOMPARE(v.value(), ok ? testQSizeF : QSizeF()); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toSizeF()), testQSizeF); - - QFETCH(QLine, testQLine); - CustomConvertibleType::s_value = testQLine; - QCOMPARE(v.toLine(), testQLine); - QCOMPARE(v.value(), testQLine); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toLine()), testQLine); - - QFETCH(QLineF, testQLineF); - CustomConvertibleType::s_value = testQLineF; - QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF()); - QCOMPARE(v.value(), ok ? testQLineF : QLineF()); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toLineF()), testQLineF); - - QFETCH(QChar, testQChar); - CustomConvertibleType::s_value = testQChar; - QCOMPARE(v.toChar(), testQChar); - QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toChar()), testQChar); - - QFETCH(CustomConvertibleType, testCustom); - v = QVariant::fromValue(testCustom); - QVERIFY(v.canConvert(::qMetaTypeId())); - QCOMPARE(v.value().m_foo, testCustom.m_foo); -} - -void tst_QMetaType::compareCustomEqualOnlyType() -{ - QMetaType type = QMetaType::fromType(); - - CustomEqualsOnlyType val50(50); - CustomEqualsOnlyType val100(100); - CustomEqualsOnlyType val100x(100); - - QVariant variant50 = QVariant::fromValue(val50); - QVariant variant100 = QVariant::fromValue(val100); - QVariant variant100x = QVariant::fromValue(val100x); - - QVERIFY(variant50 != variant100); - QVERIFY(variant50 != variant100x); - QVERIFY(variant100 != variant50); - QVERIFY(variant100x != variant50); - QCOMPARE(variant100, variant100x); - QCOMPARE(variant100, variant100); - - // check QMetaType::compare works/doesn't crash for equals only comparators - auto cmp = type.compare(variant50.constData(), variant50.constData()); - QCOMPARE(cmp, QPartialOrdering::Unordered); - bool equals = type.equals(variant50.constData(), variant50.constData()); - QVERIFY(equals); - - cmp = type.compare(variant100.constData(), variant100x.constData()); - QCOMPARE(cmp, QPartialOrdering::Unordered); - equals = type.equals(variant100.constData(), variant100x.constData()); - QVERIFY(equals); - - cmp = type.compare(variant50.constData(), variant100.constData()); - QCOMPARE(cmp, QPartialOrdering::Unordered); - equals = type.equals(variant50.constData(), variant100.constData()); - QVERIFY(!equals); - - //check QMetaType::equals for type w/o equals comparator being registered - CustomMovable movable1; - CustomMovable movable2; - type = QMetaType::fromType(); - equals = type.equals(&movable1, &movable2); -} - -struct MessageHandlerCustom : public MessageHandler -{ - MessageHandlerCustom(const int typeId) - : MessageHandler(typeId, handler) - {} - static void handler(QtMsgType, const QMessageLogContext &, const QString &msg) - { - QCOMPARE(msg.trimmed(), expectedMessage.trimmed()); - } - static QString expectedMessage; -}; - -QString MessageHandlerCustom::expectedMessage; - -void tst_QMetaType::customDebugStream() -{ - MessageHandlerCustom handler(::qMetaTypeId()); - QVariant v1 = QVariant::fromValue(CustomDebugStreamableType()); - handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)"; - qDebug() << v1; - - MessageHandlerCustom handler2(::qMetaTypeId()); - QMetaType::registerConverter(&CustomDebugStreamableType2::toString); - handler2.expectedMessage = "QVariant(CustomDebugStreamableType2, \"test\")"; - QVariant v2 = QVariant::fromValue(CustomDebugStreamableType2()); - qDebug() << v2; -} - -void tst_QMetaType::unknownType() -{ - QMetaType invalid(QMetaType::UnknownType); - QVERIFY(!invalid.create()); - QVERIFY(!invalid.sizeOf()); - QVERIFY(!invalid.metaObject()); - int buffer = 0xBAD; - invalid.construct(&buffer); - QCOMPARE(buffer, 0xBAD); -} - -void tst_QMetaType::fromType() -{ - #define FROMTYPE_CHECK(MetaTypeName, MetaTypeId, RealType) \ - QCOMPARE(QMetaType::fromType(), QMetaType(MetaTypeId)); \ - QVERIFY(QMetaType::fromType() == QMetaType(MetaTypeId)); \ - QVERIFY(!(QMetaType::fromType() != QMetaType(MetaTypeId))); \ - if (MetaTypeId != QMetaType::Void) \ - QCOMPARE(QMetaType::fromType().id(), MetaTypeId); - - FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK) - - QVERIFY(QMetaType::fromType() != QMetaType()); - QCOMPARE(QMetaType(), QMetaType()); - QCOMPARE(QMetaType(QMetaType::UnknownType), QMetaType()); - - FROMTYPE_CHECK(_, ::qMetaTypeId>(), Whity) - #undef FROMTYPE_CHECK -} - -template -struct CharTemplate -{ - struct - { - int a; - } x; -}; - -void tst_QMetaType::operatorEq_data() -{ - QTest::addColumn("typeA"); - QTest::addColumn("typeB"); - QTest::addColumn("eq"); - - QTest::newRow("String") << QMetaType(QMetaType::QString) - << QMetaType::fromType() << true; - QTest::newRow("void1") << QMetaType(QMetaType::UnknownType) << QMetaType::fromType() - << false; - QTest::newRow("void2") << QMetaType::fromType() << QMetaType::fromType() - << true; - QTest::newRow("list1") << QMetaType::fromType>() - << QMetaType::fromType>() << true; - QTest::newRow("list2") << QMetaType::fromType>() - << QMetaType::fromType>() << false; - QTest::newRow("char1") << QMetaType::fromType'>>() - << QMetaType::fromType', void>>() << true; - QTest::newRow("annon1") << QMetaType::fromType'>::x)>() - << QMetaType::fromType'>::x)>() << true; - QTest::newRow("annon2") << QMetaType::fromType'>::x)>() - << QMetaType::fromType::x)>() << false; -} - -void tst_QMetaType::operatorEq() -{ - QFETCH(QMetaType, typeA); - QFETCH(QMetaType, typeB); - QFETCH(bool, eq); - - QCOMPARE(typeA == typeB, eq); - QCOMPARE(typeB == typeA, eq); - QCOMPARE(typeA != typeB, !eq); - QCOMPARE(typeB != typeA, !eq); -} - -class WithPrivateDTor { - ~WithPrivateDTor(){}; -}; - -struct WithDeletedDtor { - ~WithDeletedDtor() = delete; -}; - -void tst_QMetaType::typesWithInaccessibleDTors() -{ - // should compile - Q_UNUSED(QMetaType::fromType()); - Q_UNUSED(QMetaType::fromType()); -} - -void tst_QMetaType::voidIsNotUnknown() -{ - QMetaType voidType = QMetaType::fromType(); - QMetaType voidType2 = QMetaType(QMetaType::Void); - QCOMPARE(voidType, voidType2); - QVERIFY(voidType != QMetaType(QMetaType::UnknownType)); -} - -void tst_QMetaType::typeNameNormalization() -{ - // check the we normalize types the right way - -#define CHECK_TYPE_NORMALIZATION(Normalized, ...) \ - do { \ - /*QCOMPARE(QtPrivate::typenameHelper(), Normalized);*/ \ - QByteArray typeName = QMetaObject::normalizedType(#__VA_ARGS__); \ - QCOMPARE(typeName, Normalized); \ - typeName = QMetaType::fromType<__VA_ARGS__>().name(); \ - QCOMPARE(typeName, Normalized); \ - } while (0) - - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("uint", uint); - CHECK_TYPE_NORMALIZATION("QList>", QList>); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); - CHECK_TYPE_NORMALIZATION("QList", QList); -#ifdef Q_CC_MSVC - CHECK_TYPE_NORMALIZATION("qulonglong", __int64 unsigned); -#endif - CHECK_TYPE_NORMALIZATION("std::pair", QPair); - - // The string based normalization doesn't handle aliases, QMetaType::fromType() does -// CHECK_TYPE_NORMALIZATION("qulonglong", quint64); - QCOMPARE(QMetaType::fromType().name(), "qulonglong"); -} - -// Compile-time test, it should be possible to register function pointer types -class Undefined; - -typedef Undefined (*UndefinedFunction0)(); -typedef Undefined (*UndefinedFunction1)(Undefined); -typedef Undefined (*UndefinedFunction2)(Undefined, Undefined); -typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined); -typedef Undefined (*UndefinedFunction4)(Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined); - -Q_DECLARE_METATYPE(UndefinedFunction0); -Q_DECLARE_METATYPE(UndefinedFunction1); -Q_DECLARE_METATYPE(UndefinedFunction2); -Q_DECLARE_METATYPE(UndefinedFunction3); -Q_DECLARE_METATYPE(UndefinedFunction4); - QTEST_MAIN(tst_QMetaType) #include "tst_qmetatype.moc" diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h index 43a099de17..2a0e177be1 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -26,273 +26,207 @@ ** ****************************************************************************/ -// Used by both tst_qmetatype and tst_qsettings +#include +#include +#include "tst_qmetatype_common.h" +#include "tst_qvariant_common.h" -#ifndef TST_QMETATYPE_H -#define TST_QMETATYPE_H - -#include -#include - -#define FOR_EACH_PRIMITIVE_METATYPE(F) \ - QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \ - QT_FOR_EACH_STATIC_CORE_POINTER(F) \ +struct MessageHandlerCustom : public MessageHandler +{ + MessageHandlerCustom(const int typeId) + : MessageHandler(typeId, handler) + {} + static void handler(QtMsgType, const QMessageLogContext &, const QString &msg) + { + QCOMPARE(msg.trimmed(), expectedMessage.trimmed()); + } + inline static QString expectedMessage; +}; -#define FOR_EACH_COMPLEX_CORE_METATYPE(F) \ - QT_FOR_EACH_STATIC_CORE_CLASS(F) \ - QT_FOR_EACH_STATIC_CORE_TEMPLATE(F) +class tst_QMetaType: public QObject +{ + Q_OBJECT + Q_PROPERTY(QList prop READ prop WRITE setProp) + +public: + struct GadgetPropertyType { + QByteArray type; + QByteArray name; + QVariant testData; + }; + + tst_QMetaType() { propList << 42 << "Hello"; } + + QList prop() const { return propList; } + void setProp(const QList &list) { propList = list; } + +private: + void registerGadget(const char * name, const QList &gadgetProperties); + QList propList; + +private slots: + void defined(); + void threadSafety(); + void namespaces(); + void id(); + void qMetaTypeId(); + void properties(); + void normalizedTypes(); + void typeName_data(); + void typeName(); + void type_data(); + void type(); + void type_fromSubString_data(); + void type_fromSubString(); + void create_data(); + void create(); + void createCopy_data(); + void createCopy(); + void sizeOf_data(); + void sizeOf(); + void sizeOfStaticLess_data(); + void sizeOfStaticLess(); + void alignOf_data(); + void alignOf(); + void flags_data(); + void flags(); + void flagsStaticLess_data(); + void flagsStaticLess(); + void flagsBinaryCompatibility6_0_data(); + void flagsBinaryCompatibility6_0(); + void construct_data(); + void construct(); + void typedConstruct(); + void constructCopy_data(); + void constructCopy(); + void typedefs(); + void registerType(); + void isRegistered_data(); + void isRegistered(); + void isRegisteredStaticLess_data(); + void isRegisteredStaticLess(); + void isEnum(); + void automaticTemplateRegistration(); + void saveAndLoadBuiltin_data(); + void saveAndLoadBuiltin(); + void saveAndLoadCustom(); + void metaObject_data(); + void metaObject(); + void constexprMetaTypeIds(); + + // tst_qmetatype2.cpp + void constRefs(); + void convertCustomType_data(); + void convertCustomType(); + void compareCustomEqualOnlyType(); + void customDebugStream(); + void unknownType(); + void fromType(); + void operatorEq_data(); + void operatorEq(); + void typesWithInaccessibleDTors(); + void voidIsNotUnknown(); + void typeNameNormalization(); +}; + +template +struct Whity { T t; Whity() {} }; + +Q_DECLARE_METATYPE(Whity) +Q_DECLARE_METATYPE(Whity) + +#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501 +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(Whity, Q_RELOCATABLE_TYPE); +QT_END_NAMESPACE +#endif -#define FOR_EACH_CORE_METATYPE(F) \ - FOR_EACH_PRIMITIVE_METATYPE(F) \ - FOR_EACH_COMPLEX_CORE_METATYPE(F) \ +struct CustomConvertibleType +{ + explicit CustomConvertibleType(const QVariant &foo = QVariant()) : m_foo(foo) {} + virtual ~CustomConvertibleType() {} + QString toString() const { return m_foo.toString(); } + operator QPoint() const { return QPoint(12, 34); } + template + To convert() const { return s_value.value();} + template + To convertOk(bool *ok) const { *ok = s_ok; return s_value.value();} + + QVariant m_foo; + inline static QVariant s_value; + inline static bool s_ok = true; + + friend bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) + { return lhs.m_foo.toString() < rhs.m_foo.toString(); } + friend bool operator==(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) + { return lhs.m_foo == rhs.m_foo; } + friend bool operator!=(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) + { return !operator==(lhs, rhs); } +}; + +struct CustomConvertibleType2 +{ + // implicit + CustomConvertibleType2(const CustomConvertibleType &t = CustomConvertibleType()) + : m_foo(t.m_foo) {} + virtual ~CustomConvertibleType2() {} -template -struct MetaEnumToType {}; + QVariant m_foo; -#define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \ -template<> \ -struct MetaEnumToType { \ - typedef RealType Type; \ + friend bool operator==(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs) + { return lhs.m_foo == rhs.m_foo; } + friend bool operator!=(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs) + { return !operator==(lhs, rhs); } }; -FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE) -#undef DEFINE_META_ENUM_TO_TYPE -template -struct DefaultValueFactory +struct CustomDebugStreamableType { - typedef typename MetaEnumToType::Type Type; - static Type *create() { return new Type; } -}; + QString toString() const { return "test"; } -template <> -struct DefaultValueFactory -{ - typedef MetaEnumToType::Type Type; - static Type *create() { return 0; } + friend QDebug operator<<(QDebug dbg, const CustomDebugStreamableType&) + { + return dbg << "string-content"; + } }; -template -struct DefaultValueTraits +struct CustomDebugStreamableType2 { - // 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 }; + QString toString() const { return "test"; } }; -#define DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS(MetaTypeName, MetaTypeId, RealType) \ -template<> struct DefaultValueTraits { \ - 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 +struct CustomEqualsOnlyType +{ + explicit CustomEqualsOnlyType(int value = 0) : val(value) {} + virtual ~CustomEqualsOnlyType() {} -template -struct TestValueFactory {}; + int val; -template<> struct TestValueFactory { - static void *create() { return 0; } + friend bool operator==(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs) + { return lhs.val == rhs.val;} + friend bool operator!=(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs) + { return !operator==(lhs, rhs); } }; -template<> struct TestValueFactory { - static QString *create() { return new QString(QString::fromLatin1("QString")); } -}; -template<> struct TestValueFactory { - static int *create() { return new int(INT_MIN); } -}; -template<> struct TestValueFactory { - static uint *create() { return new uint(UINT_MAX); } -}; -template<> struct TestValueFactory { - static bool *create() { return new bool(true); } -}; -template<> struct TestValueFactory { - static double *create() { return new double(DBL_MIN); } -}; -template<> struct TestValueFactory { - static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); } -}; -template<> struct TestValueFactory { - static QByteArrayList *create() { return new QByteArrayList(QByteArrayList() << "Q" << "Byte" << "Array" << "List"); } -}; -template<> struct TestValueFactory { - static QVariantMap *create() { return new QVariantMap(); } -}; -template<> struct TestValueFactory { - static QVariantHash *create() { return new QVariantHash(); } -}; -template<> struct TestValueFactory { - static QVariantPair *create() { return new QVariantPair(); } -}; +static_assert(QTypeTraits::has_operator_equal_v); +static_assert(!QTypeTraits::has_operator_less_than_v); -template<> struct TestValueFactory { - static QVariantList *create() { return new QVariantList(QVariantList() << 123 << "Q" << "Variant" << "List"); } -}; -template<> struct TestValueFactory { - static QChar *create() { return new QChar(QChar('q')); } -}; -template<> struct TestValueFactory { - static long *create() { return new long(LONG_MIN); } -}; -template<> struct TestValueFactory { - static short *create() { return new short(SHRT_MIN); } -}; -template<> struct TestValueFactory { - static char *create() { return new char('c'); } -}; -template<> struct TestValueFactory { - static char16_t *create() { return new char16_t('c'); } -}; -template<> struct TestValueFactory { - static char32_t *create() { return new char32_t('c'); } -}; -template<> struct TestValueFactory { - static ulong *create() { return new ulong(ULONG_MAX); } -}; -template<> struct TestValueFactory { - static ushort *create() { return new ushort(USHRT_MAX); } -}; -template<> struct TestValueFactory { - static signed char *create() { return new signed char(CHAR_MIN); } -}; -template<> struct TestValueFactory { - static uchar *create() { return new uchar(UCHAR_MAX); } -}; -template<> struct TestValueFactory { - static float *create() { return new float(FLT_MIN); } -}; -template<> struct TestValueFactory { - static QObject * *create() { return new QObject *(0); } -}; -template<> struct TestValueFactory { - static void * *create() { return new void *(0); } -}; -template<> struct TestValueFactory { - static qlonglong *create() { return new qlonglong(LLONG_MIN); } -}; -template<> struct TestValueFactory { - static qulonglong *create() { return new qulonglong(ULLONG_MAX); } -}; -template<> struct TestValueFactory { - static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); } -}; -template<> struct TestValueFactory { - static QBitArray *create() { return new QBitArray(QBitArray(256, true)); } -}; -template<> struct TestValueFactory { - static QDate *create() { return new QDate(QDate::currentDate()); } -}; -template<> struct TestValueFactory { - static QTime *create() { return new QTime(QTime::currentTime()); } -}; -template<> struct TestValueFactory { - static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); } -}; -template<> struct TestValueFactory { - static QUrl *create() { return new QUrl("http://www.example.org"); } -}; -template<> struct TestValueFactory { - static QLocale *create() { return new QLocale(QLocale::c()); } -}; -template<> struct TestValueFactory { - static QRect *create() { return new QRect(10, 20, 30, 40); } -}; -template<> struct TestValueFactory { - static QRectF *create() { return new QRectF(10, 20, 30, 40); } -}; -template<> struct TestValueFactory { - static QSize *create() { return new QSize(10, 20); } -}; -template<> struct TestValueFactory { - static QSizeF *create() { return new QSizeF(10, 20); } -}; -template<> struct TestValueFactory { - static QLine *create() { return new QLine(10, 20, 30, 40); } -}; -template<> struct TestValueFactory { - static QLineF *create() { return new QLineF(10, 20, 30, 40); } -}; -template<> struct TestValueFactory { - static QPoint *create() { return new QPoint(10, 20); } -}; -template<> struct TestValueFactory { - static QPointF *create() { return new QPointF(10, 20); } -}; -template<> struct TestValueFactory { - static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); } -}; -template<> struct TestValueFactory { - static QUuid *create() { return new QUuid(); } -}; -template<> struct TestValueFactory { - static QModelIndex *create() { return new QModelIndex(); } -}; -template<> struct TestValueFactory { - static QPersistentModelIndex *create() { return new QPersistentModelIndex(); } -}; -template<> struct TestValueFactory { - static std::nullptr_t *create() { return new std::nullptr_t; } -}; -template<> struct TestValueFactory { - static QRegularExpression *create() - { -#if QT_CONFIG(regularexpression) - return new QRegularExpression("abc.*def"); -#else - return 0; -#endif - } -}; -template<> struct TestValueFactory { - static QJsonValue *create() { return new QJsonValue(123.); } -}; -template<> struct TestValueFactory { - 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 { - 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 { - static QJsonDocument *create() { - return new QJsonDocument( - QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }") - ); - } -}; +Q_DECLARE_METATYPE(CustomConvertibleType); +Q_DECLARE_METATYPE(CustomConvertibleType2); +Q_DECLARE_METATYPE(CustomDebugStreamableType); +Q_DECLARE_METATYPE(CustomEqualsOnlyType); -template<> struct TestValueFactory { - static QCborSimpleType *create() { return new QCborSimpleType(QCborSimpleType::True); } -}; -template<> struct TestValueFactory { - static QCborValue *create() { return new QCborValue(123.); } -}; -template<> struct TestValueFactory { - static QCborMap *create() { - return new QCborMap{{0, 0}, {"Hello", 1}, {1, nullptr}}; - } -}; -template<> struct TestValueFactory { - static QCborArray *create() { - return new QCborArray{0, 1, -2, 2.5, false, nullptr, "Hello", QByteArray("World") }; - } -}; +struct CustomMovable { + CustomMovable() {} -template<> struct TestValueFactory { - static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); } + friend bool operator==(const CustomMovable &, const CustomMovable &) { return true; } + // needed for QSet. We actually check that it makes sense. + friend qsizetype qHash(const CustomMovable &, qsizetype seed = 0) { return seed; } }; -#endif // TST_QMETATYPE_H +#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501 +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(CustomMovable, Q_RELOCATABLE_TYPE); +QT_END_NAMESPACE +#endif + +Q_DECLARE_METATYPE(CustomMovable); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp new file mode 100644 index 0000000000..3c097ad0d8 --- /dev/null +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp @@ -0,0 +1,483 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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$ +** +****************************************************************************/ + +#include "tst_qmetatype.h" +#include "tst_qvariant_common.h" + +#include + +void tst_QMetaType::constRefs() +{ + QCOMPARE(::qMetaTypeId(), ::qMetaTypeId()); + QCOMPARE(::qMetaTypeId(), ::qMetaTypeId()); + QCOMPARE(::qMetaTypeId(), ::qMetaTypeId()); + QCOMPARE(::qMetaTypeId &>(), ::qMetaTypeId >()); + static_assert(::qMetaTypeId() == ::qMetaTypeId()); +} + +template +U convert(const T &t) +{ + return t; +} + +template +struct ConvertFunctor +{ + CustomConvertibleType operator()(const From& f) const + { + return CustomConvertibleType(QVariant::fromValue(f)); + } +}; + +template +bool hasRegisteredConverterFunction() +{ + return QMetaType::hasRegisteredConverterFunction(); +} + +template +void testCustomTypeNotYetConvertible() +{ + QVERIFY((!hasRegisteredConverterFunction())); + QVERIFY((!QVariant::fromValue(From()).template canConvert())); +} + +template +void testCustomTypeConvertible() +{ + QVERIFY((hasRegisteredConverterFunction())); + QVERIFY((QVariant::fromValue(From()).template canConvert())); +} + +void customTypeNotYetConvertible() +{ + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); + testCustomTypeNotYetConvertible(); +} + +void registerCustomTypeConversions() +{ + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); + QVERIFY((QMetaType::registerConverter(convert))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convertOk))); + QVERIFY((QMetaType::registerConverter(&CustomConvertibleType::convert))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter(ConvertFunctor()))); + QVERIFY((QMetaType::registerConverter())); + QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2"); + QVERIFY((!QMetaType::registerConverter())); +} + +void tst_QMetaType::convertCustomType_data() +{ + customTypeNotYetConvertible(); + registerCustomTypeConversions(); + + QTest::addColumn("ok"); + QTest::addColumn("testQString"); + QTest::addColumn("testBool"); + QTest::addColumn("testInt"); + QTest::addColumn("testDouble"); + QTest::addColumn("testFloat"); + QTest::addColumn("testQRect"); + QTest::addColumn("testQRectF"); + QTest::addColumn("testQPoint"); + QTest::addColumn("testQPointF"); + QTest::addColumn("testQSize"); + QTest::addColumn("testQSizeF"); + QTest::addColumn("testQLine"); + QTest::addColumn("testQLineF"); + QTest::addColumn("testQChar"); + QTest::addColumn("testCustom"); + + QTest::newRow("default") << true + << QString::fromLatin1("string") << true << 15 + << double(3.14) << float(3.6) << QRect(1, 2, 3, 4) + << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34) + << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8) + << QLine(3, 9, 29, 4) << QLineF(38.9, 28.9, 102.3, 0.0) + << QChar('Q') << CustomConvertibleType(QString::fromLatin1("test")); + QTest::newRow("not ok") << false + << QString::fromLatin1("string") << true << 15 + << double(3.14) << float(3.6) << QRect(1, 2, 3, 4) + << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34) + << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8) + << QLine(3, 9, 29, 4) << QLineF() + << QChar('Q') << CustomConvertibleType(42); +} + +void tst_QMetaType::convertCustomType() +{ + QFETCH(bool, ok); + CustomConvertibleType::s_ok = ok; + + CustomConvertibleType t; + QVariant v = QVariant::fromValue(t); + QFETCH(QString, testQString); + CustomConvertibleType::s_value = testQString; + QCOMPARE(v.toString(), ok ? testQString : QString()); + QCOMPARE(v.value(), ok ? testQString : QString()); + QVERIFY(CustomConvertibleType::s_value.canConvert()); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toString()), testQString); + + QFETCH(bool, testBool); + CustomConvertibleType::s_value = testBool; + QCOMPARE(v.toBool(), testBool); + QCOMPARE(v.value(), testBool); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toBool()), testBool); + + QFETCH(int, testInt); + CustomConvertibleType::s_value = testInt; + QCOMPARE(v.toInt(), ok ? testInt : 0); + QCOMPARE(v.value(), ok ? testInt : 0); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toInt()), testInt); + + QFETCH(double, testDouble); + CustomConvertibleType::s_value = testDouble; + QCOMPARE(v.toDouble(), testDouble); + QCOMPARE(v.value(), testDouble); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toDouble()), testDouble); + + QFETCH(float, testFloat); + CustomConvertibleType::s_value = testFloat; + QCOMPARE(v.toFloat(), ok ? testFloat : 0.0); + QCOMPARE(v.value(), ok ? testFloat : 0.0); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toFloat()), testFloat); + + QFETCH(QRect, testQRect); + CustomConvertibleType::s_value = testQRect; + QCOMPARE(v.toRect(), testQRect); + QCOMPARE(v.value(), testQRect); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toRect()), testQRect); + + QFETCH(QRectF, testQRectF); + CustomConvertibleType::s_value = testQRectF; + QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF()); + QCOMPARE(v.value(), ok ? testQRectF : QRectF()); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toRectF()), testQRectF); + + QFETCH(QPoint, testQPoint); + CustomConvertibleType::s_value = testQPoint; + QCOMPARE(v.toPoint(), testQPoint); + QCOMPARE(v.value(), testQPoint); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toPoint()), testQPoint); + + QFETCH(QPointF, testQPointF); + CustomConvertibleType::s_value = testQPointF; + QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF()); + QCOMPARE(v.value(), ok ? testQPointF : QPointF()); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toPointF()), testQPointF); + + QFETCH(QSize, testQSize); + CustomConvertibleType::s_value = testQSize; + QCOMPARE(v.toSize(), testQSize); + QCOMPARE(v.value(), testQSize); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toSize()), testQSize); + + QFETCH(QSizeF, testQSizeF); + CustomConvertibleType::s_value = testQSizeF; + QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF()); + QCOMPARE(v.value(), ok ? testQSizeF : QSizeF()); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toSizeF()), testQSizeF); + + QFETCH(QLine, testQLine); + CustomConvertibleType::s_value = testQLine; + QCOMPARE(v.toLine(), testQLine); + QCOMPARE(v.value(), testQLine); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toLine()), testQLine); + + QFETCH(QLineF, testQLineF); + CustomConvertibleType::s_value = testQLineF; + QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF()); + QCOMPARE(v.value(), ok ? testQLineF : QLineF()); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toLineF()), testQLineF); + + QFETCH(QChar, testQChar); + CustomConvertibleType::s_value = testQChar; + QCOMPARE(v.toChar(), testQChar); + QCOMPARE((CustomConvertibleType::s_value.value().m_foo.toChar()), testQChar); + + QFETCH(CustomConvertibleType, testCustom); + v = QVariant::fromValue(testCustom); + QVERIFY(v.canConvert(::qMetaTypeId())); + QCOMPARE(v.value().m_foo, testCustom.m_foo); +} + +void tst_QMetaType::compareCustomEqualOnlyType() +{ + QMetaType type = QMetaType::fromType(); + + CustomEqualsOnlyType val50(50); + CustomEqualsOnlyType val100(100); + CustomEqualsOnlyType val100x(100); + + QVariant variant50 = QVariant::fromValue(val50); + QVariant variant100 = QVariant::fromValue(val100); + QVariant variant100x = QVariant::fromValue(val100x); + + QVERIFY(variant50 != variant100); + QVERIFY(variant50 != variant100x); + QVERIFY(variant100 != variant50); + QVERIFY(variant100x != variant50); + QCOMPARE(variant100, variant100x); + QCOMPARE(variant100, variant100); + + // check QMetaType::compare works/doesn't crash for equals only comparators + auto cmp = type.compare(variant50.constData(), variant50.constData()); + QCOMPARE(cmp, QPartialOrdering::Unordered); + bool equals = type.equals(variant50.constData(), variant50.constData()); + QVERIFY(equals); + + cmp = type.compare(variant100.constData(), variant100x.constData()); + QCOMPARE(cmp, QPartialOrdering::Unordered); + equals = type.equals(variant100.constData(), variant100x.constData()); + QVERIFY(equals); + + cmp = type.compare(variant50.constData(), variant100.constData()); + QCOMPARE(cmp, QPartialOrdering::Unordered); + equals = type.equals(variant50.constData(), variant100.constData()); + QVERIFY(!equals); + + //check QMetaType::equals for type w/o equals comparator being registered + CustomMovable movable1; + CustomMovable movable2; + type = QMetaType::fromType(); + equals = type.equals(&movable1, &movable2); +} + +void tst_QMetaType::customDebugStream() +{ + MessageHandlerCustom handler(::qMetaTypeId()); + QVariant v1 = QVariant::fromValue(CustomDebugStreamableType()); + handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)"; + qDebug() << v1; + + MessageHandlerCustom handler2(::qMetaTypeId()); + QMetaType::registerConverter(&CustomDebugStreamableType2::toString); + handler2.expectedMessage = "QVariant(CustomDebugStreamableType2, \"test\")"; + QVariant v2 = QVariant::fromValue(CustomDebugStreamableType2()); + qDebug() << v2; +} + +void tst_QMetaType::unknownType() +{ + QMetaType invalid(QMetaType::UnknownType); + QVERIFY(!invalid.create()); + QVERIFY(!invalid.sizeOf()); + QVERIFY(!invalid.metaObject()); + int buffer = 0xBAD; + invalid.construct(&buffer); + QCOMPARE(buffer, 0xBAD); +} + +void tst_QMetaType::fromType() +{ + #define FROMTYPE_CHECK(MetaTypeName, MetaTypeId, RealType) \ + QCOMPARE(QMetaType::fromType(), QMetaType(MetaTypeId)); \ + QVERIFY(QMetaType::fromType() == QMetaType(MetaTypeId)); \ + QVERIFY(!(QMetaType::fromType() != QMetaType(MetaTypeId))); \ + if (MetaTypeId != QMetaType::Void) \ + QCOMPARE(QMetaType::fromType().id(), MetaTypeId); + + FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK) + + QVERIFY(QMetaType::fromType() != QMetaType()); + QCOMPARE(QMetaType(), QMetaType()); + QCOMPARE(QMetaType(QMetaType::UnknownType), QMetaType()); + + FROMTYPE_CHECK(_, ::qMetaTypeId>(), Whity) + #undef FROMTYPE_CHECK +} + +template +struct CharTemplate +{ + struct + { + int a; + } x; +}; + +void tst_QMetaType::operatorEq_data() +{ + QTest::addColumn("typeA"); + QTest::addColumn("typeB"); + QTest::addColumn("eq"); + QTest::newRow("String") << QMetaType(QMetaType::QString) + << QMetaType::fromType() << true; + QTest::newRow("void1") << QMetaType(QMetaType::UnknownType) << QMetaType::fromType() + << false; + QTest::newRow("void2") << QMetaType::fromType() << QMetaType::fromType() + << true; + QTest::newRow("list1") << QMetaType::fromType>() + << QMetaType::fromType>() << true; + QTest::newRow("list2") << QMetaType::fromType>() + << QMetaType::fromType>() << false; + QTest::newRow("char1") << QMetaType::fromType'>>() + << QMetaType::fromType', void>>() << true; + QTest::newRow("annon1") << QMetaType::fromType'>::x)>() + << QMetaType::fromType'>::x)>() << true; + QTest::newRow("annon2") << QMetaType::fromType'>::x)>() + << QMetaType::fromType::x)>() << false; +} + +void tst_QMetaType::operatorEq() +{ + QFETCH(QMetaType, typeA); + QFETCH(QMetaType, typeB); + QFETCH(bool, eq); + + QCOMPARE(typeA == typeB, eq); + QCOMPARE(typeB == typeA, eq); + QCOMPARE(typeA != typeB, !eq); + QCOMPARE(typeB != typeA, !eq); +} + +class WithPrivateDTor { + ~WithPrivateDTor(){}; +}; + +struct WithDeletedDtor { + ~WithDeletedDtor() = delete; +}; + +void tst_QMetaType::typesWithInaccessibleDTors() +{ + // should compile + Q_UNUSED(QMetaType::fromType()); + Q_UNUSED(QMetaType::fromType()); +} + +void tst_QMetaType::voidIsNotUnknown() +{ + QMetaType voidType = QMetaType::fromType(); + QMetaType voidType2 = QMetaType(QMetaType::Void); + QCOMPARE(voidType, voidType2); + QVERIFY(voidType != QMetaType(QMetaType::UnknownType)); +} + +void tst_QMetaType::typeNameNormalization() +{ + // check the we normalize types the right way +#define CHECK_TYPE_NORMALIZATION(Normalized, ...) \ + do { \ + /*QCOMPARE(QtPrivate::typenameHelper(), Normalized);*/ \ + QByteArray typeName = QMetaObject::normalizedType(#__VA_ARGS__); \ + QCOMPARE(typeName, Normalized); \ + typeName = QMetaType::fromType<__VA_ARGS__>().name(); \ + QCOMPARE(typeName, Normalized); \ + } while (0) + + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("uint", uint); + CHECK_TYPE_NORMALIZATION("QList>", QList>); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); + CHECK_TYPE_NORMALIZATION("QList", QList); +#ifdef Q_CC_MSVC + CHECK_TYPE_NORMALIZATION("qulonglong", __int64 unsigned); +#endif + CHECK_TYPE_NORMALIZATION("std::pair", QPair); + + // The string based normalization doesn't handle aliases, QMetaType::fromType() does +// CHECK_TYPE_NORMALIZATION("qulonglong", quint64); + QCOMPARE(QMetaType::fromType().name(), "qulonglong"); +} + +// Compile-time test, it should be possible to register function pointer types +class Undefined; + +typedef Undefined (*UndefinedFunction0)(); +typedef Undefined (*UndefinedFunction1)(Undefined); +typedef Undefined (*UndefinedFunction2)(Undefined, Undefined); +typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined); +typedef Undefined (*UndefinedFunction4)(Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined); + +Q_DECLARE_METATYPE(UndefinedFunction0); +Q_DECLARE_METATYPE(UndefinedFunction1); +Q_DECLARE_METATYPE(UndefinedFunction2); +Q_DECLARE_METATYPE(UndefinedFunction3); +Q_DECLARE_METATYPE(UndefinedFunction4); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h new file mode 100644 index 0000000000..6193ca93b8 --- /dev/null +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h @@ -0,0 +1,298 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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 +#include + +#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 +struct MetaEnumToType {}; + +#define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \ +template<> \ +struct MetaEnumToType { \ + typedef RealType Type; \ +}; +FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE) +#undef DEFINE_META_ENUM_TO_TYPE + +template +struct DefaultValueFactory +{ + typedef typename MetaEnumToType::Type Type; + static Type *create() { return new Type; } +}; + +template <> +struct DefaultValueFactory +{ + typedef MetaEnumToType::Type Type; + static Type *create() { return 0; } +}; + +template +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 { \ + 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 +struct TestValueFactory {}; + +template<> struct TestValueFactory { + static void *create() { return 0; } +}; + +template<> struct TestValueFactory { + static QString *create() { return new QString(QString::fromLatin1("QString")); } +}; +template<> struct TestValueFactory { + static int *create() { return new int(INT_MIN); } +}; +template<> struct TestValueFactory { + static uint *create() { return new uint(UINT_MAX); } +}; +template<> struct TestValueFactory { + static bool *create() { return new bool(true); } +}; +template<> struct TestValueFactory { + static double *create() { return new double(DBL_MIN); } +}; +template<> struct TestValueFactory { + static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); } +}; +template<> struct TestValueFactory { + static QByteArrayList *create() { return new QByteArrayList(QByteArrayList() << "Q" << "Byte" << "Array" << "List"); } +}; +template<> struct TestValueFactory { + static QVariantMap *create() { return new QVariantMap(); } +}; +template<> struct TestValueFactory { + static QVariantHash *create() { return new QVariantHash(); } +}; +template<> struct TestValueFactory { + static QVariantPair *create() { return new QVariantPair(); } +}; + +template<> struct TestValueFactory { + static QVariantList *create() { return new QVariantList(QVariantList() << 123 << "Q" << "Variant" << "List"); } +}; +template<> struct TestValueFactory { + static QChar *create() { return new QChar(QChar('q')); } +}; +template<> struct TestValueFactory { + static long *create() { return new long(LONG_MIN); } +}; +template<> struct TestValueFactory { + static short *create() { return new short(SHRT_MIN); } +}; +template<> struct TestValueFactory { + static char *create() { return new char('c'); } +}; +template<> struct TestValueFactory { + static char16_t *create() { return new char16_t('c'); } +}; +template<> struct TestValueFactory { + static char32_t *create() { return new char32_t('c'); } +}; +template<> struct TestValueFactory { + static ulong *create() { return new ulong(ULONG_MAX); } +}; +template<> struct TestValueFactory { + static ushort *create() { return new ushort(USHRT_MAX); } +}; +template<> struct TestValueFactory { + static signed char *create() { return new signed char(CHAR_MIN); } +}; +template<> struct TestValueFactory { + static uchar *create() { return new uchar(UCHAR_MAX); } +}; +template<> struct TestValueFactory { + static float *create() { return new float(FLT_MIN); } +}; +template<> struct TestValueFactory { + static QObject * *create() { return new QObject *(0); } +}; +template<> struct TestValueFactory { + static void * *create() { return new void *(0); } +}; +template<> struct TestValueFactory { + static qlonglong *create() { return new qlonglong(LLONG_MIN); } +}; +template<> struct TestValueFactory { + static qulonglong *create() { return new qulonglong(ULLONG_MAX); } +}; +template<> struct TestValueFactory { + static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); } +}; +template<> struct TestValueFactory { + static QBitArray *create() { return new QBitArray(QBitArray(256, true)); } +}; +template<> struct TestValueFactory { + static QDate *create() { return new QDate(QDate::currentDate()); } +}; +template<> struct TestValueFactory { + static QTime *create() { return new QTime(QTime::currentTime()); } +}; +template<> struct TestValueFactory { + static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); } +}; +template<> struct TestValueFactory { + static QUrl *create() { return new QUrl("http://www.example.org"); } +}; +template<> struct TestValueFactory { + static QLocale *create() { return new QLocale(QLocale::c()); } +}; +template<> struct TestValueFactory { + static QRect *create() { return new QRect(10, 20, 30, 40); } +}; +template<> struct TestValueFactory { + static QRectF *create() { return new QRectF(10, 20, 30, 40); } +}; +template<> struct TestValueFactory { + static QSize *create() { return new QSize(10, 20); } +}; +template<> struct TestValueFactory { + static QSizeF *create() { return new QSizeF(10, 20); } +}; +template<> struct TestValueFactory { + static QLine *create() { return new QLine(10, 20, 30, 40); } +}; +template<> struct TestValueFactory { + static QLineF *create() { return new QLineF(10, 20, 30, 40); } +}; +template<> struct TestValueFactory { + static QPoint *create() { return new QPoint(10, 20); } +}; +template<> struct TestValueFactory { + static QPointF *create() { return new QPointF(10, 20); } +}; +template<> struct TestValueFactory { + static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); } +}; +template<> struct TestValueFactory { + static QUuid *create() { return new QUuid(); } +}; +template<> struct TestValueFactory { + static QModelIndex *create() { return new QModelIndex(); } +}; +template<> struct TestValueFactory { + static QPersistentModelIndex *create() { return new QPersistentModelIndex(); } +}; +template<> struct TestValueFactory { + static std::nullptr_t *create() { return new std::nullptr_t; } +}; +template<> struct TestValueFactory { + static QRegularExpression *create() + { +#if QT_CONFIG(regularexpression) + return new QRegularExpression("abc.*def"); +#else + return 0; +#endif + } +}; +template<> struct TestValueFactory { + static QJsonValue *create() { return new QJsonValue(123.); } +}; +template<> struct TestValueFactory { + 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 { + 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 { + static QJsonDocument *create() { + return new QJsonDocument( + QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }") + ); + } +}; + +template<> struct TestValueFactory { + static QCborSimpleType *create() { return new QCborSimpleType(QCborSimpleType::True); } +}; +template<> struct TestValueFactory { + static QCborValue *create() { return new QCborValue(123.); } +}; +template<> struct TestValueFactory { + static QCborMap *create() { + return new QCborMap{{0, 0}, {"Hello", 1}, {1, nullptr}}; + } +}; +template<> struct TestValueFactory { + static QCborArray *create() { + return new QCborArray{0, 1, -2, 2.5, false, nullptr, "Hello", QByteArray("World") }; + } +}; + +template<> struct TestValueFactory { + static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); } +}; + +#endif // TST_QMETATYPE_H -- cgit v1.2.3