[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
This revision was automatically updated to reflect the committed changes. Closed by commit rGd0e159334f9d: Add matchers for gtests ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL (authored by zhaomo, committed by ymandel). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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() {
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo added a comment. Thanks folks! CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
ymandel accepted this revision. ymandel added a comment. Nice! CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo updated this revision to Diff 349030. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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,
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo added inline comments. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:41 } - llvm_unreachable("Unhandled GtestCmp enum"); } hokein wrote: > zhaomo wrote: > > hokein wrote: > > > why remove this `llvm_unreachable`? I think this is a common practice in > > > LLVM. > > ymandel@ suggested me removing it as the switch covers all the possible > > values of the enum. > either seems fine to me (this is just a coding style), I think the problem is > that we have inconsistencies in the patch - e.g. on Line95, `default: > llvm_unreachable`, we should stick with one style. The switch statement there does not cover all the cases so `llvm_unreachable` is necessary. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:104 +static internal::BindableMatcher +gtestComparisonInternal(MacroType Macro, GtestCmp Cmp, StatementMatcher Left, +StatementMatcher Right) { hokein wrote: > hokein wrote: > > As the function creates an AST matcher to match the gtest method, 'd rename > > the function name like `gtestComparisonIMatcher`, the same to following > > functions. > this comment seems undone. Changed it a bit and moved it to the top of this file. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo updated this revision to Diff 348998. zhaomo marked an inline comment as done. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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")));
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
hokein added a comment. a few more nits, the code looks good to me now. As discussed with @ymandel offline, we should be aware of that before moving forward to this direction -- this patch will likely have the gtest-versioning issue. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:134 +// A ON_CALL or EXPECT_CALL macro expands to different AST structures depending +// on whether the mock method has arguments or not. For example, +// `ON_CALL(mock, TwoParamMethod)` is expanded to I think `For example, ...` words are implementation details, should move to the corresponding `switch case` below. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:41 } - llvm_unreachable("Unhandled GtestCmp enum"); } zhaomo wrote: > hokein wrote: > > why remove this `llvm_unreachable`? I think this is a common practice in > > LLVM. > ymandel@ suggested me removing it as the switch covers all the possible > values of the enum. either seems fine to me (this is just a coding style), I think the problem is that we have inconsistencies in the patch - e.g. on Line95, `default: llvm_unreachable`, we should stick with one style. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:104 +static internal::BindableMatcher +gtestComparisonInternal(MacroType Macro, GtestCmp Cmp, StatementMatcher Left, +StatementMatcher Right) { hokein wrote: > As the function creates an AST matcher to match the gtest method, 'd rename > the function name like `gtestComparisonIMatcher`, the same to following > functions. this comment seems undone. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo updated this revision to Diff 348399. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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,
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo updated this revision to Diff 348384. zhaomo marked 4 inline comments as done. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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")));
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo added inline comments. Comment at: clang/include/clang/ASTMatchers/GtestMatchers.h:39 + /// Matcher for gtest's ASSERT_... macros. internal::BindableMatcher gtestAssert(GtestCmp Cmp, StatementMatcher Left, hokein wrote: > as we add a new method to handle `ASSERT_THAT`, this comment is not clear > enough to me, `ASSERT_...` makes me think `ASSERT_THAT` is included as well. > > I would suggest rephrase the comment (explicitly mentioning this is for > comparison operations, IIUC), and even rename the method to `gtestAssertCmp` > (we can defer it to a follow-up patch). I changed the comment to make it more accurate. ymandel@ and I talked about rename the APIs but we weren't sure if it is worth it as it may break some code. I would like to at least defer that to another patch. Comment at: clang/include/clang/ASTMatchers/GtestMatchers.h:81 + +/// Like the second `gtestOnCall` overload but for `EXPECT_CALL`. +internal::BindableMatcher gtestExpectCall(StatementMatcher MockCall, hokein wrote: > this comment doesn't seem to express enough information, what's the > difference from the above one? I think adding an example would be helpful. The difference between the two `gtestExpectCall` overloads is just like the difference between the two `gtestOnCall` overloads. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:41 } - llvm_unreachable("Unhandled GtestCmp enum"); } hokein wrote: > why remove this `llvm_unreachable`? I think this is a common practice in LLVM. ymandel@ suggested me removing it as the switch covers all the possible values of the enum. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:47 -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) { hokein wrote: > ymandel wrote: > > hokein wrote: > > > the `static` qualifier is not needed as you wrap it within an anonymous > > > namespace. the same below. > > nit: per the style guide > > (https://releases.llvm.org/2.7/docs/CodingStandards.html#micro_anonns), I > > think it would be better to shrink the anonymous namespace to only enclose > > the enum decl, and keep these `static` annotations and in fact add a few > > that are currently missing on the `gtestCallInternal` functions. > Up to you -- I'm fine with either (these two styles exit in LLVM codebase)- > using anonymous namespace aligns more with google style... I changed the code following ymandel@'s suggestion. Comment at: clang/unittests/ASTMatchers/GtestMatchersTest.cpp:330 + callee(functionDecl(hasName("gmock_TwoArgsMethod" + .bind("mock_call"), + MockArgs::NoMatchers))); hokein wrote: > nit: bind is not needed? Just wanted to illustrate the usage here. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
hokein added inline comments. Comment at: clang/include/clang/ASTMatchers/GtestMatchers.h:34 +enum class MockArgs { + NoMatchers, ymandel wrote: > hokein wrote: > > worth comments. > > > > out of curiosity, what do we call this `Matchers`? I'd be careful to > > introduce a different matcher concept in the ast_matcher library, it would > > easily cause confusion. > +1 Please move the comments relating to this enum from the two `gtestOnCall` > functions to here. > > hokein@ -- the "Matchers" is because its describing googletest matchers. > But, it is a bit confusing in this context and doesn't really add anything. > What do you think of `None` and `Some` instead? > What do you think of None and Some instead? this sounds good to me. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:47 -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) { ymandel wrote: > hokein wrote: > > the `static` qualifier is not needed as you wrap it within an anonymous > > namespace. the same below. > nit: per the style guide > (https://releases.llvm.org/2.7/docs/CodingStandards.html#micro_anonns), I > think it would be better to shrink the anonymous namespace to only enclose > the enum decl, and keep these `static` annotations and in fact add a few that > are currently missing on the `gtestCallInternal` functions. Up to you -- I'm fine with either (these two styles exit in LLVM codebase)- using anonymous namespace aligns more with google style... CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
ymandel added inline comments. Comment at: clang/include/clang/ASTMatchers/GtestMatchers.h:55-59 +/// Matcher for gtest's `ON_CALL` macro. When `Args` is `NoMatchers`, +/// this matches a mock call to a method without argument matchers e.g. +/// `ON_CALL(mock, TwoParamMethod)`; when `Args` is `HasMatchers`, this +/// matches a mock call to a method with argument matchers e.g. +/// `ON_CALL(mock, TwoParamMethod(m1, m2))`. `MockObject` matches the mock Please move this to a comment describing the `MockArgs` enum. Comment at: clang/include/clang/ASTMatchers/GtestMatchers.h:34 +enum class MockArgs { + NoMatchers, hokein wrote: > worth comments. > > out of curiosity, what do we call this `Matchers`? I'd be careful to > introduce a different matcher concept in the ast_matcher library, it would > easily cause confusion. +1 Please move the comments relating to this enum from the two `gtestOnCall` functions to here. hokein@ -- the "Matchers" is because its describing googletest matchers. But, it is a bit confusing in this context and doesn't really add anything. What do you think of `None` and `Some` instead? Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:47 -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) { hokein wrote: > the `static` qualifier is not needed as you wrap it within an anonymous > namespace. the same below. nit: per the style guide (https://releases.llvm.org/2.7/docs/CodingStandards.html#micro_anonns), I think it would be better to shrink the anonymous namespace to only enclose the enum decl, and keep these `static` annotations and in fact add a few that are currently missing on the `gtestCallInternal` functions. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
hokein added inline comments. Comment at: clang/include/clang/ASTMatchers/GtestMatchers.h:34 +enum class MockArgs { + NoMatchers, worth comments. out of curiosity, what do we call this `Matchers`? I'd be careful to introduce a different matcher concept in the ast_matcher library, it would easily cause confusion. Comment at: clang/include/clang/ASTMatchers/GtestMatchers.h:39 + /// Matcher for gtest's ASSERT_... macros. internal::BindableMatcher gtestAssert(GtestCmp Cmp, StatementMatcher Left, as we add a new method to handle `ASSERT_THAT`, this comment is not clear enough to me, `ASSERT_...` makes me think `ASSERT_THAT` is included as well. I would suggest rephrase the comment (explicitly mentioning this is for comparison operations, IIUC), and even rename the method to `gtestAssertCmp` (we can defer it to a follow-up patch). Comment at: clang/include/clang/ASTMatchers/GtestMatchers.h:40 /// Matcher for gtest's ASSERT_... macros. internal::BindableMatcher gtestAssert(GtestCmp Cmp, StatementMatcher Left, StatementMatcher Right); nit: I would reorder APIs in these file, grouping by assert, expect, oncall. ``` ...gtestAssert(); ...gtestAssertThat(); ...gtestExpect(); ...gtestExpectThat(); ...gtestExpectCall(); ``` Comment at: clang/include/clang/ASTMatchers/GtestMatchers.h:81 + +/// Like the second `gtestOnCall` overload but for `EXPECT_CALL`. +internal::BindableMatcher gtestExpectCall(StatementMatcher MockCall, this comment doesn't seem to express enough information, what's the difference from the above one? I think adding an example would be helpful. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:41 } - llvm_unreachable("Unhandled GtestCmp enum"); } why remove this `llvm_unreachable`? I think this is a common practice in LLVM. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:47 -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) { the `static` qualifier is not needed as you wrap it within an anonymous namespace. the same below. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:86 + case MacroType::On: +return "InternalDefaultActionSetAt"; + case MacroType::Expect: worth comments on these magic string come from -- gtest library? Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:104 +static internal::BindableMatcher +gtestComparisonInternal(MacroType Macro, GtestCmp Cmp, StatementMatcher Left, +StatementMatcher Right) { As the function creates an AST matcher to match the gtest method, 'd rename the function name like `gtestComparisonIMatcher`, the same to following functions. Comment at: clang/lib/ASTMatchers/GtestMatchers.cpp:135 +onImplicitObjectArgument(ignoringImplicit(MockCall))); + case MockArgs::HasMatchers: +return cxxMemberCallExpr( I believe this is something related to the gtest internal implementation, could you add a comment to explain that? Comment at: clang/unittests/ASTMatchers/GtestMatchersTest.cpp:330 + callee(functionDecl(hasName("gmock_TwoArgsMethod" + .bind("mock_call"), + MockArgs::NoMatchers))); nit: bind is not needed? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo updated this revision to Diff 348113. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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,
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo updated this revision to Diff 348095. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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,
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo updated this revision to Diff 348094. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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,
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo updated this revision to Diff 348093. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103195/new/ https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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,
[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL
zhaomo created this revision. zhaomo added a reviewer: ymandel. Herald added a subscriber: mstorsjo. zhaomo requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. This patch adds support for matching gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL macros. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D103195 Files: clang/include/clang/ASTMatchers/GtestMatchers.h clang/lib/ASTMatchers/GtestMatchers.cpp clang/unittests/ASTMatchers/GtestMatchersTest.cpp Index: clang/unittests/ASTMatchers/GtestMatchersTest.cpp === --- clang/unittests/ASTMatchers/GtestMatchersTest.cpp +++ clang/unittests/ASTMatchers/GtestMatchersTest.cpp @@ -42,6 +42,14 @@ #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 @@ #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 @@ 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 + 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 +int operator()(const char* value_text, const T& x) const { + return 0; +} + + private: +const M matcher_; + }; + + template + inline PredicateFormatterFromMatcher MakePredicateFormatterFromMatcher( + M matcher) { +return PredicateFormatterFromMatcher(matcher); + } + + bool GetWithoutMatchers() { return false; } + + template + class MockSpec { + public: +MockSpec() {} + +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 operator()(bool, void*) { + return *this; +} + }; // class MockSpec + } // namespace internal + + template + int StrEq(T val) { +return 0; + } + template + int Eq(T val) { +return 0; + } + } // namespace testing + + class Mock { +public: +Mock() {} +testing::internal::MockSpec gmock_TwoArgsMethod(int, int) { + return testing::internal::MockSpec(); +} +testing::internal::MockSpec gmock_TwoArgsMethod(bool, void*) { + return testing::internal::MockSpec(); +} + }; // class Mock )cc"; static std::string wrapGtest(llvm::StringRef Input) { @@ -187,5 +282,137 @@ 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;