summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@theqtcompany.com>2015-02-04 15:19:30 +0100
committerChristian Kandeler <christian.kandeler@theqtcompany.com>2015-02-09 16:48:26 +0200
commit2946364ce6ad760f732d1042e3206a0fe0a456d6 (patch)
treedab96a6e578d00d1a749a332cc2bdad7e208687c
parentc632be5c924bbef9619e79af645edadca88e0b94 (diff)
downloadqt-creator-2946364ce6ad760f732d1042e3206a0fe0a456d6.tar.gz
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>
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzer.pro6
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzer.qbs11
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h1
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp13
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzerplugin.h2
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp9
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzertool.h8
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp104
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzerunittests.h53
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzerunittests.qrc7
-rw-r--r--plugins/clangstaticanalyzer/unit-tests/simple/main.cpp5
-rw-r--r--plugins/clangstaticanalyzer/unit-tests/simple/simple.pro3
-rw-r--r--plugins/clangstaticanalyzer/unit-tests/simple/simple.qbs5
13 files changed, 227 insertions, 0 deletions
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzer.pro b/plugins/clangstaticanalyzer/clangstaticanalyzer.pro
index 5c7e91c599..df939e9f36 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzer.pro
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzer.pro
@@ -37,5 +37,11 @@ HEADERS += \
FORMS += \
clangstaticanalyzerconfigwidget.ui
+equals(TEST, 1) {
+ HEADERS += clangstaticanalyzerunittests.h
+ SOURCES += clangstaticanalyzerunittests.cpp
+ RESOURCES += clangstaticanalyzerunittests.qrc
+}
+
DISTFILES += \
tests/tests.pri
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs b/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs
index 6c2612a69c..78c7decc5d 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs
@@ -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/**/*",
+ ]
+ }
}
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h
index beccf89a84..d3af814982 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h
@@ -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
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp
index e635305b97..943d7ac7e5 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp
@@ -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
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.h b/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.h
index d96611a16f..c0a6a247fb 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.h
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.h
@@ -42,6 +42,8 @@ public:
ShutdownFlag aboutToShutdown();
private:
+ QList<QObject *> createTestObjects() const override;
+
ClangStaticAnalyzerTool *m_analyzerTool;
};
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
index ffec5af1a7..93579781a0 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
@@ -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)
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.h b/plugins/clangstaticanalyzer/clangstaticanalyzertool.h
index 8f3bb1f196..4b61ae0fda 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.h
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.h
@@ -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
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
new file mode 100644
index 0000000000..82c5ac1b29
--- /dev/null
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
@@ -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
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.h b/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.h
new file mode 100644
index 0000000000..bbf9cc88f6
--- /dev/null
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.h
@@ -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
+
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.qrc b/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.qrc
new file mode 100644
index 0000000000..0de4936d20
--- /dev/null
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.qrc
@@ -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>
diff --git a/plugins/clangstaticanalyzer/unit-tests/simple/main.cpp b/plugins/clangstaticanalyzer/unit-tests/simple/main.cpp
new file mode 100644
index 0000000000..af917a3a33
--- /dev/null
+++ b/plugins/clangstaticanalyzer/unit-tests/simple/main.cpp
@@ -0,0 +1,5 @@
+int main()
+{
+ int *i = 0;
+ *i = 42;
+}
diff --git a/plugins/clangstaticanalyzer/unit-tests/simple/simple.pro b/plugins/clangstaticanalyzer/unit-tests/simple/simple.pro
new file mode 100644
index 0000000000..fb560c2af6
--- /dev/null
+++ b/plugins/clangstaticanalyzer/unit-tests/simple/simple.pro
@@ -0,0 +1,3 @@
+CONFIG -= QT
+
+SOURCES = main.cpp
diff --git a/plugins/clangstaticanalyzer/unit-tests/simple/simple.qbs b/plugins/clangstaticanalyzer/unit-tests/simple/simple.qbs
new file mode 100644
index 0000000000..f6ae698a0c
--- /dev/null
+++ b/plugins/clangstaticanalyzer/unit-tests/simple/simple.qbs
@@ -0,0 +1,5 @@
+import qbs
+
+CppApplication {
+ files: ["main.cpp"]
+}