diff options
Diffstat (limited to 'tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp')
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 229 |
1 files changed, 109 insertions, 120 deletions
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 19b3289390..f144aad7e4 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -120,17 +120,19 @@ private slots: void constRefs(); void convertCustomType_data(); void convertCustomType(); - void compareCustomType_data(); - void compareCustomType(); void compareCustomEqualOnlyType(); void customDebugStream(); void unknownType(); void fromType(); + void operatorEq_data(); + void operatorEq(); + void typesWithInaccessibleDTors(); }; struct BaseGenericType { int m_typeId = -1; + QMetaType m_metatype; virtual void *constructor(int typeId, void *where, const void *copy) = 0; virtual void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) = 0; virtual void saveOperator(QDataStream & out) const = 0; @@ -302,11 +304,19 @@ void tst_QMetaType::registerGadget(const char *name, const QVector<GadgetPropert meta->d.static_metacall = &GadgetsStaticMetacallFunction; meta->d.superdata = nullptr; const auto flags = QMetaType::WasDeclaredAsMetaType | QMetaType::IsGadget | QMetaType::NeedsConstruction | QMetaType::NeedsDestruction; - int gadgetTypeId = QMetaType::registerType(name, - &GadgetTypedDestructor, - &GadgetTypedConstructor, - sizeof(GenericGadgetType), - flags, meta); + using TypeInfo = QtPrivate::QMetaTypeInterface; + auto typeInfo = new TypeInfo { + 0, sizeof(GenericGadgetType), alignof(GenericGadgetType), uint(flags), meta, name, 0, + QtPrivate::RefCount{ 0 }, + [](TypeInfo *self) { delete self; }, + [](const TypeInfo *self, void *where) { GadgetTypedConstructor(self->typeId, where, nullptr); }, + [](const TypeInfo *self, void *where, const void *copy) { GadgetTypedConstructor(self->typeId, where, copy); }, + [](const TypeInfo *self, void *where, void *copy) { GadgetTypedConstructor(self->typeId, where, copy); }, + [](const TypeInfo *self, void *ptr) { GadgetTypedDestructor(self->typeId, ptr); }, + nullptr }; + QMetaType gadgetMetaType(typeInfo); + dynamicGadgetProperties->m_metatype = gadgetMetaType; + int gadgetTypeId = QMetaType(typeInfo).id(); QVERIFY(gadgetTypeId > 0); QMetaType::registerStreamOperators(gadgetTypeId, &GadgetSaveOperator, &GadgetLoadOperator); s_managedTypes[gadgetTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{meta, [](QMetaObject *ptr){ ::free(ptr); }}); @@ -392,10 +402,6 @@ protected: ++failureCount; qWarning() << "Wrong metatype returned for" << name; } - if (QMetaType::typeName(tp) != name) { - ++failureCount; - qWarning() << "Wrong typeName returned for" << tp; - } void *buf1 = QMetaType::create(tp, 0); void *buf2 = QMetaType::create(tp, buf1); void *buf3 = info.create(tp, 0); @@ -574,11 +580,13 @@ void tst_QMetaType::typeName_data() QTest::newRow("124125534") << 124125534 << QString(); // automatic registration - QTest::newRow("QList<int>") << ::qMetaTypeId<QList<int> >() << QString::fromLatin1("QList<int>"); QTest::newRow("QHash<int,int>") << ::qMetaTypeId<QHash<int, int> >() << QString::fromLatin1("QHash<int,int>"); QTest::newRow("QMap<int,int>") << ::qMetaTypeId<QMap<int, int> >() << QString::fromLatin1("QMap<int,int>"); - QTest::newRow("QVector<QList<int>>") << ::qMetaTypeId<QVector<QList<int> > >() << QString::fromLatin1("QVector<QList<int> >"); - QTest::newRow("QVector<QMap<int,int>>") << ::qMetaTypeId<QVector<QMap<int, int> > >() << QString::fromLatin1("QVector<QMap<int,int> >"); + QTest::newRow("QVector<QMap<int,int>>") << ::qMetaTypeId<QVector<QMap<int, int> > >() << QString::fromLatin1("QVector<QMap<int,int>>"); + + // automatic registration with automatic QList to QVector aliasing + QTest::newRow("QList<int>") << ::qMetaTypeId<QList<int> >() << QString::fromLatin1("QVector<int>"); + QTest::newRow("QVector<QList<int>>") << ::qMetaTypeId<QVector<QList<int> > >() << QString::fromLatin1("QVector<QVector<int>>"); QTest::newRow("CustomQObject*") << ::qMetaTypeId<CustomQObject*>() << QString::fromLatin1("CustomQObject*"); QTest::newRow("CustomGadget") << ::qMetaTypeId<CustomGadget>() << QString::fromLatin1("CustomGadget"); @@ -1006,6 +1014,10 @@ void tst_QMetaType::flagsBinaryCompatibility5_0_data() for (int i = 0; i < buffer.size(); i+=2) { const quint32 id = buffer.at(i); const quint32 flags = buffer.at(i + 1); + if (id > QMetaType::LastCoreType) + continue; // We do not link against QtGui, so we do longer consider such type as registered + if (id == QMetaType::Void) + continue; // The meaning of QMetaType::Void has changed in Qt6 QVERIFY2(QMetaType::isRegistered(id), "A type could not be removed in BC way"); QTest::newRow(QMetaType::typeName(id)) << id << flags; } @@ -1032,9 +1044,9 @@ static void testConstructHelper() typedef typename MetaEnumToType<ID>::Type Type; QMetaType info(ID); int size = info.sizeOf(); - void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type)); + void *storage1 = qMallocAligned(size, alignof(Type)); void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0); - void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type)); + void *storage2 = qMallocAligned(size, alignof(Type)); void *actual2 = info.construct(storage2, /*copy=*/0); QCOMPARE(actual1, storage1); QCOMPARE(actual2, storage2); @@ -1158,11 +1170,19 @@ void tst_QMetaType::typedConstruct() auto dynamicGadgetProperties = std::make_shared<GenericPODType>(); dynamicGadgetProperties->podData = myPodTesData; const auto flags = QMetaType::NeedsConstruction | QMetaType::NeedsDestruction; - int podTypeId = QMetaType::registerType(podTypeName, - &GadgetTypedDestructor, - &GadgetTypedConstructor, - sizeof(GenericGadgetType), - flags, nullptr); + using TypeInfo = QtPrivate::QMetaTypeInterface; + auto typeInfo = new TypeInfo { + 0, sizeof(GenericGadgetType), alignof(GenericGadgetType), uint(flags), nullptr, podTypeName, + 0, QtPrivate::RefCount{0}, + [](TypeInfo *self) { delete self; }, + [](const TypeInfo *self, void *where) { GadgetTypedConstructor(self->typeId, where, nullptr); }, + [](const TypeInfo *self, void *where, const void *copy) { GadgetTypedConstructor(self->typeId, where, copy); }, + [](const TypeInfo *self, void *where, void *copy) { GadgetTypedConstructor(self->typeId, where, copy); }, + [](const TypeInfo *self, void *ptr) { GadgetTypedDestructor(self->typeId, ptr); }, + nullptr }; + QMetaType metatype(typeInfo); + dynamicGadgetProperties->m_metatype = metatype; + int podTypeId = metatype.id(); QVERIFY(podTypeId > 0); QMetaType::registerStreamOperators(podTypeId, &GadgetSaveOperator, &GadgetLoadOperator); s_managedTypes[podTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{}); @@ -1186,9 +1206,9 @@ static void testConstructCopyHelper() QMetaType info(ID); int size = QMetaType::sizeOf(ID); QCOMPARE(info.sizeOf(), size); - void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type)); + void *storage1 = qMallocAligned(size, alignof(Type)); void *actual1 = QMetaType::construct(ID, storage1, expected); - void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type)); + void *storage2 = qMallocAligned(size, alignof(Type)); void *actual2 = info.construct(storage2, expected); QCOMPARE(actual1, storage1); QCOMPARE(actual2, storage2); @@ -1309,54 +1329,6 @@ void tst_QMetaType::registerType() QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId); QCOMPARE(QMetaType::type("MyFoo"), fooId); - - // cannot unregister built-in types - QVERIFY(!QMetaType::unregisterType(QMetaType::QString)); - QCOMPARE(QMetaType::type("QString"), int(QMetaType::QString)); - QCOMPARE(QMetaType::type("MyString"), int(QMetaType::QString)); - - // cannot unregister declared types - QVERIFY(!QMetaType::unregisterType(fooId)); - QCOMPARE(QMetaType::type("TestSpace::Foo"), fooId); - QCOMPARE(QMetaType::type("MyFoo"), fooId); - - // test unregistration of dynamic types (used by Qml) - int unregId = QMetaType::registerType("UnregisterMe", - 0, - 0, - QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct, - QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct, - 0, QMetaType::TypeFlags(), 0); - QCOMPARE(QMetaType::registerTypedef("UnregisterMeTypedef", unregId), unregId); - int unregId2 = QMetaType::registerType("UnregisterMe2", - 0, - 0, - QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct, - QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct, - 0, QMetaType::TypeFlags(), 0); - QVERIFY(unregId >= int(QMetaType::User)); - QCOMPARE(unregId2, unregId + 2); - - QVERIFY(QMetaType::unregisterType(unregId)); - QCOMPARE(QMetaType::type("UnregisterMe"), 0); - QCOMPARE(QMetaType::type("UnregisterMeTypedef"), 0); - QCOMPARE(QMetaType::type("UnregisterMe2"), unregId2); - QVERIFY(QMetaType::unregisterType(unregId2)); - QCOMPARE(QMetaType::type("UnregisterMe2"), 0); - - // re-registering should always return the lowest free index - QCOMPARE(QMetaType::registerType("UnregisterMe2", - 0, - 0, - QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct, - QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct, - 0, QMetaType::TypeFlags(), 0), unregId); - QCOMPARE(QMetaType::registerType("UnregisterMe", - 0, - 0, - QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct, - QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct, - 0, QMetaType::TypeFlags(), 0), unregId + 1); } class IsRegisteredDummyType { }; @@ -1367,7 +1339,7 @@ void tst_QMetaType::isRegistered_data() QTest::addColumn<bool>("registered"); // predefined/custom types - QTest::newRow("QMetaType::Void") << int(QMetaType::Void) << true; + QTest::newRow("QMetaType::Void") << int(QMetaType::Void) << false; QTest::newRow("QMetaType::Int") << int(QMetaType::Int) << true; int dummyTypeId = qRegisterMetaType<IsRegisteredDummyType>("IsRegisteredDummyType"); @@ -1733,8 +1705,8 @@ void tst_QMetaType::automaticTemplateRegistration() CONTAINER< __VA_ARGS__ > t; \ const QVariant v = QVariant::fromValue(t); \ QByteArray tn = createTypeName(#CONTAINER "<", #__VA_ARGS__); \ - const int type = QMetaType::type(tn); \ const int expectedType = ::qMetaTypeId<CONTAINER< __VA_ARGS__ > >(); \ + const int type = QMetaType::type(tn); \ QCOMPARE(type, expectedType); \ QCOMPARE((QMetaType::fromType<CONTAINER< __VA_ARGS__ >>().id()), expectedType); \ } @@ -1742,7 +1714,6 @@ void tst_QMetaType::automaticTemplateRegistration() #define FOR_EACH_1ARG_TEMPLATE_TYPE(F, TYPE) \ F(QList, TYPE) \ F(QVector, TYPE) \ - F(QLinkedList, TYPE) \ F(QVector, TYPE) \ F(QVector, TYPE) \ F(QQueue, TYPE) \ @@ -1777,7 +1748,7 @@ void tst_QMetaType::automaticTemplateRegistration() PRINT_2ARG_TEMPLATE ) - CREATE_AND_VERIFY_CONTAINER(QList, QList<QMap<int, QHash<char, QVariantList> > >) + CREATE_AND_VERIFY_CONTAINER(QList, QList<QMap<int, QHash<char, QList<QVariant> > > >) CREATE_AND_VERIFY_CONTAINER(QVector, void*) CREATE_AND_VERIFY_CONTAINER(QVector, const void*) CREATE_AND_VERIFY_CONTAINER(QList, void*) @@ -2017,7 +1988,7 @@ void tst_QMetaType::metaObject_data() QTest::newRow("MyGadget") << ::qMetaTypeId<MyGadget>() << &MyGadget::staticMetaObject << true << false << false; QTest::newRow("MyGadget*") << ::qMetaTypeId<MyGadget*>() << &MyGadget::staticMetaObject << false << true << false; QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false << false; - QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &QObject::staticQtMetaObject << false << false << false; + QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &Qt::staticMetaObject << false << false << false; QTest::newRow("MyQObjectFromGadget*") << ::qMetaTypeId<MyQObjectFromGadget*>() << &MyQObjectFromGadget::staticMetaObject << false << false << true; QTest::newRow("GadgetDerivedAndTyped<int>") << ::qMetaTypeId<GadgetDerivedAndTyped<int>>() << &GadgetDerivedAndTyped<int>::staticMetaObject << true << false << false; @@ -2139,7 +2110,7 @@ struct CustomConvertibleType }; bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) -{ return lhs.m_foo < rhs.m_foo; } +{ 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) @@ -2429,43 +2400,6 @@ void tst_QMetaType::convertCustomType() QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo); } -void tst_QMetaType::compareCustomType_data() -{ - QMetaType::registerComparators<CustomConvertibleType>(); - - QTest::addColumn<QVariantList>("unsorted"); - QTest::addColumn<QVariantList>("sorted"); - - QTest::newRow("int") << (QVariantList() << 37 << 458 << 1 << 243 << -4 << 383) - << (QVariantList() << -4 << 1 << 37 << 243 << 383 << 458); - - QTest::newRow("dobule") << (QVariantList() << 4934.93 << 0.0 << 302.39 << -39.0) - << (QVariantList() << -39.0 << 0.0 << 302.39 << 4934.93); - - QTest::newRow("QString") << (QVariantList() << "Hello" << "World" << "this" << "is" << "a" << "test") - << (QVariantList() << "a" << "Hello" << "is" << "test" << "this" << "World"); - - QTest::newRow("QTime") << (QVariantList() << QTime(14, 39) << QTime(0, 0) << QTime(18, 18) << QTime(9, 27)) - << (QVariantList() << QTime(0, 0) << QTime(9, 27) << QTime(14, 39) << QTime(18, 18)); - - QTest::newRow("QDate") << (QVariantList() << QDate(2013, 3, 23) << QDate(1900, 12, 1) << QDate(2001, 2, 2) << QDate(1982, 12, 16)) - << (QVariantList() << QDate(1900, 12, 1) << QDate(1982, 12, 16) << QDate(2001, 2, 2) << QDate(2013, 3, 23)); - - QTest::newRow("mixed") << (QVariantList() << "Hello" << "World" << QChar('a') << 38 << QChar('z') << -39 << 4.6) - << (QVariantList() << -39 << 4.6 << 38 << QChar('a') << "Hello" << "World" << QChar('z')); - - QTest::newRow("custom") << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(100)) << QVariant::fromValue(CustomConvertibleType(50))) - << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(50)) << QVariant::fromValue(CustomConvertibleType(100))); -} - -void tst_QMetaType::compareCustomType() -{ - QFETCH(QVariantList, unsorted); - QFETCH(QVariantList, sorted); - std::sort(unsorted.begin(), unsorted.end()); - QCOMPARE(unsorted, sorted); -} - void tst_QMetaType::compareCustomEqualOnlyType() { int metaTypeId = qRegisterMetaType<CustomEqualsOnlyType>(); @@ -2487,11 +2421,6 @@ void tst_QMetaType::compareCustomEqualOnlyType() QCOMPARE(variant100, variant100x); QCOMPARE(variant100, variant100); - // compare always fails - QVERIFY(!(variant50 < variant50)); - QVERIFY(!(variant50 < variant100)); - QVERIFY(!(variant100 < variant50)); - // check QMetaType::compare works/doesn't crash for equals only comparators bool wasSuccess = QMetaType::compare(variant50.constData(), variant50.constData(), metaTypeId, &result); @@ -2588,7 +2517,8 @@ void tst_QMetaType::fromType() QCOMPARE(QMetaType::fromType<RealType>(), QMetaType(MetaTypeId)); \ QVERIFY(QMetaType::fromType<RealType>() == QMetaType(MetaTypeId)); \ QVERIFY(!(QMetaType::fromType<RealType>() != QMetaType(MetaTypeId))); \ - QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId); + if (MetaTypeId != QMetaType::Void) \ + QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId); FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK) @@ -2600,6 +2530,65 @@ void tst_QMetaType::fromType() #undef FROMTYPE_CHECK } +template<char X, typename T = void> +struct CharTemplate +{ + struct + { + int a; + } x; +}; + +void tst_QMetaType::operatorEq_data() +{ + QTest::addColumn<QMetaType>("typeA"); + QTest::addColumn<QMetaType>("typeB"); + QTest::addColumn<bool>("eq"); + + QTest::newRow("String") << QMetaType(QMetaType::QString) + << QMetaType::fromType<const QString &>() << true; + QTest::newRow("void1") << QMetaType(QMetaType::UnknownType) << QMetaType::fromType<void>() + << true; + QTest::newRow("void2") << QMetaType::fromType<const void>() << QMetaType::fromType<void>() + << true; + QTest::newRow("vec1") << QMetaType::fromType<QVector<const int *>>() + << QMetaType::fromType<QVector<const int *>>() << true; + QTest::newRow("vec2") << QMetaType::fromType<QVector<const int *>>() + << QMetaType::fromType<QVector<int *>>() << false; + QTest::newRow("char1") << QMetaType::fromType<CharTemplate<'>'>>() + << QMetaType::fromType<CharTemplate<'>', void>>() << true; + QTest::newRow("annon1") << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>() + << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>() << true; + QTest::newRow("annon2") << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>() + << QMetaType::fromType<decltype(CharTemplate<'<'>::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<WithPrivateDTor>()); + Q_UNUSED(QMetaType::fromType<WithDeletedDtor>()); +} // Compile-time test, it should be possible to register function pointer types class Undefined; |