diff --git a/tests/auto/corelib/global/qlogging/CMakeLists.txt b/tests/auto/corelib/global/qlogging/CMakeLists.txt index 06f24a675f..47ee7adca0 100644 --- a/tests/auto/corelib/global/qlogging/CMakeLists.txt +++ b/tests/auto/corelib/global/qlogging/CMakeLists.txt @@ -24,3 +24,9 @@ qt_internal_add_test(tst_qlogging SOURCES tst_qlogging.cpp ) target_compile_definitions(tst_qlogging PRIVATE QT_CMAKE_BUILD) # special case # to fix the binary name + +qt_internal_add_test(tst_qmessagelogger SOURCES tst_qmessagelogger.cpp + DEFINES + QT_MESSAGELOGCONTEXT + QT_DISABLE_DEPRECATED_BEFORE=0 +) diff --git a/tests/auto/corelib/global/qlogging/qlogging.pro b/tests/auto/corelib/global/qlogging/qlogging.pro index c81e257a2d..86396cf51c 100644 --- a/tests/auto/corelib/global/qlogging/qlogging.pro +++ b/tests/auto/corelib/global/qlogging/qlogging.pro @@ -4,3 +4,5 @@ test.depends = app SUBDIRS += app SUBDIRS += test + +SUBDIRS += test_qmessagelogger diff --git a/tests/auto/corelib/global/qlogging/test_qmessagelogger/test_qmessagelogger.pro b/tests/auto/corelib/global/qlogging/test_qmessagelogger/test_qmessagelogger.pro new file mode 100644 index 0000000000..6f2cea20ad --- /dev/null +++ b/tests/auto/corelib/global/qlogging/test_qmessagelogger/test_qmessagelogger.pro @@ -0,0 +1,17 @@ +CONFIG += testcase +qtConfig(c++17): CONFIG += c++17 +debug_and_release { + CONFIG(debug, debug|release) { + TARGET = ../../debug/tst_qmessagelogger + } else { + TARGET = ../../release/tst_qmessagelogger + } +} else { + TARGET = ../tst_qmessagelogger +} + +QT = core testlib +SOURCES = ../tst_qmessagelogger.cpp + +DEFINES += QT_MESSAGELOGCONTEXT +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/global/qlogging/tst_qmessagelogger.cpp b/tests/auto/corelib/global/qlogging/tst_qmessagelogger.cpp new file mode 100644 index 0000000000..4ff0469a49 --- /dev/null +++ b/tests/auto/corelib/global/qlogging/tst_qmessagelogger.cpp @@ -0,0 +1,359 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +Q_LOGGING_CATEGORY(debugTestCategory, "debug", QtDebugMsg) +Q_LOGGING_CATEGORY(infoTestCategory, "info", QtInfoMsg) +Q_LOGGING_CATEGORY(warningTestCategory, "warning", QtWarningMsg) +Q_LOGGING_CATEGORY(criticalTestCategory, "critical", QtCriticalMsg) + +struct LoggerMessageInfo +{ + QtMsgType messageType { QtFatalMsg }; + QString message; + const char *file { nullptr }; + int line { 0 }; + const char *function { nullptr }; + const char *category { nullptr }; +}; + +LoggerMessageInfo messageInfo; + +static void customMessageHandler(QtMsgType type, const QMessageLogContext &context, + const QString &message) +{ + messageInfo.messageType = type; + messageInfo.message = message; + messageInfo.file = context.file; + messageInfo.line = context.line; + messageInfo.function = context.function; + messageInfo.category = context.category; +} + +class tst_QMessageLogger : public QObject +{ + Q_OBJECT +private slots: + void initTestCase_data(); + + void init(); + void cleanup(); + + void logMessage(); + void logMessageWithLoggingCategory(); + void logMessageWithLoggingCategoryDisabled(); + void logMessageWithCategoryFunction(); + void logMessageWithNoDebug(); + +private: + void logWithLoggingCategoryHelper(bool messageTypeEnabled); +}; + +void tst_QMessageLogger::initTestCase_data() +{ + QTest::addColumn("messageType"); + QTest::addColumn("categoryName"); + QTest::addColumn("messageText"); + QTest::addColumn("useDebugStream"); + + // not testing QtFatalMsg, as it terminates the application + QTest::newRow("debug") << QtDebugMsg << QByteArray("categoryDebug") + << QByteArray("debug message") << false; + QTest::newRow("info") << QtInfoMsg << QByteArray("categoryInfo") << QByteArray("info message") + << false; + QTest::newRow("warning") << QtWarningMsg << QByteArray("categoryWarning") + << QByteArray("warning message") << false; + QTest::newRow("critical") << QtCriticalMsg << QByteArray("categoryCritical") + << QByteArray("critical message") << false; + +#ifndef QT_NO_DEBUG_STREAM + QTest::newRow("stream debug") << QtDebugMsg << QByteArray("categoryDebug") + << QByteArray("debug message") << true; + QTest::newRow("stream info") << QtInfoMsg << QByteArray("categoryInfo") + << QByteArray("info message") << true; + QTest::newRow("stream warning") << QtWarningMsg << QByteArray("categoryWarning") + << QByteArray("warning message") << true; + QTest::newRow("stream critical") << QtCriticalMsg << QByteArray("categoryCritical") + << QByteArray("critical message") << true; +#endif +} + +void tst_QMessageLogger::init() +{ + qInstallMessageHandler(customMessageHandler); +} + +void tst_QMessageLogger::cleanup() +{ + qInstallMessageHandler((QtMessageHandler)0); + messageInfo.messageType = QtFatalMsg; + messageInfo.message.clear(); + messageInfo.file = nullptr; + messageInfo.line = 0; + messageInfo.function = nullptr; + messageInfo.category = nullptr; +} + +void tst_QMessageLogger::logMessage() +{ + const int line = QT_MESSAGELOG_LINE; + QMessageLogger logger(QT_MESSAGELOG_FILE, line, QT_MESSAGELOG_FUNC); + + QFETCH_GLOBAL(QtMsgType, messageType); + QFETCH_GLOBAL(QByteArray, messageText); + QFETCH_GLOBAL(bool, useDebugStream); + if (useDebugStream) { +#ifndef QT_NO_DEBUG_STREAM + switch (messageType) { + case QtDebugMsg: + logger.debug().noquote() << messageText; + break; + case QtInfoMsg: + logger.info().noquote() << messageText; + break; + case QtWarningMsg: + logger.warning().noquote() << messageText; + break; + case QtCriticalMsg: + logger.critical().noquote() << messageText; + break; + default: + QFAIL("Invalid message type"); + break; + } +#else + QSKIP("Qt debug stream disabled"); +#endif + } else { + switch (messageType) { + case QtDebugMsg: + logger.debug("%s", messageText.constData()); + break; + case QtInfoMsg: + logger.info("%s", messageText.constData()); + break; + case QtWarningMsg: + logger.warning("%s", messageText.constData()); + break; + case QtCriticalMsg: + logger.critical("%s", messageText.constData()); + break; + default: + QFAIL("Invalid message type"); + break; + } + } + + QCOMPARE(messageInfo.messageType, messageType); + QCOMPARE(messageInfo.message, messageText); + QCOMPARE(messageInfo.file, __FILE__); + QCOMPARE(messageInfo.line, line); + QCOMPARE(messageInfo.function, Q_FUNC_INFO); +} + +void tst_QMessageLogger::logMessageWithLoggingCategory() +{ + logWithLoggingCategoryHelper(true); +} + +void tst_QMessageLogger::logMessageWithLoggingCategoryDisabled() +{ + logWithLoggingCategoryHelper(false); +} + +void tst_QMessageLogger::logMessageWithCategoryFunction() +{ + const int line = QT_MESSAGELOG_LINE; + QMessageLogger logger(QT_MESSAGELOG_FILE, line, QT_MESSAGELOG_FUNC); + + const QLoggingCategory *category = nullptr; + QFETCH_GLOBAL(QtMsgType, messageType); + QFETCH_GLOBAL(QByteArray, messageText); + QFETCH_GLOBAL(bool, useDebugStream); + if (useDebugStream) { +#ifndef QT_NO_DEBUG_STREAM + switch (messageType) { + case QtDebugMsg: + logger.debug(debugTestCategory()).noquote() << messageText; + category = &debugTestCategory(); + break; + case QtInfoMsg: + logger.info(infoTestCategory()).noquote() << messageText; + category = &infoTestCategory(); + break; + case QtWarningMsg: + logger.warning(warningTestCategory()).noquote() << messageText; + category = &warningTestCategory(); + break; + case QtCriticalMsg: + logger.critical(criticalTestCategory()).noquote() << messageText; + category = &criticalTestCategory(); + break; + default: + QFAIL("Invalid message type"); + break; + } +#else + QSKIP("Qt debug stream disabled"); +#endif + } else { + switch (messageType) { + case QtDebugMsg: + logger.debug(debugTestCategory(), "%s", messageText.constData()); + category = &debugTestCategory(); + break; + case QtInfoMsg: + logger.info(infoTestCategory(), "%s", messageText.constData()); + category = &infoTestCategory(); + break; + case QtWarningMsg: + logger.warning(warningTestCategory(), "%s", messageText.constData()); + category = &warningTestCategory(); + break; + case QtCriticalMsg: + logger.critical(criticalTestCategory(), "%s", messageText.constData()); + category = &criticalTestCategory(); + break; + default: + QFAIL("Invalid message type"); + break; + } + } + + QCOMPARE(messageInfo.messageType, messageType); + QCOMPARE(messageInfo.message, messageText); + QCOMPARE(messageInfo.file, __FILE__); + QCOMPARE(messageInfo.line, line); + QCOMPARE(messageInfo.function, Q_FUNC_INFO); + QCOMPARE(messageInfo.category, category->categoryName()); +} + +void tst_QMessageLogger::logMessageWithNoDebug() +{ + const int line = QT_MESSAGELOG_LINE; + QMessageLogger logger(QT_MESSAGELOG_FILE, line, QT_MESSAGELOG_FUNC); + + QFETCH_GLOBAL(QByteArray, messageText); + QFETCH_GLOBAL(bool, useDebugStream); + if (useDebugStream) { +#ifndef QT_NO_DEBUG_STREAM + logger.noDebug().noquote() << messageText; +#else + QSKIP("Qt debug stream disabled"); +#endif + } else { + logger.noDebug("%s", messageText.constData()); + } + + // the callback was not called + QVERIFY(messageInfo.messageType == QtFatalMsg); + QVERIFY(messageInfo.message.isEmpty()); + QVERIFY(messageInfo.file == nullptr); + QVERIFY(messageInfo.line == 0); + QVERIFY(messageInfo.function == nullptr); + QVERIFY(messageInfo.category == nullptr); +} + +void tst_QMessageLogger::logWithLoggingCategoryHelper(bool messageTypeEnabled) +{ + QFETCH_GLOBAL(QtMsgType, messageType); + QFETCH_GLOBAL(QByteArray, categoryName); + QLoggingCategory category(categoryName.constData(), messageType); + if (!messageTypeEnabled) + category.setEnabled(messageType, false); + + const int line = QT_MESSAGELOG_LINE; + QMessageLogger logger(QT_MESSAGELOG_FILE, line, QT_MESSAGELOG_FUNC); + + QFETCH_GLOBAL(QByteArray, messageText); + QFETCH_GLOBAL(bool, useDebugStream); + if (useDebugStream) { +#ifndef QT_NO_DEBUG_STREAM + switch (messageType) { + case QtDebugMsg: + logger.debug(category).noquote() << messageText; + break; + case QtInfoMsg: + logger.info(category).noquote() << messageText; + break; + case QtWarningMsg: + logger.warning(category).noquote() << messageText; + break; + case QtCriticalMsg: + logger.critical(category).noquote() << messageText; + break; + default: + QFAIL("Invalid message type"); + break; + } +#else + QSKIP("Qt debug stream disabled"); +#endif + } else { + switch (messageType) { + case QtDebugMsg: + logger.debug(category, "%s", messageText.constData()); + break; + case QtInfoMsg: + logger.info(category, "%s", messageText.constData()); + break; + case QtWarningMsg: + logger.warning(category, "%s", messageText.constData()); + break; + case QtCriticalMsg: + logger.critical(category, "%s", messageText.constData()); + break; + default: + QFAIL("Invalid message type"); + break; + } + } + + if (messageTypeEnabled) { + QCOMPARE(messageInfo.messageType, messageType); + QCOMPARE(messageInfo.message, messageText); + QCOMPARE(messageInfo.file, __FILE__); + QCOMPARE(messageInfo.line, line); + QCOMPARE(messageInfo.function, Q_FUNC_INFO); + QCOMPARE(messageInfo.category, categoryName); + } else { + // the callback was not called + QVERIFY(messageInfo.messageType == QtFatalMsg); + QVERIFY(messageInfo.message.isEmpty()); + QVERIFY(messageInfo.file == nullptr); + QVERIFY(messageInfo.line == 0); + QVERIFY(messageInfo.function == nullptr); + QVERIFY(messageInfo.category == nullptr); + } +} + +QTEST_MAIN(tst_QMessageLogger) +#include "tst_qmessagelogger.moc"