/**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include Q_DECLARE_METATYPE(QMetaType::Type) class tst_QGuiMetaType: public QObject { Q_OBJECT private slots: void create_data(); void create(); void createCopy_data(); void createCopy(); void sizeOf_data(); void sizeOf(); void flags_data(); void flags(); void construct_data(); void construct(); void constructCopy_data(); void constructCopy(); }; #define FOR_EACH_GUI_METATYPE(F) \ F(QFont, QFont) \ F(QPixmap, QPixmap) \ F(QBrush, QBrush) \ F(QColor, QColor) \ F(QPalette, QPalette) \ F(QImage, QImage) \ F(QPolygon, QPolygon) \ F(QRegion, QRegion) \ F(QBitmap, QBitmap) \ F(QCursor, QCursor) \ F(QKeySequence, QKeySequence) \ F(QPen, QPen) \ F(QTextLength, QTextLength) \ F(QTextFormat, QTextFormat) \ F(QMatrix, QMatrix) \ F(QTransform, QTransform) \ F(QMatrix4x4, QMatrix4x4) \ F(QVector2D, QVector2D) \ F(QVector3D, QVector3D) \ F(QVector4D, QVector4D) \ F(QQuaternion, QQuaternion) template struct MetaEnumToType {}; #define DEFINE_META_ENUM_TO_TYPE(TYPE, ID) \ template<> \ struct MetaEnumToType { \ typedef TYPE Type; \ }; FOR_EACH_GUI_METATYPE(DEFINE_META_ENUM_TO_TYPE) #undef DEFINE_META_ENUM_TO_TYPE // Not all types have operator== template struct TypeComparator { typedef typename MetaEnumToType::Type Type; static bool equal(const Type &v1, const Type &v2) { return v1 == v2; } }; template<> struct TypeComparator { static bool equal(const QPixmap &v1, const QPixmap &v2) { return v1.size() == v2.size(); } }; template<> struct TypeComparator { static bool equal(const QBitmap &v1, const QBitmap &v2) { return v1.size() == v2.size(); } }; template<> struct TypeComparator { static bool equal(const QCursor &v1, const QCursor &v2) { return v1.shape() == v2.shape(); } }; template struct DefaultValueFactory { typedef typename MetaEnumToType::Type Type; static Type *create() { return new Type; } }; template struct TestValueFactory {}; template<> struct TestValueFactory { static QFont *create() { return new QFont("Arial"); } }; template<> struct TestValueFactory { static QPixmap *create() { return new QPixmap(16, 32); } }; template<> struct TestValueFactory { static QBrush *create() { return new QBrush(Qt::SolidPattern); } }; template<> struct TestValueFactory { static QColor *create() { return new QColor(Qt::blue); } }; template<> struct TestValueFactory { static QPalette *create() { return new QPalette(Qt::yellow, Qt::green); } }; template<> struct TestValueFactory { static QImage *create() { return new QImage(16, 32, QImage::Format_ARGB32_Premultiplied); } }; template<> struct TestValueFactory { static QPolygon *create() { return new QPolygon(QRect(10, 20, 30, 40), true); } }; template<> struct TestValueFactory { static QRegion *create() { return new QRegion(QRect(10, 20, 30, 40), QRegion::Ellipse); } }; template<> struct TestValueFactory { static QBitmap *create() { return new QBitmap(16, 32); } }; template<> struct TestValueFactory { static QCursor *create() { return new QCursor(Qt::WaitCursor); } }; template<> struct TestValueFactory { static QKeySequence *create() { return new QKeySequence(QKeySequence::Close); } }; template<> struct TestValueFactory { static QPen *create() { return new QPen(Qt::DashDotDotLine); } }; template<> struct TestValueFactory { static QTextLength *create() { return new QTextLength(QTextLength::PercentageLength, 50); } }; template<> struct TestValueFactory { static QTextFormat *create() { return new QTextFormat(QTextFormat::TableFormat); } }; template<> struct TestValueFactory { static QMatrix *create() { return new QMatrix(10, 20, 30, 40, 50, 60); } }; template<> struct TestValueFactory { static QTransform *create() { return new QTransform(10, 20, 30, 40, 50, 60); } }; template<> struct TestValueFactory { static QMatrix4x4 *create() { return new QMatrix4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); } }; template<> struct TestValueFactory { static QVector2D *create() { return new QVector2D(10, 20); } }; template<> struct TestValueFactory { static QVector3D *create() { return new QVector3D(10, 20, 30); } }; template<> struct TestValueFactory { static QVector4D *create() { return new QVector4D(10, 20, 30, 40); } }; template<> struct TestValueFactory { static QQuaternion *create() { return new QQuaternion(10, 20, 30, 40); } }; void tst_QGuiMetaType::create_data() { QTest::addColumn("type"); #define ADD_METATYPE_TEST_ROW(TYPE, ID) \ QTest::newRow(QMetaType::typeName(QMetaType::ID)) << QMetaType::ID; FOR_EACH_GUI_METATYPE(ADD_METATYPE_TEST_ROW) #undef ADD_METATYPE_TEST_ROW } template static void testCreateHelper() { typedef typename MetaEnumToType::Type Type; void *actual = QMetaType::create(ID); Type *expected = DefaultValueFactory::create(); QVERIFY(TypeComparator::equal(*static_cast(actual), *expected)); delete expected; QMetaType::destroy(ID, actual); } typedef void (*TypeTestFunction)(); void tst_QGuiMetaType::create() { struct TypeTestFunctionGetter { static TypeTestFunction get(int type) { switch (type) { #define RETURN_CREATE_FUNCTION(TYPE, ID) \ case QMetaType::ID: \ return testCreateHelper; FOR_EACH_GUI_METATYPE(RETURN_CREATE_FUNCTION) #undef RETURN_CREATE_FUNCTION } return 0; } }; QFETCH(QMetaType::Type, type); TypeTestFunctionGetter::get(type)(); } void tst_QGuiMetaType::createCopy_data() { create_data(); } template static void testCreateCopyHelper() { typedef typename MetaEnumToType::Type Type; Type *expected = TestValueFactory::create(); void *actual = QMetaType::create(ID, expected); QVERIFY(TypeComparator::equal(*static_cast(actual), *expected)); QMetaType::destroy(ID, actual); delete expected; } void tst_QGuiMetaType::createCopy() { struct TypeTestFunctionGetter { static TypeTestFunction get(int type) { switch (type) { #define RETURN_CREATE_COPY_FUNCTION(TYPE, ID) \ case QMetaType::ID: \ return testCreateCopyHelper; FOR_EACH_GUI_METATYPE(RETURN_CREATE_COPY_FUNCTION) #undef RETURN_CREATE_COPY_FUNCTION } return 0; } }; QFETCH(QMetaType::Type, type); TypeTestFunctionGetter::get(type)(); } void tst_QGuiMetaType::sizeOf_data() { QTest::addColumn("type"); QTest::addColumn("size"); #define ADD_METATYPE_TEST_ROW(TYPE, ID) \ QTest::newRow(QMetaType::typeName(QMetaType::ID)) << QMetaType::ID << int(sizeof(TYPE)); FOR_EACH_GUI_METATYPE(ADD_METATYPE_TEST_ROW) #undef ADD_METATYPE_TEST_ROW } void tst_QGuiMetaType::sizeOf() { QFETCH(QMetaType::Type, type); QFETCH(int, size); QCOMPARE(QMetaType::sizeOf(type), size); } #ifndef Q_ALIGNOF template struct RoundToNextHighestPowerOfTwo { private: enum { V1 = N-1 }; enum { V2 = V1 | (V1 >> 1) }; enum { V3 = V2 | (V2 >> 2) }; enum { V4 = V3 | (V3 >> 4) }; enum { V5 = V4 | (V4 >> 8) }; enum { V6 = V5 | (V5 >> 16) }; public: enum { Value = V6 + 1 }; }; #endif template struct TypeAlignment { #ifdef Q_ALIGNOF enum { Value = Q_ALIGNOF(T) }; #else enum { Value = RoundToNextHighestPowerOfTwo::Value }; #endif }; void tst_QGuiMetaType::flags_data() { QTest::addColumn("type"); QTest::addColumn("isMovable"); QTest::addColumn("isComplex"); #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ QTest::newRow(#RealType) << MetaTypeId << bool(!QTypeInfo::isStatic) << bool(QTypeInfo::isComplex); QT_FOR_EACH_STATIC_GUI_CLASS(ADD_METATYPE_TEST_ROW) #undef ADD_METATYPE_TEST_ROW } void tst_QGuiMetaType::flags() { QFETCH(int, type); QFETCH(bool, isMovable); QFETCH(bool, isComplex); QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsConstruction), isComplex); QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsDestruction), isComplex); QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::MovableType), isMovable); } void tst_QGuiMetaType::construct_data() { create_data(); } template static void testConstructHelper() { typedef typename MetaEnumToType::Type Type; int size = QMetaType::sizeOf(ID); void *storage = qMallocAligned(size, TypeAlignment::Value); void *actual = QMetaType::construct(ID, storage, /*copy=*/0); QCOMPARE(actual, storage); Type *expected = DefaultValueFactory::create(); QVERIFY2(TypeComparator::equal(*static_cast(actual), *expected), QMetaType::typeName(ID)); delete expected; QMetaType::destruct(ID, actual); qFreeAligned(storage); } void tst_QGuiMetaType::construct() { struct TypeTestFunctionGetter { static TypeTestFunction get(int type) { switch (type) { #define RETURN_CONSTRUCT_FUNCTION(TYPE, ID) \ case QMetaType::ID: \ return testConstructHelper; FOR_EACH_GUI_METATYPE(RETURN_CONSTRUCT_FUNCTION) #undef RETURN_CONSTRUCT_FUNCTION } return 0; } }; QFETCH(QMetaType::Type, type); TypeTestFunctionGetter::get(type)(); } void tst_QGuiMetaType::constructCopy_data() { create_data(); } template static void testConstructCopyHelper() { typedef typename MetaEnumToType::Type Type; Type *expected = TestValueFactory::create(); int size = QMetaType::sizeOf(ID); void *storage = qMallocAligned(size, TypeAlignment::Value); void *actual = QMetaType::construct(ID, storage, expected); QCOMPARE(actual, storage); QVERIFY2(TypeComparator::equal(*static_cast(actual), *expected), QMetaType::typeName(ID)); QMetaType::destruct(ID, actual); qFreeAligned(storage); delete expected; } void tst_QGuiMetaType::constructCopy() { struct TypeTestFunctionGetter { static TypeTestFunction get(int type) { switch (type) { #define RETURN_CONSTRUCT_COPY_FUNCTION(TYPE, ID) \ case QMetaType::ID: \ return testConstructCopyHelper; FOR_EACH_GUI_METATYPE(RETURN_CONSTRUCT_COPY_FUNCTION) #undef RETURN_CONSTRUCT_COPY_FUNCTION } return 0; } }; QFETCH(QMetaType::Type, type); TypeTestFunctionGetter::get(type)(); } QTEST_MAIN(tst_QGuiMetaType) #include "tst_qguimetatype.moc"