Implements ReturnPointee() and ReturnRefOfCopy().

This commit is contained in:
zhanyong.wan 2010-07-03 00:16:42 +00:00
parent 02c1505ebf
commit e3bd0981ca
4 changed files with 95 additions and 0 deletions

View File

@ -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();

View File

@ -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

View File

@ -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 {};

View File

@ -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