diff options
author | Abseil Team <absl-team@google.com> | 2020-12-08 17:37:32 (GMT) |
---|---|---|
committer | Andy Getz <durandal@google.com> | 2020-12-09 00:15:35 (GMT) |
commit | e5644f5f12ff3d5b2232dabc1c5ea272a52e8155 (patch) | |
tree | 170e3f0de02818b0c15709da473cfb6efdd7f0b6 | |
parent | 8779937dd05016e3a96e477d2bb1f94947486605 (diff) | |
download | googletest-e5644f5f12ff3d5b2232dabc1c5ea272a52e8155.zip googletest-e5644f5f12ff3d5b2232dabc1c5ea272a52e8155.tar.gz googletest-e5644f5f12ff3d5b2232dabc1c5ea272a52e8155.tar.bz2 |
Googletest export
Introduce a new `Address` matcher to gmock.
PiperOrigin-RevId: 346344591
-rw-r--r-- | googlemock/docs/cheat_sheet.md | 1 | ||||
-rw-r--r-- | googlemock/include/gmock/gmock-matchers.h | 51 | ||||
-rw-r--r-- | googlemock/test/gmock-matchers_test.cc | 40 |
3 files changed, 92 insertions, 0 deletions
diff --git a/googlemock/docs/cheat_sheet.md b/googlemock/docs/cheat_sheet.md index fcb9201..dc2428e 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 ae064b5..9641ed4 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 8084e29..3ac1668 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); } |