mirror of
https://github.com/google/googletest.git
synced 2025-03-10 17:36:10 +00:00
Adds more tests for using SetArgumentPointee with protobufs; works around a compiler bug on Symbian that gmock-printers.h triggers; reduces template code bloat in gmock-matchers.h; avoids RTTI when it's disabled.
This commit is contained in:
parent
18490653e8
commit
c6a412397b
@ -960,30 +960,15 @@ GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ne, !=, "not equal to");
|
|||||||
|
|
||||||
#undef GMOCK_IMPLEMENT_COMPARISON2_MATCHER_
|
#undef GMOCK_IMPLEMENT_COMPARISON2_MATCHER_
|
||||||
|
|
||||||
// TODO(vladl@google.com): Move Impl outside of NotMatcher and rename it
|
|
||||||
// NotMatcherImpl to reduce compilation overhead and the size of the binary.
|
|
||||||
// This also applies to BothOfMatcher::Impl and EitherOfMatcher::Impl.
|
|
||||||
//
|
|
||||||
// Implements the Not(m) matcher, which matches a value that doesn't
|
|
||||||
// match matcher m.
|
|
||||||
template <typename InnerMatcher>
|
|
||||||
class NotMatcher {
|
|
||||||
public:
|
|
||||||
explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {}
|
|
||||||
|
|
||||||
// This template type conversion operator allows Not(m) to be used
|
|
||||||
// to match any type m can match.
|
|
||||||
template <typename T>
|
|
||||||
operator Matcher<T>() const {
|
|
||||||
return Matcher<T>(new Impl<T>(matcher_));
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
// Implements the Not(...) matcher for a particular argument type T.
|
// Implements the Not(...) matcher for a particular argument type T.
|
||||||
|
// We do not nest it inside the NotMatcher class template, as that
|
||||||
|
// will prevent different instantiations of NotMatcher from sharing
|
||||||
|
// the same NotMatcherImpl<T> class.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Impl : public MatcherInterface<T> {
|
class NotMatcherImpl : public MatcherInterface<T> {
|
||||||
public:
|
public:
|
||||||
explicit Impl(InnerMatcher matcher)
|
explicit NotMatcherImpl(const Matcher<T>& matcher)
|
||||||
: matcher_(SafeMatcherCast<T>(matcher)) {}
|
: matcher_(matcher) {}
|
||||||
|
|
||||||
virtual bool Matches(T x) const {
|
virtual bool Matches(T x) const {
|
||||||
return !matcher_.Matches(x);
|
return !matcher_.Matches(x);
|
||||||
@ -1004,34 +989,33 @@ class NotMatcher {
|
|||||||
const Matcher<T> matcher_;
|
const Matcher<T> matcher_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Implements the Not(m) matcher, which matches a value that doesn't
|
||||||
|
// match matcher m.
|
||||||
|
template <typename InnerMatcher>
|
||||||
|
class NotMatcher {
|
||||||
|
public:
|
||||||
|
explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {}
|
||||||
|
|
||||||
|
// This template type conversion operator allows Not(m) to be used
|
||||||
|
// to match any type m can match.
|
||||||
|
template <typename T>
|
||||||
|
operator Matcher<T>() const {
|
||||||
|
return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_)));
|
||||||
|
}
|
||||||
|
private:
|
||||||
InnerMatcher matcher_;
|
InnerMatcher matcher_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used for implementing the AllOf(m_1, ..., m_n) matcher, which
|
// Implements the AllOf(m1, m2) matcher for a particular argument type
|
||||||
// matches a value that matches all of the matchers m_1, ..., and m_n.
|
// T. We do not nest it inside the BothOfMatcher class template, as
|
||||||
template <typename Matcher1, typename Matcher2>
|
// that will prevent different instantiations of BothOfMatcher from
|
||||||
class BothOfMatcher {
|
// sharing the same BothOfMatcherImpl<T> class.
|
||||||
|
template <typename T>
|
||||||
|
class BothOfMatcherImpl : public MatcherInterface<T> {
|
||||||
public:
|
public:
|
||||||
BothOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
|
BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
|
||||||
: matcher1_(matcher1), matcher2_(matcher2) {}
|
: matcher1_(matcher1), matcher2_(matcher2) {}
|
||||||
|
|
||||||
// This template type conversion operator allows a
|
|
||||||
// BothOfMatcher<Matcher1, Matcher2> object to match any type that
|
|
||||||
// both Matcher1 and Matcher2 can match.
|
|
||||||
template <typename T>
|
|
||||||
operator Matcher<T>() const {
|
|
||||||
return Matcher<T>(new Impl<T>(matcher1_, matcher2_));
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
// Implements the AllOf(m1, m2) matcher for a particular argument
|
|
||||||
// type T.
|
|
||||||
template <typename T>
|
|
||||||
class Impl : public MatcherInterface<T> {
|
|
||||||
public:
|
|
||||||
Impl(Matcher1 matcher1, Matcher2 matcher2)
|
|
||||||
: matcher1_(SafeMatcherCast<T>(matcher1)),
|
|
||||||
matcher2_(SafeMatcherCast<T>(matcher2)) {}
|
|
||||||
|
|
||||||
virtual bool Matches(T x) const {
|
virtual bool Matches(T x) const {
|
||||||
return matcher1_.Matches(x) && matcher2_.Matches(x);
|
return matcher1_.Matches(x) && matcher2_.Matches(x);
|
||||||
}
|
}
|
||||||
@ -1084,36 +1068,37 @@ class BothOfMatcher {
|
|||||||
const Matcher<T> matcher2_;
|
const Matcher<T> matcher2_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used for implementing the AllOf(m_1, ..., m_n) matcher, which
|
||||||
|
// matches a value that matches all of the matchers m_1, ..., and m_n.
|
||||||
|
template <typename Matcher1, typename Matcher2>
|
||||||
|
class BothOfMatcher {
|
||||||
|
public:
|
||||||
|
BothOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
|
||||||
|
: matcher1_(matcher1), matcher2_(matcher2) {}
|
||||||
|
|
||||||
|
// This template type conversion operator allows a
|
||||||
|
// BothOfMatcher<Matcher1, Matcher2> object to match any type that
|
||||||
|
// both Matcher1 and Matcher2 can match.
|
||||||
|
template <typename T>
|
||||||
|
operator Matcher<T>() const {
|
||||||
|
return Matcher<T>(new BothOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_),
|
||||||
|
SafeMatcherCast<T>(matcher2_)));
|
||||||
|
}
|
||||||
|
private:
|
||||||
Matcher1 matcher1_;
|
Matcher1 matcher1_;
|
||||||
Matcher2 matcher2_;
|
Matcher2 matcher2_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used for implementing the AnyOf(m_1, ..., m_n) matcher, which
|
// Implements the AnyOf(m1, m2) matcher for a particular argument type
|
||||||
// matches a value that matches at least one of the matchers m_1, ...,
|
// T. We do not nest it inside the AnyOfMatcher class template, as
|
||||||
// and m_n.
|
// that will prevent different instantiations of AnyOfMatcher from
|
||||||
template <typename Matcher1, typename Matcher2>
|
// sharing the same EitherOfMatcherImpl<T> class.
|
||||||
class EitherOfMatcher {
|
template <typename T>
|
||||||
|
class EitherOfMatcherImpl : public MatcherInterface<T> {
|
||||||
public:
|
public:
|
||||||
EitherOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
|
EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
|
||||||
: matcher1_(matcher1), matcher2_(matcher2) {}
|
: matcher1_(matcher1), matcher2_(matcher2) {}
|
||||||
|
|
||||||
// This template type conversion operator allows a
|
|
||||||
// EitherOfMatcher<Matcher1, Matcher2> object to match any type that
|
|
||||||
// both Matcher1 and Matcher2 can match.
|
|
||||||
template <typename T>
|
|
||||||
operator Matcher<T>() const {
|
|
||||||
return Matcher<T>(new Impl<T>(matcher1_, matcher2_));
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
// Implements the AnyOf(m1, m2) matcher for a particular argument
|
|
||||||
// type T.
|
|
||||||
template <typename T>
|
|
||||||
class Impl : public MatcherInterface<T> {
|
|
||||||
public:
|
|
||||||
Impl(Matcher1 matcher1, Matcher2 matcher2)
|
|
||||||
: matcher1_(SafeMatcherCast<T>(matcher1)),
|
|
||||||
matcher2_(SafeMatcherCast<T>(matcher2)) {}
|
|
||||||
|
|
||||||
virtual bool Matches(T x) const {
|
virtual bool Matches(T x) const {
|
||||||
return matcher1_.Matches(x) || matcher2_.Matches(x);
|
return matcher1_.Matches(x) || matcher2_.Matches(x);
|
||||||
}
|
}
|
||||||
@ -1165,6 +1150,24 @@ class EitherOfMatcher {
|
|||||||
const Matcher<T> matcher2_;
|
const Matcher<T> matcher2_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used for implementing the AnyOf(m_1, ..., m_n) matcher, which
|
||||||
|
// matches a value that matches at least one of the matchers m_1, ...,
|
||||||
|
// and m_n.
|
||||||
|
template <typename Matcher1, typename Matcher2>
|
||||||
|
class EitherOfMatcher {
|
||||||
|
public:
|
||||||
|
EitherOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
|
||||||
|
: matcher1_(matcher1), matcher2_(matcher2) {}
|
||||||
|
|
||||||
|
// This template type conversion operator allows a
|
||||||
|
// EitherOfMatcher<Matcher1, Matcher2> object to match any type that
|
||||||
|
// both Matcher1 and Matcher2 can match.
|
||||||
|
template <typename T>
|
||||||
|
operator Matcher<T>() const {
|
||||||
|
return Matcher<T>(new EitherOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_),
|
||||||
|
SafeMatcherCast<T>(matcher2_)));
|
||||||
|
}
|
||||||
|
private:
|
||||||
Matcher1 matcher1_;
|
Matcher1 matcher1_;
|
||||||
Matcher2 matcher2_;
|
Matcher2 matcher2_;
|
||||||
};
|
};
|
||||||
|
@ -211,7 +211,9 @@ class UniversalPrinter;
|
|||||||
// Used to print an STL-style container when the user doesn't define
|
// Used to print an STL-style container when the user doesn't define
|
||||||
// a PrintTo() for it.
|
// a PrintTo() for it.
|
||||||
template <typename C>
|
template <typename C>
|
||||||
void DefaultPrintTo(IsContainer, const C& container, ::std::ostream* os) {
|
void DefaultPrintTo(IsContainer /* dummy */,
|
||||||
|
false_type /* is not a pointer */,
|
||||||
|
const C& container, ::std::ostream* os) {
|
||||||
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||||
*os << '{';
|
*os << '{';
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
@ -234,9 +236,31 @@ void DefaultPrintTo(IsContainer, const C& container, ::std::ostream* os) {
|
|||||||
*os << '}';
|
*os << '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to print a value when the user doesn't define PrintTo() for it.
|
// Used to print a pointer that is neither a char pointer nor a member
|
||||||
|
// pointer, when the user doesn't define PrintTo() for it. (A member
|
||||||
|
// variable pointer or member function pointer doesn't really point to
|
||||||
|
// a location in the address space. Their representation is
|
||||||
|
// implementation-defined. Therefore they will be printed as raw
|
||||||
|
// bytes.)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void DefaultPrintTo(IsNotContainer, const T& value, ::std::ostream* os) {
|
void DefaultPrintTo(IsNotContainer /* dummy */,
|
||||||
|
true_type /* is a pointer */,
|
||||||
|
T* p, ::std::ostream* os) {
|
||||||
|
if (p == NULL) {
|
||||||
|
*os << "NULL";
|
||||||
|
} else {
|
||||||
|
// We cannot use implicit_cast or static_cast here, as they don't
|
||||||
|
// work when p is a function pointer.
|
||||||
|
*os << reinterpret_cast<const void*>(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to print a non-container, non-pointer value when the user
|
||||||
|
// doesn't define PrintTo() for it.
|
||||||
|
template <typename T>
|
||||||
|
void DefaultPrintTo(IsNotContainer /* dummy */,
|
||||||
|
false_type /* is not a pointer */,
|
||||||
|
const T& value, ::std::ostream* os) {
|
||||||
::testing_internal::DefaultPrintNonContainerTo(value, os);
|
::testing_internal::DefaultPrintNonContainerTo(value, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,10 +277,11 @@ void DefaultPrintTo(IsNotContainer, const T& value, ::std::ostream* os) {
|
|||||||
// wants).
|
// wants).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void PrintTo(const T& value, ::std::ostream* os) {
|
void PrintTo(const T& value, ::std::ostream* os) {
|
||||||
// DefaultPrintTo() is overloaded. The type of its first argument
|
// DefaultPrintTo() is overloaded. The type of its first two
|
||||||
// determines which version will be picked. If T is an STL-style
|
// arguments determine which version will be picked. If T is an
|
||||||
// container, the version for container will be called. Otherwise
|
// STL-style container, the version for container will be called; if
|
||||||
// the generic version will be called.
|
// T is a pointer, the pointer version will be called; otherwise the
|
||||||
|
// generic version will be called.
|
||||||
//
|
//
|
||||||
// Note that we check for container types here, prior to we check
|
// Note that we check for container types here, prior to we check
|
||||||
// for protocol message types in our operator<<. The rationale is:
|
// for protocol message types in our operator<<. The rationale is:
|
||||||
@ -267,7 +292,14 @@ void PrintTo(const T& value, ::std::ostream* os) {
|
|||||||
// incompatible with Google Mock's format for the container
|
// incompatible with Google Mock's format for the container
|
||||||
// elements; therefore we check for container types here to ensure
|
// elements; therefore we check for container types here to ensure
|
||||||
// that our format is used.
|
// that our format is used.
|
||||||
DefaultPrintTo(IsContainerTest<T>(0), value, os);
|
//
|
||||||
|
// The second argument of DefaultPrintTo() is needed to bypass a bug
|
||||||
|
// in Symbian's C++ compiler that prevents it from picking the right
|
||||||
|
// overload between:
|
||||||
|
//
|
||||||
|
// PrintTo(const T& x, ...);
|
||||||
|
// PrintTo(T* x, ...);
|
||||||
|
DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following list of PrintTo() overloads tells
|
// The following list of PrintTo() overloads tells
|
||||||
@ -323,22 +355,6 @@ inline void PrintTo(wchar_t* s, ::std::ostream* os) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Overload for pointers that are neither char pointers nor member
|
|
||||||
// pointers. (A member variable pointer or member function pointer
|
|
||||||
// doesn't really points to a location in the address space. Their
|
|
||||||
// representation is implementation-defined. Therefore they will be
|
|
||||||
// printed as raw bytes.)
|
|
||||||
template <typename T>
|
|
||||||
void PrintTo(T* p, ::std::ostream* os) {
|
|
||||||
if (p == NULL) {
|
|
||||||
*os << "NULL";
|
|
||||||
} else {
|
|
||||||
// We cannot use implicit_cast or static_cast here, as they don't
|
|
||||||
// work when p is a function pointer.
|
|
||||||
*os << reinterpret_cast<const void*>(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overload for C arrays. Multi-dimensional arrays are printed
|
// Overload for C arrays. Multi-dimensional arrays are printed
|
||||||
// properly.
|
// properly.
|
||||||
|
|
||||||
|
@ -162,7 +162,9 @@ inline To down_cast(From* f) { // so we only accept pointers
|
|||||||
implicit_cast<From*, To>(0);
|
implicit_cast<From*, To>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_RTTI
|
||||||
assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
|
assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
|
||||||
|
#endif
|
||||||
return static_cast<To>(f);
|
return static_cast<To>(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,16 +646,15 @@ TEST(SetArgumentPointeeTest, SetsTheNthPointee) {
|
|||||||
|
|
||||||
#if GMOCK_HAS_PROTOBUF_
|
#if GMOCK_HAS_PROTOBUF_
|
||||||
|
|
||||||
// Tests that SetArgumentPointee<N>(proto_buffer) sets the variable
|
// Tests that SetArgumentPointee<N>(proto_buffer) sets the v1 protobuf
|
||||||
// pointed to by the N-th (0-based) argument to proto_buffer.
|
// variable pointed to by the N-th (0-based) argument to proto_buffer.
|
||||||
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferType) {
|
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferType) {
|
||||||
typedef void MyFunction(bool, TestMessage*);
|
|
||||||
TestMessage* const msg = new TestMessage;
|
TestMessage* const msg = new TestMessage;
|
||||||
msg->set_member("yes");
|
msg->set_member("yes");
|
||||||
TestMessage orig_msg;
|
TestMessage orig_msg;
|
||||||
orig_msg.CopyFrom(*msg);
|
orig_msg.CopyFrom(*msg);
|
||||||
|
|
||||||
Action<MyFunction> a = SetArgumentPointee<1>(*msg);
|
Action<void(bool, TestMessage*)> a = SetArgumentPointee<1>(*msg);
|
||||||
// SetArgumentPointee<N>(proto_buffer) makes a copy of proto_buffer
|
// SetArgumentPointee<N>(proto_buffer) makes a copy of proto_buffer
|
||||||
// s.t. the action works even when the original proto_buffer has
|
// s.t. the action works even when the original proto_buffer has
|
||||||
// died. We ensure this behavior by deleting msg before using the
|
// died. We ensure this behavior by deleting msg before using the
|
||||||
@ -668,18 +667,41 @@ TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferType) {
|
|||||||
EXPECT_TRUE(orig_msg.Equals(dest));
|
EXPECT_TRUE(orig_msg.Equals(dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that SetArgumentPointee<N>(proto2_buffer) sets the variable
|
// Tests that SetArgumentPointee<N>(proto_buffer) sets the
|
||||||
// pointed to by the N-th (0-based) argument to proto2_buffer.
|
// ::ProtocolMessage variable pointed to by the N-th (0-based)
|
||||||
|
// argument to proto_buffer.
|
||||||
|
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferBaseType) {
|
||||||
|
TestMessage* const msg = new TestMessage;
|
||||||
|
msg->set_member("yes");
|
||||||
|
TestMessage orig_msg;
|
||||||
|
orig_msg.CopyFrom(*msg);
|
||||||
|
|
||||||
|
Action<void(bool, ::ProtocolMessage*)> a = SetArgumentPointee<1>(*msg);
|
||||||
|
// SetArgumentPointee<N>(proto_buffer) makes a copy of proto_buffer
|
||||||
|
// s.t. the action works even when the original proto_buffer has
|
||||||
|
// died. We ensure this behavior by deleting msg before using the
|
||||||
|
// action.
|
||||||
|
delete msg;
|
||||||
|
|
||||||
|
TestMessage dest;
|
||||||
|
::ProtocolMessage* const dest_base = &dest;
|
||||||
|
EXPECT_FALSE(orig_msg.Equals(dest));
|
||||||
|
a.Perform(make_tuple(true, dest_base));
|
||||||
|
EXPECT_TRUE(orig_msg.Equals(dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that SetArgumentPointee<N>(proto2_buffer) sets the v2
|
||||||
|
// protobuf variable pointed to by the N-th (0-based) argument to
|
||||||
|
// proto2_buffer.
|
||||||
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferType) {
|
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferType) {
|
||||||
using testing::internal::FooMessage;
|
using testing::internal::FooMessage;
|
||||||
typedef void MyFunction(bool, FooMessage*);
|
|
||||||
FooMessage* const msg = new FooMessage;
|
FooMessage* const msg = new FooMessage;
|
||||||
msg->set_int_field(2);
|
msg->set_int_field(2);
|
||||||
msg->set_string_field("hi");
|
msg->set_string_field("hi");
|
||||||
FooMessage orig_msg;
|
FooMessage orig_msg;
|
||||||
orig_msg.CopyFrom(*msg);
|
orig_msg.CopyFrom(*msg);
|
||||||
|
|
||||||
Action<MyFunction> a = SetArgumentPointee<1>(*msg);
|
Action<void(bool, FooMessage*)> a = SetArgumentPointee<1>(*msg);
|
||||||
// SetArgumentPointee<N>(proto2_buffer) makes a copy of
|
// SetArgumentPointee<N>(proto2_buffer) makes a copy of
|
||||||
// proto2_buffer s.t. the action works even when the original
|
// proto2_buffer s.t. the action works even when the original
|
||||||
// proto2_buffer has died. We ensure this behavior by deleting msg
|
// proto2_buffer has died. We ensure this behavior by deleting msg
|
||||||
@ -693,6 +715,32 @@ TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferType) {
|
|||||||
EXPECT_EQ("hi", dest.string_field());
|
EXPECT_EQ("hi", dest.string_field());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that SetArgumentPointee<N>(proto2_buffer) sets the
|
||||||
|
// proto2::Message variable pointed to by the N-th (0-based) argument
|
||||||
|
// to proto2_buffer.
|
||||||
|
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferBaseType) {
|
||||||
|
using testing::internal::FooMessage;
|
||||||
|
FooMessage* const msg = new FooMessage;
|
||||||
|
msg->set_int_field(2);
|
||||||
|
msg->set_string_field("hi");
|
||||||
|
FooMessage orig_msg;
|
||||||
|
orig_msg.CopyFrom(*msg);
|
||||||
|
|
||||||
|
Action<void(bool, ::proto2::Message*)> a = SetArgumentPointee<1>(*msg);
|
||||||
|
// SetArgumentPointee<N>(proto2_buffer) makes a copy of
|
||||||
|
// proto2_buffer s.t. the action works even when the original
|
||||||
|
// proto2_buffer has died. We ensure this behavior by deleting msg
|
||||||
|
// before using the action.
|
||||||
|
delete msg;
|
||||||
|
|
||||||
|
FooMessage dest;
|
||||||
|
dest.set_int_field(0);
|
||||||
|
::proto2::Message* const dest_base = &dest;
|
||||||
|
a.Perform(make_tuple(true, dest_base));
|
||||||
|
EXPECT_EQ(2, dest.int_field());
|
||||||
|
EXPECT_EQ("hi", dest.string_field());
|
||||||
|
}
|
||||||
|
|
||||||
#endif // GMOCK_HAS_PROTOBUF_
|
#endif // GMOCK_HAS_PROTOBUF_
|
||||||
|
|
||||||
// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
|
// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
|
||||||
|
Loading…
x
Reference in New Issue
Block a user