From 7ef2d81aad4ebc6449199c9f0dcd6d76a3a7c9c8 Mon Sep 17 00:00:00 2001 From: Tobias Hunger <tobias.hunger@nokia.com> Date: Wed, 6 Oct 2010 11:53:59 +0200 Subject: [PATCH] Symbian: Add unit tests for RVCT parser * Add unit tests for RVCT parser * Make the unit tests pass. --- .../qt4projectmanager/qt-s60/rvctparser.cpp | 222 +++++++++++++++--- .../qt4projectmanager/qt-s60/rvctparser.h | 11 +- .../qt4projectmanagerplugin.h | 2 + 3 files changed, 195 insertions(+), 40 deletions(-) diff --git a/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp b/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp index 5702d3611b5..cde0deeee40 100644 --- a/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp @@ -36,65 +36,217 @@ using namespace ProjectExplorer::Constants; using namespace Qt4ProjectManager; RvctParser::RvctParser() : - m_additionalInfo(false), - m_lastLine(0) + m_task(0) { setObjectName(QLatin1String("RvctParser")); // Start of a error or warning: - m_warningOrError.setPattern("^\"([^\\(\\)]+[^\\d])\", line (\\d+):(\\s(Warning|Error):)\\s(.+)$"); + m_warningOrError.setPattern("^\"([^\\(\\)]+[^\\d])\", line (\\d+):(\\s(Warning|Error):)\\s+([^\\s].*)$"); m_warningOrError.setMinimal(true); // Last message for any file with warnings/errors. - m_doneWithFile.setPattern("^([^\\(\\)]+[^\\d]):\\s(\\d+) warnings?,\\s(\\d+) errors?$"); - m_doneWithFile.setMinimal(true); + m_wrapUpTask.setPattern("^([^\\(\\)]+[^\\d]):\\s(\\d+) warnings?,\\s(\\d+) errors?$"); + m_wrapUpTask.setMinimal(true); // linker problems: - m_linkerProblem.setPattern("^(\\S*)\\(\\S+\\):\\s(.+)$"); - m_linkerProblem.setMinimal(true); + m_genericProblem.setPattern("^(Error|Warning): (.*)$"); + m_genericProblem.setMinimal(true); +} + +RvctParser::~RvctParser() +{ + sendTask(); } void RvctParser::stdError(const QString &line) { QString lne = line.trimmed(); - if (m_linkerProblem.indexIn(lne) > -1) { - emit addTask(Task(Task::Error, - m_linkerProblem.cap(2) /* description */, - m_linkerProblem.cap(1) /* filename */, - -1 /* linenumber */, - TASK_CATEGORY_COMPILE)); - return; - } + if (m_genericProblem.indexIn(lne) > -1) { + sendTask(); + + m_task = new Task(Task::Error, + m_genericProblem.cap(2) /* description */, + QString(), + -1 /* linenumber */, + TASK_CATEGORY_COMPILE); + if (m_warningOrError.cap(4) == "Warning") + m_task->type = Task::Warning; + else if (m_warningOrError.cap(4) == "Error") + m_task->type = Task::Error; + return; + } if (m_warningOrError.indexIn(lne) > -1) { - m_lastFile = m_warningOrError.cap(1); - m_lastLine = m_warningOrError.cap(2).toInt(); + sendTask(); - Task task(Task::Unknown, - m_warningOrError.cap(5) /* description */, - m_lastFile, m_lastLine, - TASK_CATEGORY_COMPILE); + m_task = new Task(Task::Unknown, + m_warningOrError.cap(5) /* description */, + m_warningOrError.cap(1) /* file */, m_warningOrError.cap(2).toInt() /* line */, + TASK_CATEGORY_COMPILE); if (m_warningOrError.cap(4) == "Warning") - task.type = Task::Warning; + m_task->type = Task::Warning; else if (m_warningOrError.cap(4) == "Error") - task.type = Task::Error; - - m_additionalInfo = true; - - emit addTask(task); + m_task->type = Task::Error; return; } - if (m_doneWithFile.indexIn(lne) > -1) { - m_additionalInfo = false; + if (m_wrapUpTask.indexIn(lne) > -1) { + sendTask(); return; } - if (m_additionalInfo) { - // Report any lines after a error/warning message as these contain - // additional information on the problem. - emit addTask(Task(Task::Unknown, lne, - m_lastFile, m_lastLine, - TASK_CATEGORY_COMPILE)); + if (m_task) { + QString description = line; + if (description.startsWith(QLatin1String(" "))) + description = description.mid(2); + if (description.endsWith('\n')) + description.chop(1); + if (m_task->formats.isEmpty()) { + QTextLayout::FormatRange fr; + fr.start = m_task->description.count(); // incl. '\n' we are about to add! + fr.length = description.count() - 1; + fr.format.setFontItalic(true); + m_task->formats.append(fr); + } else { + m_task->formats[0].length += description.count() - 2 + 1; + } + m_task->description += QLatin1Char('\n') + description; + + // Wrap up license error: + if (description.endsWith(QLatin1String("at \"www.macrovision.com\"."))) + sendTask(); + return; } IOutputParser::stdError(line); } + +void RvctParser::sendTask() +{ + if (!m_task) + return; + emit addTask(*m_task); + delete m_task; + m_task = 0; +} + +// Unit tests: + +#ifdef WITH_TESTS +# include <QTest> + +# include "qt4projectmanagerplugin.h" +# include <projectexplorer/metatypedeclarations.h> +# include <projectexplorer/outputparser_test.h> + +using namespace Qt4ProjectManager::Internal; + +void Qt4ProjectManagerPlugin::testRvctOutputParser_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<OutputParserTester::Channel>("inputChannel"); + QTest::addColumn<QString>("childStdOutLines"); + QTest::addColumn<QString>("childStdErrLines"); + QTest::addColumn<QList<ProjectExplorer::Task> >("tasks"); + QTest::addColumn<QString>("outputLines"); + + + QTest::newRow("pass-through stdout") + << QString::fromLatin1("Sometext") << OutputParserTester::STDOUT + << QString::fromLatin1("Sometext") << QString() + << QList<ProjectExplorer::Task>() + << QString(); + QTest::newRow("pass-through stderr") + << QString::fromLatin1("Sometext") << OutputParserTester::STDERR + << QString() << QString::fromLatin1("Sometext") + << QList<ProjectExplorer::Task>() + << QString(); + + QTest::newRow("Rvct warning") + << QString::fromLatin1("\"../../../../s60-sdk/epoc32/include/stdapis/stlport/stl/_limits.h\", line 256: Warning: #68-D: integer conversion resulted in a change of sign\n" + " : public _Integer_limits<char, CHAR_MIN, CHAR_MAX, -1, true>\n" + " ^") + << OutputParserTester::STDERR + << QString() << QString() + << (QList<ProjectExplorer::Task>() + << Task(Task::Warning, + QLatin1String("#68-D: integer conversion resulted in a change of sign\n" + " : public _Integer_limits<char, CHAR_MIN, CHAR_MAX, -1, true>\n" + " ^"), + QLatin1String("../../../../s60-sdk/epoc32/include/stdapis/stlport/stl/_limits.h"), 256, + Constants::TASK_CATEGORY_COMPILE) + ) + << QString(); + QTest::newRow("Rvct error") + << QString::fromLatin1("\"mainwindow.cpp\", line 22: Error: #20: identifier \"e\" is undefined\n" + " delete ui;e\n" + " ^") + << OutputParserTester::STDERR + << QString() << QString() + << (QList<ProjectExplorer::Task>() + << Task(Task::Error, + QLatin1String("#20: identifier \"e\" is undefined\n" + " delete ui;e\n" + " ^"), + QLatin1String("mainwindow.cpp"), 22, + Constants::TASK_CATEGORY_COMPILE) + ) + << QString(); + QTest::newRow("Rvct linking error") + << QString::fromLatin1("Error: L6218E: Undefined symbol MainWindow::sth() (referred from mainwindow.o)") + << OutputParserTester::STDERR + << QString() << QString() + << (QList<ProjectExplorer::Task>() + << Task(Task::Error, + QLatin1String("L6218E: Undefined symbol MainWindow::sth() (referred from mainwindow.o)"), + QString(), -1, + Constants::TASK_CATEGORY_COMPILE) + ) + << QString(); + QTest::newRow("Rvct license error") + << QString::fromLatin1("Error: C3397E: Cannot obtain license for Compiler (feature compiler) with license version >= 2.2:\n" + "Cannot find license file.\n" + " The license files (or license server system network addresses) attempted are \n" + "listed below. Use LM_LICENSE_FILE to use a different license file,\n" + " or contact your software provider for a license file.\n" + "Feature: compiler\n" + "Filename: /usr/local/flexlm/licenses/license.dat\n" + "License path: /usr/local/flexlm/licenses/license.dat\n" + "FLEXnet Licensing error:-1,359. System Error: 2 \"No such file or directory\"\n" + "For further information, refer to the FLEXnet Licensing End User Guide,\n" + "available at \"www.macrovision.com\".") + << OutputParserTester::STDERR + << QString() << QString() + << (QList<ProjectExplorer::Task>() + << Task(Task::Error, + QLatin1String("C3397E: Cannot obtain license for Compiler (feature compiler) with license version >= 2.2:\n" + "Cannot find license file.\n" + " The license files (or license server system network addresses) attempted are \n" + "listed below. Use LM_LICENSE_FILE to use a different license file,\n" + " or contact your software provider for a license file.\n" + "Feature: compiler\n" + "Filename: /usr/local/flexlm/licenses/license.dat\n" + "License path: /usr/local/flexlm/licenses/license.dat\n" + "FLEXnet Licensing error:-1,359. System Error: 2 \"No such file or directory\"\n" + "For further information, refer to the FLEXnet Licensing End User Guide,\n" + "available at \"www.macrovision.com\"."), + QString(), -1, + Constants::TASK_CATEGORY_COMPILE) + ) + << QString(); +} + +void Qt4ProjectManagerPlugin::testRvctOutputParser() +{ + OutputParserTester testbench; + testbench.appendOutputParser(new RvctParser); + QFETCH(QString, input); + QFETCH(OutputParserTester::Channel, inputChannel); + QFETCH(QList<Task>, tasks); + QFETCH(QString, childStdOutLines); + QFETCH(QString, childStdErrLines); + QFETCH(QString, outputLines); + + testbench.testParsing(input, inputChannel, + tasks, childStdOutLines, childStdErrLines, + outputLines); +} +#endif diff --git a/src/plugins/qt4projectmanager/qt-s60/rvctparser.h b/src/plugins/qt4projectmanager/qt-s60/rvctparser.h index 8c29c26617f..7f588902b9e 100644 --- a/src/plugins/qt4projectmanager/qt-s60/rvctparser.h +++ b/src/plugins/qt4projectmanager/qt-s60/rvctparser.h @@ -42,16 +42,17 @@ class RvctParser : public ProjectExplorer::IOutputParser public: RvctParser(); + ~RvctParser(); virtual void stdError(const QString & line); private: + void sendTask(); + QRegExp m_warningOrError; - QRegExp m_doneWithFile; - QRegExp m_linkerProblem; + QRegExp m_wrapUpTask; + QRegExp m_genericProblem; - bool m_additionalInfo; - QString m_lastFile; - int m_lastLine; + ProjectExplorer::Task * m_task; }; } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h index 3fcfc8eb40c..f05803e11db 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h +++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h @@ -85,6 +85,8 @@ private slots: void testQtOutputParser(); void testSbsV2OutputParsers_data(); void testSbsV2OutputParsers(); + void testRvctOutputParser_data(); + void testRvctOutputParser(); #endif private: -- GitLab