aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386>2010-07-03 00:16:42 +0000
committerzhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386>2010-07-03 00:16:42 +0000
commite3bd0981ca06e682bcd03659286d7a3267c4d999 (patch)
treef5d9cad74e0398f6b18613220b5c7b0c52464a0d
parent02c1505ebfaadbc34b4cb85546796521d6f0e634 (diff)
downloadgoogletest-e3bd0981ca06e682bcd03659286d7a3267c4d999.tar.gz
googletest-e3bd0981ca06e682bcd03659286d7a3267c4d999.tar.bz2
googletest-e3bd0981ca06e682bcd03659286d7a3267c4d999.zip
Implements ReturnPointee() and ReturnRefOfCopy().
-rw-r--r--include/gmock/gmock-actions.h57
-rw-r--r--include/gmock/gmock-more-actions.h3
-rw-r--r--test/gmock-actions_test.cc25
-rw-r--r--test/gmock-more-actions_test.cc10
4 files changed, 95 insertions, 0 deletions
diff --git a/include/gmock/gmock-actions.h b/include/gmock/gmock-actions.h
index 9fe19644..ddaaef24 100644
--- a/include/gmock/gmock-actions.h
+++ b/include/gmock/gmock-actions.h
@@ -584,6 +584,55 @@ class ReturnRefAction {
GTEST_DISALLOW_ASSIGN_(ReturnRefAction);
};
+// Implements the polymorphic ReturnRefOfCopy(x) action, which can be
+// used in any function that returns a reference to the type of x,
+// regardless of the argument types.
+template <typename T>
+class ReturnRefOfCopyAction {
+ public:
+ // Constructs a ReturnRefOfCopyAction object from the reference to
+ // be returned.
+ explicit ReturnRefOfCopyAction(const T& value) : value_(value) {} // NOLINT
+
+ // This template type conversion operator allows ReturnRefOfCopy(x) to be
+ // used in ANY function that returns a reference to x's type.
+ template <typename F>
+ operator Action<F>() const {
+ typedef typename Function<F>::Result Result;
+ // Asserts that the function return type is a reference. This
+ // catches the user error of using ReturnRefOfCopy(x) when Return(x)
+ // should be used, and generates some helpful error message.
+ GTEST_COMPILE_ASSERT_(
+ internal::is_reference<Result>::value,
+ use_Return_instead_of_ReturnRefOfCopy_to_return_a_value);
+ return Action<F>(new Impl<F>(value_));
+ }
+
+ private:
+ // Implements the ReturnRefOfCopy(x) action for a particular function type F.
+ template <typename F>
+ class Impl : public ActionInterface<F> {
+ public:
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+
+ explicit Impl(const T& value) : value_(value) {} // NOLINT
+
+ virtual Result Perform(const ArgumentTuple&) {
+ return value_;
+ }
+
+ private:
+ T value_;
+
+ GTEST_DISALLOW_ASSIGN_(Impl);
+ };
+
+ const T value_;
+
+ GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction);
+};
+
// Implements the DoDefault() action for a particular function type F.
template <typename F>
class MonomorphicDoDefaultActionImpl : public ActionInterface<F> {
@@ -948,6 +997,14 @@ inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT
return internal::ReturnRefAction<R>(x);
}
+// Creates an action that returns the reference to a copy of the
+// argument. The copy is created when the action is constructed and
+// lives as long as the action.
+template <typename R>
+inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) {
+ return internal::ReturnRefOfCopyAction<R>(x);
+}
+
// Creates an action that does the default action for the give mock function.
inline internal::DoDefaultAction DoDefault() {
return internal::DoDefaultAction();
diff --git a/include/gmock/gmock-more-actions.h b/include/gmock/gmock-more-actions.h
index 6d686cd1..c60557e6 100644
--- a/include/gmock/gmock-more-actions.h
+++ b/include/gmock/gmock-more-actions.h
@@ -195,6 +195,9 @@ ACTION_TEMPLATE(DeleteArg,
delete ::std::tr1::get<k>(args);
}
+// This action returns the value pointed to by 'pointer'.
+ACTION_P(ReturnPointee, pointer) { return *pointer; }
+
// Action Throw(exception) can be used in a mock function of any type
// to throw the given exception. Any copyable value can be thrown.
#if GTEST_HAS_EXCEPTIONS
diff --git a/test/gmock-actions_test.cc b/test/gmock-actions_test.cc
index 8391e5fe..50cc6f98 100644
--- a/test/gmock-actions_test.cc
+++ b/test/gmock-actions_test.cc
@@ -68,6 +68,7 @@ using testing::PolymorphicAction;
using testing::Return;
using testing::ReturnNull;
using testing::ReturnRef;
+using testing::ReturnRefOfCopy;
using testing::SetArgumentPointee;
#if !GTEST_OS_WINDOWS_MOBILE
@@ -584,6 +585,30 @@ TEST(ReturnRefTest, IsCovariant) {
EXPECT_EQ(&derived, &a.Perform(make_tuple()));
}
+// Tests that ReturnRefOfCopy(v) works for reference types.
+TEST(ReturnRefOfCopyTest, WorksForReference) {
+ int n = 42;
+ const Action<const int&()> ret = ReturnRefOfCopy(n);
+
+ EXPECT_NE(&n, &ret.Perform(make_tuple()));
+ EXPECT_EQ(42, ret.Perform(make_tuple()));
+
+ n = 43;
+ EXPECT_NE(&n, &ret.Perform(make_tuple()));
+ EXPECT_EQ(42, ret.Perform(make_tuple()));
+}
+
+// Tests that ReturnRefOfCopy(v) is covariant.
+TEST(ReturnRefOfCopyTest, IsCovariant) {
+ Base base;
+ Derived derived;
+ Action<Base&()> a = ReturnRefOfCopy(base);
+ EXPECT_NE(&base, &a.Perform(make_tuple()));
+
+ a = ReturnRefOfCopy(derived);
+ EXPECT_NE(&derived, &a.Perform(make_tuple()));
+}
+
// Tests that DoDefault() does the default action for the mock method.
class MyClass {};
diff --git a/test/gmock-more-actions_test.cc b/test/gmock-more-actions_test.cc
index b3b17d33..be7b1273 100644
--- a/test/gmock-more-actions_test.cc
+++ b/test/gmock-more-actions_test.cc
@@ -57,6 +57,7 @@ using testing::DeleteArg;
using testing::Invoke;
using testing::Return;
using testing::ReturnArg;
+using testing::ReturnPointee;
using testing::SaveArg;
using testing::SetArgReferee;
using testing::SetArgumentPointee;
@@ -664,5 +665,14 @@ TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
EXPECT_EQ(letters, s);
}
+TEST(ReturnPointeeTest, Works) {
+ int n = 42;
+ const Action<int()> a = ReturnPointee(&n);
+ EXPECT_EQ(42, a.Perform(make_tuple()));
+
+ n = 43;
+ EXPECT_EQ(43, a.Perform(make_tuple()));
+}
+
} // namespace gmock_generated_actions_test
} // namespace testing