Files
qt-creator/tests/unit/unittest/cppprojectinfogenerator-test.cpp
Nikolai Kosjar 5900766ecb Toolchains: Detect unspecified language version
We checked the command line from the project manager for "-std=X" and
friends to figure out the language version to use. However, if such a
flag was not provided, we assumed the latest version we support. This
could conflict with the actual version of the compiler and its
predefined macros.

Figure out the version by inspecting __cplusplus/__STDC_VERSION__ in the
predefined macros of the toolchain. The MSVC compiler is an exception to
this, as it does not seem to properly set the value - check for
_MSVC_LANG if possible, otherwise simply assume some versions as before.

While at it, add also support for C17/C18 and the upcoming C++2a.

Task-number: QTCREATORBUG-20884
Task-number: QTCREATORBUG-21188
Change-Id: I464ffcd52d2120c0208275a050e82efda44fae1c
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
2018-10-08 09:07:56 +00:00

175 lines
5.8 KiB
C++

/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** 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.
**
** 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.
**
****************************************************************************/
#include "googletest.h"
#include "gtest-qt-printing.h"
#include "mimedatabase-utilities.h"
#include <cpptools/cppprojectinfogenerator.h>
#include <cpptools/projectinfo.h>
#include <utils/mimetypes/mimedatabase.h>
using CppTools::Internal::ProjectInfoGenerator;
using CppTools::ProjectFile;
using CppTools::ProjectInfo;
using CppTools::ProjectUpdateInfo;
using CppTools::ProjectPart;
using CppTools::RawProjectPart;
using ProjectExplorer::Macros;
using ProjectExplorer::ToolChain;
using testing::Eq;
using testing::UnorderedElementsAre;
using testing::PrintToString;
namespace {
MATCHER_P2(IsProjectPart, languageVersion, fileKind,
std::string(negation ? "isn't" : "is")
+ " project part with language version " + PrintToString(languageVersion)
+ " and file kind " + PrintToString(fileKind))
{
const ProjectPart::Ptr &projectPart = arg;
return projectPart->languageVersion == languageVersion
&& projectPart->files.at(0).kind == fileKind;
}
class ProjectInfoGenerator : public ::testing::Test
{
protected:
void SetUp() override;
ProjectInfo generate();
protected:
ProjectUpdateInfo projectUpdateInfo;
RawProjectPart rawProjectPart;
};
TEST_F(ProjectInfoGenerator, CreateNoProjectPartsForEmptyFileList)
{
const ProjectInfo projectInfo = generate();
ASSERT_TRUE(projectInfo.projectParts().isEmpty());
}
TEST_F(ProjectInfoGenerator, CreateSingleProjectPart)
{
rawProjectPart.files = QStringList{ "foo.cpp", "foo.h"};
const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
}
TEST_F(ProjectInfoGenerator, CreateMultipleProjectParts)
{
rawProjectPart.files = QStringList{ "foo.cpp", "foo.h", "bar.c", "bar.h" };
const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts().size(), Eq(2));
}
TEST_F(ProjectInfoGenerator, ProjectPartIndicatesObjectiveCExtensionsByDefault)
{
rawProjectPart.files = QStringList{ "foo.mm" };
const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
ASSERT_TRUE(projectPart.languageExtensions & ProjectPart::ObjectiveCExtensions);
}
TEST_F(ProjectInfoGenerator, ProjectPartHasLatestLanguageVersionByDefault)
{
rawProjectPart.files = QStringList{ "foo.cpp" };
const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::LatestCxxVersion));
}
TEST_F(ProjectInfoGenerator, UseMacroInspectionReportForLanguageVersion)
{
projectUpdateInfo.cxxToolChainInfo.macroInspectionRunner = [](const QStringList &) {
return ToolChain::MacroInspectionReport{Macros(), ToolChain::LanguageVersion::CXX17};
};
rawProjectPart.files = QStringList{ "foo.cpp" };
const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::CXX17));
}
TEST_F(ProjectInfoGenerator, UseCompilerFlagsForLanguageExtensions)
{
rawProjectPart.files = QStringList{ "foo.cpp" };
rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::MicrosoftExtensions;
const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
ASSERT_TRUE(projectPart.languageExtensions & ProjectPart::MicrosoftExtensions);
}
TEST_F(ProjectInfoGenerator, ProjectFileKindsMatchProjectPartVersion)
{
rawProjectPart.files = QStringList{ "foo.h" };
const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts(),
UnorderedElementsAre(IsProjectPart(ProjectPart::LatestCVersion, ProjectFile::CHeader),
IsProjectPart(ProjectPart::LatestCVersion, ProjectFile::ObjCHeader),
IsProjectPart(ProjectPart::LatestCxxVersion, ProjectFile::CXXHeader),
IsProjectPart(ProjectPart::LatestCxxVersion, ProjectFile::ObjCXXHeader)));
}
void ProjectInfoGenerator::SetUp()
{
ASSERT_TRUE(MimeDataBaseUtilities::addCppToolsMimeTypes());
}
ProjectInfo ProjectInfoGenerator::generate()
{
QFutureInterface<void> fi;
projectUpdateInfo.rawProjectParts += rawProjectPart;
::ProjectInfoGenerator generator(fi, projectUpdateInfo);
return generator.generate();
}
} // anonymous namespace