summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2020-12-08 12:37:32 -0500
committerAndy Getz <durandal@google.com>2020-12-08 19:15:35 -0500
commite5644f5f12ff3d5b2232dabc1c5ea272a52e8155 (patch)
tree170e3f0de02818b0c15709da473cfb6efdd7f0b6
parent8779937dd05016e3a96e477d2bb1f94947486605 (diff)
downloadgoogletest-e5644f5f12ff3d5b2232dabc1c5ea272a52e8155.tar.gz
googletest-e5644f5f12ff3d5b2232dabc1c5ea272a52e8155.zip
Googletest export
Introduce a new `Address` matcher to gmock. PiperOrigin-RevId: 346344591
-rw-r--r--googlemock/docs/cheat_sheet.md1
-rw-r--r--googlemock/include/gmock/gmock-matchers.h51
-rw-r--r--googlemock/test/gmock-matchers_test.cc40
3 files changed, 92 insertions, 0 deletions
diff --git a/googlemock/docs/cheat_sheet.md b/googlemock/docs/cheat_sheet.md
index fcb9201a..dc2428ef 100644
--- a/googlemock/docs/cheat_sheet.md
+++ b/googlemock/docs/cheat_sheet.md
@@ -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`. |
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h
index ae064b5d..9641ed42 100644
--- a/googlemock/include/gmock/gmock-matchers.h
+++ b/googlemock/include/gmock/gmock-matchers.h
@@ -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
diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc
index 8084e29f..3ac16682 100644
--- a/googlemock/test/gmock-matchers_test.cc
+++ b/googlemock/test/gmock-matchers_test.cc
@@ -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);
}
OpenPOWER on IntegriCloud