From 7123d831328321e854b78047effe7a57192a764f Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 17 Nov 2014 02:04:46 +0000 Subject: [PATCH] Fix gmock Action behaviour when return type is Wrapper --- include/gmock/gmock-actions.h | 8 ++++++-- test/gmock-actions_test.cc | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/gmock/gmock-actions.h b/include/gmock/gmock-actions.h index de502048..f92e479f 100644 --- a/include/gmock/gmock-actions.h +++ b/include/gmock/gmock-actions.h @@ -534,16 +534,20 @@ class ReturnAction { // Result without considering explicit constructors, thus resolving the // ambiguity. value_ is then initialized using its copy constructor. explicit Impl(const linked_ptr& value) - : value_(ImplicitCast_(*value)) {} + : value_before_cast_(*value), + value_(ImplicitCast_(value_before_cast_)) {} virtual Result Perform(const ArgumentTuple&) { return value_; } private: GTEST_COMPILE_ASSERT_(!is_reference::value, Result_cannot_be_a_reference_type); + // We save the value before casting just in case it is being cast to a + // wrapper type. + R value_before_cast_; Result value_; - GTEST_DISALLOW_ASSIGN_(Impl); + GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); }; // Partially specialize for ByMoveWrapper. This version of ReturnAction will diff --git a/test/gmock-actions_test.cc b/test/gmock-actions_test.cc index 28b48f16..8089a81d 100644 --- a/test/gmock-actions_test.cc +++ b/test/gmock-actions_test.cc @@ -509,6 +509,26 @@ TEST(ReturnTest, AcceptsStringLiteral) { EXPECT_EQ("world", a2.Perform(make_tuple())); } +// Test struct which wraps a vector of integers. Used in +// 'SupportsWrapperReturnType' test. +struct IntegerVectorWrapper { + std::vector * v; + IntegerVectorWrapper(std::vector& _v) : v(&_v) {} // NOLINT +}; + +// Tests that Return() works when return type is a wrapper type. +TEST(ReturnTest, SupportsWrapperReturnType) { + // Initialize vector of integers. + std::vector v; + for (int i = 0; i < 5; ++i) v.push_back(i); + + // Return() called with 'v' as argument. The Action will return the same data + // as 'v' (copy) but it will be wrapped in an IntegerVectorWrapper. + Action a = Return(v); + const std::vector& result = *(a.Perform(make_tuple()).v); + EXPECT_THAT(result, ::testing::ElementsAre(0, 1, 2, 3, 4)); +} + // Tests that Return(v) is covaraint. struct Base {