1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef GOOGLE_CACHEINVALIDATION_DEPS_GMOCK_H_ 6 #define GOOGLE_CACHEINVALIDATION_DEPS_GMOCK_H_ 7 8 #include "testing/gmock/include/gmock/gmock.h" 9 10 namespace testing { 11 namespace internal { 12 13 // WhenDeserializedAs and EqualsProto are utilities that aren't part of gmock. 14 15 // Implements WhenDeserializedAs<Proto>(proto_matcher). 16 template <class Proto> 17 class WhenDeserializedAsMatcher { 18 public: 19 typedef Matcher<const Proto&> InnerMatcher; 20 WhenDeserializedAsMatcher(const InnerMatcher & proto_matcher)21 explicit WhenDeserializedAsMatcher(const InnerMatcher& proto_matcher) 22 : proto_matcher_(proto_matcher) {} 23 ~WhenDeserializedAsMatcher()24 virtual ~WhenDeserializedAsMatcher() {} 25 26 // Deserializes the string as a protobuf of the same type as the expected 27 // protobuf. Deserialize(const string & str)28 Proto* Deserialize(const string& str) const { 29 Proto* proto = new Proto; 30 if (proto->ParsePartialFromString(str)) { 31 return proto; 32 } else { 33 delete proto; 34 return NULL; 35 } 36 } 37 DescribeTo(::std::ostream * os)38 void DescribeTo(::std::ostream* os) const { 39 *os << "can be deserialized as a protobuf that "; 40 proto_matcher_.DescribeTo(os); 41 } 42 DescribeNegationTo(::std::ostream * os)43 void DescribeNegationTo(::std::ostream* os) const { 44 *os << "cannot be deserialized as a protobuf that "; 45 proto_matcher_.DescribeTo(os); 46 } 47 MatchAndExplain(const string & arg,MatchResultListener * listener)48 bool MatchAndExplain(const string& arg, MatchResultListener* listener) const { 49 // Deserializes the string arg as a protobuf of the same type as the 50 // expected protobuf. 51 scoped_ptr<const Proto> deserialized_arg(Deserialize(arg)); 52 // No need to explain the match result. 53 return (deserialized_arg.get() != NULL) && 54 proto_matcher_.Matches(*deserialized_arg); 55 } 56 57 private: 58 const InnerMatcher proto_matcher_; 59 }; 60 61 } // namespace internal 62 63 namespace proto { 64 65 // WhenDeserializedAs<Proto>(m) is a matcher that matches a string 66 // that can be deserialized as a protobuf of type Proto that matches 67 // m, which can be any valid protobuf matcher. 68 template <class Proto, class InnerMatcher> 69 inline PolymorphicMatcher<internal::WhenDeserializedAsMatcher<Proto> > WhenDeserializedAs(const InnerMatcher & inner_matcher)70WhenDeserializedAs(const InnerMatcher& inner_matcher) { 71 return MakePolymorphicMatcher( 72 internal::WhenDeserializedAsMatcher<Proto>( 73 SafeMatcherCast<const Proto&>(inner_matcher))); 74 } 75 76 } // namespace proto 77 78 MATCHER_P(EqualsProto, message, "") { 79 // TOOD(ghc): This implementation assume protobuf serialization is 80 // deterministic, which is true in practice but technically not something that 81 // code is supposed to rely on. However, it vastly simplifies the 82 // implementation... 83 std::string expected_serialized, actual_serialized; 84 message.SerializeToString(&expected_serialized); 85 arg.SerializeToString(&actual_serialized); 86 return expected_serialized == actual_serialized; 87 } 88 89 } // namespace testing 90 91 #endif // GOOGLE_CACHEINVALIDATION_DEPS_GMOCK_H_ 92