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 <fabian.kosmale@qt.io>
This commit is contained in:
parent
2861cfb6f8
commit
85416ae6fd
@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include "tst_qmetatype.h"
|
#include "tst_qmetatype_common.h"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -9,7 +9,7 @@ list(APPEND test_data "./typeFlags.bin")
|
|||||||
|
|
||||||
qt_internal_add_test(tst_qmetatype
|
qt_internal_add_test(tst_qmetatype
|
||||||
SOURCES
|
SOURCES
|
||||||
tst_qmetatype.cpp
|
tst_qmetatype.h tst_qmetatype.cpp tst_qmetatype2.cpp
|
||||||
DEFINES
|
DEFINES
|
||||||
QT_DISABLE_DEPRECATED_BEFORE=0
|
QT_DISABLE_DEPRECATED_BEFORE=0
|
||||||
INCLUDE_DIRECTORIES
|
INCLUDE_DIRECTORIES
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the test suite of the Qt Toolkit.
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
@ -26,13 +26,9 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <QtCore>
|
|
||||||
#include <QTest>
|
|
||||||
#include <QtCore/private/qmetaobjectbuilder_p.h>
|
|
||||||
|
|
||||||
#include "tst_qmetatype.h"
|
#include "tst_qmetatype.h"
|
||||||
#include "tst_qvariant_common.h"
|
|
||||||
|
#include <QtCore/private/qmetaobjectbuilder_p.h>
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
@ -153,91 +149,6 @@ static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested2>>);
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class tst_QMetaType: public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
|
|
||||||
|
|
||||||
public:
|
|
||||||
struct GadgetPropertyType {
|
|
||||||
QByteArray type;
|
|
||||||
QByteArray name;
|
|
||||||
QVariant testData;
|
|
||||||
};
|
|
||||||
|
|
||||||
tst_QMetaType() { propList << 42 << "Hello"; }
|
|
||||||
|
|
||||||
QList<QVariant> prop() const { return propList; }
|
|
||||||
void setProp(const QList<QVariant> &list) { propList = list; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void registerGadget(const char * name, const QList<GadgetPropertyType> &gadgetProperties);
|
|
||||||
QList<QVariant> 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
|
struct BaseGenericType
|
||||||
{
|
{
|
||||||
int m_typeId = -1;
|
int m_typeId = -1;
|
||||||
@ -647,18 +558,6 @@ void tst_QMetaType::properties()
|
|||||||
QCOMPARE(v.toList().count(), 4);
|
QCOMPARE(v.toList().count(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct Whity { T t; Whity() {} };
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE( Whity < int > )
|
|
||||||
Q_DECLARE_METATYPE(Whity<double>)
|
|
||||||
|
|
||||||
#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
Q_DECLARE_TYPEINFO(Whity<double>, Q_RELOCATABLE_TYPE);
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void tst_QMetaType::normalizedTypes()
|
void tst_QMetaType::normalizedTypes()
|
||||||
{
|
{
|
||||||
int WhityIntId = ::qMetaTypeId<Whity<int> >();
|
int WhityIntId = ::qMetaTypeId<Whity<int> >();
|
||||||
@ -1011,20 +910,6 @@ void tst_QMetaType::alignOf()
|
|||||||
QCOMPARE(size_t(QMetaType(type).alignOf()), size);
|
QCOMPARE(size_t(QMetaType(type).alignOf()), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CustomMovable { CustomMovable() {} };
|
|
||||||
|
|
||||||
// needed for QSet<CustomMovable>. 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
|
class CustomObject : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -2234,549 +2119,5 @@ void tst_QMetaType::constexprMetaTypeIds()
|
|||||||
Q_UNUSED(metaType);
|
Q_UNUSED(metaType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QMetaType::constRefs()
|
|
||||||
{
|
|
||||||
QCOMPARE(::qMetaTypeId<const int &>(), ::qMetaTypeId<int>());
|
|
||||||
QCOMPARE(::qMetaTypeId<const QString &>(), ::qMetaTypeId<QString>());
|
|
||||||
QCOMPARE(::qMetaTypeId<const CustomMovable &>(), ::qMetaTypeId<CustomMovable>());
|
|
||||||
QCOMPARE(::qMetaTypeId<const QList<CustomMovable> &>(), ::qMetaTypeId<QList<CustomMovable> >());
|
|
||||||
static_assert(::qMetaTypeId<const int &>() == ::qMetaTypeId<int>());
|
|
||||||
}
|
|
||||||
|
|
||||||
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<typename To>
|
|
||||||
To convert() const { return s_value.value<To>();}
|
|
||||||
template<typename To>
|
|
||||||
To convertOk(bool *ok) const { *ok = s_ok; return s_value.value<To>();}
|
|
||||||
|
|
||||||
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<CustomEqualsOnlyType>);
|
|
||||||
static_assert(!QTypeTraits::has_operator_less_than_v<CustomEqualsOnlyType>);
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(CustomConvertibleType);
|
|
||||||
Q_DECLARE_METATYPE(CustomConvertibleType2);
|
|
||||||
Q_DECLARE_METATYPE(CustomDebugStreamableType);
|
|
||||||
Q_DECLARE_METATYPE(CustomEqualsOnlyType);
|
|
||||||
|
|
||||||
template<typename T, typename U>
|
|
||||||
U convert(const T &t)
|
|
||||||
{
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename From>
|
|
||||||
struct ConvertFunctor
|
|
||||||
{
|
|
||||||
CustomConvertibleType operator()(const From& f) const
|
|
||||||
{
|
|
||||||
return CustomConvertibleType(QVariant::fromValue(f));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename From, typename To>
|
|
||||||
bool hasRegisteredConverterFunction()
|
|
||||||
{
|
|
||||||
return QMetaType::hasRegisteredConverterFunction<From, To>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename From, typename To>
|
|
||||||
void testCustomTypeNotYetConvertible()
|
|
||||||
{
|
|
||||||
QVERIFY((!hasRegisteredConverterFunction<From, To>()));
|
|
||||||
QVERIFY((!QVariant::fromValue<From>(From()).template canConvert<To>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename From, typename To>
|
|
||||||
void testCustomTypeConvertible()
|
|
||||||
{
|
|
||||||
QVERIFY((hasRegisteredConverterFunction<From, To>()));
|
|
||||||
QVERIFY((QVariant::fromValue<From>(From()).template canConvert<To>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void customTypeNotYetConvertible()
|
|
||||||
{
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QString>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, bool>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, int>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, double>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, float>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QRect>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QRectF>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QPoint>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QPointF>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QSize>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QSizeF>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QLine>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QLineF>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, QChar>();
|
|
||||||
testCustomTypeNotYetConvertible<QString, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<bool, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<int, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<double, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<float, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<QRect, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<QRectF, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<QPoint, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<QPointF, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<QSize, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<QSizeF, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<QLine, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<QLineF, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<QChar, CustomConvertibleType>();
|
|
||||||
testCustomTypeNotYetConvertible<CustomConvertibleType, CustomConvertibleType2>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void registerCustomTypeConversions()
|
|
||||||
{
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QString>(&CustomConvertibleType::convertOk<QString>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, bool>(&CustomConvertibleType::convert<bool>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, int>(&CustomConvertibleType::convertOk<int>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, double>(&CustomConvertibleType::convert<double>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, float>(&CustomConvertibleType::convertOk<float>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRect>(&CustomConvertibleType::convert<QRect>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRectF>(&CustomConvertibleType::convertOk<QRectF>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPoint>(convert<CustomConvertibleType,QPoint>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPointF>(&CustomConvertibleType::convertOk<QPointF>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSize>(&CustomConvertibleType::convert<QSize>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSizeF>(&CustomConvertibleType::convertOk<QSizeF>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLine>(&CustomConvertibleType::convert<QLine>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLineF>(&CustomConvertibleType::convertOk<QLineF>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QChar>(&CustomConvertibleType::convert<QChar>)));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QString, CustomConvertibleType>(ConvertFunctor<QString>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<bool, CustomConvertibleType>(ConvertFunctor<bool>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<int, CustomConvertibleType>(ConvertFunctor<int>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<double, CustomConvertibleType>(ConvertFunctor<double>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<float, CustomConvertibleType>(ConvertFunctor<float>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QRect, CustomConvertibleType>(ConvertFunctor<QRect>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QRectF, CustomConvertibleType>(ConvertFunctor<QRectF>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QPoint, CustomConvertibleType>(ConvertFunctor<QPoint>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QPointF, CustomConvertibleType>(ConvertFunctor<QPointF>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QSize, CustomConvertibleType>(ConvertFunctor<QSize>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QSizeF, CustomConvertibleType>(ConvertFunctor<QSizeF>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QLine, CustomConvertibleType>(ConvertFunctor<QLine>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QLineF, CustomConvertibleType>(ConvertFunctor<QLineF>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<QChar, CustomConvertibleType>(ConvertFunctor<QChar>())));
|
|
||||||
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
|
|
||||||
QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2");
|
|
||||||
QVERIFY((!QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QMetaType::convertCustomType_data()
|
|
||||||
{
|
|
||||||
customTypeNotYetConvertible();
|
|
||||||
registerCustomTypeConversions();
|
|
||||||
|
|
||||||
QTest::addColumn<bool>("ok");
|
|
||||||
QTest::addColumn<QString>("testQString");
|
|
||||||
QTest::addColumn<bool>("testBool");
|
|
||||||
QTest::addColumn<int>("testInt");
|
|
||||||
QTest::addColumn<double>("testDouble");
|
|
||||||
QTest::addColumn<float>("testFloat");
|
|
||||||
QTest::addColumn<QRect>("testQRect");
|
|
||||||
QTest::addColumn<QRectF>("testQRectF");
|
|
||||||
QTest::addColumn<QPoint>("testQPoint");
|
|
||||||
QTest::addColumn<QPointF>("testQPointF");
|
|
||||||
QTest::addColumn<QSize>("testQSize");
|
|
||||||
QTest::addColumn<QSizeF>("testQSizeF");
|
|
||||||
QTest::addColumn<QLine>("testQLine");
|
|
||||||
QTest::addColumn<QLineF>("testQLineF");
|
|
||||||
QTest::addColumn<QChar>("testQChar");
|
|
||||||
QTest::addColumn<CustomConvertibleType>("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<QString>(), ok ? testQString : QString());
|
|
||||||
QVERIFY(CustomConvertibleType::s_value.canConvert<CustomConvertibleType>());
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toString()), testQString);
|
|
||||||
|
|
||||||
QFETCH(bool, testBool);
|
|
||||||
CustomConvertibleType::s_value = testBool;
|
|
||||||
QCOMPARE(v.toBool(), testBool);
|
|
||||||
QCOMPARE(v.value<bool>(), testBool);
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toBool()), testBool);
|
|
||||||
|
|
||||||
QFETCH(int, testInt);
|
|
||||||
CustomConvertibleType::s_value = testInt;
|
|
||||||
QCOMPARE(v.toInt(), ok ? testInt : 0);
|
|
||||||
QCOMPARE(v.value<int>(), ok ? testInt : 0);
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toInt()), testInt);
|
|
||||||
|
|
||||||
QFETCH(double, testDouble);
|
|
||||||
CustomConvertibleType::s_value = testDouble;
|
|
||||||
QCOMPARE(v.toDouble(), testDouble);
|
|
||||||
QCOMPARE(v.value<double>(), testDouble);
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toDouble()), testDouble);
|
|
||||||
|
|
||||||
QFETCH(float, testFloat);
|
|
||||||
CustomConvertibleType::s_value = testFloat;
|
|
||||||
QCOMPARE(v.toFloat(), ok ? testFloat : 0.0);
|
|
||||||
QCOMPARE(v.value<float>(), ok ? testFloat : 0.0);
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toFloat()), testFloat);
|
|
||||||
|
|
||||||
QFETCH(QRect, testQRect);
|
|
||||||
CustomConvertibleType::s_value = testQRect;
|
|
||||||
QCOMPARE(v.toRect(), testQRect);
|
|
||||||
QCOMPARE(v.value<QRect>(), testQRect);
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRect()), testQRect);
|
|
||||||
|
|
||||||
QFETCH(QRectF, testQRectF);
|
|
||||||
CustomConvertibleType::s_value = testQRectF;
|
|
||||||
QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF());
|
|
||||||
QCOMPARE(v.value<QRectF>(), ok ? testQRectF : QRectF());
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRectF()), testQRectF);
|
|
||||||
|
|
||||||
QFETCH(QPoint, testQPoint);
|
|
||||||
CustomConvertibleType::s_value = testQPoint;
|
|
||||||
QCOMPARE(v.toPoint(), testQPoint);
|
|
||||||
QCOMPARE(v.value<QPoint>(), testQPoint);
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPoint()), testQPoint);
|
|
||||||
|
|
||||||
QFETCH(QPointF, testQPointF);
|
|
||||||
CustomConvertibleType::s_value = testQPointF;
|
|
||||||
QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF());
|
|
||||||
QCOMPARE(v.value<QPointF>(), ok ? testQPointF : QPointF());
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPointF()), testQPointF);
|
|
||||||
|
|
||||||
QFETCH(QSize, testQSize);
|
|
||||||
CustomConvertibleType::s_value = testQSize;
|
|
||||||
QCOMPARE(v.toSize(), testQSize);
|
|
||||||
QCOMPARE(v.value<QSize>(), testQSize);
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSize()), testQSize);
|
|
||||||
|
|
||||||
QFETCH(QSizeF, testQSizeF);
|
|
||||||
CustomConvertibleType::s_value = testQSizeF;
|
|
||||||
QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF());
|
|
||||||
QCOMPARE(v.value<QSizeF>(), ok ? testQSizeF : QSizeF());
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSizeF()), testQSizeF);
|
|
||||||
|
|
||||||
QFETCH(QLine, testQLine);
|
|
||||||
CustomConvertibleType::s_value = testQLine;
|
|
||||||
QCOMPARE(v.toLine(), testQLine);
|
|
||||||
QCOMPARE(v.value<QLine>(), testQLine);
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLine()), testQLine);
|
|
||||||
|
|
||||||
QFETCH(QLineF, testQLineF);
|
|
||||||
CustomConvertibleType::s_value = testQLineF;
|
|
||||||
QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF());
|
|
||||||
QCOMPARE(v.value<QLineF>(), ok ? testQLineF : QLineF());
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLineF()), testQLineF);
|
|
||||||
|
|
||||||
QFETCH(QChar, testQChar);
|
|
||||||
CustomConvertibleType::s_value = testQChar;
|
|
||||||
QCOMPARE(v.toChar(), testQChar);
|
|
||||||
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toChar()), testQChar);
|
|
||||||
|
|
||||||
QFETCH(CustomConvertibleType, testCustom);
|
|
||||||
v = QVariant::fromValue(testCustom);
|
|
||||||
QVERIFY(v.canConvert(::qMetaTypeId<CustomConvertibleType2>()));
|
|
||||||
QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QMetaType::compareCustomEqualOnlyType()
|
|
||||||
{
|
|
||||||
QMetaType type = QMetaType::fromType<CustomEqualsOnlyType>();
|
|
||||||
|
|
||||||
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<CustomMovable>();
|
|
||||||
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<CustomDebugStreamableType>());
|
|
||||||
QVariant v1 = QVariant::fromValue(CustomDebugStreamableType());
|
|
||||||
handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)";
|
|
||||||
qDebug() << v1;
|
|
||||||
|
|
||||||
MessageHandlerCustom handler2(::qMetaTypeId<CustomDebugStreamableType2>());
|
|
||||||
QMetaType::registerConverter<CustomDebugStreamableType2, QString>(&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<RealType>(), QMetaType(MetaTypeId)); \
|
|
||||||
QVERIFY(QMetaType::fromType<RealType>() == QMetaType(MetaTypeId)); \
|
|
||||||
QVERIFY(!(QMetaType::fromType<RealType>() != QMetaType(MetaTypeId))); \
|
|
||||||
if (MetaTypeId != QMetaType::Void) \
|
|
||||||
QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId);
|
|
||||||
|
|
||||||
FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK)
|
|
||||||
|
|
||||||
QVERIFY(QMetaType::fromType<QString>() != QMetaType());
|
|
||||||
QCOMPARE(QMetaType(), QMetaType());
|
|
||||||
QCOMPARE(QMetaType(QMetaType::UnknownType), QMetaType());
|
|
||||||
|
|
||||||
FROMTYPE_CHECK(_, ::qMetaTypeId<Whity<int>>(), Whity<int>)
|
|
||||||
#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>()
|
|
||||||
<< false;
|
|
||||||
QTest::newRow("void2") << QMetaType::fromType<const void>() << QMetaType::fromType<void>()
|
|
||||||
<< true;
|
|
||||||
QTest::newRow("list1") << QMetaType::fromType<QList<const int *>>()
|
|
||||||
<< QMetaType::fromType<QList<const int *>>() << true;
|
|
||||||
QTest::newRow("list2") << QMetaType::fromType<QList<const int *>>()
|
|
||||||
<< QMetaType::fromType<QList<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>());
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QMetaType::voidIsNotUnknown()
|
|
||||||
{
|
|
||||||
QMetaType voidType = QMetaType::fromType<void>();
|
|
||||||
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<Type>(), 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<QString*const>", QList<QString * const>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<const QString * >);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<const QString*const>", QList<const QString * const>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<QString const *>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<signed char>", QList<signed char>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<uint>", QList<unsigned>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("uint", uint);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<QHash<uint,QString*>>", QList<QHash<unsigned, QString *>>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<qlonglong>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<qulonglong>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<long long>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<unsigned long long>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<qulonglong*>", QList<unsigned long long *>);
|
|
||||||
CHECK_TYPE_NORMALIZATION("QList<ulong>", QList<long unsigned >);
|
|
||||||
#ifdef Q_CC_MSVC
|
|
||||||
CHECK_TYPE_NORMALIZATION("qulonglong", __int64 unsigned);
|
|
||||||
#endif
|
|
||||||
CHECK_TYPE_NORMALIZATION("std::pair<const QString&&,short>", QPair<const QString &&, signed short>);
|
|
||||||
|
|
||||||
// The string based normalization doesn't handle aliases, QMetaType::fromType() does
|
|
||||||
// CHECK_TYPE_NORMALIZATION("qulonglong", quint64);
|
|
||||||
QCOMPARE(QMetaType::fromType<quint64>().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)
|
QTEST_MAIN(tst_QMetaType)
|
||||||
#include "tst_qmetatype.moc"
|
#include "tst_qmetatype.moc"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the test suite of the Qt Toolkit.
|
** 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 <QtCore>
|
||||||
|
#include <QTest>
|
||||||
|
#include "tst_qmetatype_common.h"
|
||||||
|
#include "tst_qvariant_common.h"
|
||||||
|
|
||||||
#ifndef TST_QMETATYPE_H
|
struct MessageHandlerCustom : public MessageHandler
|
||||||
#define TST_QMETATYPE_H
|
|
||||||
|
|
||||||
#include <qmetatype.h>
|
|
||||||
#include <float.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;
|
MessageHandlerCustom(const int typeId)
|
||||||
static Type *create() { return new Type; }
|
: MessageHandler(typeId, handler)
|
||||||
};
|
{}
|
||||||
|
static void handler(QtMsgType, const QMessageLogContext &, const QString &msg)
|
||||||
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(INT_MIN); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::UInt> {
|
|
||||||
static uint *create() { return new uint(UINT_MAX); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Bool> {
|
|
||||||
static bool *create() { return new bool(true); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Double> {
|
|
||||||
static double *create() { return new double(DBL_MIN); }
|
|
||||||
};
|
|
||||||
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::QVariantPair> {
|
|
||||||
static QVariantPair *create() { return new QVariantPair(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
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(LONG_MIN); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Short> {
|
|
||||||
static short *create() { return new short(SHRT_MIN); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Char> {
|
|
||||||
static char *create() { return new char('c'); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Char16> {
|
|
||||||
static char16_t *create() { return new char16_t('c'); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Char32> {
|
|
||||||
static char32_t *create() { return new char32_t('c'); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::ULong> {
|
|
||||||
static ulong *create() { return new ulong(ULONG_MAX); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::UShort> {
|
|
||||||
static ushort *create() { return new ushort(USHRT_MAX); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::SChar> {
|
|
||||||
static signed char *create() { return new signed char(CHAR_MIN); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::UChar> {
|
|
||||||
static uchar *create() { return new uchar(UCHAR_MAX); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::Float> {
|
|
||||||
static float *create() { return new float(FLT_MIN); }
|
|
||||||
};
|
|
||||||
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(LLONG_MIN); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::ULongLong> {
|
|
||||||
static qulonglong *create() { return new qulonglong(ULLONG_MAX); }
|
|
||||||
};
|
|
||||||
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::QRegularExpression> {
|
|
||||||
static QRegularExpression *create()
|
|
||||||
{
|
{
|
||||||
#if QT_CONFIG(regularexpression)
|
QCOMPARE(msg.trimmed(), expectedMessage.trimmed());
|
||||||
return new QRegularExpression("abc.*def");
|
}
|
||||||
#else
|
inline static QString expectedMessage;
|
||||||
return 0;
|
};
|
||||||
|
|
||||||
|
class tst_QMetaType: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct GadgetPropertyType {
|
||||||
|
QByteArray type;
|
||||||
|
QByteArray name;
|
||||||
|
QVariant testData;
|
||||||
|
};
|
||||||
|
|
||||||
|
tst_QMetaType() { propList << 42 << "Hello"; }
|
||||||
|
|
||||||
|
QList<QVariant> prop() const { return propList; }
|
||||||
|
void setProp(const QList<QVariant> &list) { propList = list; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void registerGadget(const char * name, const QList<GadgetPropertyType> &gadgetProperties);
|
||||||
|
QList<QVariant> 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 <typename T>
|
||||||
|
struct Whity { T t; Whity() {} };
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Whity<int>)
|
||||||
|
Q_DECLARE_METATYPE(Whity<double>)
|
||||||
|
|
||||||
|
#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
Q_DECLARE_TYPEINFO(Whity<double>, Q_RELOCATABLE_TYPE);
|
||||||
|
QT_END_NAMESPACE
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
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<typename To>
|
||||||
|
To convert() const { return s_value.value<To>();}
|
||||||
|
template<typename To>
|
||||||
|
To convertOk(bool *ok) const { *ok = s_ok; return s_value.value<To>();}
|
||||||
|
|
||||||
|
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); }
|
||||||
};
|
};
|
||||||
template<> struct TestValueFactory<QMetaType::QJsonValue> {
|
|
||||||
static QJsonValue *create() { return new QJsonValue(123.); }
|
struct CustomConvertibleType2
|
||||||
|
{
|
||||||
|
// implicit
|
||||||
|
CustomConvertibleType2(const CustomConvertibleType &t = CustomConvertibleType())
|
||||||
|
: m_foo(t.m_foo) {}
|
||||||
|
virtual ~CustomConvertibleType2() {}
|
||||||
|
|
||||||
|
QVariant m_foo;
|
||||||
|
|
||||||
|
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); }
|
||||||
};
|
};
|
||||||
template<> struct TestValueFactory<QMetaType::QJsonObject> {
|
|
||||||
static QJsonObject *create() {
|
struct CustomDebugStreamableType
|
||||||
QJsonObject *o = new QJsonObject();
|
{
|
||||||
o->insert("a", 123.);
|
QString toString() const { return "test"; }
|
||||||
o->insert("b", true);
|
|
||||||
o->insert("c", QJsonValue::Null);
|
friend QDebug operator<<(QDebug dbg, const CustomDebugStreamableType&)
|
||||||
o->insert("d", QLatin1String("ciao"));
|
{
|
||||||
return o;
|
return dbg << "string-content";
|
||||||
}
|
|
||||||
};
|
|
||||||
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::QCborSimpleType> {
|
struct CustomDebugStreamableType2
|
||||||
static QCborSimpleType *create() { return new QCborSimpleType(QCborSimpleType::True); }
|
{
|
||||||
};
|
QString toString() const { return "test"; }
|
||||||
template<> struct TestValueFactory<QMetaType::QCborValue> {
|
|
||||||
static QCborValue *create() { return new QCborValue(123.); }
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QCborMap> {
|
|
||||||
static QCborMap *create() {
|
|
||||||
return new QCborMap{{0, 0}, {"Hello", 1}, {1, nullptr}};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<> struct TestValueFactory<QMetaType::QCborArray> {
|
|
||||||
static QCborArray *create() {
|
|
||||||
return new QCborArray{0, 1, -2, 2.5, false, nullptr, "Hello", QByteArray("World") };
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct TestValueFactory<QMetaType::QVariant> {
|
struct CustomEqualsOnlyType
|
||||||
static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
|
{
|
||||||
|
explicit CustomEqualsOnlyType(int value = 0) : val(value) {}
|
||||||
|
virtual ~CustomEqualsOnlyType() {}
|
||||||
|
|
||||||
|
int val;
|
||||||
|
|
||||||
|
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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TST_QMETATYPE_H
|
static_assert(QTypeTraits::has_operator_equal_v<CustomEqualsOnlyType>);
|
||||||
|
static_assert(!QTypeTraits::has_operator_less_than_v<CustomEqualsOnlyType>);
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(CustomConvertibleType);
|
||||||
|
Q_DECLARE_METATYPE(CustomConvertibleType2);
|
||||||
|
Q_DECLARE_METATYPE(CustomDebugStreamableType);
|
||||||
|
Q_DECLARE_METATYPE(CustomEqualsOnlyType);
|
||||||
|
|
||||||
|
struct CustomMovable {
|
||||||
|
CustomMovable() {}
|
||||||
|
|
||||||
|
friend bool operator==(const CustomMovable &, const CustomMovable &) { return true; }
|
||||||
|
// needed for QSet<CustomMovable>. We actually check that it makes sense.
|
||||||
|
friend 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);
|
||||||
|
483
tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp
Normal file
483
tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp
Normal file
@ -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 <QtCore/private/qmetaobjectbuilder_p.h>
|
||||||
|
|
||||||
|
void tst_QMetaType::constRefs()
|
||||||
|
{
|
||||||
|
QCOMPARE(::qMetaTypeId<const int &>(), ::qMetaTypeId<int>());
|
||||||
|
QCOMPARE(::qMetaTypeId<const QString &>(), ::qMetaTypeId<QString>());
|
||||||
|
QCOMPARE(::qMetaTypeId<const CustomMovable &>(), ::qMetaTypeId<CustomMovable>());
|
||||||
|
QCOMPARE(::qMetaTypeId<const QList<CustomMovable> &>(), ::qMetaTypeId<QList<CustomMovable> >());
|
||||||
|
static_assert(::qMetaTypeId<const int &>() == ::qMetaTypeId<int>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
U convert(const T &t)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename From>
|
||||||
|
struct ConvertFunctor
|
||||||
|
{
|
||||||
|
CustomConvertibleType operator()(const From& f) const
|
||||||
|
{
|
||||||
|
return CustomConvertibleType(QVariant::fromValue(f));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename From, typename To>
|
||||||
|
bool hasRegisteredConverterFunction()
|
||||||
|
{
|
||||||
|
return QMetaType::hasRegisteredConverterFunction<From, To>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename From, typename To>
|
||||||
|
void testCustomTypeNotYetConvertible()
|
||||||
|
{
|
||||||
|
QVERIFY((!hasRegisteredConverterFunction<From, To>()));
|
||||||
|
QVERIFY((!QVariant::fromValue<From>(From()).template canConvert<To>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename From, typename To>
|
||||||
|
void testCustomTypeConvertible()
|
||||||
|
{
|
||||||
|
QVERIFY((hasRegisteredConverterFunction<From, To>()));
|
||||||
|
QVERIFY((QVariant::fromValue<From>(From()).template canConvert<To>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void customTypeNotYetConvertible()
|
||||||
|
{
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QString>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, bool>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, int>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, double>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, float>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QRect>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QRectF>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QPoint>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QPointF>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QSize>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QSizeF>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QLine>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QLineF>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, QChar>();
|
||||||
|
testCustomTypeNotYetConvertible<QString, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<bool, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<int, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<double, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<float, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<QRect, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<QRectF, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<QPoint, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<QPointF, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<QSize, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<QSizeF, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<QLine, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<QLineF, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<QChar, CustomConvertibleType>();
|
||||||
|
testCustomTypeNotYetConvertible<CustomConvertibleType, CustomConvertibleType2>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerCustomTypeConversions()
|
||||||
|
{
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QString>(&CustomConvertibleType::convertOk<QString>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, bool>(&CustomConvertibleType::convert<bool>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, int>(&CustomConvertibleType::convertOk<int>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, double>(&CustomConvertibleType::convert<double>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, float>(&CustomConvertibleType::convertOk<float>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRect>(&CustomConvertibleType::convert<QRect>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRectF>(&CustomConvertibleType::convertOk<QRectF>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPoint>(convert<CustomConvertibleType,QPoint>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPointF>(&CustomConvertibleType::convertOk<QPointF>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSize>(&CustomConvertibleType::convert<QSize>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSizeF>(&CustomConvertibleType::convertOk<QSizeF>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLine>(&CustomConvertibleType::convert<QLine>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLineF>(&CustomConvertibleType::convertOk<QLineF>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QChar>(&CustomConvertibleType::convert<QChar>)));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QString, CustomConvertibleType>(ConvertFunctor<QString>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<bool, CustomConvertibleType>(ConvertFunctor<bool>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<int, CustomConvertibleType>(ConvertFunctor<int>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<double, CustomConvertibleType>(ConvertFunctor<double>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<float, CustomConvertibleType>(ConvertFunctor<float>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QRect, CustomConvertibleType>(ConvertFunctor<QRect>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QRectF, CustomConvertibleType>(ConvertFunctor<QRectF>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QPoint, CustomConvertibleType>(ConvertFunctor<QPoint>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QPointF, CustomConvertibleType>(ConvertFunctor<QPointF>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QSize, CustomConvertibleType>(ConvertFunctor<QSize>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QSizeF, CustomConvertibleType>(ConvertFunctor<QSizeF>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QLine, CustomConvertibleType>(ConvertFunctor<QLine>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QLineF, CustomConvertibleType>(ConvertFunctor<QLineF>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<QChar, CustomConvertibleType>(ConvertFunctor<QChar>())));
|
||||||
|
QVERIFY((QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2");
|
||||||
|
QVERIFY((!QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaType::convertCustomType_data()
|
||||||
|
{
|
||||||
|
customTypeNotYetConvertible();
|
||||||
|
registerCustomTypeConversions();
|
||||||
|
|
||||||
|
QTest::addColumn<bool>("ok");
|
||||||
|
QTest::addColumn<QString>("testQString");
|
||||||
|
QTest::addColumn<bool>("testBool");
|
||||||
|
QTest::addColumn<int>("testInt");
|
||||||
|
QTest::addColumn<double>("testDouble");
|
||||||
|
QTest::addColumn<float>("testFloat");
|
||||||
|
QTest::addColumn<QRect>("testQRect");
|
||||||
|
QTest::addColumn<QRectF>("testQRectF");
|
||||||
|
QTest::addColumn<QPoint>("testQPoint");
|
||||||
|
QTest::addColumn<QPointF>("testQPointF");
|
||||||
|
QTest::addColumn<QSize>("testQSize");
|
||||||
|
QTest::addColumn<QSizeF>("testQSizeF");
|
||||||
|
QTest::addColumn<QLine>("testQLine");
|
||||||
|
QTest::addColumn<QLineF>("testQLineF");
|
||||||
|
QTest::addColumn<QChar>("testQChar");
|
||||||
|
QTest::addColumn<CustomConvertibleType>("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<QString>(), ok ? testQString : QString());
|
||||||
|
QVERIFY(CustomConvertibleType::s_value.canConvert<CustomConvertibleType>());
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toString()), testQString);
|
||||||
|
|
||||||
|
QFETCH(bool, testBool);
|
||||||
|
CustomConvertibleType::s_value = testBool;
|
||||||
|
QCOMPARE(v.toBool(), testBool);
|
||||||
|
QCOMPARE(v.value<bool>(), testBool);
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toBool()), testBool);
|
||||||
|
|
||||||
|
QFETCH(int, testInt);
|
||||||
|
CustomConvertibleType::s_value = testInt;
|
||||||
|
QCOMPARE(v.toInt(), ok ? testInt : 0);
|
||||||
|
QCOMPARE(v.value<int>(), ok ? testInt : 0);
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toInt()), testInt);
|
||||||
|
|
||||||
|
QFETCH(double, testDouble);
|
||||||
|
CustomConvertibleType::s_value = testDouble;
|
||||||
|
QCOMPARE(v.toDouble(), testDouble);
|
||||||
|
QCOMPARE(v.value<double>(), testDouble);
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toDouble()), testDouble);
|
||||||
|
|
||||||
|
QFETCH(float, testFloat);
|
||||||
|
CustomConvertibleType::s_value = testFloat;
|
||||||
|
QCOMPARE(v.toFloat(), ok ? testFloat : 0.0);
|
||||||
|
QCOMPARE(v.value<float>(), ok ? testFloat : 0.0);
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toFloat()), testFloat);
|
||||||
|
|
||||||
|
QFETCH(QRect, testQRect);
|
||||||
|
CustomConvertibleType::s_value = testQRect;
|
||||||
|
QCOMPARE(v.toRect(), testQRect);
|
||||||
|
QCOMPARE(v.value<QRect>(), testQRect);
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRect()), testQRect);
|
||||||
|
|
||||||
|
QFETCH(QRectF, testQRectF);
|
||||||
|
CustomConvertibleType::s_value = testQRectF;
|
||||||
|
QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF());
|
||||||
|
QCOMPARE(v.value<QRectF>(), ok ? testQRectF : QRectF());
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRectF()), testQRectF);
|
||||||
|
|
||||||
|
QFETCH(QPoint, testQPoint);
|
||||||
|
CustomConvertibleType::s_value = testQPoint;
|
||||||
|
QCOMPARE(v.toPoint(), testQPoint);
|
||||||
|
QCOMPARE(v.value<QPoint>(), testQPoint);
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPoint()), testQPoint);
|
||||||
|
|
||||||
|
QFETCH(QPointF, testQPointF);
|
||||||
|
CustomConvertibleType::s_value = testQPointF;
|
||||||
|
QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF());
|
||||||
|
QCOMPARE(v.value<QPointF>(), ok ? testQPointF : QPointF());
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPointF()), testQPointF);
|
||||||
|
|
||||||
|
QFETCH(QSize, testQSize);
|
||||||
|
CustomConvertibleType::s_value = testQSize;
|
||||||
|
QCOMPARE(v.toSize(), testQSize);
|
||||||
|
QCOMPARE(v.value<QSize>(), testQSize);
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSize()), testQSize);
|
||||||
|
|
||||||
|
QFETCH(QSizeF, testQSizeF);
|
||||||
|
CustomConvertibleType::s_value = testQSizeF;
|
||||||
|
QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF());
|
||||||
|
QCOMPARE(v.value<QSizeF>(), ok ? testQSizeF : QSizeF());
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSizeF()), testQSizeF);
|
||||||
|
|
||||||
|
QFETCH(QLine, testQLine);
|
||||||
|
CustomConvertibleType::s_value = testQLine;
|
||||||
|
QCOMPARE(v.toLine(), testQLine);
|
||||||
|
QCOMPARE(v.value<QLine>(), testQLine);
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLine()), testQLine);
|
||||||
|
|
||||||
|
QFETCH(QLineF, testQLineF);
|
||||||
|
CustomConvertibleType::s_value = testQLineF;
|
||||||
|
QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF());
|
||||||
|
QCOMPARE(v.value<QLineF>(), ok ? testQLineF : QLineF());
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLineF()), testQLineF);
|
||||||
|
|
||||||
|
QFETCH(QChar, testQChar);
|
||||||
|
CustomConvertibleType::s_value = testQChar;
|
||||||
|
QCOMPARE(v.toChar(), testQChar);
|
||||||
|
QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toChar()), testQChar);
|
||||||
|
|
||||||
|
QFETCH(CustomConvertibleType, testCustom);
|
||||||
|
v = QVariant::fromValue(testCustom);
|
||||||
|
QVERIFY(v.canConvert(::qMetaTypeId<CustomConvertibleType2>()));
|
||||||
|
QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaType::compareCustomEqualOnlyType()
|
||||||
|
{
|
||||||
|
QMetaType type = QMetaType::fromType<CustomEqualsOnlyType>();
|
||||||
|
|
||||||
|
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<CustomMovable>();
|
||||||
|
equals = type.equals(&movable1, &movable2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaType::customDebugStream()
|
||||||
|
{
|
||||||
|
MessageHandlerCustom handler(::qMetaTypeId<CustomDebugStreamableType>());
|
||||||
|
QVariant v1 = QVariant::fromValue(CustomDebugStreamableType());
|
||||||
|
handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)";
|
||||||
|
qDebug() << v1;
|
||||||
|
|
||||||
|
MessageHandlerCustom handler2(::qMetaTypeId<CustomDebugStreamableType2>());
|
||||||
|
QMetaType::registerConverter<CustomDebugStreamableType2, QString>(&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<RealType>(), QMetaType(MetaTypeId)); \
|
||||||
|
QVERIFY(QMetaType::fromType<RealType>() == QMetaType(MetaTypeId)); \
|
||||||
|
QVERIFY(!(QMetaType::fromType<RealType>() != QMetaType(MetaTypeId))); \
|
||||||
|
if (MetaTypeId != QMetaType::Void) \
|
||||||
|
QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId);
|
||||||
|
|
||||||
|
FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK)
|
||||||
|
|
||||||
|
QVERIFY(QMetaType::fromType<QString>() != QMetaType());
|
||||||
|
QCOMPARE(QMetaType(), QMetaType());
|
||||||
|
QCOMPARE(QMetaType(QMetaType::UnknownType), QMetaType());
|
||||||
|
|
||||||
|
FROMTYPE_CHECK(_, ::qMetaTypeId<Whity<int>>(), Whity<int>)
|
||||||
|
#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>()
|
||||||
|
<< false;
|
||||||
|
QTest::newRow("void2") << QMetaType::fromType<const void>() << QMetaType::fromType<void>()
|
||||||
|
<< true;
|
||||||
|
QTest::newRow("list1") << QMetaType::fromType<QList<const int *>>()
|
||||||
|
<< QMetaType::fromType<QList<const int *>>() << true;
|
||||||
|
QTest::newRow("list2") << QMetaType::fromType<QList<const int *>>()
|
||||||
|
<< QMetaType::fromType<QList<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>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaType::voidIsNotUnknown()
|
||||||
|
{
|
||||||
|
QMetaType voidType = QMetaType::fromType<void>();
|
||||||
|
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<Type>(), 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<QString*const>", QList<QString * const>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<const QString * >);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<const QString*const>", QList<const QString * const>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<QString const *>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<signed char>", QList<signed char>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<uint>", QList<unsigned>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("uint", uint);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<QHash<uint,QString*>>", QList<QHash<unsigned, QString *>>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<qlonglong>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<qulonglong>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<long long>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<unsigned long long>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<qulonglong*>", QList<unsigned long long *>);
|
||||||
|
CHECK_TYPE_NORMALIZATION("QList<ulong>", QList<long unsigned >);
|
||||||
|
#ifdef Q_CC_MSVC
|
||||||
|
CHECK_TYPE_NORMALIZATION("qulonglong", __int64 unsigned);
|
||||||
|
#endif
|
||||||
|
CHECK_TYPE_NORMALIZATION("std::pair<const QString&&,short>", QPair<const QString &&, signed short>);
|
||||||
|
|
||||||
|
// The string based normalization doesn't handle aliases, QMetaType::fromType() does
|
||||||
|
// CHECK_TYPE_NORMALIZATION("qulonglong", quint64);
|
||||||
|
QCOMPARE(QMetaType::fromType<quint64>().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);
|
298
tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h
Normal file
298
tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h
Normal file
@ -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 <qmetatype.h>
|
||||||
|
#include <float.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(INT_MIN); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::UInt> {
|
||||||
|
static uint *create() { return new uint(UINT_MAX); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Bool> {
|
||||||
|
static bool *create() { return new bool(true); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Double> {
|
||||||
|
static double *create() { return new double(DBL_MIN); }
|
||||||
|
};
|
||||||
|
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::QVariantPair> {
|
||||||
|
static QVariantPair *create() { return new QVariantPair(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
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(LONG_MIN); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Short> {
|
||||||
|
static short *create() { return new short(SHRT_MIN); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Char> {
|
||||||
|
static char *create() { return new char('c'); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Char16> {
|
||||||
|
static char16_t *create() { return new char16_t('c'); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Char32> {
|
||||||
|
static char32_t *create() { return new char32_t('c'); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::ULong> {
|
||||||
|
static ulong *create() { return new ulong(ULONG_MAX); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::UShort> {
|
||||||
|
static ushort *create() { return new ushort(USHRT_MAX); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::SChar> {
|
||||||
|
static signed char *create() { return new signed char(CHAR_MIN); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::UChar> {
|
||||||
|
static uchar *create() { return new uchar(UCHAR_MAX); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::Float> {
|
||||||
|
static float *create() { return new float(FLT_MIN); }
|
||||||
|
};
|
||||||
|
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(LLONG_MIN); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::ULongLong> {
|
||||||
|
static qulonglong *create() { return new qulonglong(ULLONG_MAX); }
|
||||||
|
};
|
||||||
|
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::QRegularExpression> {
|
||||||
|
static QRegularExpression *create()
|
||||||
|
{
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
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::QCborSimpleType> {
|
||||||
|
static QCborSimpleType *create() { return new QCborSimpleType(QCborSimpleType::True); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QCborValue> {
|
||||||
|
static QCborValue *create() { return new QCborValue(123.); }
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QCborMap> {
|
||||||
|
static QCborMap *create() {
|
||||||
|
return new QCborMap{{0, 0}, {"Hello", 1}, {1, nullptr}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct TestValueFactory<QMetaType::QCborArray> {
|
||||||
|
static QCborArray *create() {
|
||||||
|
return new QCborArray{0, 1, -2, 2.5, false, nullptr, "Hello", QByteArray("World") };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct TestValueFactory<QMetaType::QVariant> {
|
||||||
|
static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TST_QMETATYPE_H
|
@ -72,11 +72,9 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
QtMessageHandler oldMsgHandler;
|
QtMessageHandler oldMsgHandler;
|
||||||
static int currentId;
|
inline static int currentId = {};
|
||||||
static bool ok;
|
inline static bool ok = {};
|
||||||
};
|
};
|
||||||
bool MessageHandler::ok;
|
|
||||||
int MessageHandler::currentId;
|
|
||||||
|
|
||||||
#define TST_QVARIANT_CANCONVERT_DATATABLE_HEADERS \
|
#define TST_QVARIANT_CANCONVERT_DATATABLE_HEADERS \
|
||||||
QTest::addColumn<QVariant>("val"); \
|
QTest::addColumn<QVariant>("val"); \
|
||||||
|
Loading…
Reference in New Issue
Block a user