forked from OSchip/llvm-project
Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
This patch adds support for matching gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL macros. Reviewed By: ymandel, hokein Differential Revision: https://reviews.llvm.org/D103195
This commit is contained in:
parent
b532455ac7
commit
d0e159334f
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace clang {
|
||||
namespace ast_matchers {
|
||||
|
@ -30,14 +31,55 @@ enum class GtestCmp {
|
|||
Lt,
|
||||
};
|
||||
|
||||
/// Matcher for gtest's ASSERT_... macros.
|
||||
/// This enum indicates whether the mock method in the matched ON_CALL or
|
||||
/// EXPECT_CALL macro has arguments. For example, `None` can be used to match
|
||||
/// `ON_CALL(mock, TwoParamMethod)` whereas `Some` can be used to match
|
||||
/// `ON_CALL(mock, TwoParamMethod(m1, m2))`.
|
||||
enum class MockArgs {
|
||||
None,
|
||||
Some,
|
||||
};
|
||||
|
||||
/// Matcher for gtest's ASSERT comparison macros including ASSERT_EQ, ASSERT_NE,
|
||||
/// ASSERT_GE, ASSERT_GT, ASSERT_LE and ASSERT_LT.
|
||||
internal::BindableMatcher<Stmt> gtestAssert(GtestCmp Cmp, StatementMatcher Left,
|
||||
StatementMatcher Right);
|
||||
|
||||
/// Matcher for gtest's EXPECT_... macros.
|
||||
/// Matcher for gtest's ASSERT_THAT macro.
|
||||
internal::BindableMatcher<Stmt> gtestAssertThat(StatementMatcher Actual,
|
||||
StatementMatcher Matcher);
|
||||
|
||||
/// Matcher for gtest's EXPECT comparison macros including EXPECT_EQ, EXPECT_NE,
|
||||
/// EXPECT_GE, EXPECT_GT, EXPECT_LE and EXPECT_LT.
|
||||
internal::BindableMatcher<Stmt> gtestExpect(GtestCmp Cmp, StatementMatcher Left,
|
||||
StatementMatcher Right);
|
||||
|
||||
/// Matcher for gtest's EXPECT_THAT macro.
|
||||
internal::BindableMatcher<Stmt> gtestExpectThat(StatementMatcher Actual,
|
||||
StatementMatcher Matcher);
|
||||
|
||||
/// Matcher for gtest's EXPECT_CALL macro. `MockObject` matches the mock
|
||||
/// object and `MockMethodName` is the name of the method invoked on the mock
|
||||
/// object.
|
||||
internal::BindableMatcher<Stmt> gtestExpectCall(StatementMatcher MockObject,
|
||||
llvm::StringRef MockMethodName,
|
||||
MockArgs Args);
|
||||
|
||||
/// Matcher for gtest's EXPECT_CALL macro. `MockCall` matches the whole mock
|
||||
/// member method call. This API is more flexible but requires more knowledge of
|
||||
/// the AST structure of EXPECT_CALL macros.
|
||||
internal::BindableMatcher<Stmt> gtestExpectCall(StatementMatcher MockCall,
|
||||
MockArgs Args);
|
||||
|
||||
/// Like the first `gtestExpectCall` overload but for `ON_CALL`.
|
||||
internal::BindableMatcher<Stmt> gtestOnCall(StatementMatcher MockObject,
|
||||
llvm::StringRef MockMethodName,
|
||||
MockArgs Args);
|
||||
|
||||
/// Like the second `gtestExpectCall` overload but for `ON_CALL`.
|
||||
internal::BindableMatcher<Stmt> gtestOnCall(StatementMatcher MockCall,
|
||||
MockArgs Args);
|
||||
|
||||
} // namespace ast_matchers
|
||||
} // namespace clang
|
||||
|
||||
|
|
|
@ -5,76 +5,105 @@
|
|||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements several matchers for popular gtest macros. In general,
|
||||
// AST matchers cannot match calls to macros. However, we can simulate such
|
||||
// matches if the macro definition has identifiable elements that themselves can
|
||||
// be matched. In that case, we can match on those elements and then check that
|
||||
// the match occurs within an expansion of the desired macro. The more uncommon
|
||||
// the identified elements, the more efficient this process will be.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/ASTMatchers/GtestMatchers.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace clang {
|
||||
namespace ast_matchers {
|
||||
namespace {
|
||||
|
||||
enum class MacroType {
|
||||
Expect,
|
||||
Assert,
|
||||
On,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static DeclarationMatcher getComparisonDecl(GtestCmp Cmp) {
|
||||
switch (Cmp) {
|
||||
case GtestCmp::Eq:
|
||||
return cxxMethodDecl(hasName("Compare"),
|
||||
ofClass(cxxRecordDecl(isSameOrDerivedFrom(
|
||||
hasName("::testing::internal::EqHelper")))));
|
||||
case GtestCmp::Ne:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperNE"));
|
||||
case GtestCmp::Ge:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperGE"));
|
||||
case GtestCmp::Gt:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperGT"));
|
||||
case GtestCmp::Le:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperLE"));
|
||||
case GtestCmp::Lt:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperLT"));
|
||||
case GtestCmp::Eq:
|
||||
return cxxMethodDecl(hasName("Compare"),
|
||||
ofClass(cxxRecordDecl(isSameOrDerivedFrom(
|
||||
hasName("::testing::internal::EqHelper")))));
|
||||
case GtestCmp::Ne:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperNE"));
|
||||
case GtestCmp::Ge:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperGE"));
|
||||
case GtestCmp::Gt:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperGT"));
|
||||
case GtestCmp::Le:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperLE"));
|
||||
case GtestCmp::Lt:
|
||||
return functionDecl(hasName("::testing::internal::CmpHelperLT"));
|
||||
}
|
||||
llvm_unreachable("Unhandled GtestCmp enum");
|
||||
}
|
||||
|
||||
static llvm::StringRef getAssertMacro(GtestCmp Cmp) {
|
||||
switch (Cmp) {
|
||||
case GtestCmp::Eq:
|
||||
return "ASSERT_EQ";
|
||||
case GtestCmp::Ne:
|
||||
return "ASSERT_NE";
|
||||
case GtestCmp::Ge:
|
||||
return "ASSERT_GE";
|
||||
case GtestCmp::Gt:
|
||||
return "ASSERT_GT";
|
||||
case GtestCmp::Le:
|
||||
return "ASSERT_LE";
|
||||
case GtestCmp::Lt:
|
||||
return "ASSERT_LT";
|
||||
static llvm::StringRef getMacroTypeName(MacroType Macro) {
|
||||
switch (Macro) {
|
||||
case MacroType::Expect:
|
||||
return "EXPECT";
|
||||
case MacroType::Assert:
|
||||
return "ASSERT";
|
||||
case MacroType::On:
|
||||
return "ON";
|
||||
}
|
||||
llvm_unreachable("Unhandled GtestCmp enum");
|
||||
}
|
||||
|
||||
static llvm::StringRef getExpectMacro(GtestCmp Cmp) {
|
||||
static llvm::StringRef getComparisonTypeName(GtestCmp Cmp) {
|
||||
switch (Cmp) {
|
||||
case GtestCmp::Eq:
|
||||
return "EXPECT_EQ";
|
||||
case GtestCmp::Ne:
|
||||
return "EXPECT_NE";
|
||||
case GtestCmp::Ge:
|
||||
return "EXPECT_GE";
|
||||
case GtestCmp::Gt:
|
||||
return "EXPECT_GT";
|
||||
case GtestCmp::Le:
|
||||
return "EXPECT_LE";
|
||||
case GtestCmp::Lt:
|
||||
return "EXPECT_LT";
|
||||
case GtestCmp::Eq:
|
||||
return "EQ";
|
||||
case GtestCmp::Ne:
|
||||
return "NE";
|
||||
case GtestCmp::Ge:
|
||||
return "GE";
|
||||
case GtestCmp::Gt:
|
||||
return "GT";
|
||||
case GtestCmp::Le:
|
||||
return "LE";
|
||||
case GtestCmp::Lt:
|
||||
return "LT";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string getMacroName(MacroType Macro, GtestCmp Cmp) {
|
||||
return (getMacroTypeName(Macro) + "_" + getComparisonTypeName(Cmp)).str();
|
||||
}
|
||||
|
||||
static std::string getMacroName(MacroType Macro, llvm::StringRef Operation) {
|
||||
return (getMacroTypeName(Macro) + "_" + Operation).str();
|
||||
}
|
||||
|
||||
// Under the hood, ON_CALL is expanded to a call to `InternalDefaultActionSetAt`
|
||||
// to set a default action spec to the underlying function mocker, while
|
||||
// EXPECT_CALL is expanded to a call to `InternalExpectedAt` to set a new
|
||||
// expectation spec.
|
||||
static llvm::StringRef getSpecSetterName(MacroType Macro) {
|
||||
switch (Macro) {
|
||||
case MacroType::On:
|
||||
return "InternalDefaultActionSetAt";
|
||||
case MacroType::Expect:
|
||||
return "InternalExpectedAt";
|
||||
default:
|
||||
llvm_unreachable("Unhandled MacroType enum");
|
||||
}
|
||||
llvm_unreachable("Unhandled GtestCmp enum");
|
||||
}
|
||||
|
||||
// In general, AST matchers cannot match calls to macros. However, we can
|
||||
|
@ -86,18 +115,114 @@ static llvm::StringRef getExpectMacro(GtestCmp Cmp) {
|
|||
//
|
||||
// We use this approach to implement the derived matchers gtestAssert and
|
||||
// gtestExpect.
|
||||
static internal::BindableMatcher<Stmt>
|
||||
gtestComparisonInternal(MacroType Macro, GtestCmp Cmp, StatementMatcher Left,
|
||||
StatementMatcher Right) {
|
||||
return callExpr(isExpandedFromMacro(getMacroName(Macro, Cmp)),
|
||||
callee(getComparisonDecl(Cmp)), hasArgument(2, Left),
|
||||
hasArgument(3, Right));
|
||||
}
|
||||
|
||||
static internal::BindableMatcher<Stmt>
|
||||
gtestThatInternal(MacroType Macro, StatementMatcher Actual,
|
||||
StatementMatcher Matcher) {
|
||||
return cxxOperatorCallExpr(
|
||||
isExpandedFromMacro(getMacroName(Macro, "THAT")),
|
||||
hasOverloadedOperatorName("()"), hasArgument(2, Actual),
|
||||
hasArgument(
|
||||
0, expr(hasType(classTemplateSpecializationDecl(hasName(
|
||||
"::testing::internal::PredicateFormatterFromMatcher"))),
|
||||
ignoringImplicit(
|
||||
callExpr(callee(functionDecl(hasName(
|
||||
"::testing::internal::"
|
||||
"MakePredicateFormatterFromMatcher"))),
|
||||
hasArgument(0, ignoringImplicit(Matcher)))))));
|
||||
}
|
||||
|
||||
static internal::BindableMatcher<Stmt>
|
||||
gtestCallInternal(MacroType Macro, StatementMatcher MockCall, MockArgs Args) {
|
||||
// A ON_CALL or EXPECT_CALL macro expands to different AST structures
|
||||
// depending on whether the mock method has arguments or not.
|
||||
switch (Args) {
|
||||
// For example,
|
||||
// `ON_CALL(mock, TwoParamMethod)` is expanded to
|
||||
// `mock.gmock_TwoArgsMethod(WithoutMatchers(),
|
||||
// nullptr).InternalDefaultActionSetAt(...)`.
|
||||
// EXPECT_CALL is the same except
|
||||
// that it calls `InternalExpectedAt` instead of `InternalDefaultActionSetAt`
|
||||
// in the end.
|
||||
case MockArgs::None:
|
||||
return cxxMemberCallExpr(
|
||||
isExpandedFromMacro(getMacroName(Macro, "CALL")),
|
||||
callee(functionDecl(hasName(getSpecSetterName(Macro)))),
|
||||
onImplicitObjectArgument(ignoringImplicit(MockCall)));
|
||||
// For example,
|
||||
// `ON_CALL(mock, TwoParamMethod(m1, m2))` is expanded to
|
||||
// `mock.gmock_TwoParamMethod(m1,m2)(WithoutMatchers(),
|
||||
// nullptr).InternalDefaultActionSetAt(...)`.
|
||||
// EXPECT_CALL is the same except that it calls `InternalExpectedAt` instead
|
||||
// of `InternalDefaultActionSetAt` in the end.
|
||||
case MockArgs::Some:
|
||||
return cxxMemberCallExpr(
|
||||
isExpandedFromMacro(getMacroName(Macro, "CALL")),
|
||||
callee(functionDecl(hasName(getSpecSetterName(Macro)))),
|
||||
onImplicitObjectArgument(ignoringImplicit(cxxOperatorCallExpr(
|
||||
hasOverloadedOperatorName("()"), argumentCountIs(3),
|
||||
hasArgument(0, ignoringImplicit(MockCall))))));
|
||||
}
|
||||
}
|
||||
|
||||
static internal::BindableMatcher<Stmt>
|
||||
gtestCallInternal(MacroType Macro, StatementMatcher MockObject,
|
||||
llvm::StringRef MockMethodName, MockArgs Args) {
|
||||
return gtestCallInternal(
|
||||
Macro,
|
||||
cxxMemberCallExpr(
|
||||
onImplicitObjectArgument(MockObject),
|
||||
callee(functionDecl(hasName(("gmock_" + MockMethodName).str())))),
|
||||
Args);
|
||||
}
|
||||
|
||||
internal::BindableMatcher<Stmt> gtestAssert(GtestCmp Cmp, StatementMatcher Left,
|
||||
StatementMatcher Right) {
|
||||
return callExpr(callee(getComparisonDecl(Cmp)),
|
||||
isExpandedFromMacro(getAssertMacro(Cmp).str()),
|
||||
hasArgument(2, Left), hasArgument(3, Right));
|
||||
return gtestComparisonInternal(MacroType::Assert, Cmp, Left, Right);
|
||||
}
|
||||
|
||||
internal::BindableMatcher<Stmt> gtestExpect(GtestCmp Cmp, StatementMatcher Left,
|
||||
StatementMatcher Right) {
|
||||
return callExpr(callee(getComparisonDecl(Cmp)),
|
||||
isExpandedFromMacro(getExpectMacro(Cmp).str()),
|
||||
hasArgument(2, Left), hasArgument(3, Right));
|
||||
return gtestComparisonInternal(MacroType::Expect, Cmp, Left, Right);
|
||||
}
|
||||
|
||||
internal::BindableMatcher<Stmt> gtestAssertThat(StatementMatcher Actual,
|
||||
StatementMatcher Matcher) {
|
||||
return gtestThatInternal(MacroType::Assert, Actual, Matcher);
|
||||
}
|
||||
|
||||
internal::BindableMatcher<Stmt> gtestExpectThat(StatementMatcher Actual,
|
||||
StatementMatcher Matcher) {
|
||||
return gtestThatInternal(MacroType::Expect, Actual, Matcher);
|
||||
}
|
||||
|
||||
internal::BindableMatcher<Stmt> gtestOnCall(StatementMatcher MockObject,
|
||||
llvm::StringRef MockMethodName,
|
||||
MockArgs Args) {
|
||||
return gtestCallInternal(MacroType::On, MockObject, MockMethodName, Args);
|
||||
}
|
||||
|
||||
internal::BindableMatcher<Stmt> gtestOnCall(StatementMatcher MockCall,
|
||||
MockArgs Args) {
|
||||
return gtestCallInternal(MacroType::On, MockCall, Args);
|
||||
}
|
||||
|
||||
internal::BindableMatcher<Stmt> gtestExpectCall(StatementMatcher MockObject,
|
||||
llvm::StringRef MockMethodName,
|
||||
MockArgs Args) {
|
||||
return gtestCallInternal(MacroType::Expect, MockObject, MockMethodName, Args);
|
||||
}
|
||||
|
||||
internal::BindableMatcher<Stmt> gtestExpectCall(StatementMatcher MockCall,
|
||||
MockArgs Args) {
|
||||
return gtestCallInternal(MacroType::Expect, MockCall, Args);
|
||||
}
|
||||
|
||||
} // end namespace ast_matchers
|
||||
|
|
|
@ -42,6 +42,14 @@ constexpr llvm::StringLiteral GtestMockDecls = R"cc(
|
|||
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||
|
||||
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \
|
||||
GTEST_ASSERT_(pred_format(#v1, v1), on_failure)
|
||||
|
||||
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
|
||||
|
||||
#define EXPECT_EQ(val1, val2) \
|
||||
EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
|
||||
#define EXPECT_NE(val1, val2) \
|
||||
|
@ -55,11 +63,29 @@ constexpr llvm::StringLiteral GtestMockDecls = R"cc(
|
|||
#define EXPECT_LT(val1, val2) \
|
||||
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
|
||||
|
||||
#define ASSERT_THAT(value, matcher) \
|
||||
ASSERT_PRED_FORMAT1( \
|
||||
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
|
||||
#define EXPECT_THAT(value, matcher) \
|
||||
EXPECT_PRED_FORMAT1( \
|
||||
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
|
||||
|
||||
#define ASSERT_EQ(val1, val2) \
|
||||
ASSERT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
|
||||
#define ASSERT_NE(val1, val2) \
|
||||
ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
|
||||
|
||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \
|
||||
nullptr) \
|
||||
.Setter(nullptr, 0, #mock_expr, #call)
|
||||
|
||||
#define ON_CALL(obj, call) \
|
||||
GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call)
|
||||
|
||||
#define EXPECT_CALL(obj, call) \
|
||||
GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
class EqHelper {
|
||||
|
@ -96,8 +122,77 @@ constexpr llvm::StringLiteral GtestMockDecls = R"cc(
|
|||
const T2& val2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// For implementing ASSERT_THAT() and EXPECT_THAT(). The template
|
||||
// argument M must be a type that can be converted to a matcher.
|
||||
template <typename M>
|
||||
class PredicateFormatterFromMatcher {
|
||||
public:
|
||||
explicit PredicateFormatterFromMatcher(M m) : matcher_(m) {}
|
||||
|
||||
// This template () operator allows a PredicateFormatterFromMatcher
|
||||
// object to act as a predicate-formatter suitable for using with
|
||||
// Google Test's EXPECT_PRED_FORMAT1() macro.
|
||||
template <typename T>
|
||||
int operator()(const char* value_text, const T& x) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const M matcher_;
|
||||
};
|
||||
|
||||
template <typename M>
|
||||
inline PredicateFormatterFromMatcher<M> MakePredicateFormatterFromMatcher(
|
||||
M matcher) {
|
||||
return PredicateFormatterFromMatcher<M>(matcher);
|
||||
}
|
||||
|
||||
bool GetWithoutMatchers() { return false; }
|
||||
|
||||
template <typename F>
|
||||
class MockSpec {
|
||||
public:
|
||||
MockSpec<F>() {}
|
||||
|
||||
bool InternalDefaultActionSetAt(
|
||||
const char* file, int line, const char* obj, const char* call) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InternalExpectedAt(
|
||||
const char* file, int line, const char* obj, const char* call) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MockSpec<F> operator()(bool, void*) {
|
||||
return *this;
|
||||
}
|
||||
}; // class MockSpec
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
int StrEq(T val) {
|
||||
return 0;
|
||||
}
|
||||
template <typename T>
|
||||
int Eq(T val) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
class Mock {
|
||||
public:
|
||||
Mock() {}
|
||||
testing::internal::MockSpec<int> gmock_TwoArgsMethod(int, int) {
|
||||
return testing::internal::MockSpec<int>();
|
||||
}
|
||||
testing::internal::MockSpec<int> gmock_TwoArgsMethod(bool, void*) {
|
||||
return testing::internal::MockSpec<int>();
|
||||
}
|
||||
}; // class Mock
|
||||
)cc";
|
||||
|
||||
static std::string wrapGtest(llvm::StringRef Input) {
|
||||
|
@ -187,5 +282,137 @@ TEST(GtestExpectTest, GtShouldMatchExpectGt) {
|
|||
matches(wrapGtest(Input), gtestExpect(GtestCmp::Gt, expr(), expr())));
|
||||
}
|
||||
|
||||
TEST(GtestExpectTest, ThatShouldMatchAssertThat) {
|
||||
std::string Input = R"cc(
|
||||
using ::testing::Eq;
|
||||
void Test() { ASSERT_THAT(2, Eq(2)); }
|
||||
)cc";
|
||||
EXPECT_TRUE(matches(
|
||||
wrapGtest(Input),
|
||||
gtestAssertThat(
|
||||
expr(), callExpr(callee(functionDecl(hasName("::testing::Eq")))))));
|
||||
}
|
||||
|
||||
TEST(GtestExpectTest, ThatShouldMatchExpectThat) {
|
||||
std::string Input = R"cc(
|
||||
using ::testing::Eq;
|
||||
void Test() { EXPECT_THAT(2, Eq(2)); }
|
||||
)cc";
|
||||
EXPECT_TRUE(matches(
|
||||
wrapGtest(Input),
|
||||
gtestExpectThat(
|
||||
expr(), callExpr(callee(functionDecl(hasName("::testing::Eq")))))));
|
||||
}
|
||||
|
||||
TEST(GtestOnCallTest, CallShouldMatchOnCallWithoutParams1) {
|
||||
std::string Input = R"cc(
|
||||
void Test() {
|
||||
Mock mock;
|
||||
ON_CALL(mock, TwoArgsMethod);
|
||||
}
|
||||
)cc";
|
||||
EXPECT_TRUE(matches(wrapGtest(Input),
|
||||
gtestOnCall(expr(hasType(cxxRecordDecl(hasName("Mock")))),
|
||||
"TwoArgsMethod", MockArgs::None)));
|
||||
}
|
||||
|
||||
TEST(GtestOnCallTest, CallShouldMatchOnCallWithoutParams2) {
|
||||
std::string Input = R"cc(
|
||||
void Test() {
|
||||
Mock mock;
|
||||
ON_CALL(mock, TwoArgsMethod);
|
||||
}
|
||||
)cc";
|
||||
EXPECT_TRUE(matches(
|
||||
wrapGtest(Input),
|
||||
gtestOnCall(cxxMemberCallExpr(
|
||||
callee(functionDecl(hasName("gmock_TwoArgsMethod"))))
|
||||
.bind("mock_call"),
|
||||
MockArgs::None)));
|
||||
}
|
||||
|
||||
TEST(GtestOnCallTest, CallShouldMatchOnCallWithParams1) {
|
||||
std::string Input = R"cc(
|
||||
void Test() {
|
||||
Mock mock;
|
||||
ON_CALL(mock, TwoArgsMethod(1, 2));
|
||||
}
|
||||
)cc";
|
||||
EXPECT_TRUE(matches(wrapGtest(Input),
|
||||
gtestOnCall(expr(hasType(cxxRecordDecl(hasName("Mock")))),
|
||||
"TwoArgsMethod", MockArgs::Some)));
|
||||
}
|
||||
|
||||
TEST(GtestOnCallTest, CallShouldMatchOnCallWithParams2) {
|
||||
std::string Input = R"cc(
|
||||
void Test() {
|
||||
Mock mock;
|
||||
ON_CALL(mock, TwoArgsMethod(1, 2));
|
||||
}
|
||||
)cc";
|
||||
EXPECT_TRUE(matches(
|
||||
wrapGtest(Input),
|
||||
gtestOnCall(cxxMemberCallExpr(
|
||||
callee(functionDecl(hasName("gmock_TwoArgsMethod"))))
|
||||
.bind("mock_call"),
|
||||
MockArgs::Some)));
|
||||
}
|
||||
|
||||
TEST(GtestExpectCallTest, CallShouldMatchExpectCallWithoutParams1) {
|
||||
std::string Input = R"cc(
|
||||
void Test() {
|
||||
Mock mock;
|
||||
EXPECT_CALL(mock, TwoArgsMethod);
|
||||
}
|
||||
)cc";
|
||||
EXPECT_TRUE(
|
||||
matches(wrapGtest(Input),
|
||||
gtestExpectCall(expr(hasType(cxxRecordDecl(hasName("Mock")))),
|
||||
"TwoArgsMethod", MockArgs::None)));
|
||||
}
|
||||
|
||||
TEST(GtestExpectCallTest, CallShouldMatchExpectCallWithoutParams2) {
|
||||
std::string Input = R"cc(
|
||||
void Test() {
|
||||
Mock mock;
|
||||
EXPECT_CALL(mock, TwoArgsMethod);
|
||||
}
|
||||
)cc";
|
||||
EXPECT_TRUE(matches(
|
||||
wrapGtest(Input),
|
||||
gtestExpectCall(cxxMemberCallExpr(
|
||||
callee(functionDecl(hasName("gmock_TwoArgsMethod"))))
|
||||
.bind("mock_call"),
|
||||
MockArgs::None)));
|
||||
}
|
||||
|
||||
TEST(GtestExpectCallTest, CallShouldMatchExpectCallWithParams1) {
|
||||
std::string Input = R"cc(
|
||||
void Test() {
|
||||
Mock mock;
|
||||
EXPECT_CALL(mock, TwoArgsMethod(1, 2));
|
||||
}
|
||||
)cc";
|
||||
EXPECT_TRUE(
|
||||
matches(wrapGtest(Input),
|
||||
gtestExpectCall(expr(hasType(cxxRecordDecl(hasName("Mock")))),
|
||||
"TwoArgsMethod", MockArgs::Some)));
|
||||
}
|
||||
|
||||
TEST(GtestExpectCallTest, CallShouldMatchExpectCallWithParams2) {
|
||||
std::string Input = R"cc(
|
||||
void Test() {
|
||||
Mock mock;
|
||||
EXPECT_CALL(mock, TwoArgsMethod(1, 2));
|
||||
}
|
||||
)cc";
|
||||
EXPECT_TRUE(matches(
|
||||
wrapGtest(Input),
|
||||
gtestExpectCall(cxxMemberCallExpr(
|
||||
callee(functionDecl(hasName("gmock_TwoArgsMethod"))))
|
||||
.bind("mock_call"),
|
||||
MockArgs::Some)));
|
||||
}
|
||||
|
||||
} // end namespace ast_matchers
|
||||
} // end namespace clang
|
||||
|
|
Loading…
Reference in New Issue