diff options
Diffstat (limited to 'src/testlib/qtestlog.cpp')
-rw-r--r-- | src/testlib/qtestlog.cpp | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp new file mode 100644 index 0000000..aa56e6c --- /dev/null +++ b/src/testlib/qtestlog.cpp @@ -0,0 +1,364 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtTest module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "QtTest/qtestassert.h" + +#include "QtTest/private/qtestlog_p.h" +#include "QtTest/private/qtestresult_p.h" +#include "QtTest/private/qabstracttestlogger_p.h" +#include "QtTest/private/qplaintestlogger_p.h" +#include "QtTest/private/qxmltestlogger_p.h" + +#include <QtCore/qatomic.h> +#include <QtCore/qbytearray.h> + +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +QT_BEGIN_NAMESPACE + +namespace QTest { + + struct IgnoreResultList + { + inline IgnoreResultList(QtMsgType tp, const char *message) + : type(tp), next(0) + { msg = qstrdup(message); } + inline ~IgnoreResultList() + { delete [] msg; } + + static inline void clearList(IgnoreResultList *&list) + { + while (list) { + IgnoreResultList *current = list; + list = list->next; + delete current; + } + } + + QtMsgType type; + char *msg; + IgnoreResultList *next; + }; + + static IgnoreResultList *ignoreResultList = 0; + + static QTestLog::LogMode logMode = QTestLog::Plain; + static int verbosity = 0; + static int maxWarnings = 2002; + + static QAbstractTestLogger *testLogger = 0; + static const char *outFile = 0; + + static QtMsgHandler oldMessageHandler; + + static bool handleIgnoredMessage(QtMsgType type, const char *msg) + { + IgnoreResultList *last = 0; + IgnoreResultList *list = ignoreResultList; + while (list) { + if (list->type == type && strcmp(msg, list->msg) == 0) { + // remove the item from the list + if (last) + last->next = list->next; + else if (list->next) + ignoreResultList = list->next; + else + ignoreResultList = 0; + + delete list; + return true; + } + + last = list; + list = list->next; + } + return false; + } + + static void messageHandler(QtMsgType type, const char *msg) + { + static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings); + + if (!msg || !QTest::testLogger) { + // if this goes wrong, something is seriously broken. + qInstallMsgHandler(oldMessageHandler); + QTEST_ASSERT(msg); + QTEST_ASSERT(QTest::testLogger); + } + + if (handleIgnoredMessage(type, msg)) + // the message is expected, so just swallow it. + return; + + if (type != QtFatalMsg) { + if (counter <= 0) + return; + + if (!counter.deref()) { + QTest::testLogger->addMessage(QAbstractTestLogger::QSystem, + "Maximum amount of warnings exceeded."); + return; + } + } + + switch (type) { + case QtDebugMsg: + QTest::testLogger->addMessage(QAbstractTestLogger::QDebug, msg); + break; + case QtCriticalMsg: + QTest::testLogger->addMessage(QAbstractTestLogger::QSystem, msg); + break; + case QtWarningMsg: + QTest::testLogger->addMessage(QAbstractTestLogger::QWarning, msg); + break; + case QtFatalMsg: + QTest::testLogger->addMessage(QAbstractTestLogger::QFatal, msg); + /* Right now, we're inside the custom message handler and we're + * being qt_message_output in qglobal.cpp. After we return from + * this function, it will proceed with calling exit() and abort() + * and hence crash. Therefore, we call these logging functions such + * that we wrap up nicely, and in particular produce well-formed XML. */ + QTestResult::addFailure("Received a fatal error.", "Unknown file", 0); + QTestLog::leaveTestFunction(); + QTestLog::stopLogging(); + break; + } + } + +} + +QTestLog::QTestLog() +{ +} + +QTestLog::~QTestLog() +{ +} + +void QTestLog::enterTestFunction(const char* function) +{ + QTEST_ASSERT(QTest::testLogger); + QTEST_ASSERT(function); + + QTest::testLogger->enterTestFunction(function); +} + +int QTestLog::unhandledIgnoreMessages() +{ + int i = 0; + QTest::IgnoreResultList *list = QTest::ignoreResultList; + while (list) { + ++i; + list = list->next; + } + return i; +} + +void QTestLog::leaveTestFunction() +{ + QTEST_ASSERT(QTest::testLogger); + + QTest::IgnoreResultList::clearList(QTest::ignoreResultList); + QTest::testLogger->leaveTestFunction(); +} + +void QTestLog::printUnhandledIgnoreMessages() +{ + QTEST_ASSERT(QTest::testLogger); + + char msg[1024]; + QTest::IgnoreResultList *list = QTest::ignoreResultList; + while (list) { + QTest::qt_snprintf(msg, 1024, "Did not receive message: \"%s\"", list->msg); + QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg); + + list = list->next; + } +} + +void QTestLog::addPass(const char *msg) +{ + QTEST_ASSERT(QTest::testLogger); + QTEST_ASSERT(msg); + + QTest::testLogger->addIncident(QAbstractTestLogger::Pass, msg); +} + +void QTestLog::addFail(const char *msg, const char *file, int line) +{ + QTEST_ASSERT(QTest::testLogger); + + QTest::testLogger->addIncident(QAbstractTestLogger::Fail, msg, file, line); +} + +void QTestLog::addXFail(const char *msg, const char *file, int line) +{ + QTEST_ASSERT(QTest::testLogger); + QTEST_ASSERT(msg); + QTEST_ASSERT(file); + + QTest::testLogger->addIncident(QAbstractTestLogger::XFail, msg, file, line); +} + +void QTestLog::addXPass(const char *msg, const char *file, int line) +{ + QTEST_ASSERT(QTest::testLogger); + QTEST_ASSERT(msg); + QTEST_ASSERT(file); + + QTest::testLogger->addIncident(QAbstractTestLogger::XPass, msg, file, line); +} + +void QTestLog::addSkip(const char *msg, QTest::SkipMode /*mode*/, + const char *file, int line) +{ + QTEST_ASSERT(QTest::testLogger); + QTEST_ASSERT(msg); + QTEST_ASSERT(file); + + QTest::testLogger->addMessage(QAbstractTestLogger::Skip, msg, file, line); +} + +void QTestLog::addBenchmarkResult(const QBenchmarkResult &result) +{ + QTEST_ASSERT(QTest::testLogger); + QTest::testLogger->addBenchmarkResult(result); +} + +void QTestLog::startLogging() +{ + QTEST_ASSERT(!QTest::testLogger); + + switch (QTest::logMode) { + case QTestLog::Plain: + QTest::testLogger = new QPlainTestLogger(); + break; + case QTestLog::XML: + QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Complete); + break; + case QTestLog::LightXML: + QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Light); + } + + QTest::testLogger->startLogging(); + + QTest::oldMessageHandler = qInstallMsgHandler(QTest::messageHandler); +} + +void QTestLog::stopLogging() +{ + qInstallMsgHandler(QTest::oldMessageHandler); + + QTEST_ASSERT(QTest::testLogger); + QTest::testLogger->stopLogging(); + delete QTest::testLogger; + QTest::testLogger = 0; +} + +void QTestLog::warn(const char *msg) +{ + QTEST_ASSERT(msg); + + QTest::testLogger->addMessage(QAbstractTestLogger::Warn, msg); +} + +void QTestLog::info(const char *msg, const char *file, int line) +{ + QTEST_ASSERT(msg); + + if (QTest::testLogger) + QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg, file, line); +} + +void QTestLog::setLogMode(LogMode mode) +{ + QTest::logMode = mode; +} + +QTestLog::LogMode QTestLog::logMode() +{ + return QTest::logMode; +} + +void QTestLog::setVerboseLevel(int level) +{ + QTest::verbosity = level; +} + +int QTestLog::verboseLevel() +{ + return QTest::verbosity; +} + +void QTestLog::addIgnoreMessage(QtMsgType type, const char *msg) +{ + QTest::IgnoreResultList *item = new QTest::IgnoreResultList(type, msg); + + QTest::IgnoreResultList *list = QTest::ignoreResultList; + if (!list) { + QTest::ignoreResultList = item; + return; + } + while (list->next) + list = list->next; + list->next = item; +} + +void QTestLog::redirectOutput(const char *fileName) +{ + QTEST_ASSERT(fileName); + + QTest::outFile = fileName; +} + +const char *QTestLog::outputFileName() +{ + return QTest::outFile; +} + +void QTestLog::setMaxWarnings(int m) +{ + QTest::maxWarnings = m <= 0 ? INT_MAX : m + 2; +} + +QT_END_NAMESPACE |