diff options
Diffstat (limited to 'tests/auto/corelib/kernel')
-rw-r--r-- | tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp | 30 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/qmetatype.pro | 1 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 450 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 51 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 314 |
5 files changed, 810 insertions, 36 deletions
diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp index df374ffc23..c6d04e64db 100644 --- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp +++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp @@ -195,11 +195,11 @@ protected: void tst_QEventLoop::processEvents() { - QSignalSpy spy1(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock())); - QSignalSpy spy2(QAbstractEventDispatcher::instance(), SIGNAL(awake())); + QSignalSpy aboutToBlockSpy(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock())); + QSignalSpy awakeSpy(QAbstractEventDispatcher::instance(), SIGNAL(awake())); - QVERIFY(spy1.isValid()); - QVERIFY(spy2.isValid()); + QVERIFY(aboutToBlockSpy.isValid()); + QVERIFY(awakeSpy.isValid()); QEventLoop eventLoop; @@ -208,8 +208,8 @@ void tst_QEventLoop::processEvents() // process posted events, QEventLoop::processEvents() should return // true QVERIFY(eventLoop.processEvents()); - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 1); + QCOMPARE(aboutToBlockSpy.count(), 0); + QCOMPARE(awakeSpy.count(), 1); // allow any session manager to complete its handshake, so that // there are no pending events left. @@ -222,28 +222,28 @@ void tst_QEventLoop::processEvents() // no events to process, QEventLoop::processEvents() should return // false - spy1.clear(); - spy2.clear(); + aboutToBlockSpy.clear(); + awakeSpy.clear(); QVERIFY(!eventLoop.processEvents()); - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 1); + QCOMPARE(aboutToBlockSpy.count(), 0); + QCOMPARE(awakeSpy.count(), 1); // make sure the test doesn't block forever int timerId = startTimer(100); // wait for more events to process, QEventLoop::processEvents() // should return true - spy1.clear(); - spy2.clear(); + aboutToBlockSpy.clear(); + awakeSpy.clear(); QVERIFY(eventLoop.processEvents(QEventLoop::WaitForMoreEvents)); // Verify that the eventloop has blocked and woken up. Some eventloops // may block and wake up multiple times. - QVERIFY(spy1.count() > 0); - QVERIFY(spy2.count() > 0); + QVERIFY(aboutToBlockSpy.count() > 0); + QVERIFY(awakeSpy.count() > 0); // We should get one awake for each aboutToBlock, plus one awake when // processEvents is entered. - QVERIFY(spy2.count() >= spy1.count()); + QVERIFY(awakeSpy.count() >= aboutToBlockSpy.count()); killTimer(timerId); } diff --git a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro index 5009fedc4f..23a8e6d23a 100644 --- a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro +++ b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro @@ -1,6 +1,7 @@ CONFIG += testcase parallel_test TARGET = tst_qmetatype QT = core testlib +INCLUDEPATH += $$PWD/../../../other/qvariant_common SOURCES = tst_qmetatype.cpp TESTDATA=./typeFlags.bin DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 77ea39da53..47900204e7 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -43,6 +43,8 @@ #include <QtCore> #include <QtTest/QtTest> +#include "tst_qvariant_common.h" + #ifdef Q_OS_LINUX # include <pthread.h> #endif @@ -111,6 +113,11 @@ private slots: void metaObject(); void constexprMetaTypeIds(); void constRefs(); + void convertCustomType_data(); + void convertCustomType(); + void compareCustomType_data(); + void compareCustomType(); + void customDebugStream(); }; struct Foo { int i; }; @@ -1302,15 +1309,20 @@ Q_DECLARE_METATYPE(MyObjectPtr) void tst_QMetaType::automaticTemplateRegistration() { - { - QList<int> intList; - intList << 42; - QVERIFY(QVariant::fromValue(intList).value<QList<int> >().first() == 42); - QVector<QList<int> > vectorList; - vectorList << intList; - QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<int> > >().first().first() == 42); +#define TEST_SEQUENTIAL_CONTAINER(CONTAINER, VALUE_TYPE) \ + { \ + CONTAINER<VALUE_TYPE> innerContainer; \ + innerContainer.push_back(42); \ + QVERIFY(*QVariant::fromValue(innerContainer).value<CONTAINER<VALUE_TYPE> >().begin() == 42); \ + QVector<CONTAINER<VALUE_TYPE> > outerContainer; \ + outerContainer << innerContainer; \ + QVERIFY(*QVariant::fromValue(outerContainer).value<QVector<CONTAINER<VALUE_TYPE> > >().first().begin() == 42); \ } + TEST_SEQUENTIAL_CONTAINER(QList, int) + TEST_SEQUENTIAL_CONTAINER(std::vector, int) + TEST_SEQUENTIAL_CONTAINER(std::list, int) + { QList<QByteArray> bytearrayList; bytearrayList << QByteArray("foo"); @@ -1323,14 +1335,9 @@ void tst_QMetaType::automaticTemplateRegistration() QCOMPARE(::qMetaTypeId<QVariantList>(), (int)QMetaType::QVariantList); QCOMPARE(::qMetaTypeId<QList<QVariant> >(), (int)QMetaType::QVariantList); - { - QList<QVariant> variantList; - variantList << 42; - QVERIFY(QVariant::fromValue(variantList).value<QList<QVariant> >().first() == 42); - QVector<QList<QVariant> > vectorList; - vectorList << variantList; - QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QVariant> > >().first().first() == 42); - } + TEST_SEQUENTIAL_CONTAINER(QList, QVariant) + TEST_SEQUENTIAL_CONTAINER(std::vector, QVariant) + TEST_SEQUENTIAL_CONTAINER(std::list, QVariant) { QList<QSharedPointer<QObject> > sharedPointerList; @@ -1395,6 +1402,31 @@ void tst_QMetaType::automaticTemplateRegistration() QCOMPARE(QVariant::fromValue(variantMap).value<QVariantMap>().value(QStringLiteral("4")), QVariant(2)); } { + typedef std::map<int, int> IntIntMap; + IntIntMap intIntMap; + intIntMap[4] = 2; + QCOMPARE(QVariant::fromValue(intIntMap).value<IntIntMap>()[4], 2); + } + { + typedef std::map<int, uint> StdIntUIntMap; + StdIntUIntMap intUIntMap; + intUIntMap[4] = 2; + QCOMPARE(QVariant::fromValue(intUIntMap).value<StdIntUIntMap>()[4], (uint)2); + } + { + typedef std::map<int, CustomObject*> StdMapIntCustomObject ; + StdMapIntCustomObject intComparableMap; + CustomObject *o = 0; + intComparableMap[4] = o; + QCOMPARE(QVariant::fromValue(intComparableMap).value<StdMapIntCustomObject >()[4], o); + } + { + typedef std::map<QString, QVariant> StdMapStringVariant; + StdMapStringVariant variantMap; + variantMap[QStringLiteral("4")] = 2; + QCOMPARE(QVariant::fromValue(variantMap).value<StdMapStringVariant>()[QStringLiteral("4")], QVariant(2)); + } + { typedef QPair<int, int> IntIntPair; IntIntPair intIntPair = qMakePair(4, 2); QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().first, 4); @@ -1412,6 +1444,25 @@ void tst_QMetaType::automaticTemplateRegistration() QCOMPARE(QVariant::fromValue(intComparablePair).value<IntComparablePair>().second, m); } { + typedef std::pair<int, int> IntIntPair; + IntIntPair intIntPair = std::make_pair(4, 2); + QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().first, 4); + QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().second, 2); + } + { + typedef std::pair<int, uint> StdIntUIntPair; + StdIntUIntPair intUIntPair = std::make_pair<int, uint>(4, 2); + QCOMPARE(QVariant::fromValue(intUIntPair).value<StdIntUIntPair>().first, 4); + QCOMPARE(QVariant::fromValue(intUIntPair).value<StdIntUIntPair>().second, (uint)2); + } + { + typedef std::pair<int, CustomQObject*> StdIntComparablePair; + CustomQObject* o = 0; + StdIntComparablePair intComparablePair = std::make_pair(4, o); + QCOMPARE(QVariant::fromValue(intComparablePair).value<StdIntComparablePair>().first, 4); + QCOMPARE(QVariant::fromValue(intComparablePair).value<StdIntComparablePair>().second, o); + } + { typedef QHash<int, UnregisteredType> IntUnregisteredTypeHash; QVERIFY(qRegisterMetaType<IntUnregisteredTypeHash>("IntUnregisteredTypeHash") > 0); } @@ -1446,17 +1497,14 @@ void tst_QMetaType::automaticTemplateRegistration() F(uint, __VA_ARGS__) \ F(qlonglong, __VA_ARGS__) \ F(qulonglong, __VA_ARGS__) \ - F(double, __VA_ARGS__) \ F(long, __VA_ARGS__) \ F(short, __VA_ARGS__) \ F(char, __VA_ARGS__) \ F(ulong, __VA_ARGS__) \ F(ushort, __VA_ARGS__) \ F(uchar, __VA_ARGS__) \ - F(float, __VA_ARGS__) \ F(QObject*, __VA_ARGS__) \ - F(QString, __VA_ARGS__) \ - F(CustomMovable, __VA_ARGS__) + F(QString, __VA_ARGS__) #define CREATE_AND_VERIFY_CONTAINER(CONTAINER, ...) \ @@ -1774,6 +1822,366 @@ void tst_QMetaType::constRefs() #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; + static QVariant s_value; + static bool s_ok; +}; + +bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) +{ return lhs.m_foo < rhs.m_foo; } +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"; } +}; + +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); } + +Q_DECLARE_METATYPE(CustomConvertibleType); +Q_DECLARE_METATYPE(CustomConvertibleType2); +Q_DECLARE_METATYPE(CustomDebugStreamableType); + +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()).canConvert(qMetaTypeId<To>()))); +} + +template<typename From, typename To> +void testCustomTypeConvertible() +{ + QVERIFY((hasRegisteredConverterFunction<From, To>())); + QVERIFY((QVariant::fromValue<From>(From()).canConvert(qMetaTypeId<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::compareCustomType_data() +{ + QMetaType::registerComparators<CustomConvertibleType>(); + + QTest::addColumn<QVariantList>("unsorted"); + QTest::addColumn<QVariantList>("sorted"); + + QTest::newRow("int") << (QVariantList() << 37 << 458 << 1 << 243 << -4 << 383) + << (QVariantList() << -4 << 1 << 37 << 243 << 383 << 458); + + QTest::newRow("dobule") << (QVariantList() << 4934.93 << 0.0 << 302.39 << -39.0) + << (QVariantList() << -39.0 << 0.0 << 302.39 << 4934.93); + + QTest::newRow("QString") << (QVariantList() << "Hello" << "World" << "this" << "is" << "a" << "test") + << (QVariantList() << "a" << "Hello" << "is" << "test" << "this" << "World"); + + QTest::newRow("QTime") << (QVariantList() << QTime(14, 39) << QTime(0, 0) << QTime(18, 18) << QTime(9, 27)) + << (QVariantList() << QTime(0, 0) << QTime(9, 27) << QTime(14, 39) << QTime(18, 18)); + + QTest::newRow("QDate") << (QVariantList() << QDate(2013, 3, 23) << QDate(1900, 12, 1) << QDate(2001, 2, 2) << QDate(1982, 12, 16)) + << (QVariantList() << QDate(1900, 12, 1) << QDate(1982, 12, 16) << QDate(2001, 2, 2) << QDate(2013, 3, 23)); + + QTest::newRow("mixed") << (QVariantList() << "Hello" << "World" << QChar('a') << 38 << QChar('z') << -39 << 4.6) + << (QVariantList() << -39 << 4.6 << 38 << QChar('a') << "Hello" << "World" << QChar('z')); + + QTest::newRow("custom") << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(100)) << QVariant::fromValue(CustomConvertibleType(50))) + << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(50)) << QVariant::fromValue(CustomConvertibleType(100))); +} + +void tst_QMetaType::compareCustomType() +{ + QFETCH(QVariantList, unsorted); + QFETCH(QVariantList, sorted); + qSort(unsorted); + QCOMPARE(unsorted, sorted); +} + +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, )"; + qDebug() << v1; + + QMetaType::registerConverter<CustomDebugStreamableType, QString>(&CustomDebugStreamableType::toString); + handler.expectedMessage = "QVariant(CustomDebugStreamableType, \"test\")"; + qDebug() << v1; + + QMetaType::registerDebugStreamOperator<CustomDebugStreamableType>(); + handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)"; + qDebug() << v1; +} + // Compile-time test, it should be possible to register function pointer types class Undefined; @@ -1781,11 +2189,15 @@ 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); +#ifdef Q_COMPILER_VARIADIC_TEMPLATES +Q_DECLARE_METATYPE(UndefinedFunction4); +#endif QTEST_MAIN(tst_QMetaType) #include "tst_qmetatype.moc" diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 1cdf39018b..8d1ea3b510 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -146,6 +146,7 @@ private slots: void connectFunctorOverloads(); void disconnectDoesNotLeakFunctor(); void connectBase(); + void qmlConnect(); }; struct QObjectCreatedOnShutdown @@ -5879,6 +5880,56 @@ void tst_QObject::connectBase() QCOMPARE( r1.count_slot3, 1 ); } +struct QmlReceiver : public QtPrivate::QSlotObjectBase +{ + int callCount; + void *magic; + + QmlReceiver() + : QtPrivate::QSlotObjectBase(&impl) + , callCount(0) + , magic(0) + {} + + static void impl(int which, QSlotObjectBase *this_, QObject *, void **metaArgs, bool *ret) + { + switch (which) { + case Destroy: delete static_cast<QmlReceiver*>(this_); return; + case Call: static_cast<QmlReceiver*>(this_)->callCount++; return; + case Compare: *ret = static_cast<QmlReceiver*>(this_)->magic == metaArgs[0]; return; + case NumOperations: break; + } + } +}; + +void tst_QObject::qmlConnect() +{ +#ifdef QT_BUILD_INTERNAL + SenderObject sender; + QmlReceiver *receiver = new QmlReceiver; + receiver->magic = receiver; + receiver->ref(); + + QVERIFY(QObjectPrivate::connect(&sender, sender.metaObject()->indexOfSignal("signal1()"), + receiver, Qt::AutoConnection)); + + QCOMPARE(receiver->callCount, 0); + sender.emitSignal1(); + QCOMPARE(receiver->callCount, 1); + + void *a[] = { + receiver + }; + QVERIFY(QObjectPrivate::disconnect(&sender, sender.metaObject()->indexOfSignal("signal1()"), reinterpret_cast<void**>(&a))); + + sender.emitSignal1(); + QCOMPARE(receiver->callCount, 1); + + receiver->destroyIfLastRef(); +#else + QSKIP("Needs QT_BUILD_INTERNAL"); +#endif +} QTEST_MAIN(tst_QObject) #include "tst_qobject.moc" diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 4d862f4fc5..dab40db0ec 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -242,6 +242,9 @@ private slots: void saveNewBuiltinWithOldStream(); void implicitConstruction(); + + void iterateContainerElements(); + void pairElements(); private: void dataStream_data(QDataStream::Version version); void loadQVariantFromDataStream(QDataStream::Version version); @@ -990,8 +993,8 @@ void tst_QVariant::toString_data() QTest::newRow( "float" ) << QVariant( 123.456f ) << QString( "123.456" ); QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" ); - QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" ); - QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56" ); + QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56.000" ); + QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56.000" ); QTest::newRow( "llong" ) << QVariant( (qlonglong)Q_INT64_C(123456789012) ) << QString( "123456789012" ); QTest::newRow("QJsonValue") << QVariant(QJsonValue(QString("hello"))) << QString("hello"); @@ -3392,5 +3395,312 @@ void tst_QVariant::saveNewBuiltinWithOldStream() QCOMPARE(int(data.constData()[3]), 0); } +template<typename Container, typename Value_Type = typename Container::value_type> +struct ContainerAPI +{ + static void insert(Container &container, typename Container::value_type value) + { + container.push_back(value); + } + + static bool compare(const QVariant &variant, typename Container::value_type value) + { + return variant.value<typename Container::value_type>() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +template<typename Container> +struct ContainerAPI<Container, QVariant> +{ + static void insert(Container &container, int value) + { + container.push_back(QVariant::fromValue(value)); + } + + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +template<typename Container> +struct ContainerAPI<Container, QString> +{ + static void insert(Container &container, int value) + { + container.push_back(QString::number(value)); + } + + static bool compare(const QVariant &variant, QString value) + { + return variant.value<QString>() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +// We have no built-in defines to check the stdlib features. +// #define TEST_FORWARD_LIST + +#ifdef TEST_FORWARD_LIST +#include <forward_list> +Q_DECLARE_METATYPE(std::forward_list<int>) +Q_DECLARE_METATYPE(std::forward_list<QVariant>) +Q_DECLARE_METATYPE(std::forward_list<QString>) + +template<typename Value_Type> +struct ContainerAPI<std::forward_list<Value_Type> > +{ + static void insert(std::forward_list<Value_Type> &container, Value_Type value) + { + container.push_front(value); + } + static bool compare(const QVariant &variant, Value_Type value) + { + return variant.value<Value_Type>() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +template<> +struct ContainerAPI<std::forward_list<QVariant> > +{ + static void insert(std::forward_list<QVariant> &container, int value) + { + container.push_front(QVariant::fromValue(value)); + } + + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +template<> +struct ContainerAPI<std::forward_list<QString> > +{ + static void insert(std::forward_list<QString> &container, int value) + { + container.push_front(QString::number(value)); + } + static bool compare(const QVariant &variant, QString value) + { + return variant.value<QString>() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; +#endif + +template<typename Container> +struct KeyGetter +{ + static const typename Container::key_type & get(const typename Container::const_iterator &it) + { + return it.key(); + } + static const typename Container::mapped_type & value(const typename Container::const_iterator &it) + { + return it.value(); + } +}; + +template<typename T, typename U> +struct KeyGetter<std::map<T, U> > +{ + static const T & get(const typename std::map<T, U>::const_iterator &it) + { + return it->first; + } + static const U & value(const typename std::map<T, U>::const_iterator &it) + { + return it->second; + } +}; + + +// We have no built-in defines to check the stdlib features. +// #define TEST_UNORDERED_MAP + +#ifdef TEST_UNORDERED_MAP +#include <unordered_map> +typedef std::unordered_map<int, bool> StdUnorderedMap_int_bool; +Q_DECLARE_METATYPE(StdUnorderedMap_int_bool) + +template<typename T, typename U> +struct KeyGetter<std::unordered_map<T, U> > +{ + static const T & get(const typename std::unordered_map<T, U>::const_iterator &it) + { + return it->first; + } + static const U & value(const typename std::unordered_map<T, U>::const_iterator &it) + { + return it->second; + } +}; +#endif + +void tst_QVariant::iterateContainerElements() +{ +#ifdef Q_COMPILER_RANGE_FOR + +#define TEST_RANGE_FOR(CONTAINER, VALUE_TYPE) \ + numSeen = 0; \ + containerIter = intList.begin(); \ + for (QVariant v : listIter) { \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, *containerIter)); \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, varList.at(numSeen))); \ + ++containerIter; \ + ++numSeen; \ + } \ + QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); + +#else + +#define TEST_RANGE_FOR(CONTAINER, VALUE_TYPE) + +#endif + +#define TEST_SEQUENTIAL_ITERATION(CONTAINER, VALUE_TYPE) \ + { \ + int numSeen = 0; \ + CONTAINER<VALUE_TYPE > intList; \ + ContainerAPI<CONTAINER<VALUE_TYPE > >::insert(intList, 1); \ + ContainerAPI<CONTAINER<VALUE_TYPE > >::insert(intList, 2); \ + ContainerAPI<CONTAINER<VALUE_TYPE > >::insert(intList, 3); \ + \ + QVariant listVariant = QVariant::fromValue(intList); \ + QVERIFY(listVariant.canConvert<QVariantList>()); \ + QVariantList varList = listVariant.value<QVariantList>(); \ + QCOMPARE(varList.size(), (int)std::distance(intList.begin(), intList.end())); \ + QSequentialIterable listIter = listVariant.value<QSequentialIterable>(); \ + QCOMPARE(varList.size(), listIter.size()); \ + \ + CONTAINER<VALUE_TYPE >::iterator containerIter = intList.begin(); \ + const CONTAINER<VALUE_TYPE >::iterator containerEnd = intList.end(); \ + for (int i = 0; i < listIter.size(); ++i, ++containerIter, ++numSeen) \ + { \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(listIter.at(i), *containerIter)); \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(listIter.at(i), varList.at(i))); \ + } \ + QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \ + QCOMPARE(containerIter, containerEnd); \ + \ + containerIter = intList.begin(); \ + numSeen = 0; \ + Q_FOREACH (const QVariant &v, listIter) { \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, *containerIter)); \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, varList.at(numSeen))); \ + ++containerIter; \ + ++numSeen; \ + } \ + QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \ + TEST_RANGE_FOR(CONTAINER, VALUE_TYPE) \ + } + + TEST_SEQUENTIAL_ITERATION(QVector, int) + TEST_SEQUENTIAL_ITERATION(QVector, QVariant) + TEST_SEQUENTIAL_ITERATION(QVector, QString) + TEST_SEQUENTIAL_ITERATION(QQueue, int) + TEST_SEQUENTIAL_ITERATION(QQueue, QVariant) + TEST_SEQUENTIAL_ITERATION(QQueue, QString) + TEST_SEQUENTIAL_ITERATION(QList, int) + TEST_SEQUENTIAL_ITERATION(QList, QVariant) + TEST_SEQUENTIAL_ITERATION(QList, QString) + TEST_SEQUENTIAL_ITERATION(QStack, int) + TEST_SEQUENTIAL_ITERATION(QStack, QVariant) + TEST_SEQUENTIAL_ITERATION(QStack, QString) + TEST_SEQUENTIAL_ITERATION(std::vector, int) + TEST_SEQUENTIAL_ITERATION(std::vector, QVariant) + TEST_SEQUENTIAL_ITERATION(std::vector, QString) + TEST_SEQUENTIAL_ITERATION(std::list, int) + TEST_SEQUENTIAL_ITERATION(std::list, QVariant) + TEST_SEQUENTIAL_ITERATION(std::list, QString) + +#ifdef TEST_FORWARD_LIST + qRegisterSequentialConverter<std::forward_list<int> >(); + qRegisterSequentialConverter<std::forward_list<QVariant> >(); + qRegisterSequentialConverter<std::forward_list<QString> >(); + TEST_SEQUENTIAL_ITERATION(std::forward_list, int) + TEST_SEQUENTIAL_ITERATION(std::forward_list, QVariant) + TEST_SEQUENTIAL_ITERATION(std::forward_list, QString) +#endif + +#define TEST_ASSOCIATIVE_ITERATION(CONTAINER, KEY_TYPE, MAPPED_TYPE) \ + { \ + int numSeen = 0; \ + CONTAINER<KEY_TYPE, MAPPED_TYPE> mapping; \ + mapping[5] = true; \ + mapping[15] = false; \ + \ + QVariant mappingVariant = QVariant::fromValue(mapping); \ + QVariantMap varMap = mappingVariant.value<QVariantMap>(); \ + QVariantMap varHash = mappingVariant.value<QVariantMap>(); \ + QAssociativeIterable mappingIter = mappingVariant.value<QAssociativeIterable>(); \ + \ + CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerIter = mapping.begin(); \ + const CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerEnd = mapping.end(); \ + for ( ; containerIter != containerEnd; ++containerIter, ++numSeen) \ + { \ + MAPPED_TYPE expected = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::value(containerIter); \ + KEY_TYPE key = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::get(containerIter); \ + MAPPED_TYPE actual = mappingIter.value(key).value<MAPPED_TYPE >(); \ + QCOMPARE(varMap.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \ + QCOMPARE(varHash.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \ + QCOMPARE(actual, expected); \ + } \ + QCOMPARE(numSeen, (int)std::distance(mapping.begin(), mapping.end())); \ + QCOMPARE(containerIter, containerEnd); \ + \ + } + + TEST_ASSOCIATIVE_ITERATION(QHash, int, bool) + TEST_ASSOCIATIVE_ITERATION(QMap, int, bool) + TEST_ASSOCIATIVE_ITERATION(std::map, int, bool) +#ifdef TEST_UNORDERED_MAP + qRegisterAssociativeConverter<StdUnorderedMap_int_bool>(); + TEST_ASSOCIATIVE_ITERATION(std::unordered_map, int, bool) +#endif +} + +void tst_QVariant::pairElements() +{ + typedef QPair<QVariant, QVariant> QVariantPair; + +#define TEST_PAIR_ELEMENT_ACCESS(PAIR, T1, T2, VALUE1, VALUE2) \ + { \ + PAIR<T1, T2> p(VALUE1, VALUE2); \ + QVariant v = QVariant::fromValue(p); \ + \ + QVERIFY(v.canConvert<QVariantPair>()); \ + QVariantPair pi = v.value<QVariantPair>(); \ + QCOMPARE(pi.first, QVariant::fromValue(VALUE1)); \ + QCOMPARE(pi.second, QVariant::fromValue(VALUE2)); \ + } + + TEST_PAIR_ELEMENT_ACCESS(QPair, int, int, 4, 5) + TEST_PAIR_ELEMENT_ACCESS(std::pair, int, int, 4, 5) + TEST_PAIR_ELEMENT_ACCESS(QPair, QString, QString, QStringLiteral("one"), QStringLiteral("two")) + TEST_PAIR_ELEMENT_ACCESS(std::pair, QString, QString, QStringLiteral("one"), QStringLiteral("two")) + TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, QVariant, 4, 5) + TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, QVariant, 4, 5) + TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, int, 41, 15) + TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, int, 34, 65) + TEST_PAIR_ELEMENT_ACCESS(QPair, int, QVariant, 24, 25) + TEST_PAIR_ELEMENT_ACCESS(std::pair, int, QVariant, 44, 15) +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" |