Fix qDebug stream for an invalid QVariant.
authorJędrzej Nowacki <jedrzej.nowacki@nokia.com>
Fri, 16 Mar 2012 15:32:38 +0000 (16:32 +0100)
committerQt by Nokia <qt-info@nokia.com>
Wed, 21 Mar 2012 05:55:33 +0000 (06:55 +0100)
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 <kent.hansen@nokia.com>
src/corelib/kernel/qvariant.cpp
tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp

index 43d867f..cbef475 100644 (file)
@@ -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
index 3d4692d..89c8f77 100644 (file)
@@ -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<QBitArray>();
     QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>();
     QTest::newRow("MyClass") << QVariant(qMetaTypeId<MyClass>(), 0) << qMetaTypeId<MyClass>();
+    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"