aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@nokia.com>2010-03-03 18:05:37 +0100
committerTobias Hunger <tobias.hunger@nokia.com>2010-03-04 15:25:25 +0100
commitc2303b3c76499c728cc7aa5bbd65d208e7eac1e2 (patch)
tree2b18ee8984bdb1d08e245a530b0aea79f0a395d5
parentc59912819fa1ecffa0219a9e13d15e3a7c5ef0f7 (diff)
Add unit test for the gcc output parser
-rw-r--r--src/plugins/projectexplorer/gccparser.cpp159
-rw-r--r--src/plugins/projectexplorer/outputparser_test.cpp159
-rw-r--r--src/plugins/projectexplorer/outputparser_test.h89
-rw-r--r--src/plugins/projectexplorer/projectexplorer.h5
-rw-r--r--src/plugins/projectexplorer/projectexplorer.pro7
5 files changed, 419 insertions, 0 deletions
diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp
index 32a0b929461..949e9b042b6 100644
--- a/src/plugins/projectexplorer/gccparser.cpp
+++ b/src/plugins/projectexplorer/gccparser.cpp
@@ -88,3 +88,162 @@ void GccParser::stdError(const QString &line)
}
IOutputParser::stdError(line);
}
+
+// Unit tests:
+
+#ifdef WITH_TESTS
+# include <QTest>
+
+# include "projectexplorer.h"
+# include "metatypedeclarations.h"
+# include "outputparser_test.h"
+
+void ProjectExplorerPlugin::testGccOutputParsers_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<OutputParserTester::Channel>("inputChannel");
+ QTest::addColumn<QString>("childStdOutLines");
+ QTest::addColumn<QString>("childStdErrLines");
+ QTest::addColumn<QList<ProjectExplorer::TaskWindow::Task> >("tasks");
+ QTest::addColumn<QString>("outputLines");
+
+
+ QTest::newRow("pass-through stdout")
+ << QString::fromLatin1("Sometext") << OutputParserTester::STDOUT
+ << QString::fromLatin1("Sometext") << QString()
+ << QList<ProjectExplorer::TaskWindow::Task>()
+ << QString();
+ QTest::newRow("pass-through stderr")
+ << QString::fromLatin1("Sometext") << OutputParserTester::STDERR
+ << QString() << QString::fromLatin1("Sometext")
+ << QList<ProjectExplorer::TaskWindow::Task>()
+ << QString();
+
+ QTest::newRow("GCCE error")
+ << QString::fromLatin1("/temp/test/untitled8/main.cpp: In function `int main(int, char**)':\n"
+ "/temp/test/untitled8/main.cpp:9: error: `sfasdf' undeclared (first use this function)\n"
+ "/temp/test/untitled8/main.cpp:9: error: (Each undeclared identifier is reported only once for each function it appears in.)")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << (QList<ProjectExplorer::TaskWindow::Task>()
+ << TaskWindow::Task(TaskWindow::Unknown,
+ QLatin1String("In function `int main(int, char**)':"),
+ QLatin1String("/temp/test/untitled8/main.cpp"), -1,
+ Constants::TASK_CATEGORY_COMPILE)
+ << TaskWindow::Task(TaskWindow::Error,
+ QLatin1String("`sfasdf' undeclared (first use this function)"),
+ QLatin1String("/temp/test/untitled8/main.cpp"), 9,
+ Constants::TASK_CATEGORY_COMPILE)
+ << TaskWindow::Task(TaskWindow::Error,
+ QLatin1String("(Each undeclared identifier is reported only once for each function it appears in.)"),
+ QLatin1String("/temp/test/untitled8/main.cpp"), 9,
+ Constants::TASK_CATEGORY_COMPILE)
+ )
+ << QString();
+ QTest::newRow("GCCE warning")
+ << QString::fromLatin1("/src/corelib/global/qglobal.h:1635: warning: inline function `QDebug qDebug()' used but never defined")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << (QList<ProjectExplorer::TaskWindow::Task>()
+ << TaskWindow::Task(TaskWindow::Warning,
+ QLatin1String("inline function `QDebug qDebug()' used but never defined"),
+ QLatin1String("/src/corelib/global/qglobal.h"), 1635,
+ Constants::TASK_CATEGORY_COMPILE))
+ << QString();
+ QTest::newRow("warning")
+ << QString::fromLatin1("main.cpp:7:2: warning: Some warning")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << (QList<ProjectExplorer::TaskWindow::Task>() << TaskWindow::Task(TaskWindow::Warning,
+ QLatin1String("Some warning"),
+ QLatin1String("main.cpp"), 7,
+ Constants::TASK_CATEGORY_COMPILE))
+ << QString();
+ QTest::newRow("GCCE #error")
+ << QString::fromLatin1("C:\\temp\\test\\untitled8\\main.cpp:7: #error Symbian error")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << (QList<ProjectExplorer::TaskWindow::Task>() << TaskWindow::Task(TaskWindow::Error,
+ QLatin1String("#error Symbian error"),
+ QLatin1String("C:\\temp\\test\\untitled8\\main.cpp"), 7,
+ Constants::TASK_CATEGORY_COMPILE))
+ << QString();
+ // Symbian reports #warning(s) twice (using different syntax).
+ QTest::newRow("GCCE #warning1")
+ << QString::fromLatin1("C:\\temp\\test\\untitled8\\main.cpp:8: warning: #warning Symbian warning")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << (QList<ProjectExplorer::TaskWindow::Task>() << TaskWindow::Task(TaskWindow::Warning,
+ QLatin1String("#warning Symbian warning"),
+ QLatin1String("C:\\temp\\test\\untitled8\\main.cpp"), 8,
+ Constants::TASK_CATEGORY_COMPILE))
+ << QString();
+ QTest::newRow("GCCE #warning2")
+ << QString::fromLatin1("/temp/test/untitled8/main.cpp:8:2: warning: #warning Symbian warning")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << (QList<ProjectExplorer::TaskWindow::Task>() << TaskWindow::Task(TaskWindow::Warning,
+ QLatin1String("#warning Symbian warning"),
+ QLatin1String("/temp/test/untitled8/main.cpp"), 8,
+ Constants::TASK_CATEGORY_COMPILE))
+ << QString();
+ QTest::newRow("Undefined reference (debug)")
+ << QString::fromLatin1("main.o: In function `main':\n"
+ "C:\\temp\\test\\untitled8/main.cpp:8: undefined reference to `MainWindow::doSomething()'\n"
+ "collect2: ld returned 1 exit status")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << (QList<ProjectExplorer::TaskWindow::Task>()
+ << TaskWindow::Task(TaskWindow::Unknown,
+ QLatin1String("In function `main':"),
+ QLatin1String("main.o"), -1,
+ Constants::TASK_CATEGORY_COMPILE)
+ << TaskWindow::Task(TaskWindow::Error,
+ QLatin1String("undefined reference to `MainWindow::doSomething()'"),
+ QLatin1String("C:\\temp\\test\\untitled8/main.cpp"), 8,
+ Constants::TASK_CATEGORY_COMPILE)
+ << TaskWindow::Task(TaskWindow::Error,
+ QLatin1String("collect2: ld returned 1 exit status"),
+ QString(), -1,
+ Constants::TASK_CATEGORY_COMPILE)
+ )
+ << QString();
+ QTest::newRow("Undefined reference (release)")
+ << QString::fromLatin1("main.o: In function `main':\n"
+ "C:\\temp\\test\\untitled8/main.cpp:(.text+0x40): undefined reference to `MainWindow::doSomething()'\n"
+ "collect2: ld returned 1 exit status")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << (QList<ProjectExplorer::TaskWindow::Task>()
+ << TaskWindow::Task(TaskWindow::Unknown,
+ QLatin1String("In function `main':"),
+ QLatin1String("main.o"), -1,
+ Constants::TASK_CATEGORY_COMPILE)
+ << TaskWindow::Task(TaskWindow::Error,
+ QLatin1String("undefined reference to `MainWindow::doSomething()'"),
+ QLatin1String("C:\\temp\\test\\untitled8/main.cpp"), -1,
+ Constants::TASK_CATEGORY_COMPILE)
+ << TaskWindow::Task(TaskWindow::Error,
+ QLatin1String("collect2: ld returned 1 exit status"),
+ QString(), -1,
+ Constants::TASK_CATEGORY_COMPILE)
+ )
+ << QString();
+}
+
+void ProjectExplorerPlugin::testGccOutputParsers()
+{
+ OutputParserTester testbench;
+ testbench.appendOutputParser(new GccParser);
+ QFETCH(QString, input);
+ QFETCH(OutputParserTester::Channel, inputChannel);
+ QFETCH(QList<TaskWindow::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/projectexplorer/outputparser_test.cpp b/src/plugins/projectexplorer/outputparser_test.cpp
new file mode 100644
index 00000000000..26b6b053f79
--- /dev/null
+++ b/src/plugins/projectexplorer/outputparser_test.cpp
@@ -0,0 +1,159 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "outputparser_test.h"
+
+#include <QtTest>
+
+using namespace ProjectExplorer;
+
+OutputParserTester::OutputParserTester() :
+ m_debug(false)
+{
+}
+
+OutputParserTester::~OutputParserTester()
+{
+ if (childParser())
+ childParser()->takeOutputParserChain();
+}
+
+// test methods:
+void OutputParserTester::testParsing(const QString &lines,
+ Channel inputChannel,
+ QList<TaskWindow::Task> tasks,
+ const QString &childStdOutLines,
+ const QString &childStdErrLines,
+ const QString &outputLines)
+{
+ reset();
+ Q_ASSERT(childParser());
+
+ QStringList inputLines = lines.split(QChar('\n'));
+ foreach (const QString &input, inputLines) {
+ if (inputChannel == STDOUT)
+ childParser()->stdOutput(input);
+ else
+ childParser()->stdError(input);
+ }
+
+ QCOMPARE(m_receivedOutput, outputLines);
+ QCOMPARE(m_receivedStdErrChildLine, childStdErrLines);
+ QCOMPARE(m_receivedStdOutChildLine, childStdOutLines);
+ QCOMPARE(m_receivedTasks.size(), tasks.size());
+ if (m_receivedTasks.size() == tasks.size()) {
+ for(int i = 0; i < tasks.size(); ++i) {
+ QCOMPARE(m_receivedTasks.at(i).category, tasks.at(i).category);
+ QCOMPARE(m_receivedTasks.at(i).description, tasks.at(i).description);
+ QCOMPARE(m_receivedTasks.at(i).file, tasks.at(i).file);
+ QCOMPARE(m_receivedTasks.at(i).line, tasks.at(i).line);
+ QCOMPARE(m_receivedTasks.at(i).type, tasks.at(i).type);
+ }
+ }
+}
+
+void OutputParserTester::testTaskMangling(const TaskWindow::Task input,
+ const TaskWindow::Task output)
+{
+ reset();
+ childParser()->taskAdded(input);
+
+ QVERIFY(m_receivedOutput.isNull());
+ QVERIFY(m_receivedStdErrChildLine.isNull());
+ QVERIFY(m_receivedStdOutChildLine.isNull());
+ QVERIFY(m_receivedTasks.size() == 1);
+ if (m_receivedTasks.size() == 1) {
+ QCOMPARE(m_receivedTasks.at(0).category, output.category);
+ QCOMPARE(m_receivedTasks.at(0).description, output.description);
+ QCOMPARE(m_receivedTasks.at(0).file, output.file);
+ QCOMPARE(m_receivedTasks.at(0).line, output.line);
+ QCOMPARE(m_receivedTasks.at(0).type, output.type);
+ }
+}
+
+void OutputParserTester::testOutputMangling(const QString &input,
+ const QString &output)
+{
+ reset();
+
+ childParser()->outputAdded(input);
+
+ QCOMPARE(m_receivedOutput, output);
+ QVERIFY(m_receivedStdErrChildLine.isNull());
+ QVERIFY(m_receivedStdOutChildLine.isNull());
+ QVERIFY(m_receivedTasks.isEmpty());
+}
+
+void OutputParserTester::setDebugEnabled(bool debug)
+{
+ m_debug = debug;
+}
+
+void OutputParserTester::stdOutput(const QString &line)
+{
+ if (!m_receivedStdOutChildLine.isEmpty())
+ m_receivedStdOutChildLine.append(QChar('\n'));
+ m_receivedStdOutChildLine.append(line);
+}
+
+void OutputParserTester::stdError(const QString &line)
+{
+ if (!m_receivedStdErrChildLine.isEmpty())
+ m_receivedStdErrChildLine.append(QChar('\n'));
+ m_receivedStdErrChildLine.append(line);
+}
+
+void OutputParserTester::appendOutputParser(IOutputParser *parser)
+{
+ Q_ASSERT(!childParser());
+ Q_ASSERT(!parser->childParser());
+
+ IOutputParser::appendOutputParser(parser);
+ parser->appendOutputParser(this);
+}
+
+void OutputParserTester::outputAdded(const QString &line)
+{
+ if (!m_receivedOutput.isEmpty())
+ m_receivedOutput.append(QChar('\n'));
+ m_receivedOutput.append(line);
+}
+
+void OutputParserTester::taskAdded(const ProjectExplorer::TaskWindow::Task &task)
+{
+ m_receivedTasks.append(task);
+}
+
+void OutputParserTester::reset()
+{
+ m_receivedStdErrChildLine = QString();
+ m_receivedStdOutChildLine = QString();
+ m_receivedTasks.clear();
+ m_receivedOutput = QString();
+}
diff --git a/src/plugins/projectexplorer/outputparser_test.h b/src/plugins/projectexplorer/outputparser_test.h
new file mode 100644
index 00000000000..5f53a7681b7
--- /dev/null
+++ b/src/plugins/projectexplorer/outputparser_test.h
@@ -0,0 +1,89 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef OUTPUTPARSER_TESTER_H
+#define OUTPUTPARSER_TESTER_H
+
+#include "projectexplorer_export.h"
+#include "ioutputparser.h"
+
+namespace ProjectExplorer {
+
+class PROJECTEXPLORER_EXPORT OutputParserTester : public IOutputParser
+{
+ Q_OBJECT
+
+public:
+ enum Channel {
+ STDOUT,
+ STDERR
+ };
+
+ OutputParserTester();
+ ~OutputParserTester();
+
+ // test methods:
+ void testParsing(const QString &lines, Channel inputChannel,
+ QList<TaskWindow::Task> tasks,
+ const QString &childStdOutLines,
+ const QString &childStdErrLines,
+ const QString &outputLines);
+ void testTaskMangling(const TaskWindow::Task input,
+ const TaskWindow::Task output);
+ void testOutputMangling(const QString &input,
+ const QString &output);
+
+ void setDebugEnabled(bool);
+
+ // IOutputParser interface:
+ void stdOutput(const QString &line);
+ void stdError(const QString &line);
+
+ void appendOutputParser(IOutputParser *parser);
+
+private slots:
+ void outputAdded(const QString &line);
+ void taskAdded(const ProjectExplorer::TaskWindow::Task &task);
+
+private:
+ void reset();
+
+ bool m_debug;
+
+ QString m_receivedStdErrChildLine;
+ QString m_receivedStdOutChildLine;
+ QList<TaskWindow::Task> m_receivedTasks;
+ QString m_receivedOutput;
+};
+
+} // namespace ProjectExplorer
+
+Q_DECLARE_METATYPE(ProjectExplorer::OutputParserTester::Channel)
+
+#endif // OUTPUTPARSER_TESTER_H
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index e964ce8b4b8..1f35e261f3b 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -220,6 +220,11 @@ private slots:
void currentModeChanged(Core::IMode *mode, Core::IMode *oldMode);
void updateActions();
+#ifdef WITH_TESTS
+ void testGccOutputParsers_data();
+ void testGccOutputParsers();
+#endif
+
private:
void runProjectImpl(Project *pro, QString mode);
void executeRunConfiguration(RunConfiguration *, const QString &mode);
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index cbdf7c71e0a..c912a1985d6 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -149,6 +149,13 @@ FORMS += processstep.ui \
doubletabwidget.ui \
addtargetdialog.ui
+equals(TEST, 1) {
+ SOURCES += \
+ outputparser_test.cpp
+ HEADERS += \
+ outputparser_test.h
+}
+
win32 {
SOURCES += applicationlauncher_win.cpp \
winguiprocess.cpp