[PATCH] D103195: Add matchers for gtest's ASSERT_THAT, EXPECT_THAT, ON_CALL and EXPECT_CALL

2021-06-02 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
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

2021-06-02 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-06-02 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
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

2021-06-01 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-06-01 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-06-01 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-06-01 Thread Haojian Wu via Phabricator via cfe-commits
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

2021-05-27 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-05-27 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-05-27 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-05-27 Thread Haojian Wu via Phabricator via cfe-commits
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

2021-05-27 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
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

2021-05-27 Thread Haojian Wu via Phabricator via cfe-commits
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

2021-05-26 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-05-26 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-05-26 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-05-26 Thread Zhaomo Yang via Phabricator via cfe-commits
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

2021-05-26 Thread Zhaomo Yang via Phabricator via cfe-commits
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;