[clang-tidy]: Google: new check 'google-upgrade-googletest-case'

Introduce a new check to upgrade user code based on API changes in Googletest.

The check finds uses of old Googletest APIs with "case" in their name and replaces them with the new APIs named with "suite".

Patch by Alex Strelnikov (strel@google.com)
Reviewed as D62977.

llvm-svn: 367263
This commit is contained in:
Eric Fiselier 2019-07-29 21:38:56 +00:00
parent 9a5fbc8163
commit a2a6f85366
13 changed files with 1617 additions and 0 deletions

View File

@ -17,6 +17,7 @@ add_clang_library(clangTidyGoogleModule
OverloadedUnaryAndCheck.cpp
TodoCommentCheck.cpp
UnnamedNamespaceInHeaderCheck.cpp
UpgradeGoogletestCaseCheck.cpp
UsingNamespaceDirectiveCheck.cpp
LINK_LIBS

View File

@ -27,6 +27,7 @@
#include "OverloadedUnaryAndCheck.h"
#include "TodoCommentCheck.h"
#include "UnnamedNamespaceInHeaderCheck.h"
#include "UpgradeGoogletestCaseCheck.h"
#include "UsingNamespaceDirectiveCheck.h"
using namespace clang::ast_matchers;
@ -79,6 +80,8 @@ class GoogleModule : public ClangTidyModule {
CheckFactories
.registerCheck<clang::tidy::readability::NamespaceCommentCheck>(
"google-readability-namespace-comments");
CheckFactories.registerCheck<UpgradeGoogletestCaseCheck>(
"google-upgrade-googletest-case");
}
ClangTidyOptions getModuleOptions() override {

View File

@ -0,0 +1,354 @@
//===--- UpgradeGoogletestCaseCheck.cpp - clang-tidy ----------------------===//
//
// 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 "UpgradeGoogletestCaseCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace google {
static const llvm::StringRef RenameCaseToSuiteMessage =
"Google Test APIs named with 'case' are deprecated; use equivalent APIs "
"named with 'suite'";
static llvm::Optional<llvm::StringRef>
getNewMacroName(llvm::StringRef MacroName) {
std::pair<llvm::StringRef, llvm::StringRef> ReplacementMap[] = {
{"TYPED_TEST_CASE", "TYPED_TEST_SUITE"},
{"TYPED_TEST_CASE_P", "TYPED_TEST_SUITE_P"},
{"REGISTER_TYPED_TEST_CASE_P", "REGISTER_TYPED_TEST_SUITE_P"},
{"INSTANTIATE_TYPED_TEST_CASE_P", "INSTANTIATE_TYPED_TEST_SUITE_P"},
{"INSTANTIATE_TEST_CASE_P", "INSTANTIATE_TEST_SUITE_P"},
};
for (auto &Mapping : ReplacementMap) {
if (MacroName == Mapping.first)
return Mapping.second;
}
return llvm::None;
}
namespace {
class UpgradeGoogletestCasePPCallback : public PPCallbacks {
public:
UpgradeGoogletestCasePPCallback(UpgradeGoogletestCaseCheck *Check,
Preprocessor *PP)
: ReplacementFound(false), Check(Check), PP(PP) {}
void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *) override {
macroUsed(MacroNameTok, MD, Range.getBegin(), CheckAction::Rename);
}
void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD,
const MacroDirective *Undef) override {
if (Undef != nullptr)
macroUsed(MacroNameTok, MD, Undef->getLocation(), CheckAction::Warn);
}
void MacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) override {
if (!ReplacementFound && MD != nullptr) {
// We check if the newly defined macro is one of the target replacements.
// This ensures that the check creates warnings only if it is including a
// recent enough version of Google Test.
llvm::StringRef FileName = PP->getSourceManager().getFilename(
MD->getMacroInfo()->getDefinitionLoc());
ReplacementFound = FileName.endswith("gtest/gtest-typed-test.h") &&
PP->getSpelling(MacroNameTok) == "TYPED_TEST_SUITE";
}
}
void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) override {
macroUsed(MacroNameTok, MD, Range.getBegin(), CheckAction::Warn);
}
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDefinition &MD) override {
macroUsed(MacroNameTok, MD, Loc, CheckAction::Warn);
}
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDefinition &MD) override {
macroUsed(MacroNameTok, MD, Loc, CheckAction::Warn);
}
private:
enum class CheckAction { Warn, Rename };
void macroUsed(const clang::Token &MacroNameTok, const MacroDefinition &MD,
SourceLocation Loc, CheckAction Action) {
if (!ReplacementFound)
return;
std::string Name = PP->getSpelling(MacroNameTok);
llvm::Optional<llvm::StringRef> Replacement = getNewMacroName(Name);
if (!Replacement)
return;
llvm::StringRef FileName = PP->getSourceManager().getFilename(
MD.getMacroInfo()->getDefinitionLoc());
if (!FileName.endswith("gtest/gtest-typed-test.h"))
return;
DiagnosticBuilder Diag = Check->diag(Loc, RenameCaseToSuiteMessage);
if (Action == CheckAction::Rename)
Diag << FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(Loc, Loc), *Replacement);
}
bool ReplacementFound;
UpgradeGoogletestCaseCheck *Check;
Preprocessor *PP;
};
} // namespace
void UpgradeGoogletestCaseCheck::registerPPCallbacks(const SourceManager &,
Preprocessor *PP,
Preprocessor *) {
if (!getLangOpts().CPlusPlus)
return;
PP->addPPCallbacks(
llvm::make_unique<UpgradeGoogletestCasePPCallback>(this, PP));
}
void UpgradeGoogletestCaseCheck::registerMatchers(MatchFinder *Finder) {
if (!getLangOpts().CPlusPlus)
return;
auto LocationFilter =
unless(isExpansionInFileMatching("gtest/gtest(-typed-test)?\\.h$"));
// Matchers for the member functions that are being renamed. In each matched
// Google Test class, we check for the existence of one new method name. This
// makes sure the check gives warnings only if the included version of Google
// Test is recent enough.
auto Methods =
cxxMethodDecl(
anyOf(
cxxMethodDecl(
hasAnyName("SetUpTestCase", "TearDownTestCase"),
ofClass(
cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
hasName("::testing::Test"),
hasMethod(hasName("SetUpTestSuite")))))
.bind("class"))),
cxxMethodDecl(
hasName("test_case_name"),
ofClass(
cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
hasName("::testing::TestInfo"),
hasMethod(hasName("test_suite_name")))))
.bind("class"))),
cxxMethodDecl(
hasAnyName("OnTestCaseStart", "OnTestCaseEnd"),
ofClass(cxxRecordDecl(
isSameOrDerivedFrom(cxxRecordDecl(
hasName("::testing::TestEventListener"),
hasMethod(hasName("OnTestSuiteStart")))))
.bind("class"))),
cxxMethodDecl(
hasAnyName("current_test_case", "successful_test_case_count",
"failed_test_case_count", "total_test_case_count",
"test_case_to_run_count", "GetTestCase"),
ofClass(cxxRecordDecl(
isSameOrDerivedFrom(cxxRecordDecl(
hasName("::testing::UnitTest"),
hasMethod(hasName("current_test_suite")))))
.bind("class")))))
.bind("method");
Finder->addMatcher(expr(anyOf(callExpr(callee(Methods)).bind("call"),
declRefExpr(to(Methods)).bind("ref")),
LocationFilter),
this);
Finder->addMatcher(
usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(Methods)), LocationFilter)
.bind("using"),
this);
Finder->addMatcher(cxxMethodDecl(Methods, LocationFilter), this);
// Matchers for `TestCase` -> `TestSuite`. The fact that `TestCase` is an
// alias and not a class declaration ensures we only match with a recent
// enough version of Google Test.
auto TestCaseTypeAlias =
typeAliasDecl(hasName("::testing::TestCase")).bind("test-case");
Finder->addMatcher(
typeLoc(loc(qualType(typedefType(hasDeclaration(TestCaseTypeAlias)))),
unless(hasAncestor(decl(isImplicit()))), LocationFilter)
.bind("typeloc"),
this);
Finder->addMatcher(
usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(TestCaseTypeAlias)))
.bind("using"),
this);
}
static llvm::StringRef getNewMethodName(llvm::StringRef CurrentName) {
std::pair<llvm::StringRef, llvm::StringRef> ReplacementMap[] = {
{"SetUpTestCase", "SetUpTestSuite"},
{"TearDownTestCase", "TearDownTestSuite"},
{"test_case_name", "test_suite_name"},
{"OnTestCaseStart", "OnTestSuiteStart"},
{"OnTestCaseEnd", "OnTestSuiteEnd"},
{"current_test_case", "current_test_suite"},
{"successful_test_case_count", "successful_test_suite_count"},
{"failed_test_case_count", "failed_test_suite_count"},
{"total_test_case_count", "total_test_suite_count"},
{"test_case_to_run_count", "test_suite_to_run_count"},
{"GetTestCase", "GetTestSuite"}};
for (auto &Mapping : ReplacementMap) {
if (CurrentName == Mapping.first)
return Mapping.second;
}
llvm_unreachable("Unexpected function name");
}
template <typename NodeType>
static bool isInInstantiation(const NodeType &Node,
const MatchFinder::MatchResult &Result) {
return !match(isInTemplateInstantiation(), Node, *Result.Context).empty();
}
template <typename NodeType>
static bool isInTemplate(const NodeType &Node,
const MatchFinder::MatchResult &Result) {
internal::Matcher<NodeType> IsInsideTemplate =
hasAncestor(decl(anyOf(classTemplateDecl(), functionTemplateDecl())));
return !match(IsInsideTemplate, Node, *Result.Context).empty();
}
static bool
derivedTypeHasReplacementMethod(const MatchFinder::MatchResult &Result,
llvm::StringRef ReplacementMethod) {
const auto *Class = Result.Nodes.getNodeAs<CXXRecordDecl>("class");
return !match(cxxRecordDecl(
unless(isExpansionInFileMatching(
"gtest/gtest(-typed-test)?\\.h$")),
hasMethod(cxxMethodDecl(hasName(ReplacementMethod)))),
*Class, *Result.Context)
.empty();
}
static CharSourceRange
getAliasNameRange(const MatchFinder::MatchResult &Result) {
if (const auto *Using = Result.Nodes.getNodeAs<UsingDecl>("using")) {
return CharSourceRange::getTokenRange(
Using->getNameInfo().getSourceRange());
}
return CharSourceRange::getTokenRange(
Result.Nodes.getNodeAs<TypeLoc>("typeloc")->getSourceRange());
}
void UpgradeGoogletestCaseCheck::check(const MatchFinder::MatchResult &Result) {
llvm::StringRef ReplacementText;
CharSourceRange ReplacementRange;
if (const auto *Method = Result.Nodes.getNodeAs<CXXMethodDecl>("method")) {
ReplacementText = getNewMethodName(Method->getName());
bool IsInInstantiation;
bool IsInTemplate;
bool AddFix = true;
if (const auto *Call = Result.Nodes.getNodeAs<CXXMemberCallExpr>("call")) {
const auto *Callee = llvm::cast<MemberExpr>(Call->getCallee());
ReplacementRange = CharSourceRange::getTokenRange(Callee->getMemberLoc(),
Callee->getMemberLoc());
IsInInstantiation = isInInstantiation(*Call, Result);
IsInTemplate = isInTemplate<Stmt>(*Call, Result);
} else if (const auto *Ref = Result.Nodes.getNodeAs<DeclRefExpr>("ref")) {
ReplacementRange =
CharSourceRange::getTokenRange(Ref->getNameInfo().getSourceRange());
IsInInstantiation = isInInstantiation(*Ref, Result);
IsInTemplate = isInTemplate<Stmt>(*Ref, Result);
} else if (const auto *Using = Result.Nodes.getNodeAs<UsingDecl>("using")) {
ReplacementRange =
CharSourceRange::getTokenRange(Using->getNameInfo().getSourceRange());
IsInInstantiation = isInInstantiation(*Using, Result);
IsInTemplate = isInTemplate<Decl>(*Using, Result);
} else {
// This branch means we have matched a function declaration / definition
// either for a function from googletest or for a function in a derived
// class.
ReplacementRange = CharSourceRange::getTokenRange(
Method->getNameInfo().getSourceRange());
IsInInstantiation = isInInstantiation(*Method, Result);
IsInTemplate = isInTemplate<Decl>(*Method, Result);
// If the type of the matched method is strictly derived from a googletest
// type and has both the old and new member function names, then we cannot
// safely rename (or delete) the old name version.
AddFix = !derivedTypeHasReplacementMethod(Result, ReplacementText);
}
if (IsInInstantiation) {
if (MatchedTemplateLocations.count(
ReplacementRange.getBegin().getRawEncoding()) == 0) {
// For each location matched in a template instantiation, we check if
// the location can also be found in `MatchedTemplateLocations`. If it
// is not found, that means the expression did not create a match
// without the instantiation and depends on template parameters. A
// manual fix is probably required so we provide only a warning.
diag(ReplacementRange.getBegin(), RenameCaseToSuiteMessage);
}
return;
}
if (IsInTemplate) {
// We gather source locations from template matches not in template
// instantiations for future matches.
MatchedTemplateLocations.insert(
ReplacementRange.getBegin().getRawEncoding());
}
if (!AddFix) {
diag(ReplacementRange.getBegin(), RenameCaseToSuiteMessage);
return;
}
} else {
// This is a match for `TestCase` to `TestSuite` refactoring.
assert(Result.Nodes.getNodeAs<TypeAliasDecl>("test-case") != nullptr);
ReplacementText = "TestSuite";
ReplacementRange = getAliasNameRange(Result);
// We do not need to keep track of template instantiations for this branch,
// because we are matching a `TypeLoc` for the alias declaration. Templates
// will only be instantiated with the true type name, `TestSuite`.
}
DiagnosticBuilder Diag =
diag(ReplacementRange.getBegin(), RenameCaseToSuiteMessage);
ReplacementRange = Lexer::makeFileCharRange(
ReplacementRange, *Result.SourceManager, Result.Context->getLangOpts());
if (ReplacementRange.isInvalid())
// An invalid source range likely means we are inside a macro body. A manual
// fix is likely needed so we do not create a fix-it hint.
return;
Diag << FixItHint::CreateReplacement(ReplacementRange, ReplacementText);
}
} // namespace google
} // namespace tidy
} // namespace clang

View File

@ -0,0 +1,40 @@
//===--- UpgradeGoogletestCaseCheck.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_UPGRADEGOOGLETESTCASECHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UPGRADEGOOGLETESTCASECHECK_H
#include "../ClangTidyCheck.h"
namespace clang {
namespace tidy {
namespace google {
/// Finds uses of deprecated Googletest APIs with names containing "case" and
/// replaces them with equivalent names containing "suite".
///
/// For the user-facing documentation see:
/// https://clang.llvm.org/extra/clang-tidy/checks/google-upgrade-googletest-case.html
class UpgradeGoogletestCaseCheck : public ClangTidyCheck {
public:
UpgradeGoogletestCaseCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
llvm::DenseSet<unsigned> MatchedTemplateLocations;
};
} // namespace google
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UPGRADEGOOGLETESTCASECHECK_H

View File

@ -81,6 +81,13 @@ Improvements to clang-tidy
``__attribute__((warn_unused_result))``, but some kernel versions do not have
this warning enabled for clang.
- New :doc:`google-upgrade-googletest-case
<clang-tidy/checks/google-upgrade-googletest-case>` check.
Finds uses of deprecated Googletest APIs with names containing ``case`` and
replaces them with equivalent APIs with ``suite``.
Improvements to include-fixer
-----------------------------

View File

@ -0,0 +1,53 @@
.. title:: clang-tidy - google-upgrade-googletest-case
google-upgrade-googletest-case
==============================
Finds uses of deprecated Google Test version 1.9 APIs with names containing
``case`` and replaces them with equivalent APIs with ``suite``.
All names containing ``case`` are being replaced to be consistent with the
meanings of "test case" and "test suite" as used by the International
Software Testing Qualifications Board and ISO 29119.
The new names are a part of Google Test version 1.9 (release pending). It is
recommended that users update their dependency to version 1.9 and then use this
check to remove deprecated names.
The affected APIs are:
- Member functions of ``testing::Test``, ``testing::TestInfo``,
``testing::TestEventListener``, ``testing::UnitTest``, and any type inheriting
from these types
- The macros ``TYPED_TEST_CASE``, ``TYPED_TEST_CASE_P``,
``REGISTER_TYPED_TEST_CASE_P``, and ``INSTANTIATE_TYPED_TEST_CASE_P``
- The type alias ``testing::TestCase``
Examples of fixes created by this check:
.. code-block:: c++
class FooTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
};
TYPED_TEST_CASE(BarTest, BarTypes);
becomes
.. code-block:: c++
class FooTest : public testing::Test {
public:
static void SetUpTestSuite();
static void TearDownTestSuite();
};
TYPED_TEST_SUITE(BarTest, BarTypes);
For better consistency of user code, the check renames both virtual and
non-virtual member functions with matching names in derived types. The check
tries to provide a only warning when a fix cannot be made safely, as is the case
with some template and macro uses.

View File

@ -153,6 +153,7 @@ Clang-Tidy Checks
google-runtime-int
google-runtime-operator
google-runtime-references
google-upgrade-googletest-case
hicpp-avoid-c-arrays (redirects to modernize-avoid-c-arrays) <hicpp-avoid-c-arrays>
hicpp-avoid-goto
hicpp-braces-around-statements (redirects to readability-braces-around-statements) <hicpp-braces-around-statements>

View File

@ -0,0 +1,16 @@
#ifndef THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_TYPED_TEST_H_
#define THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_TYPED_TEST_H_
#define TYPED_TEST_SUITE(CaseName, Types, ...)
#define TYPED_TEST_CASE TYPED_TEST_SUITE
#define TYPED_TEST_SUITE_P(SuiteName)
#define TYPED_TEST_CASE_P TYPED_TEST_SUITE_P
#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...)
#define REGISTER_TYPED_TEST_CASE_P REGISTER_TYPED_TEST_SUITE_P
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...)
#define INSTANTIATE_TYPED_TEST_CASE_P INSTANTIATE_TYPED_TEST_SUITE_P
#endif // THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_TYPED_TEST_H_

View File

@ -0,0 +1,66 @@
#ifndef THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_H_
#define THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_H_
#include "gtest/gtest-typed-test.h"
namespace testing {
class Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
static void SetUpTestSuite();
static void TearDownTestSuite();
};
class TestSuite {};
using TestCase = TestSuite;
class TestInfo {
public:
const char *test_case_name() const;
const char *test_suite_name() const;
};
class TestEventListener {
public:
virtual void OnTestCaseStart(const TestCase &);
virtual void OnTestCaseEnd(const TestCase &);
virtual void OnTestSuiteStart(const TestCase &);
virtual void OnTestSuiteEnd(const TestCase &);
};
class EmptyTestEventListener : public TestEventListener {
public:
void OnTestCaseStart(const TestCase &) override;
void OnTestCaseEnd(const TestCase &) override;
void OnTestSuiteStart(const TestCase &) override;
void OnTestSuiteEnd(const TestCase &) override;
};
class UnitTest {
public:
static UnitTest *GetInstance();
TestCase *current_test_case() const;
int successful_test_case_count() const;
int failed_test_case_count() const;
int total_test_case_count() const;
int test_case_to_run_count() const;
const TestCase *GetTestCase(int) const;
TestSuite *current_test_suite() const;
int successful_test_suite_count() const;
int failed_test_suite_count() const;
int total_test_suite_count() const;
int test_suite_to_run_count() const;
const TestSuite *GetTestSuite(int) const;
};
} // namespace testing
#endif // THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_H_

View File

@ -0,0 +1,12 @@
#ifndef THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_TYPED_TEST_H_
#define THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_TYPED_TEST_H_
#define TYPED_TEST_CASE(CaseName, Types, ...)
#define TYPED_TEST_CASE_P(SuiteName)
#define REGISTER_TYPED_TEST_CASE_P(SuiteName, ...)
#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, SuiteName, Types, ...)
#endif // THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_TYPED_TEST_H_

View File

@ -0,0 +1,47 @@
#ifndef THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_H_
#define THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_H_
#include "gtest/gtest-typed-test.h"
namespace testing {
class Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
};
class TestCase {};
class TestInfo {
public:
const char *test_case_name() const;
};
class TestEventListener {
public:
virtual void OnTestCaseStart(const TestCase &);
virtual void OnTestCaseEnd(const TestCase &);
};
class EmptyTestEventListener : public TestEventListener {
public:
void OnTestCaseStart(const TestCase &) override;
void OnTestCaseEnd(const TestCase &) override;
};
class UnitTest {
public:
static UnitTest *GetInstance();
TestCase *current_test_case() const;
int successful_test_case_count() const;
int failed_test_case_count() const;
int total_test_case_count() const;
int test_case_to_run_count() const;
const TestCase *GetTestCase(int) const;
};
} // namespace testing
#endif // THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_H_

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@ static_library("google") {
"OverloadedUnaryAndCheck.cpp",
"TodoCommentCheck.cpp",
"UnnamedNamespaceInHeaderCheck.cpp",
"UpgradeGoogletestCaseCheck.cpp",
"UsingNamespaceDirectiveCheck.cpp",
]
}