From 25fc90e48b279d61dfcedb3ecfe7818e29eca341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 19 Dec 2018 16:46:47 +0100 Subject: Allow more fine grained control over QMetaEnum debug output Useful in contexts such as other QDebug operators, where the class is already known, and the full scope of the enum is not needed. Change-Id: Ibd04b1fd4f0f914c7224a007fc248d4ebabcde3e Reviewed-by: Thiago Macieira --- .../corelib/kernel/qmetaobject/tst_qmetaobject.cpp | 49 +++++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'tests/auto/corelib/kernel/qmetaobject') diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 9855bec520..68e9040ce2 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -324,6 +324,7 @@ private slots: void signal(); void signalIndex_data(); void signalIndex(); + void enumDebugStream_data(); void enumDebugStream(); void inherits_data(); @@ -1741,16 +1742,52 @@ void tst_QMetaObject::signalIndex() SignalTestHelper::signalIndex(mm)); } +void tst_QMetaObject::enumDebugStream_data() +{ + QTest::addColumn("verbosity"); + QTest::addColumn("normalEnumMsg"); + QTest::addColumn("scopedEnumMsg"); + QTest::addColumn("globalEnumMsg"); + + QTest::newRow("verbosity=0") << 0 + << "WindowTitleHint Window Desktop WindowSystemMenuHint"; + << "hello MyEnum2 world" + << "hello MyScopedEnum::Enum3 scoped world" + + QTest::newRow("verbosity=1") << 1 + << "WindowType::WindowTitleHint WindowType::Window WindowType::Desktop WindowType::WindowSystemMenuHint"; + << "hello MyEnum::MyEnum2 world" + << "hello MyScopedEnum::Enum3 scoped world" + + QTest::newRow("verbosity=2") << 2 + << "Qt::WindowTitleHint Qt::Window Qt::Desktop Qt::WindowSystemMenuHint"; + << "hello MyNamespace::MyClass::MyEnum2 world" + << "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world" + + QTest::newRow("verbosity=3") << 3 + << "Qt::WindowType::WindowTitleHint Qt::WindowType::Window Qt::WindowType::Desktop Qt::WindowType::WindowSystemMenuHint"; + << "hello MyNamespace::MyClass::MyEnum::MyEnum2 world" + << "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world" +} + void tst_QMetaObject::enumDebugStream() { - QTest::ignoreMessage(QtDebugMsg, "hello MyNamespace::MyClass::MyEnum2 world "); - qDebug() << "hello" << MyNamespace::MyClass::MyEnum2 << "world"; + QFETCH(int, verbosity); + QFETCH(QString, normalEnumMsg); + QFETCH(QString, scopedEnumMsg); + QFETCH(QString, globalEnumMsg); + + QTest::ignoreMessage(QtDebugMsg, qPrintable(normalEnumMsg)); + qDebug().verbosity(verbosity) << "hello" << MyNamespace::MyClass::MyEnum2 << "world"; + + QTest::ignoreMessage(QtDebugMsg, qPrintable(scopedEnumMsg)); + qDebug().verbosity(verbosity) << "hello" << MyNamespace::MyClass::MyScopedEnum::Enum3 << "scoped world"; - QTest::ignoreMessage(QtDebugMsg, "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world "); - qDebug() << "hello" << MyNamespace::MyClass::MyScopedEnum::Enum3 << "scoped world"; + QTest::ignoreMessage(QtDebugMsg, qPrintable(globalEnumMsg)); + qDebug().verbosity(verbosity) << Qt::WindowTitleHint << Qt::Window << Qt::Desktop << Qt::WindowSystemMenuHint; - QTest::ignoreMessage(QtDebugMsg, "Qt::WindowTitleHint Qt::Window Qt::Desktop Qt::WindowSystemMenuHint"); - qDebug() << Qt::WindowTitleHint << Qt::Window << Qt::Desktop << Qt::WindowSystemMenuHint; + if (verbosity != 2) + return; QTest::ignoreMessage(QtDebugMsg, "hello QFlags(MyFlag1) world"); MyNamespace::MyClass::MyFlags f1 = MyNamespace::MyClass::MyFlag1; -- cgit v1.2.3 From 237c3972fd8869698cea69ff57f751c982bec487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 19 Dec 2018 20:13:02 +0100 Subject: Allow more fine grained control over QFlags debug output Useful in contexts such as other QDebug operators, where the class is already known, and the full scope of the flags is not needed. Change-Id: I546381b1722c9c846e2412e56763563b8f625212 Reviewed-by: Thiago Macieira --- .../corelib/kernel/qmetaobject/tst_qmetaobject.cpp | 65 ++++++++++++++++------ 1 file changed, 48 insertions(+), 17 deletions(-) (limited to 'tests/auto/corelib/kernel/qmetaobject') diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 68e9040ce2..467d299526 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -1748,35 +1748,68 @@ void tst_QMetaObject::enumDebugStream_data() QTest::addColumn("normalEnumMsg"); QTest::addColumn("scopedEnumMsg"); QTest::addColumn("globalEnumMsg"); + QTest::addColumn("normalFlagMsg"); + QTest::addColumn("normalFlagsMsg"); + QTest::addColumn("scopedFlagMsg"); + QTest::addColumn("scopedFlagsMsg"); + QTest::addColumn("flagAsEnumMsg"); QTest::newRow("verbosity=0") << 0 - << "WindowTitleHint Window Desktop WindowSystemMenuHint"; << "hello MyEnum2 world" << "hello MyScopedEnum::Enum3 scoped world" + << "WindowTitleHint Window Desktop WindowSystemMenuHint" + << "hello MyFlag1 world" + << "MyFlag1 MyFlag2|MyFlag3" + << "MyScopedFlag(MyFlag2)" + << "MyScopedFlag(MyFlag2|MyFlag3)" + << "MyFlag1"; QTest::newRow("verbosity=1") << 1 - << "WindowType::WindowTitleHint WindowType::Window WindowType::Desktop WindowType::WindowSystemMenuHint"; << "hello MyEnum::MyEnum2 world" << "hello MyScopedEnum::Enum3 scoped world" + << "WindowType::WindowTitleHint WindowType::Window WindowType::Desktop WindowType::WindowSystemMenuHint" + << "hello MyFlag(MyFlag1) world" + << "MyFlag(MyFlag1) MyFlag(MyFlag2|MyFlag3)" + << "MyScopedFlag(MyFlag2)" + << "MyScopedFlag(MyFlag2|MyFlag3)" + << "MyFlag::MyFlag1"; QTest::newRow("verbosity=2") << 2 - << "Qt::WindowTitleHint Qt::Window Qt::Desktop Qt::WindowSystemMenuHint"; << "hello MyNamespace::MyClass::MyEnum2 world" << "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world" + << "Qt::WindowTitleHint Qt::Window Qt::Desktop Qt::WindowSystemMenuHint" + << "hello QFlags(MyFlag1) world" + << "QFlags(MyFlag1) QFlags(MyFlag2|MyFlag3)" + << "QFlags(MyFlag2)" + << "QFlags(MyFlag2|MyFlag3)" + << "MyNamespace::MyClass::MyFlag1"; QTest::newRow("verbosity=3") << 3 - << "Qt::WindowType::WindowTitleHint Qt::WindowType::Window Qt::WindowType::Desktop Qt::WindowType::WindowSystemMenuHint"; << "hello MyNamespace::MyClass::MyEnum::MyEnum2 world" << "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world" + << "Qt::WindowType::WindowTitleHint Qt::WindowType::Window Qt::WindowType::Desktop Qt::WindowType::WindowSystemMenuHint" + << "hello QFlags(MyFlag1) world" + << "QFlags(MyFlag1) QFlags(MyFlag2|MyFlag3)" + << "QFlags(MyFlag2)" + << "QFlags(MyFlag2|MyFlag3)" + << "MyNamespace::MyClass::MyFlag::MyFlag1"; } void tst_QMetaObject::enumDebugStream() { QFETCH(int, verbosity); + QFETCH(QString, normalEnumMsg); QFETCH(QString, scopedEnumMsg); QFETCH(QString, globalEnumMsg); + QFETCH(QString, normalFlagMsg); + QFETCH(QString, normalFlagsMsg); + QFETCH(QString, scopedFlagMsg); + QFETCH(QString, scopedFlagsMsg); + QFETCH(QString, flagAsEnumMsg); + + // Enums QTest::ignoreMessage(QtDebugMsg, qPrintable(normalEnumMsg)); qDebug().verbosity(verbosity) << "hello" << MyNamespace::MyClass::MyEnum2 << "world"; @@ -1786,29 +1819,27 @@ void tst_QMetaObject::enumDebugStream() QTest::ignoreMessage(QtDebugMsg, qPrintable(globalEnumMsg)); qDebug().verbosity(verbosity) << Qt::WindowTitleHint << Qt::Window << Qt::Desktop << Qt::WindowSystemMenuHint; - if (verbosity != 2) - return; - - QTest::ignoreMessage(QtDebugMsg, "hello QFlags(MyFlag1) world"); + // Flags + QTest::ignoreMessage(QtDebugMsg, qPrintable(normalFlagMsg)); MyNamespace::MyClass::MyFlags f1 = MyNamespace::MyClass::MyFlag1; - qDebug() << "hello" << f1 << "world"; + qDebug().verbosity(verbosity) << "hello" << f1 << "world"; MyNamespace::MyClass::MyFlags f2 = MyNamespace::MyClass::MyFlag2 | MyNamespace::MyClass::MyFlag3; - QTest::ignoreMessage(QtDebugMsg, "QFlags(MyFlag1) QFlags(MyFlag2|MyFlag3)"); - qDebug() << f1 << f2; + QTest::ignoreMessage(QtDebugMsg, qPrintable(normalFlagsMsg)); + qDebug().verbosity(verbosity) << f1 << f2; - QTest::ignoreMessage(QtDebugMsg, "QFlags(MyFlag2)"); + QTest::ignoreMessage(QtDebugMsg, qPrintable(scopedFlagMsg)); MyNamespace::MyClass::MyScopedFlags f3 = MyNamespace::MyClass::MyScopedFlag::MyFlag2; - qDebug() << f3; + qDebug().verbosity(verbosity) << f3; - QTest::ignoreMessage(QtDebugMsg, "QFlags(MyFlag2|MyFlag3)"); + QTest::ignoreMessage(QtDebugMsg, qPrintable(scopedFlagsMsg)); f3 |= MyNamespace::MyClass::MyScopedFlag::MyFlag3; - qDebug() << f3; + qDebug().verbosity(verbosity) << f3; // Single flag recognized as enum: - QTest::ignoreMessage(QtDebugMsg, "MyNamespace::MyClass::MyFlag1"); + QTest::ignoreMessage(QtDebugMsg, qPrintable(flagAsEnumMsg)); MyNamespace::MyClass::MyFlag f4 = MyNamespace::MyClass::MyFlag1; - qDebug() << f4; + qDebug().verbosity(verbosity) << f4; } void tst_QMetaObject::inherits_data() -- cgit v1.2.3 From 5f2afe18ccb0bbe258d4016ef65218cd3656cac2 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Tue, 9 Apr 2019 13:38:06 +0200 Subject: Fix QMetaObject::newInstance on non-QObject meta object QMetaObject::newInstance returns a QObject, thus it's not possible to create a new instance of a Q_GADGET using this function. Previously, we returned a non-null QObject pointer for such scenarios, which then leads to crashes when one tries to use it. Now, we check whether the meta object inherits QObject's meta object, and error out early otherwise. Change-Id: I7b1fb6c8d48b3e98161894be2f281a491963345e Reviewed-by: Thiago Macieira --- tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tests/auto/corelib/kernel/qmetaobject') diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 9855bec520..cfe1443fd3 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -40,6 +40,13 @@ struct MyStruct int i; }; +class MyGadget +{ + Q_GADGET +public: + Q_INVOKABLE MyGadget() {} +}; + namespace MyNamespace { // Used in tst_QMetaObject::checkScope class MyClass : public QObject @@ -1207,6 +1214,12 @@ void tst_QMetaObject::invokeMetaConstructor() QCOMPARE(obj2->parent(), (QObject*)&obj); QVERIFY(qobject_cast(obj2) != 0); } + // gadget shouldn't return a valid pointer + { + QCOMPARE(MyGadget::staticMetaObject.constructorCount(), 1); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::newInstance: type MyGadget does not inherit QObject"); + QVERIFY(!MyGadget::staticMetaObject.newInstance()); + } } void tst_QMetaObject::invokeTypedefTypes() -- cgit v1.2.3