From 37b0a8e7e645b97df57aae44059b2aa35bc909c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Fri, 16 Mar 2012 16:32:38 +0100 Subject: Fix qDebug stream for an invalid QVariant. This patch changes invalid QVariant qDebug stream value from "QVariant(, QVariant::Invalid)" to "QVariant(Invalid)" New tests were added. Change-Id: Ia57d4fc2d775cc9fce28e03eba402c2173845b35 Reviewed-by: Kent Hansen --- src/corelib/kernel/qvariant.cpp | 15 ++++-- .../auto/corelib/kernel/qvariant/tst_qvariant.cpp | 57 ++++++++++++++++++++-- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 43d867f61c..cbef47566c 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2686,15 +2686,24 @@ bool QVariant::isNull() const #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QVariant &v) { - dbg.nospace() << "QVariant(" << QMetaType::typeName(v.userType()) << ", "; - handlerManager[v.d.type]->debugStream(dbg, v); + const uint typeId = v.d.type; + dbg.nospace() << "QVariant("; + if (typeId != QMetaType::UnknownType) { + dbg.nospace() << QMetaType::typeName(typeId) << ", "; + handlerManager[typeId]->debugStream(dbg, v); + } else { + dbg.nospace() << "Invalid"; + } dbg.nospace() << ')'; return dbg.space(); } QDebug operator<<(QDebug dbg, const QVariant::Type p) { - dbg.nospace() << "QVariant::" << QMetaType::typeName(p); + dbg.nospace() << "QVariant::" + << (int(p) != int(QMetaType::UnknownType) + ? QMetaType::typeName(p) + : "Invalid"); return dbg.space(); } #endif diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 3d4692db39..89c8f77e4a 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -275,6 +275,8 @@ private slots: void forwardDeclare(); void debugStream_data(); void debugStream(); + void debugStreamType_data(); + void debugStreamType(); void loadQt4Stream_data(); void loadQt4Stream(); @@ -3630,8 +3632,8 @@ void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version) class MessageHandler { public: - MessageHandler(const int typeId) - : oldMsgHandler(qInstallMsgHandler(handler)) + MessageHandler(const int typeId, QtMsgHandler msgHandler = handler) + : oldMsgHandler(qInstallMsgHandler(msgHandler)) { currentId = typeId; } @@ -3645,13 +3647,24 @@ public: { return ok; } -private: +protected: static void handler(QtMsgType, const char *txt) { QString msg = QString::fromLatin1(txt); // Format itself is not important, but basic data as a type name should be included in the output - ok = msg.startsWith("QVariant(") + QMetaType::typeName(currentId); - QVERIFY2(ok, (QString::fromLatin1("Message is not valid: '") + msg + '\'').toLatin1().constData()); + ok = msg.startsWith("QVariant("); + QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '") + msg + '\'').toLatin1().constData()); + ok &= (currentId == QMetaType::UnknownType + ? msg.contains("Invalid") + : msg.contains(QMetaType::typeName(currentId))); + QVERIFY2(ok, (QString::fromLatin1("Message doesn't contain type name: '") + msg + '\'').toLatin1().constData()); + if (currentId == QMetaType::Char || currentId == QMetaType::QChar) { + // Chars insert '\0' into the qdebug stream, it is not possible to find a real string length + return; + } + ok &= msg.endsWith(") "); + QVERIFY2(ok, (QString::fromLatin1("Message is not correctly finished: '") + msg + '\'').toLatin1().constData()); + } QtMsgHandler oldMsgHandler; @@ -3676,6 +3689,7 @@ void tst_QVariant::debugStream_data() QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId(); QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId(), 0) << qMetaTypeId(); QTest::newRow("MyClass") << QVariant(qMetaTypeId(), 0) << qMetaTypeId(); + QTest::newRow("InvalidVariant") << QVariant() << int(QMetaType::UnknownType); } void tst_QVariant::debugStream() @@ -3688,5 +3702,38 @@ void tst_QVariant::debugStream() QVERIFY(msgHandler.testPassed()); } +struct MessageHandlerType : public MessageHandler +{ + MessageHandlerType(const int typeId) + : MessageHandler(typeId, handler) + {} + static void handler(QtMsgType, const char *txt) + { + QString msg = QString::fromLatin1(txt); + // Format itself is not important, but basic data as a type name should be included in the output + ok = msg.startsWith("QVariant::"); + QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '") + msg + '\'').toLatin1().constData()); + ok &= (currentId == QMetaType::UnknownType + ? msg.contains("Invalid") + : msg.contains(QMetaType::typeName(currentId))); + QVERIFY2(ok, (QString::fromLatin1("Message doesn't contain type name: '") + msg + '\'').toLatin1().constData()); + } +}; + +void tst_QVariant::debugStreamType_data() +{ + debugStream_data(); +} + +void tst_QVariant::debugStreamType() +{ + QFETCH(QVariant, variant); + QFETCH(int, typeId); + + MessageHandlerType msgHandler(typeId); + qDebug() << QVariant::Type(typeId); + QVERIFY(msgHandler.testPassed()); +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" -- cgit v1.2.3