Commit c2303b3c authored by Tobias Hunger's avatar Tobias Hunger
Browse files

Add unit test for the gcc output parser

parent c5991281
......@@ -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
/**************************************************************************
**
** 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();
}
/**************************************************************************
**
** 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
......@@ -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);
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment