| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | /****************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2016-01-14 10:59:10 +01:00
										 |  |  | ** Copyright (C) 2016 The Qt Company Ltd. | 
					
						
							|  |  |  | ** Contact: https://www.qt.io/licensing/
 | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2016-01-14 10:59:10 +01:00
										 |  |  | ** This file is part of Qt Creator. | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2016-01-14 10:59:10 +01:00
										 |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							| 
									
										
										
										
											2016-01-14 10:59:10 +01:00
										 |  |  | ** a written agreement between you and The Qt Company. For licensing terms | 
					
						
							|  |  |  | ** and conditions see https://www.qt.io/terms-conditions. For further
 | 
					
						
							|  |  |  | ** information use the contact form at https://www.qt.io/contact-us.
 | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2016-01-14 10:59:10 +01:00
										 |  |  | ** GNU General Public License Usage | 
					
						
							|  |  |  | ** Alternatively, this file may be used under the terms of the GNU | 
					
						
							|  |  |  | ** General Public License version 3 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
					
						
							|  |  |  | ** included in the packaging of this file. Please review the following | 
					
						
							|  |  |  | ** information to ensure the GNU General Public License requirements will | 
					
						
							|  |  |  | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
 | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | ****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-24 15:30:19 +02:00
										 |  |  | #include "clangtoolsunittests.h"
 | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 15:08:30 +01:00
										 |  |  | #include "clangtoolsdiagnostic.h"
 | 
					
						
							| 
									
										
										
										
											2018-04-24 15:30:19 +02:00
										 |  |  | #include "clangtidyclazytool.h"
 | 
					
						
							| 
									
										
										
										
											2018-01-17 15:08:30 +01:00
										 |  |  | #include "clangtoolsutils.h"
 | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-06 11:32:32 +02:00
										 |  |  | #include <coreplugin/icore.h>
 | 
					
						
							| 
									
										
										
										
											2018-04-24 17:34:21 +02:00
										 |  |  | #include <cpptools/cppcodemodelsettings.h>
 | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | #include <cpptools/cppmodelmanager.h>
 | 
					
						
							|  |  |  | #include <cpptools/cpptoolstestcase.h>
 | 
					
						
							| 
									
										
										
										
											2018-04-24 17:34:21 +02:00
										 |  |  | #include <cpptools/cpptoolsreuse.h>
 | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | #include <projectexplorer/kitinformation.h>
 | 
					
						
							|  |  |  | #include <projectexplorer/kitmanager.h>
 | 
					
						
							|  |  |  | #include <projectexplorer/projectexplorer.h>
 | 
					
						
							|  |  |  | #include <projectexplorer/toolchain.h>
 | 
					
						
							| 
									
										
										
										
											2018-04-24 17:34:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <utils/executeondestruction.h>
 | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | #include <utils/fileutils.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QEventLoop>
 | 
					
						
							|  |  |  | #include <QSignalSpy>
 | 
					
						
							|  |  |  | #include <QTimer>
 | 
					
						
							|  |  |  | #include <QtTest>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace ProjectExplorer; | 
					
						
							|  |  |  | using namespace Utils; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 12:58:12 +01:00
										 |  |  | namespace ClangTools { | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | namespace Internal { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-24 15:30:19 +02:00
										 |  |  | void ClangToolsUnitTests::initTestCase() | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     const QList<Kit *> allKits = KitManager::kits(); | 
					
						
							|  |  |  |     if (allKits.count() != 1) | 
					
						
							|  |  |  |         QSKIP("This test requires exactly one kit to be present"); | 
					
						
							| 
									
										
										
										
											2019-02-06 12:50:51 +01:00
										 |  |  |     const ToolChain * const toolchain = ToolChainKitAspect::toolChain(allKits.first(), | 
					
						
							| 
									
										
										
										
											2016-12-16 00:43:14 +01:00
										 |  |  |                                                                            Constants::CXX_LANGUAGE_ID); | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  |     if (!toolchain) | 
					
						
							|  |  |  |         QSKIP("This test requires that there is a kit with a toolchain."); | 
					
						
							| 
									
										
										
										
											2018-04-30 15:26:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-06 11:32:32 +02:00
										 |  |  |     if (Core::ICore::clangExecutable(CLANG_BINDIR).isEmpty()) | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  |         QSKIP("No clang suitable for analyzing found"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_tmpDir = new CppTools::Tests::TemporaryCopiedDir(QLatin1String(":/unit-tests")); | 
					
						
							| 
									
										
										
										
											2015-05-18 11:32:43 +02:00
										 |  |  |     QVERIFY(m_tmpDir->isValid()); | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-24 15:30:19 +02:00
										 |  |  | void ClangToolsUnitTests::cleanupTestCase() | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     delete m_tmpDir; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-24 17:34:21 +02:00
										 |  |  | static CppTools::ClangDiagnosticConfig createTidyClazyConfig() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CppTools::ClangDiagnosticConfig config; | 
					
						
							|  |  |  |     config.setId("Test.ClangTidy"); | 
					
						
							|  |  |  |     config.setDisplayName("Test"); | 
					
						
							|  |  |  |     config.setIsReadOnly(true); | 
					
						
							|  |  |  |     config.setClangOptions(QStringList{QStringLiteral("-Wno-everything")}); | 
					
						
							| 
									
										
										
										
											2018-05-16 07:58:53 +02:00
										 |  |  |     config.setClangTidyMode(CppTools::ClangDiagnosticConfig::TidyMode::ChecksPrefixList); | 
					
						
							|  |  |  |     config.setClangTidyChecks("modernize-*, misc-*"); | 
					
						
							| 
									
										
										
										
											2018-04-24 17:34:21 +02:00
										 |  |  |     config.setClazyChecks("level2"); | 
					
						
							|  |  |  |     return config; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-24 15:30:19 +02:00
										 |  |  | void ClangToolsUnitTests::testProject() | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QFETCH(QString, projectFilePath); | 
					
						
							|  |  |  |     QFETCH(int, expectedDiagCount); | 
					
						
							| 
									
										
										
										
											2017-08-17 09:40:02 +02:00
										 |  |  |     if (projectFilePath.contains("mingw")) { | 
					
						
							|  |  |  |         const ToolChain * const toolchain | 
					
						
							| 
									
										
										
										
											2019-02-06 12:50:51 +01:00
										 |  |  |                 = ToolChainKitAspect::toolChain(KitManager::kits().constFirst(), | 
					
						
							|  |  |  |                                                 Constants::CXX_LANGUAGE_ID); | 
					
						
							| 
									
										
										
										
											2017-08-17 09:40:02 +02:00
										 |  |  |         if (toolchain->typeId() != ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) | 
					
						
							| 
									
										
										
										
											2018-05-02 12:27:35 +02:00
										 |  |  |             QSKIP("This test is mingw specific, does not run for other toolchains"); | 
					
						
							| 
									
										
										
										
											2017-08-17 09:40:02 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     CppTools::Tests::ProjectOpenerAndCloser projectManager; | 
					
						
							|  |  |  |     const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true); | 
					
						
							|  |  |  |     QVERIFY(projectInfo.isValid()); | 
					
						
							| 
									
										
										
										
											2018-05-09 09:22:01 +02:00
										 |  |  |     ClangTool *tool = ClangTidyClazyTool::instance(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Change configs
 | 
					
						
							|  |  |  |     QSharedPointer<CppTools::CppCodeModelSettings> settings = CppTools::codeModelSettings(); | 
					
						
							|  |  |  |     const CppTools::ClangDiagnosticConfigs originalConfigs = settings->clangCustomDiagnosticConfigs(); | 
					
						
							|  |  |  |     const Core::Id originalId = settings->clangDiagnosticConfigId(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CppTools::ClangDiagnosticConfigs modifiedConfigs = originalConfigs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const CppTools::ClangDiagnosticConfig clangTidyConfig = createTidyClazyConfig(); | 
					
						
							|  |  |  |     modifiedConfigs.push_back(clangTidyConfig); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ExecuteOnDestruction executeOnDestruction([=]() { | 
					
						
							|  |  |  |         // Restore configs
 | 
					
						
							|  |  |  |         settings->setClangCustomDiagnosticConfigs(originalConfigs); | 
					
						
							|  |  |  |         settings->setClangDiagnosticConfigId(originalId); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     settings->setClangCustomDiagnosticConfigs(modifiedConfigs); | 
					
						
							|  |  |  |     settings->setClangDiagnosticConfigId(clangTidyConfig.id()); | 
					
						
							| 
									
										
										
										
											2018-04-24 17:34:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 14:51:05 +02:00
										 |  |  |     tool->startTool(false); | 
					
						
							| 
									
										
										
										
											2017-05-08 09:21:48 +02:00
										 |  |  |     QSignalSpy waiter(tool, SIGNAL(finished(bool))); | 
					
						
							| 
									
										
										
										
											2015-05-04 14:57:03 +02:00
										 |  |  |     QVERIFY(waiter.wait(30000)); | 
					
						
							| 
									
										
										
										
											2018-04-24 17:34:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-04 14:57:03 +02:00
										 |  |  |     const QList<QVariant> arguments = waiter.takeFirst(); | 
					
						
							|  |  |  |     QVERIFY(arguments.first().toBool()); | 
					
						
							| 
									
										
										
										
											2017-05-08 09:21:48 +02:00
										 |  |  |     QCOMPARE(tool->diagnostics().count(), expectedDiagCount); | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-24 15:30:19 +02:00
										 |  |  | void ClangToolsUnitTests::testProject_data() | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QTest::addColumn<QString>("projectFilePath"); | 
					
						
							|  |  |  |     QTest::addColumn<int>("expectedDiagCount"); | 
					
						
							| 
									
										
										
										
											2015-04-15 18:24:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-05 10:26:35 +01:00
										 |  |  |     // For the simple project, we expect the following warning:
 | 
					
						
							|  |  |  |     //   warning: use nullptr [modernize-use-nullptr]
 | 
					
						
							| 
									
										
										
										
											2018-05-09 09:22:01 +02:00
										 |  |  |     addTestRow("simple/simple.qbs", 1); | 
					
						
							|  |  |  |     addTestRow("simple/simple.pro", 1); | 
					
						
							| 
									
										
										
										
											2016-07-08 15:30:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 09:22:01 +02:00
										 |  |  |     addTestRow("simple-library/simple-library.qbs", 0); | 
					
						
							|  |  |  |     addTestRow("simple-library/simple-library.pro", 0); | 
					
						
							| 
									
										
										
										
											2016-07-08 15:30:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 09:22:01 +02:00
										 |  |  |     addTestRow("stdc++11-includes/stdc++11-includes.qbs", 0); | 
					
						
							|  |  |  |     addTestRow("stdc++11-includes/stdc++11-includes.pro", 0); | 
					
						
							| 
									
										
										
										
											2016-07-08 15:30:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-05 10:26:35 +01:00
										 |  |  |     // For qt-widgets-app, we expect the following warning for "a.exec()",
 | 
					
						
							|  |  |  |     // "a" being the QApplication object:
 | 
					
						
							|  |  |  |     //   warning: static member accessed through instance
 | 
					
						
							|  |  |  |     //    [readability-static-accessed-through-instance]
 | 
					
						
							|  |  |  |     addTestRow("qt-widgets-app/qt-widgets-app.qbs", 1); | 
					
						
							|  |  |  |     addTestRow("qt-widgets-app/qt-widgets-app.pro", 1); | 
					
						
							| 
									
										
										
										
											2016-07-08 15:30:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 09:22:01 +02:00
										 |  |  |     addTestRow("qt-essential-includes/qt-essential-includes.qbs", 0); | 
					
						
							|  |  |  |     addTestRow("qt-essential-includes/qt-essential-includes.pro", 0); | 
					
						
							| 
									
										
										
										
											2017-08-17 09:40:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 09:22:01 +02:00
										 |  |  |     addTestRow("mingw-includes/mingw-includes.qbs", 0); | 
					
						
							|  |  |  |     addTestRow("mingw-includes/mingw-includes.pro", 0); | 
					
						
							| 
									
										
										
										
											2018-04-24 17:34:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 09:22:01 +02:00
										 |  |  |     addTestRow("clangtidy_clazy/clangtidy_clazy.pro", | 
					
						
							| 
									
										
										
										
											2018-04-24 17:34:21 +02:00
										 |  |  |                4 /* ClangTidy: modernize-*,misc-* */ | 
					
						
							|  |  |  |                + 2 /* Clazy: level1 */); | 
					
						
							| 
									
										
										
										
											2016-07-08 15:30:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 09:22:01 +02:00
										 |  |  | void ClangToolsUnitTests::addTestRow(const QByteArray &relativeFilePath, | 
					
						
							| 
									
										
										
										
											2018-04-24 15:30:19 +02:00
										 |  |  |                                      int expectedDiagCount) | 
					
						
							| 
									
										
										
										
											2016-07-08 15:30:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     const QString absoluteFilePath = m_tmpDir->absolutePath(relativeFilePath); | 
					
						
							|  |  |  |     const QString fileName = QFileInfo(absoluteFilePath).fileName(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 09:22:01 +02:00
										 |  |  |     QTest::newRow(fileName.toUtf8().constData()) << absoluteFilePath << expectedDiagCount; | 
					
						
							| 
									
										
										
										
											2015-02-04 15:19:30 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace Internal
 | 
					
						
							| 
									
										
										
										
											2018-03-14 12:58:12 +01:00
										 |  |  | } // namespace ClangTools
 |