]> git-server-git.apps.pok.os.sepia.ceph.com Git - googletest.git/commitdiff
Googletest export
authorAbseil Team <absl-team@google.com>
Tue, 8 Dec 2020 17:37:32 +0000 (12:37 -0500)
committerAndy Getz <durandal@google.com>
Wed, 9 Dec 2020 00:15:35 +0000 (19:15 -0500)
Introduce a new `Address` matcher to gmock.

PiperOrigin-RevId: 346344591

googlemock/docs/cheat_sheet.md
googlemock/include/gmock/gmock-matchers.h
googlemock/test/gmock-matchers_test.cc

index fcb9201a1ea765b81008f2f795646c16a977270d..dc2428efead5a4b5f25644116dbeb47df459426e 100644 (file)
@@ -420,6 +420,7 @@ messages, you can use:
 <!-- mdformat off(no multiline tables) -->
 | Matcher                   | Description                                     |
 | :------------------------ | :---------------------------------------------- |
+| `Address(m)`              | the result of `std::addressof(argument)` matches `m`. |
 | `Pointee(m)`              | `argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`. |
 | `Pointer(m)`              | `argument` (either a smart pointer or a raw pointer) contains a pointer that matches `m`. `m` will match against the raw pointer regardless of the type of `argument`. |
 | `WhenDynamicCastTo<T>(m)` | when `argument` is passed through `dynamic_cast<T>()`, it matches matcher `m`. |
index ae064b5da52a69bf989b3331784fb86382f71519..9641ed4264c6f75ea152ba10386697f92141aa18 100644 (file)
@@ -2833,6 +2833,49 @@ class KeyMatcher {
   const M matcher_for_key_;
 };
 
+// Implements polymorphic Address(matcher_for_address).
+template <typename InnerMatcher>
+class AddressMatcher {
+ public:
+  explicit AddressMatcher(InnerMatcher m) : matcher_(m) {}
+
+  template <typename Type>
+  operator Matcher<Type>() const {  // NOLINT
+    return Matcher<Type>(new Impl<const Type&>(matcher_));
+  }
+
+ private:
+  // The monomorphic implementation that works for a particular object type.
+  template <typename Type>
+  class Impl : public MatcherInterface<Type> {
+   public:
+    using Address = const GTEST_REMOVE_REFERENCE_AND_CONST_(Type) *;
+    explicit Impl(const InnerMatcher& matcher)
+        : matcher_(MatcherCast<Address>(matcher)) {}
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "has address that ";
+      matcher_.DescribeTo(os);
+    }
+
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "does not have address that ";
+      matcher_.DescribeTo(os);
+    }
+
+    bool MatchAndExplain(Type object,
+                         MatchResultListener* listener) const override {
+      *listener << "which has address ";
+      Address address = std::addressof(object);
+      return MatchPrintAndExplain(address, matcher_, listener);
+    }
+
+   private:
+    const Matcher<Address> matcher_;
+  };
+  const InnerMatcher matcher_;
+};
+
 // Implements Pair(first_matcher, second_matcher) for the given argument pair
 // type with its two matchers. See Pair() function below.
 template <typename PairType>
@@ -4787,6 +4830,14 @@ inline internal::PointerMatcher<InnerMatcher> Pointer(
     const InnerMatcher& inner_matcher) {
   return internal::PointerMatcher<InnerMatcher>(inner_matcher);
 }
+
+// Creates a matcher that matches an object that has an address that matches
+// inner_matcher.
+template <typename InnerMatcher>
+inline internal::AddressMatcher<InnerMatcher> Address(
+    const InnerMatcher& inner_matcher) {
+  return internal::AddressMatcher<InnerMatcher>(inner_matcher);
+}
 }  // namespace no_adl
 
 // Returns a predicate that is satisfied by anything that matches the
index 8084e29f1a818986b3ab4c85645f7a05af76dad7..3ac166827ce92afb3ff1ccada1716efe9d0568b7 100644 (file)
@@ -3787,6 +3787,46 @@ TEST(PointerTest, SmartPointerToConst) {
   EXPECT_FALSE(m.Matches(p));
 }
 
+TEST(AddressTest, NonConst) {
+  int n = 1;
+  const Matcher<int> m = Address(Eq(&n));
+
+  EXPECT_TRUE(m.Matches(n));
+
+  int other = 5;
+
+  EXPECT_FALSE(m.Matches(other));
+
+  int& n_ref = n;
+
+  EXPECT_TRUE(m.Matches(n_ref));
+}
+
+TEST(AddressTest, Const) {
+  const int n = 1;
+  const Matcher<int> m = Address(Eq(&n));
+
+  EXPECT_TRUE(m.Matches(n));
+
+  int other = 5;
+
+  EXPECT_FALSE(m.Matches(other));
+}
+
+TEST(AddressTest, MatcherDoesntCopy) {
+  std::unique_ptr<int> n(new int(1));
+  const Matcher<std::unique_ptr<int>> m = Address(Eq(&n));
+
+  EXPECT_TRUE(m.Matches(n));
+}
+
+TEST(AddressTest, Describe) {
+  Matcher<int> matcher = Address(_);
+  EXPECT_EQ("has address that is anything", Describe(matcher));
+  EXPECT_EQ("does not have address that is anything",
+            DescribeNegation(matcher));
+}
+
 MATCHER_P(FieldIIs, inner_matcher, "") {
   return ExplainMatchResult(inner_matcher, arg.i, result_listener);
 }