[clang-tidy] Add check for underscores in googletest names.

Summary: Adds a clang-tidy warning for underscores in googletest names.

Patch by Kar Epker!

Reviewers: hokein, alexfh, aaron.ballman

Reviewed By: hokein

Subscribers: Eugene.Zelenko, JonasToth, MyDeveloperDay, lebedev.ri, xazax.hun, mgorny, cfe-commits

Tags: #clang-tools-extra

Differential Revision: https://reviews.llvm.org/D56424

llvm-svn: 352183
This commit is contained in:
Haojian Wu 2019-01-25 10:03:49 +00:00
parent 914e838e63
commit c67dab5bd0
8 changed files with 278 additions and 0 deletions

View File

@ -0,0 +1,89 @@
//===--- AvoidUnderscoreInGoogletestNameCheck.cpp - clang-tidy --*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <string>
#include "AvoidUnderscoreInGoogletestNameCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/MacroArgs.h"
namespace clang {
namespace tidy {
namespace google {
namespace readability {
constexpr llvm::StringLiteral kDisabledTestPrefix = "DISABLED_";
// Determines whether the macro is a Googletest test macro.
static bool isGoogletestTestMacro(StringRef MacroName) {
static const llvm::StringSet<> MacroNames = {"TEST", "TEST_F", "TEST_P",
"TYPED_TEST", "TYPED_TEST_P"};
return MacroNames.find(MacroName) != MacroNames.end();
}
namespace {
class AvoidUnderscoreInGoogletestNameCallback : public PPCallbacks {
public:
AvoidUnderscoreInGoogletestNameCallback(
Preprocessor *PP, AvoidUnderscoreInGoogletestNameCheck *Check)
: PP(PP), Check(Check) {}
// Detects expansions of the TEST, TEST_F, TEST_P, TYPED_TEST, TYPED_TEST_P
// macros and checks that their arguments do not have any underscores.
void MacroExpands(const Token &MacroNameToken,
const MacroDefinition &MacroDefinition, SourceRange Range,
const MacroArgs *Args) override {
IdentifierInfo *NameIdentifierInfo = MacroNameToken.getIdentifierInfo();
if (!NameIdentifierInfo)
return;
StringRef MacroName = NameIdentifierInfo->getName();
if (!isGoogletestTestMacro(MacroName) || !Args ||
Args->getNumMacroArguments() < 2)
return;
const Token *TestCaseNameToken = Args->getUnexpArgument(0);
const Token *TestNameToken = Args->getUnexpArgument(1);
if (!TestCaseNameToken || !TestNameToken)
return;
std::string TestCaseName = PP->getSpelling(*TestCaseNameToken);
if (TestCaseName.find('_') != std::string::npos)
Check->diag(TestCaseNameToken->getLocation(),
"avoid using \"_\" in test case name \"%0\" according to "
"Googletest FAQ")
<< TestCaseName;
std::string TestNameMaybeDisabled = PP->getSpelling(*TestNameToken);
StringRef TestName = TestNameMaybeDisabled;
TestName.consume_front(kDisabledTestPrefix);
if (TestName.contains('_'))
Check->diag(TestNameToken->getLocation(),
"avoid using \"_\" in test name \"%0\" according to "
"Googletest FAQ")
<< TestName;
}
private:
Preprocessor *PP;
AvoidUnderscoreInGoogletestNameCheck *Check;
};
} // namespace
void AvoidUnderscoreInGoogletestNameCheck::registerPPCallbacks(
CompilerInstance &Compiler) {
Compiler.getPreprocessor().addPPCallbacks(
llvm::make_unique<AvoidUnderscoreInGoogletestNameCallback>(
&Compiler.getPreprocessor(), this));
}
} // namespace readability
} // namespace google
} // namespace tidy
} // namespace clang

View File

@ -0,0 +1,33 @@
//===--- AvoidUnderscoreInGoogletestNameCheck.h - clang-tidy ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDUNDERSCOREINGOOGLETESTNAMECHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDUNDERSCOREINGOOGLETESTNAMECHECK_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
namespace google {
namespace readability {
// Check for underscores in the names of googletest tests, per
// https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore
class AvoidUnderscoreInGoogletestNameCheck : public ClangTidyCheck {
public:
using ClangTidyCheck::ClangTidyCheck;
void registerPPCallbacks(CompilerInstance &Compiler) override;
};
} // namespace readability
} // namespace google
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDUNDERSCOREINGOOGLETESTNAMECHECK_H

View File

@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyGoogleModule
AvoidCStyleCastsCheck.cpp
AvoidThrowingObjCExceptionCheck.cpp
AvoidUnderscoreInGoogletestNameCheck.cpp
DefaultArgumentsCheck.cpp
ExplicitConstructorCheck.cpp
ExplicitMakePairCheck.cpp

View File

@ -14,6 +14,7 @@
#include "../readability/NamespaceCommentCheck.h"
#include "AvoidCStyleCastsCheck.h"
#include "AvoidThrowingObjCExceptionCheck.h"
#include "AvoidUnderscoreInGoogletestNameCheck.h"
#include "DefaultArgumentsCheck.h"
#include "ExplicitConstructorCheck.h"
#include "ExplicitMakePairCheck.h"
@ -60,6 +61,9 @@ class GoogleModule : public ClangTidyModule {
"google-runtime-operator");
CheckFactories.registerCheck<runtime::NonConstReferences>(
"google-runtime-references");
CheckFactories
.registerCheck<readability::AvoidUnderscoreInGoogletestNameCheck>(
"google-readability-avoid-underscore-in-googletest-name");
CheckFactories.registerCheck<readability::AvoidCStyleCastsCheck>(
"google-readability-casting");
CheckFactories.registerCheck<readability::TodoCommentCheck>(

View File

@ -73,6 +73,14 @@ Improvements to clang-tidy
Checks for casts of ``absl::Duration`` conversion functions, and recommends
the right conversion function instead.
- New :doc:`google-readability-avoid-underscore-in-googletest-name
<clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name>`
check.
Checks whether there are underscores in googletest test and test case names in
test macros, which is prohibited by the Googletest FAQ.
Improvements to include-fixer
-----------------------------

View File

@ -0,0 +1,34 @@
.. title:: clang-tidy - google-readability-avoid-underscore-in-googletest-name
google-readability-avoid-underscore-in-googletest-name
======================================================
Checks whether there are underscores in googletest test and test case names in
test macros:
- ``TEST``
- ``TEST_F``
- ``TEST_P``
- ``TYPED_TEST``
- ``TYPED_TEST_P``
The ``FRIEND_TEST`` macro is not included.
For example:
.. code-block:: c++
TEST(TestCaseName, Illegal_TestName) {}
TEST(Illegal_TestCaseName, TestName) {}
would trigger the check. `Underscores are not allowed`_ in test names nor test
case names.
The ``DISABLED_`` prefix, which may be used to `disable individual tests`_, is
ignored when checking test names, but the rest of the rest of the test name is
still checked.
This check does not propose any fixes.
.. _Underscores are not allowed: https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore
.. _disable individual tests: https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore

View File

@ -131,6 +131,7 @@ Clang-Tidy Checks
google-objc-avoid-throwing-exception
google-objc-function-naming
google-objc-global-variable-declaration
google-readability-avoid-underscore-in-googletest-name
google-readability-braces-around-statements (redirects to readability-braces-around-statements) <google-readability-braces-around-statements>
google-readability-casting
google-readability-function-size (redirects to readability-function-size) <google-readability-function-size>

View File

@ -0,0 +1,108 @@
// RUN: %check_clang_tidy %s google-readability-avoid-underscore-in-googletest-name %t
#define TEST(test_case_name, test_name) void test_case_name##test_name()
#define TEST_F(test_case_name, test_name) void test_case_name##test_name()
#define TEST_P(test_case_name, test_name) void test_case_name##test_name()
#define TYPED_TEST(test_case_name, test_name) void test_case_name##test_name()
#define TYPED_TEST_P(test_case_name, test_name) void test_case_name##test_name()
#define FRIEND_TEST(test_case_name, test_name) void test_case_name##test_name()
TEST(TestCaseName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST(TestCaseName, DISABLED_Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST(TestCaseName, Illegal_Test_Name) {}
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST(Illegal_TestCaseName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST(Illegal_Test_CaseName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_Test_CaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST(Illegal_TestCaseName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_F(TestCaseFixtureName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_F(TestCaseFixtureName, DISABLED_Illegal_Test_Name) {}
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_F(TestCaseFixtureName, Illegal_Test_Name) {}
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_F(Illegal_TestCaseFixtureName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_F(Illegal_TestCaseFixtureName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_F(Illegal_Test_CaseFixtureName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_Test_CaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_P(ParameterizedTestCaseFixtureName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_P(ParameterizedTestCaseFixtureName, DISABLED_Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_P(ParameterizedTestCaseFixtureName, Illegal_Test_Name) {}
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_P(Illegal_ParameterizedTestCaseFixtureName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_ParameterizedTestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_P(Illegal_ParameterizedTestCaseFixtureName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_ParameterizedTestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
// CHECK-MESSAGES: :[[@LINE-2]]:50: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TEST_P(Illegal_Parameterized_TestCaseFixtureName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_Parameterized_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST(TypedTestCaseName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST(TypedTestCaseName, DISABLED_Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST(TypedTestCaseName, Illegal_Test_Name) {}
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST(Illegal_TypedTestCaseName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_TypedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST(Illegal_TypedTestCaseName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_TypedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
// CHECK-MESSAGES: :[[@LINE-2]]:39: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST(Illegal_Typed_TestCaseName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_Typed_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST_P(TypeParameterizedTestCaseName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST_P(TypeParameterizedTestCaseName, DISABLED_Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST_P(TypeParameterizedTestCaseName, Illegal_Test_Name) {}
// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST_P(Illegal_TypeParameterizedTestCaseName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_TypeParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST_P(Illegal_TypeParameterizedTestCaseName, Illegal_TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_TypeParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
// CHECK-MESSAGES: :[[@LINE-2]]:53: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
TYPED_TEST_P(Illegal_Type_ParameterizedTestCaseName, TestName) {}
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_Type_ParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
// Underscores are allowed to disable a test with the DISABLED_ prefix.
// https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore
TEST(TestCaseName, TestName) {}
TEST(TestCaseName, DISABLED_TestName) {}
TEST_F(TestCaseFixtureName, TestName) {}
TEST_F(TestCaseFixtureName, DISABLED_TestName) {}
TEST_P(ParameterizedTestCaseFixtureName, TestName) {}
TEST_P(ParameterizedTestCaseFixtureName, DISABLED_TestName) {}
TYPED_TEST(TypedTestName, TestName) {}
TYPED_TEST(TypedTestName, DISABLED_TestName) {}
TYPED_TEST_P(TypeParameterizedTestName, TestName) {}
TYPED_TEST_P(TypeParameterizedTestName, DISABLED_TestName) {}
FRIEND_TEST(FriendTest, Is_NotChecked) {}
FRIEND_TEST(Friend_Test, IsNotChecked) {}
FRIEND_TEST(Friend_Test, Is_NotChecked) {}