teak-llvm/clang-tools-extra/unittests/clang-tidy/LLVMModuleTest.cpp
Benjamin Kramer 498cce575f [clang-tidy] Add a generic header guard checker + LLVM implementation.
The implementation is split into a generic part and a LLVM-specific part.
Other codebases can implement it with their own style. The specific features
supported are:

- Verification (and fixing) of header guards against a style based on the file path
- Automatic insertion of header guards for headers that are missing them
- A warning when the header guard doesn't enable our fancy header guard optimization
(e.g. when there's an include preceeding the guard)
- Automatic insertion of a comment with the guard name after #endif.

For the LLVM style we disable #endif comments for now, they're not very common
in the codebase. We also only flag headers in the include directories, there
doesn't seem to be a common style outside.

Differential Revision: http://reviews.llvm.org/D4867

llvm-svn: 215548
2014-08-13 13:57:57 +00:00

132 lines
5.5 KiB
C++

#include "ClangTidyTest.h"
#include "llvm/HeaderGuardCheck.h"
#include "llvm/IncludeOrderCheck.h"
#include "llvm/NamespaceCommentCheck.h"
#include "gtest/gtest.h"
namespace clang {
namespace tidy {
namespace test {
TEST(NamespaceCommentCheckTest, Basic) {
EXPECT_EQ("namespace i {\n} // namespace i",
runCheckOnCode<NamespaceCommentCheck>("namespace i {\n}"));
EXPECT_EQ("namespace {\n} // namespace",
runCheckOnCode<NamespaceCommentCheck>("namespace {\n}"));
EXPECT_EQ(
"namespace i { namespace j {\n} // namespace j\n } // namespace i",
runCheckOnCode<NamespaceCommentCheck>("namespace i { namespace j {\n} }"));
}
TEST(NamespaceCommentCheckTest, SingleLineNamespaces) {
EXPECT_EQ(
"namespace i { namespace j { } }",
runCheckOnCode<NamespaceCommentCheck>("namespace i { namespace j { } }"));
}
TEST(NamespaceCommentCheckTest, CheckExistingComments) {
EXPECT_EQ("namespace i { namespace j {\n"
"} /* namespace j */ } // namespace i\n"
" /* random comment */",
runCheckOnCode<NamespaceCommentCheck>(
"namespace i { namespace j {\n"
"} /* namespace j */ } /* random comment */"));
EXPECT_EQ("namespace {\n"
"} // namespace",
runCheckOnCode<NamespaceCommentCheck>("namespace {\n"
"} // namespace"));
EXPECT_EQ("namespace {\n"
"} //namespace",
runCheckOnCode<NamespaceCommentCheck>("namespace {\n"
"} //namespace"));
EXPECT_EQ("namespace {\n"
"} // anonymous namespace",
runCheckOnCode<NamespaceCommentCheck>("namespace {\n"
"} // anonymous namespace"));
EXPECT_EQ(
"namespace My_NameSpace123 {\n"
"} // namespace My_NameSpace123",
runCheckOnCode<NamespaceCommentCheck>("namespace My_NameSpace123 {\n"
"} // namespace My_NameSpace123"));
EXPECT_EQ(
"namespace My_NameSpace123 {\n"
"} //namespace My_NameSpace123",
runCheckOnCode<NamespaceCommentCheck>("namespace My_NameSpace123 {\n"
"} //namespace My_NameSpace123"));
EXPECT_EQ("namespace My_NameSpace123 {\n"
"} // end namespace My_NameSpace123",
runCheckOnCode<NamespaceCommentCheck>(
"namespace My_NameSpace123 {\n"
"} // end namespace My_NameSpace123"));
// Understand comments only on the same line.
EXPECT_EQ("namespace {\n"
"} // namespace\n"
"// namespace",
runCheckOnCode<NamespaceCommentCheck>("namespace {\n"
"}\n"
"// namespace"));
// Leave unknown comments.
EXPECT_EQ("namespace {\n"
"} // namespace // random text",
runCheckOnCode<NamespaceCommentCheck>("namespace {\n"
"} // random text"));
}
TEST(NamespaceCommentCheckTest, FixWrongComments) {
EXPECT_EQ("namespace i { namespace jJ0_ {\n"
"} // namespace jJ0_\n"
" } // namespace i\n"
" /* random comment */",
runCheckOnCode<NamespaceCommentCheck>(
"namespace i { namespace jJ0_ {\n"
"} /* namespace qqq */ } /* random comment */"));
EXPECT_EQ("namespace {\n"
"} // namespace",
runCheckOnCode<NamespaceCommentCheck>("namespace {\n"
"} // namespace asdf"));
}
static std::string runHeaderGuardCheck(StringRef Code, const Twine &Filename) {
return test::runCheckOnCode<LLVMHeaderGuardCheck>(
Code, /*Errors=*/nullptr, Filename, std::string("-xc++-header"));
}
TEST(LLVMHeaderGuardCheckTest, FixHeaderGuards) {
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n#define LLVM_ADT_FOO_H\n#endif\n",
runHeaderGuardCheck("#ifndef FOO\n#define FOO\n#endif\n",
"include/llvm/ADT/foo.h"));
// Allow trailing underscores.
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H_\n#define LLVM_ADT_FOO_H_\n#endif\n",
runHeaderGuardCheck(
"#ifndef LLVM_ADT_FOO_H_\n#define LLVM_ADT_FOO_H_\n#endif\n",
"include/llvm/ADT/foo.h"));
EXPECT_EQ("#ifndef LLVM_CLANG_C_BAR_H\n#define LLVM_CLANG_C_BAR_H\n\n\n#endif\n",
runHeaderGuardCheck("", "./include/clang-c/bar.h"));
EXPECT_EQ("#ifndef LLVM_CLANG_LIB_CODEGEN_C_H\n#define "
"LLVM_CLANG_LIB_CODEGEN_C_H\n\n\n#endif\n",
runHeaderGuardCheck("", "tools/clang/lib/CodeGen/c.h"));
EXPECT_EQ("#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_X_H\n#define "
"LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_X_H\n\n\n#endif\n",
runHeaderGuardCheck("", "tools/clang/tools/extra/clang-tidy/x.h"));
EXPECT_EQ(
"int foo;\n#ifndef LLVM_CLANG_BAR_H\n#define LLVM_CLANG_BAR_H\n#endif\n",
runHeaderGuardCheck("int foo;\n#ifndef LLVM_CLANG_BAR_H\n"
"#define LLVM_CLANG_BAR_H\n#endif\n",
"include/clang/bar.h"));
EXPECT_EQ("#ifndef LLVM_CLANG_BAR_H\n#define LLVM_CLANG_BAR_H\n\n"
"int foo;\n#ifndef FOOLOLO\n#define FOOLOLO\n#endif\n\n#endif\n",
runHeaderGuardCheck(
"int foo;\n#ifndef FOOLOLO\n#define FOOLOLO\n#endif\n",
"include/clang/bar.h"));
}
} // namespace test
} // namespace tidy
} // namespace clang