forked from qt-creator/qt-creator
Add unit tests.
These test the complete workflow as the user experiences it when clicking "Start". Intended usage: (1) Run sdktool to set up a kit with the toolchain you want to test against (using a temporary directory). The tests assume exactly one Kit to be present. (2) Start Creator with a matching settings path and "-load ClangStaticAnalyzer -test ClangStaticAnalyzer". (3) Repeat until all toolchains have been tested. The initial implementation tests one trivial source file with both qbs and qmake. Change-Id: I810f23e2990a789a4dd9f1dd16335fbcf5c5f39f Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
@@ -37,5 +37,11 @@ HEADERS += \
|
||||
FORMS += \
|
||||
clangstaticanalyzerconfigwidget.ui
|
||||
|
||||
equals(TEST, 1) {
|
||||
HEADERS += clangstaticanalyzerunittests.h
|
||||
SOURCES += clangstaticanalyzerunittests.cpp
|
||||
RESOURCES += clangstaticanalyzerunittests.qrc
|
||||
}
|
||||
|
||||
DISTFILES += \
|
||||
tests/tests.pri
|
||||
|
@@ -44,4 +44,15 @@ QtcPlugin {
|
||||
"clangstaticanalyzerutils.h",
|
||||
"clangstaticanalyzer_global.h",
|
||||
]
|
||||
|
||||
Group {
|
||||
name: "Unit tests"
|
||||
condition: project.testsEnabled
|
||||
files: [
|
||||
"clangstaticanalyzerunittests.cpp",
|
||||
"clangstaticanalyzerunittests.h",
|
||||
"clangstaticanalyzerunittests.qrc",
|
||||
"unit-tests/**/*",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@ public:
|
||||
ClangStaticAnalyzerDiagnosticModel(QObject *parent = 0);
|
||||
|
||||
void addDiagnostics(const QList<Diagnostic> &diagnostics);
|
||||
QList<Diagnostic> diagnostics() const { return m_diagnostics; }
|
||||
void clear();
|
||||
|
||||
// QAbstractListModel interface
|
||||
|
@@ -22,6 +22,10 @@
|
||||
#include "clangstaticanalyzerruncontrolfactory.h"
|
||||
#include "clangstaticanalyzertool.h"
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
#include "clangstaticanalyzerunittests.h"
|
||||
#endif
|
||||
|
||||
#include <analyzerbase/analyzermanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
@@ -156,5 +160,14 @@ ExtensionSystem::IPlugin::ShutdownFlag ClangStaticAnalyzerPlugin::aboutToShutdow
|
||||
return SynchronousShutdown;
|
||||
}
|
||||
|
||||
QList<QObject *> ClangStaticAnalyzerPlugin::createTestObjects() const
|
||||
{
|
||||
QList<QObject *> tests;
|
||||
#ifdef WITH_TESTS
|
||||
tests << new ClangStaticAnalyzerUnitTests(m_analyzerTool);
|
||||
#endif
|
||||
return tests;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangStaticAnalyzerPlugin
|
||||
|
@@ -42,6 +42,8 @@ public:
|
||||
ShutdownFlag aboutToShutdown();
|
||||
|
||||
private:
|
||||
QList<QObject *> createTestObjects() const override;
|
||||
|
||||
ClangStaticAnalyzerTool *m_analyzerTool;
|
||||
};
|
||||
|
||||
|
@@ -54,6 +54,7 @@ ClangStaticAnalyzerTool::ClangStaticAnalyzerTool(QObject *parent)
|
||||
, m_diagnosticView(0)
|
||||
, m_goBack(0)
|
||||
, m_goNext(0)
|
||||
, m_running(false)
|
||||
{
|
||||
setObjectName(QLatin1String("ClangStaticAnalyzerTool"));
|
||||
setRunMode(ProjectExplorer::ClangStaticAnalyzerMode);
|
||||
@@ -206,6 +207,7 @@ void ClangStaticAnalyzerTool::startTool(StartMode mode)
|
||||
QTC_ASSERT(project, return);
|
||||
m_projectInfoBeforeBuild = CppTools::CppModelManager::instance()->projectInfo(project);
|
||||
QTC_ASSERT(m_projectInfoBeforeBuild.isValid(), return);
|
||||
m_running = true;
|
||||
ProjectExplorerPlugin::instance()->runProject(project, runMode());
|
||||
}
|
||||
|
||||
@@ -220,6 +222,11 @@ void ClangStaticAnalyzerTool::resetCursorAndProjectInfoBeforeBuild()
|
||||
m_projectInfoBeforeBuild = CppTools::ProjectInfo();
|
||||
}
|
||||
|
||||
QList<Diagnostic> ClangStaticAnalyzerTool::diagnostics() const
|
||||
{
|
||||
return m_diagnosticModel->diagnostics();
|
||||
}
|
||||
|
||||
void ClangStaticAnalyzerTool::onEngineIsStarting()
|
||||
{
|
||||
QTC_ASSERT(m_diagnosticModel, return);
|
||||
@@ -246,6 +253,8 @@ void ClangStaticAnalyzerTool::onEngineFinished()
|
||||
AnalyzerManager::showStatusMessage(issuesFound > 0
|
||||
? AnalyzerManager::tr("Clang Static Analyzer finished, %n issues were found.", 0, issuesFound)
|
||||
: AnalyzerManager::tr("Clang Static Analyzer finished, no issues were found."));
|
||||
m_running = false;
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void ClangStaticAnalyzerTool::setBusyCursor(bool busy)
|
||||
|
@@ -40,6 +40,13 @@ public:
|
||||
CppTools::ProjectInfo projectInfoBeforeBuild() const;
|
||||
void resetCursorAndProjectInfoBeforeBuild();
|
||||
|
||||
// For testing.
|
||||
bool isRunning() const { return m_running; }
|
||||
QList<Diagnostic> diagnostics() const;
|
||||
|
||||
signals:
|
||||
void finished(); // For testing.
|
||||
|
||||
private:
|
||||
QWidget *createWidgets();
|
||||
Analyzer::AnalyzerRunControl *createRunControl(const Analyzer::AnalyzerStartParameters &sp,
|
||||
@@ -60,6 +67,7 @@ private:
|
||||
|
||||
QAction *m_goBack;
|
||||
QAction *m_goNext;
|
||||
bool m_running;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
104
plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
Normal file
104
plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc
|
||||
** All rights reserved.
|
||||
** For any questions to Digia, please use contact form at http://qt.digia.com <http://qt.digia.com/>
|
||||
**
|
||||
** This file is part of the Qt Enterprise Qt Quick Profiler Add-on.
|
||||
**
|
||||
** Licensees holding valid Qt Enterprise licenses may use this file in
|
||||
** accordance with the Qt Enterprise License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://qt.digia.com <http://qt.digia.com/>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clangstaticanalyzerunittests.h"
|
||||
|
||||
#include "clangstaticanalyzerdiagnostic.h"
|
||||
#include "clangstaticanalyzertool.h"
|
||||
#include "clangstaticanalyzerutils.h"
|
||||
|
||||
#include <analyzerbase/analyzermanager.h>
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/cpptoolstestcase.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/kitmanager.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QSignalSpy>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTimer>
|
||||
#include <QtTest>
|
||||
|
||||
using namespace Analyzer;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace ClangStaticAnalyzer {
|
||||
namespace Internal {
|
||||
|
||||
ClangStaticAnalyzerUnitTests::ClangStaticAnalyzerUnitTests(ClangStaticAnalyzerTool *analyzerTool,
|
||||
QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_analyzerTool(analyzerTool)
|
||||
, m_tmpDir(0)
|
||||
{
|
||||
}
|
||||
|
||||
void ClangStaticAnalyzerUnitTests::initTestCase()
|
||||
{
|
||||
const QList<Kit *> allKits = KitManager::kits();
|
||||
if (allKits.count() != 1)
|
||||
QSKIP("This test requires exactly one kit to be present");
|
||||
const ToolChain * const toolchain = ToolChainKitInformation::toolChain(allKits.first());
|
||||
if (!toolchain)
|
||||
QSKIP("This test requires that there is a kit with a toolchain.");
|
||||
bool hasClangExecutable;
|
||||
clangExecutableFromSettings(toolchain->type(), &hasClangExecutable);
|
||||
if (!hasClangExecutable)
|
||||
QSKIP("No clang suitable for analyzing found");
|
||||
|
||||
m_tmpDir = new CppTools::Tests::TemporaryCopiedDir(QLatin1String(":/unit-tests"));
|
||||
}
|
||||
|
||||
void ClangStaticAnalyzerUnitTests::cleanupTestCase()
|
||||
{
|
||||
delete m_tmpDir;
|
||||
}
|
||||
|
||||
void ClangStaticAnalyzerUnitTests::testProject()
|
||||
{
|
||||
QFETCH(QString, projectFilePath);
|
||||
QFETCH(int, expectedDiagCount);
|
||||
|
||||
CppTools::Tests::ProjectOpenerAndCloser projectManager;
|
||||
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
|
||||
QVERIFY(projectInfo.isValid());
|
||||
AnalyzerManager::selectTool(m_analyzerTool, Analyzer::StartLocal);
|
||||
AnalyzerManager::startTool();
|
||||
if (m_analyzerTool->isRunning()) {
|
||||
QSignalSpy waiter(m_analyzerTool, SIGNAL(finished()));
|
||||
QVERIFY(waiter.wait(30000));
|
||||
}
|
||||
QCOMPARE(m_analyzerTool->diagnostics().count(), expectedDiagCount);
|
||||
}
|
||||
|
||||
void ClangStaticAnalyzerUnitTests::testProject_data()
|
||||
{
|
||||
QTest::addColumn<QString>("projectFilePath");
|
||||
QTest::addColumn<int>("expectedDiagCount");
|
||||
QTest::newRow("qbs project")
|
||||
<< QString(m_tmpDir->path() + QLatin1String("/simple/simple.qbs")) << 1;
|
||||
QTest::newRow("qbs project")
|
||||
<< QString(m_tmpDir->path() + QLatin1String("/simple/simple.pro")) << 1;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangStaticAnalyzerPlugin
|
53
plugins/clangstaticanalyzer/clangstaticanalyzerunittests.h
Normal file
53
plugins/clangstaticanalyzer/clangstaticanalyzerunittests.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc
|
||||
** All rights reserved.
|
||||
** For any questions to Digia, please use contact form at http://qt.digia.com <http://qt.digia.com/>
|
||||
**
|
||||
** This file is part of the Qt Enterprise Qt Quick Profiler Add-on.
|
||||
**
|
||||
** Licensees holding valid Qt Enterprise licenses may use this file in
|
||||
** accordance with the Qt Enterprise License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://qt.digia.com <http://qt.digia.com/>
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CLANGSTATICANALYZERUNITTESTS_H
|
||||
#define CLANGSTATICANALYZERUNITTESTS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
namespace CppTools { namespace Tests { class TemporaryCopiedDir; } }
|
||||
|
||||
namespace ClangStaticAnalyzer {
|
||||
namespace Internal {
|
||||
class ClangStaticAnalyzerTool;
|
||||
|
||||
class ClangStaticAnalyzerUnitTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClangStaticAnalyzerUnitTests(ClangStaticAnalyzerTool *analyzerTool, QObject *parent = 0);
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void testProject();
|
||||
void testProject_data();
|
||||
|
||||
private:
|
||||
ClangStaticAnalyzerTool * const m_analyzerTool;
|
||||
CppTools::Tests::TemporaryCopiedDir *m_tmpDir;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangStaticAnalyzerPlugin
|
||||
|
||||
#endif // Include guard
|
||||
|
@@ -0,0 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>unit-tests/simple/main.cpp</file>
|
||||
<file>unit-tests/simple/simple.qbs</file>
|
||||
<file>unit-tests/simple/simple.pro</file>
|
||||
</qresource>
|
||||
</RCC>
|
5
plugins/clangstaticanalyzer/unit-tests/simple/main.cpp
Normal file
5
plugins/clangstaticanalyzer/unit-tests/simple/main.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
int main()
|
||||
{
|
||||
int *i = 0;
|
||||
*i = 42;
|
||||
}
|
3
plugins/clangstaticanalyzer/unit-tests/simple/simple.pro
Normal file
3
plugins/clangstaticanalyzer/unit-tests/simple/simple.pro
Normal file
@@ -0,0 +1,3 @@
|
||||
CONFIG -= QT
|
||||
|
||||
SOURCES = main.cpp
|
5
plugins/clangstaticanalyzer/unit-tests/simple/simple.qbs
Normal file
5
plugins/clangstaticanalyzer/unit-tests/simple/simple.qbs
Normal file
@@ -0,0 +1,5 @@
|
||||
import qbs
|
||||
|
||||
CppApplication {
|
||||
files: ["main.cpp"]
|
||||
}
|
Reference in New Issue
Block a user