mirror of
https://github.com/google/googletest.git
synced 2024-12-27 10:11:03 +08:00
Re-organizes the file structure for actions.
This commit is contained in:
parent
1afe1c7971
commit
a18423e0ee
@ -110,6 +110,11 @@ check_PROGRAMS += test/gmock-matchers_test
|
||||
test_gmock_matchers_test_SOURCES = test/gmock-matchers_test.cc
|
||||
test_gmock_matchers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-more-actions_test
|
||||
check_PROGRAMS += test/gmock-more-actions_test
|
||||
test_gmock_more_actions_test_SOURCES = test/gmock-more-actions_test.cc
|
||||
test_gmock_more_actions_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-nice-strict_test
|
||||
check_PROGRAMS += test/gmock-nice-strict_test
|
||||
test_gmock_nice_strict_test_SOURCES = test/gmock-nice-strict_test.cc
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <gmock/gmock-printers.h>
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
@ -787,6 +788,74 @@ class IgnoreResultAction {
|
||||
const A action_;
|
||||
};
|
||||
|
||||
// A ReferenceWrapper<T> object represents a reference to type T,
|
||||
// which can be either const or not. It can be explicitly converted
|
||||
// from, and implicitly converted to, a T&. Unlike a reference,
|
||||
// ReferenceWrapper<T> can be copied and can survive template type
|
||||
// inference. This is used to support by-reference arguments in the
|
||||
// InvokeArgument<N>(...) action. The idea was from "reference
|
||||
// wrappers" in tr1, which we don't have in our source tree yet.
|
||||
template <typename T>
|
||||
class ReferenceWrapper {
|
||||
public:
|
||||
// Constructs a ReferenceWrapper<T> object from a T&.
|
||||
explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
|
||||
|
||||
// Allows a ReferenceWrapper<T> object to be implicitly converted to
|
||||
// a T&.
|
||||
operator T&() const { return *pointer_; }
|
||||
private:
|
||||
T* pointer_;
|
||||
};
|
||||
|
||||
// Allows the expression ByRef(x) to be printed as a reference to x.
|
||||
template <typename T>
|
||||
void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
|
||||
T& value = ref;
|
||||
UniversalPrinter<T&>::Print(value, os);
|
||||
}
|
||||
|
||||
// Does two actions sequentially. Used for implementing the DoAll(a1,
|
||||
// a2, ...) action.
|
||||
template <typename Action1, typename Action2>
|
||||
class DoBothAction {
|
||||
public:
|
||||
DoBothAction(Action1 action1, Action2 action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
// This template type conversion operator allows DoAll(a1, ..., a_n)
|
||||
// to be used in ANY function of compatible type.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
return Action<F>(new Impl<F>(action1_, action2_));
|
||||
}
|
||||
|
||||
private:
|
||||
// Implements the DoAll(...) 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;
|
||||
typedef typename Function<F>::MakeResultVoid VoidResult;
|
||||
|
||||
Impl(const Action<VoidResult>& action1, const Action<F>& action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
action1_.Perform(args);
|
||||
return action2_.Perform(args);
|
||||
}
|
||||
|
||||
private:
|
||||
const Action<VoidResult> action1_;
|
||||
const Action<F> action2_;
|
||||
};
|
||||
|
||||
Action1 action1_;
|
||||
Action2 action2_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// An Unused object can be implicitly constructed from ANY value.
|
||||
@ -926,6 +995,18 @@ inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {
|
||||
return internal::IgnoreResultAction<A>(an_action);
|
||||
}
|
||||
|
||||
// Creates a reference wrapper for the given L-value. If necessary,
|
||||
// you can explicitly specify the type of the reference. For example,
|
||||
// suppose 'derived' is an object of type Derived, ByRef(derived)
|
||||
// would wrap a Derived&. If you want to wrap a const Base& instead,
|
||||
// where Base is a base class of Derived, just write:
|
||||
//
|
||||
// ByRef<const Base>(derived)
|
||||
template <typename T>
|
||||
inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
|
||||
return internal::ReferenceWrapper<T>(l_value);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||
|
@ -39,7 +39,6 @@
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
|
||||
#include <gmock/gmock-actions.h>
|
||||
#include <gmock/gmock-printers.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
@ -283,75 +282,6 @@ class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Implements the Invoke(f) action. The template argument
|
||||
// FunctionImpl is the implementation type of f, which can be either a
|
||||
// function pointer or a functor. Invoke(f) can be used as an
|
||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
||||
// assigned to a tr1::function<F>).
|
||||
template <typename FunctionImpl>
|
||||
class InvokeAction {
|
||||
public:
|
||||
// The c'tor makes a copy of function_impl (either a function
|
||||
// pointer or a functor).
|
||||
explicit InvokeAction(FunctionImpl function_impl)
|
||||
: function_impl_(function_impl) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) {
|
||||
return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
|
||||
}
|
||||
private:
|
||||
FunctionImpl function_impl_;
|
||||
};
|
||||
|
||||
// Implements the Invoke(object_ptr, &Class::Method) action.
|
||||
template <class Class, typename MethodPtr>
|
||||
class InvokeMethodAction {
|
||||
public:
|
||||
InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
|
||||
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) const {
|
||||
return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
|
||||
obj_ptr_, method_ptr_, args);
|
||||
}
|
||||
private:
|
||||
Class* const obj_ptr_;
|
||||
const MethodPtr method_ptr_;
|
||||
};
|
||||
|
||||
// TODO(wan@google.com): ReferenceWrapper and ByRef() are neither
|
||||
// action-specific nor variadic. Move them to a better place.
|
||||
|
||||
// A ReferenceWrapper<T> object represents a reference to type T,
|
||||
// which can be either const or not. It can be explicitly converted
|
||||
// from, and implicitly converted to, a T&. Unlike a reference,
|
||||
// ReferenceWrapper<T> can be copied and can survive template type
|
||||
// inference. This is used to support by-reference arguments in the
|
||||
// InvokeArgument<N>(...) action. The idea was from "reference
|
||||
// wrappers" in tr1, which we don't have in our source tree yet.
|
||||
template <typename T>
|
||||
class ReferenceWrapper {
|
||||
public:
|
||||
// Constructs a ReferenceWrapper<T> object from a T&.
|
||||
explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
|
||||
|
||||
// Allows a ReferenceWrapper<T> object to be implicitly converted to
|
||||
// a T&.
|
||||
operator T&() const { return *pointer_; }
|
||||
private:
|
||||
T* pointer_;
|
||||
};
|
||||
|
||||
// Allows the expression ByRef(x) to be printed as a reference to x.
|
||||
template <typename T>
|
||||
void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
|
||||
T& value = ref;
|
||||
UniversalPrinter<T&>::Print(value, os);
|
||||
}
|
||||
|
||||
// CallableHelper has static methods for invoking "callables",
|
||||
// i.e. function pointers and functors. It uses overloading to
|
||||
// provide a uniform interface for invoking different kinds of
|
||||
@ -687,47 +617,6 @@ class WithArgsAction {
|
||||
const InnerAction action_;
|
||||
};
|
||||
|
||||
// Does two actions sequentially. Used for implementing the DoAll(a1,
|
||||
// a2, ...) action.
|
||||
template <typename Action1, typename Action2>
|
||||
class DoBothAction {
|
||||
public:
|
||||
DoBothAction(Action1 action1, Action2 action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
// This template type conversion operator allows DoAll(a1, ..., a_n)
|
||||
// to be used in ANY function of compatible type.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
return Action<F>(new Impl<F>(action1_, action2_));
|
||||
}
|
||||
|
||||
private:
|
||||
// Implements the DoAll(...) 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;
|
||||
typedef typename Function<F>::MakeResultVoid VoidResult;
|
||||
|
||||
Impl(const Action<VoidResult>& action1, const Action<F>& action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
action1_.Perform(args);
|
||||
return action2_.Perform(args);
|
||||
}
|
||||
|
||||
private:
|
||||
const Action<VoidResult> action1_;
|
||||
const Action<F> action2_;
|
||||
};
|
||||
|
||||
Action1 action1_;
|
||||
Action2 action2_;
|
||||
};
|
||||
|
||||
// A macro from the ACTION* family (defined later in this file)
|
||||
// defines an action that can be used in a mock function. Typically,
|
||||
// these actions only care about a subset of the arguments of the mock
|
||||
@ -863,57 +752,6 @@ class ActionHelper {
|
||||
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// Creates an action that invokes 'function_impl' with the mock
|
||||
// function's arguments.
|
||||
template <typename FunctionImpl>
|
||||
PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
|
||||
FunctionImpl function_impl) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeAction<FunctionImpl>(function_impl));
|
||||
}
|
||||
|
||||
// Creates an action that invokes the given method on the given object
|
||||
// with the mock function's arguments.
|
||||
template <class Class, typename MethodPtr>
|
||||
PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
|
||||
Class* obj_ptr, MethodPtr method_ptr) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
|
||||
}
|
||||
|
||||
// Creates a reference wrapper for the given L-value. If necessary,
|
||||
// you can explicitly specify the type of the reference. For example,
|
||||
// suppose 'derived' is an object of type Derived, ByRef(derived)
|
||||
// would wrap a Derived&. If you want to wrap a const Base& instead,
|
||||
// where Base is a base class of Derived, just write:
|
||||
//
|
||||
// ByRef<const Base>(derived)
|
||||
template <typename T>
|
||||
inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
|
||||
return internal::ReferenceWrapper<T>(l_value);
|
||||
}
|
||||
|
||||
// WithoutArgs(inner_action) can be used in a mock function with a
|
||||
// non-empty argument list to perform inner_action, which takes no
|
||||
// argument. In other words, it adapts an action accepting no
|
||||
// argument to one that accepts (and ignores) arguments.
|
||||
template <typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction>
|
||||
WithoutArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction>(action);
|
||||
}
|
||||
|
||||
// WithArg<k>(an_action) creates an action that passes the k-th
|
||||
// (0-based) argument of the mock function to an_action and performs
|
||||
// it. It adapts an action accepting one argument to one that accepts
|
||||
// multiple arguments. For convenience, we also provide
|
||||
// WithArgs<k>(an_action) (defined below) as a synonym.
|
||||
template <int k, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k>
|
||||
WithArg(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k>(action);
|
||||
}
|
||||
|
||||
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
||||
// the selected arguments of the mock function to an_action and
|
||||
// performs it. It serves as an adaptor between actions with
|
||||
@ -2441,55 +2279,6 @@ ACTION_TEMPLATE(InvokeArgument,
|
||||
::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
}
|
||||
|
||||
// Action ReturnArg<k>() returns the k-th argument of the mock function.
|
||||
ACTION_TEMPLATE(ReturnArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
return std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
|
||||
// mock function to *pointer.
|
||||
ACTION_TEMPLATE(SaveArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(pointer)) {
|
||||
*pointer = ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SetArgReferee<k>(value) assigns 'value' to the variable
|
||||
// referenced by the k-th (0-based) argument of the mock function.
|
||||
ACTION_TEMPLATE(SetArgReferee,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(value)) {
|
||||
typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
|
||||
// Ensures that argument #k is a reference. If you get a compiler
|
||||
// error on the next line, you are using SetArgReferee<k>(value) in
|
||||
// a mock function whose k-th (0-based) argument is not a reference.
|
||||
GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
|
||||
SetArgReferee_must_be_used_with_a_reference_argument);
|
||||
::std::tr1::get<k>(args) = value;
|
||||
}
|
||||
|
||||
// Action SetArrayArgument<k>(first, last) copies the elements in
|
||||
// source range [first, last) to the array pointed to by the k-th
|
||||
// (0-based) argument, which can be either a pointer or an
|
||||
// iterator. The action does not take ownership of the elements in the
|
||||
// source range.
|
||||
ACTION_TEMPLATE(SetArrayArgument,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_2_VALUE_PARAMS(first, last)) {
|
||||
// Microsoft compiler deprecates ::std::copy, so we want to suppress warning
|
||||
// 4996 (Function call with parameters that may be unsafe) there.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||
#endif
|
||||
::std::copy(first, last, ::std::tr1::get<k>(args));
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif
|
||||
}
|
||||
|
||||
// Various overloads for ReturnNew<T>().
|
||||
//
|
||||
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
|
||||
@ -2561,20 +2350,6 @@ ACTION_TEMPLATE(ReturnNew,
|
||||
return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
}
|
||||
|
||||
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
|
||||
// function.
|
||||
ACTION_TEMPLATE(DeleteArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
delete ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// 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
|
||||
ACTION_P(Throw, exception) { throw exception; }
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
|
@ -43,7 +43,6 @@ $$}} This meta comment fixes auto-indentation in editors.
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
|
||||
#include <gmock/gmock-actions.h>
|
||||
#include <gmock/gmock-printers.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
@ -85,75 +84,6 @@ $import return (obj_ptr->*method_ptr)($gets);
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Implements the Invoke(f) action. The template argument
|
||||
// FunctionImpl is the implementation type of f, which can be either a
|
||||
// function pointer or a functor. Invoke(f) can be used as an
|
||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
||||
// assigned to a tr1::function<F>).
|
||||
template <typename FunctionImpl>
|
||||
class InvokeAction {
|
||||
public:
|
||||
// The c'tor makes a copy of function_impl (either a function
|
||||
// pointer or a functor).
|
||||
explicit InvokeAction(FunctionImpl function_impl)
|
||||
: function_impl_(function_impl) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) {
|
||||
return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
|
||||
}
|
||||
private:
|
||||
FunctionImpl function_impl_;
|
||||
};
|
||||
|
||||
// Implements the Invoke(object_ptr, &Class::Method) action.
|
||||
template <class Class, typename MethodPtr>
|
||||
class InvokeMethodAction {
|
||||
public:
|
||||
InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
|
||||
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) const {
|
||||
return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
|
||||
obj_ptr_, method_ptr_, args);
|
||||
}
|
||||
private:
|
||||
Class* const obj_ptr_;
|
||||
const MethodPtr method_ptr_;
|
||||
};
|
||||
|
||||
// TODO(wan@google.com): ReferenceWrapper and ByRef() are neither
|
||||
// action-specific nor variadic. Move them to a better place.
|
||||
|
||||
// A ReferenceWrapper<T> object represents a reference to type T,
|
||||
// which can be either const or not. It can be explicitly converted
|
||||
// from, and implicitly converted to, a T&. Unlike a reference,
|
||||
// ReferenceWrapper<T> can be copied and can survive template type
|
||||
// inference. This is used to support by-reference arguments in the
|
||||
// InvokeArgument<N>(...) action. The idea was from "reference
|
||||
// wrappers" in tr1, which we don't have in our source tree yet.
|
||||
template <typename T>
|
||||
class ReferenceWrapper {
|
||||
public:
|
||||
// Constructs a ReferenceWrapper<T> object from a T&.
|
||||
explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
|
||||
|
||||
// Allows a ReferenceWrapper<T> object to be implicitly converted to
|
||||
// a T&.
|
||||
operator T&() const { return *pointer_; }
|
||||
private:
|
||||
T* pointer_;
|
||||
};
|
||||
|
||||
// Allows the expression ByRef(x) to be printed as a reference to x.
|
||||
template <typename T>
|
||||
void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
|
||||
T& value = ref;
|
||||
UniversalPrinter<T&>::Print(value, os);
|
||||
}
|
||||
|
||||
// CallableHelper has static methods for invoking "callables",
|
||||
// i.e. function pointers and functors. It uses overloading to
|
||||
// provide a uniform interface for invoking different kinds of
|
||||
@ -300,47 +230,6 @@ class WithArgsAction {
|
||||
const InnerAction action_;
|
||||
};
|
||||
|
||||
// Does two actions sequentially. Used for implementing the DoAll(a1,
|
||||
// a2, ...) action.
|
||||
template <typename Action1, typename Action2>
|
||||
class DoBothAction {
|
||||
public:
|
||||
DoBothAction(Action1 action1, Action2 action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
// This template type conversion operator allows DoAll(a1, ..., a_n)
|
||||
// to be used in ANY function of compatible type.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
return Action<F>(new Impl<F>(action1_, action2_));
|
||||
}
|
||||
|
||||
private:
|
||||
// Implements the DoAll(...) 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;
|
||||
typedef typename Function<F>::MakeResultVoid VoidResult;
|
||||
|
||||
Impl(const Action<VoidResult>& action1, const Action<F>& action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
action1_.Perform(args);
|
||||
return action2_.Perform(args);
|
||||
}
|
||||
|
||||
private:
|
||||
const Action<VoidResult> action1_;
|
||||
const Action<F> action2_;
|
||||
};
|
||||
|
||||
Action1 action1_;
|
||||
Action2 action2_;
|
||||
};
|
||||
|
||||
// A macro from the ACTION* family (defined later in this file)
|
||||
// defines an action that can be used in a mock function. Typically,
|
||||
// these actions only care about a subset of the arguments of the mock
|
||||
@ -388,57 +277,6 @@ $template
|
||||
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// Creates an action that invokes 'function_impl' with the mock
|
||||
// function's arguments.
|
||||
template <typename FunctionImpl>
|
||||
PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
|
||||
FunctionImpl function_impl) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeAction<FunctionImpl>(function_impl));
|
||||
}
|
||||
|
||||
// Creates an action that invokes the given method on the given object
|
||||
// with the mock function's arguments.
|
||||
template <class Class, typename MethodPtr>
|
||||
PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
|
||||
Class* obj_ptr, MethodPtr method_ptr) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
|
||||
}
|
||||
|
||||
// Creates a reference wrapper for the given L-value. If necessary,
|
||||
// you can explicitly specify the type of the reference. For example,
|
||||
// suppose 'derived' is an object of type Derived, ByRef(derived)
|
||||
// would wrap a Derived&. If you want to wrap a const Base& instead,
|
||||
// where Base is a base class of Derived, just write:
|
||||
//
|
||||
// ByRef<const Base>(derived)
|
||||
template <typename T>
|
||||
inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
|
||||
return internal::ReferenceWrapper<T>(l_value);
|
||||
}
|
||||
|
||||
// WithoutArgs(inner_action) can be used in a mock function with a
|
||||
// non-empty argument list to perform inner_action, which takes no
|
||||
// argument. In other words, it adapts an action accepting no
|
||||
// argument to one that accepts (and ignores) arguments.
|
||||
template <typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction>
|
||||
WithoutArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction>(action);
|
||||
}
|
||||
|
||||
// WithArg<k>(an_action) creates an action that passes the k-th
|
||||
// (0-based) argument of the mock function to an_action and performs
|
||||
// it. It adapts an action accepting one argument to one that accepts
|
||||
// multiple arguments. For convenience, we also provide
|
||||
// WithArgs<k>(an_action) (defined below) as a synonym.
|
||||
template <int k, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k>
|
||||
WithArg(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k>(action);
|
||||
}
|
||||
|
||||
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
||||
// the selected arguments of the mock function to an_action and
|
||||
// performs it. It serves as an adaptor between actions with
|
||||
@ -940,55 +778,6 @@ ACTION_TEMPLATE(InvokeArgument,
|
||||
|
||||
]]
|
||||
|
||||
// Action ReturnArg<k>() returns the k-th argument of the mock function.
|
||||
ACTION_TEMPLATE(ReturnArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
return std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
|
||||
// mock function to *pointer.
|
||||
ACTION_TEMPLATE(SaveArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(pointer)) {
|
||||
*pointer = ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SetArgReferee<k>(value) assigns 'value' to the variable
|
||||
// referenced by the k-th (0-based) argument of the mock function.
|
||||
ACTION_TEMPLATE(SetArgReferee,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(value)) {
|
||||
typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
|
||||
// Ensures that argument #k is a reference. If you get a compiler
|
||||
// error on the next line, you are using SetArgReferee<k>(value) in
|
||||
// a mock function whose k-th (0-based) argument is not a reference.
|
||||
GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
|
||||
SetArgReferee_must_be_used_with_a_reference_argument);
|
||||
::std::tr1::get<k>(args) = value;
|
||||
}
|
||||
|
||||
// Action SetArrayArgument<k>(first, last) copies the elements in
|
||||
// source range [first, last) to the array pointed to by the k-th
|
||||
// (0-based) argument, which can be either a pointer or an
|
||||
// iterator. The action does not take ownership of the elements in the
|
||||
// source range.
|
||||
ACTION_TEMPLATE(SetArrayArgument,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_2_VALUE_PARAMS(first, last)) {
|
||||
// Microsoft compiler deprecates ::std::copy, so we want to suppress warning
|
||||
// 4996 (Function call with parameters that may be unsafe) there.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||
#endif
|
||||
::std::copy(first, last, ::std::tr1::get<k>(args));
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif
|
||||
}
|
||||
|
||||
// Various overloads for ReturnNew<T>().
|
||||
//
|
||||
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
|
||||
@ -1007,20 +796,6 @@ ACTION_TEMPLATE(ReturnNew,
|
||||
|
||||
]]
|
||||
|
||||
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
|
||||
// function.
|
||||
ACTION_TEMPLATE(DeleteArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
delete ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// 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
|
||||
ACTION_P(Throw, exception) { throw exception; }
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
|
190
include/gmock/gmock-more-actions.h
Normal file
190
include/gmock/gmock-more-actions.h
Normal file
@ -0,0 +1,190 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some actions that depend on gmock-generated-actions.h.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
|
||||
#include <gmock/gmock-generated-actions.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Implements the Invoke(f) action. The template argument
|
||||
// FunctionImpl is the implementation type of f, which can be either a
|
||||
// function pointer or a functor. Invoke(f) can be used as an
|
||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
||||
// assigned to a tr1::function<F>).
|
||||
template <typename FunctionImpl>
|
||||
class InvokeAction {
|
||||
public:
|
||||
// The c'tor makes a copy of function_impl (either a function
|
||||
// pointer or a functor).
|
||||
explicit InvokeAction(FunctionImpl function_impl)
|
||||
: function_impl_(function_impl) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) {
|
||||
return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
|
||||
}
|
||||
private:
|
||||
FunctionImpl function_impl_;
|
||||
};
|
||||
|
||||
// Implements the Invoke(object_ptr, &Class::Method) action.
|
||||
template <class Class, typename MethodPtr>
|
||||
class InvokeMethodAction {
|
||||
public:
|
||||
InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
|
||||
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) const {
|
||||
return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
|
||||
obj_ptr_, method_ptr_, args);
|
||||
}
|
||||
private:
|
||||
Class* const obj_ptr_;
|
||||
const MethodPtr method_ptr_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// Creates an action that invokes 'function_impl' with the mock
|
||||
// function's arguments.
|
||||
template <typename FunctionImpl>
|
||||
PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
|
||||
FunctionImpl function_impl) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeAction<FunctionImpl>(function_impl));
|
||||
}
|
||||
|
||||
// Creates an action that invokes the given method on the given object
|
||||
// with the mock function's arguments.
|
||||
template <class Class, typename MethodPtr>
|
||||
PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
|
||||
Class* obj_ptr, MethodPtr method_ptr) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
|
||||
}
|
||||
|
||||
// WithoutArgs(inner_action) can be used in a mock function with a
|
||||
// non-empty argument list to perform inner_action, which takes no
|
||||
// argument. In other words, it adapts an action accepting no
|
||||
// argument to one that accepts (and ignores) arguments.
|
||||
template <typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction>
|
||||
WithoutArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction>(action);
|
||||
}
|
||||
|
||||
// WithArg<k>(an_action) creates an action that passes the k-th
|
||||
// (0-based) argument of the mock function to an_action and performs
|
||||
// it. It adapts an action accepting one argument to one that accepts
|
||||
// multiple arguments. For convenience, we also provide
|
||||
// WithArgs<k>(an_action) (defined below) as a synonym.
|
||||
template <int k, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k>
|
||||
WithArg(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k>(action);
|
||||
}
|
||||
|
||||
// Action ReturnArg<k>() returns the k-th argument of the mock function.
|
||||
ACTION_TEMPLATE(ReturnArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
return std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
|
||||
// mock function to *pointer.
|
||||
ACTION_TEMPLATE(SaveArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(pointer)) {
|
||||
*pointer = ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SetArgReferee<k>(value) assigns 'value' to the variable
|
||||
// referenced by the k-th (0-based) argument of the mock function.
|
||||
ACTION_TEMPLATE(SetArgReferee,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(value)) {
|
||||
typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
|
||||
// Ensures that argument #k is a reference. If you get a compiler
|
||||
// error on the next line, you are using SetArgReferee<k>(value) in
|
||||
// a mock function whose k-th (0-based) argument is not a reference.
|
||||
GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
|
||||
SetArgReferee_must_be_used_with_a_reference_argument);
|
||||
::std::tr1::get<k>(args) = value;
|
||||
}
|
||||
|
||||
// Action SetArrayArgument<k>(first, last) copies the elements in
|
||||
// source range [first, last) to the array pointed to by the k-th
|
||||
// (0-based) argument, which can be either a pointer or an
|
||||
// iterator. The action does not take ownership of the elements in the
|
||||
// source range.
|
||||
ACTION_TEMPLATE(SetArrayArgument,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_2_VALUE_PARAMS(first, last)) {
|
||||
// Microsoft compiler deprecates ::std::copy, so we want to suppress warning
|
||||
// 4996 (Function call with parameters that may be unsafe) there.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||
#endif
|
||||
::std::copy(first, last, ::std::tr1::get<k>(args));
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif
|
||||
}
|
||||
|
||||
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
|
||||
// function.
|
||||
ACTION_TEMPLATE(DeleteArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
delete ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// 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
|
||||
ACTION_P(Throw, exception) { throw exception; }
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
@ -60,6 +60,7 @@
|
||||
#include <gmock/gmock-generated-actions.h>
|
||||
#include <gmock/gmock-generated-function-mockers.h>
|
||||
#include <gmock/gmock-generated-matchers.h>
|
||||
#include <gmock/gmock-more-actions.h>
|
||||
#include <gmock/gmock-generated-nice-strict.h>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gmock/gmock-printers.h>
|
||||
|
@ -56,6 +56,7 @@ using testing::_;
|
||||
using testing::Action;
|
||||
using testing::ActionInterface;
|
||||
using testing::Assign;
|
||||
using testing::ByRef;
|
||||
using testing::DefaultValue;
|
||||
using testing::DoDefault;
|
||||
using testing::IgnoreResult;
|
||||
@ -68,7 +69,6 @@ using testing::Return;
|
||||
using testing::ReturnNull;
|
||||
using testing::ReturnRef;
|
||||
using testing::SetArgumentPointee;
|
||||
using testing::SetArrayArgument;
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
using testing::SetErrnoAndReturn;
|
||||
@ -743,85 +743,6 @@ TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferBaseType) {
|
||||
|
||||
#endif // GMOCK_HAS_PROTOBUF_
|
||||
|
||||
// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
|
||||
// pointed to by the N-th (0-based) argument to values in range [first, last).
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArray) {
|
||||
typedef void MyFunction(bool, int*, char*);
|
||||
int numbers[] = { 1, 2, 3 };
|
||||
Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
|
||||
|
||||
int n[4] = {};
|
||||
int* pn = n;
|
||||
char ch[4] = {};
|
||||
char* pch = ch;
|
||||
a.Perform(make_tuple(true, pn, pch));
|
||||
EXPECT_EQ(1, n[0]);
|
||||
EXPECT_EQ(2, n[1]);
|
||||
EXPECT_EQ(3, n[2]);
|
||||
EXPECT_EQ(0, n[3]);
|
||||
EXPECT_EQ('\0', ch[0]);
|
||||
EXPECT_EQ('\0', ch[1]);
|
||||
EXPECT_EQ('\0', ch[2]);
|
||||
EXPECT_EQ('\0', ch[3]);
|
||||
|
||||
// Tests first and last are iterators.
|
||||
std::string letters = "abc";
|
||||
a = SetArrayArgument<2>(letters.begin(), letters.end());
|
||||
std::fill_n(n, 4, 0);
|
||||
std::fill_n(ch, 4, '\0');
|
||||
a.Perform(make_tuple(true, pn, pch));
|
||||
EXPECT_EQ(0, n[0]);
|
||||
EXPECT_EQ(0, n[1]);
|
||||
EXPECT_EQ(0, n[2]);
|
||||
EXPECT_EQ(0, n[3]);
|
||||
EXPECT_EQ('a', ch[0]);
|
||||
EXPECT_EQ('b', ch[1]);
|
||||
EXPECT_EQ('c', ch[2]);
|
||||
EXPECT_EQ('\0', ch[3]);
|
||||
}
|
||||
|
||||
// Tests SetArrayArgument<N>(first, last) where first == last.
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
|
||||
typedef void MyFunction(bool, int*);
|
||||
int numbers[] = { 1, 2, 3 };
|
||||
Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
|
||||
|
||||
int n[4] = {};
|
||||
int* pn = n;
|
||||
a.Perform(make_tuple(true, pn));
|
||||
EXPECT_EQ(0, n[0]);
|
||||
EXPECT_EQ(0, n[1]);
|
||||
EXPECT_EQ(0, n[2]);
|
||||
EXPECT_EQ(0, n[3]);
|
||||
}
|
||||
|
||||
// Tests SetArrayArgument<N>(first, last) where *first is convertible
|
||||
// (but not equal) to the argument type.
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
|
||||
typedef void MyFunction(bool, char*);
|
||||
int codes[] = { 97, 98, 99 };
|
||||
Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
|
||||
|
||||
char ch[4] = {};
|
||||
char* pch = ch;
|
||||
a.Perform(make_tuple(true, pch));
|
||||
EXPECT_EQ('a', ch[0]);
|
||||
EXPECT_EQ('b', ch[1]);
|
||||
EXPECT_EQ('c', ch[2]);
|
||||
EXPECT_EQ('\0', ch[3]);
|
||||
}
|
||||
|
||||
// Test SetArrayArgument<N>(first, last) with iterator as argument.
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
|
||||
typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
|
||||
std::string letters = "abc";
|
||||
Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
|
||||
|
||||
std::string s;
|
||||
a.Perform(make_tuple(true, back_inserter(s)));
|
||||
EXPECT_EQ(letters, s);
|
||||
}
|
||||
|
||||
// Sample functions and functors for testing Invoke() and etc.
|
||||
int Nullary() { return 1; }
|
||||
|
||||
@ -1031,4 +952,87 @@ TEST_F(SetErrnoAndReturnTest, CompatibleTypes) {
|
||||
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
// Tests ByRef().
|
||||
|
||||
// Tests that ReferenceWrapper<T> is copyable.
|
||||
TEST(ByRefTest, IsCopyable) {
|
||||
const std::string s1 = "Hi";
|
||||
const std::string s2 = "Hello";
|
||||
|
||||
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper = ByRef(s1);
|
||||
const std::string& r1 = ref_wrapper;
|
||||
EXPECT_EQ(&s1, &r1);
|
||||
|
||||
// Assigns a new value to ref_wrapper.
|
||||
ref_wrapper = ByRef(s2);
|
||||
const std::string& r2 = ref_wrapper;
|
||||
EXPECT_EQ(&s2, &r2);
|
||||
|
||||
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 = ByRef(s1);
|
||||
// Copies ref_wrapper1 to ref_wrapper.
|
||||
ref_wrapper = ref_wrapper1;
|
||||
const std::string& r3 = ref_wrapper;
|
||||
EXPECT_EQ(&s1, &r3);
|
||||
}
|
||||
|
||||
// Tests using ByRef() on a const value.
|
||||
TEST(ByRefTest, ConstValue) {
|
||||
const int n = 0;
|
||||
// int& ref = ByRef(n); // This shouldn't compile - we have a
|
||||
// negative compilation test to catch it.
|
||||
const int& const_ref = ByRef(n);
|
||||
EXPECT_EQ(&n, &const_ref);
|
||||
}
|
||||
|
||||
// Tests using ByRef() on a non-const value.
|
||||
TEST(ByRefTest, NonConstValue) {
|
||||
int n = 0;
|
||||
|
||||
// ByRef(n) can be used as either an int&,
|
||||
int& ref = ByRef(n);
|
||||
EXPECT_EQ(&n, &ref);
|
||||
|
||||
// or a const int&.
|
||||
const int& const_ref = ByRef(n);
|
||||
EXPECT_EQ(&n, &const_ref);
|
||||
}
|
||||
|
||||
// Tests explicitly specifying the type when using ByRef().
|
||||
TEST(ByRefTest, ExplicitType) {
|
||||
int n = 0;
|
||||
const int& r1 = ByRef<const int>(n);
|
||||
EXPECT_EQ(&n, &r1);
|
||||
|
||||
// ByRef<char>(n); // This shouldn't compile - we have a negative
|
||||
// compilation test to catch it.
|
||||
|
||||
Derived d;
|
||||
Derived& r2 = ByRef<Derived>(d);
|
||||
EXPECT_EQ(&d, &r2);
|
||||
|
||||
const Derived& r3 = ByRef<const Derived>(d);
|
||||
EXPECT_EQ(&d, &r3);
|
||||
|
||||
Base& r4 = ByRef<Base>(d);
|
||||
EXPECT_EQ(&d, &r4);
|
||||
|
||||
const Base& r5 = ByRef<const Base>(d);
|
||||
EXPECT_EQ(&d, &r5);
|
||||
|
||||
// The following shouldn't compile - we have a negative compilation
|
||||
// test for it.
|
||||
//
|
||||
// Base b;
|
||||
// ByRef<Derived>(b);
|
||||
}
|
||||
|
||||
// Tests that Google Mock prints expression ByRef(x) as a reference to x.
|
||||
TEST(ByRefTest, PrintsCorrectly) {
|
||||
int n = 42;
|
||||
::std::stringstream expected, actual;
|
||||
testing::internal::UniversalPrinter<const int&>::Print(n, &expected);
|
||||
testing::internal::UniversalPrint(ByRef(n), &actual);
|
||||
EXPECT_EQ(expected.str(), actual.str());
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
||||
|
@ -54,23 +54,16 @@ using testing::_;
|
||||
using testing::Action;
|
||||
using testing::ActionInterface;
|
||||
using testing::ByRef;
|
||||
using testing::DeleteArg;
|
||||
using testing::DoAll;
|
||||
using testing::Invoke;
|
||||
using testing::InvokeArgument;
|
||||
using testing::Return;
|
||||
using testing::ReturnArg;
|
||||
using testing::ReturnNew;
|
||||
using testing::SaveArg;
|
||||
using testing::SetArgReferee;
|
||||
using testing::SetArgumentPointee;
|
||||
using testing::StaticAssertTypeEq;
|
||||
using testing::Unused;
|
||||
using testing::WithArg;
|
||||
using testing::WithArgs;
|
||||
using testing::WithoutArgs;
|
||||
|
||||
// Sample functions and functors for testing Invoke() and etc.
|
||||
// Sample functions and functors for testing various actions.
|
||||
int Nullary() { return 1; }
|
||||
|
||||
class NullaryFunctor {
|
||||
@ -79,19 +72,11 @@ class NullaryFunctor {
|
||||
};
|
||||
|
||||
bool g_done = false;
|
||||
void VoidNullary() { g_done = true; }
|
||||
|
||||
class VoidNullaryFunctor {
|
||||
public:
|
||||
void operator()() { g_done = true; }
|
||||
};
|
||||
|
||||
bool Unary(int x) { return x < 0; }
|
||||
|
||||
const char* Plus1(const char* s) { return s + 1; }
|
||||
|
||||
void VoidUnary(int n) { g_done = true; }
|
||||
|
||||
bool ByConstRef(const string& s) { return s == "Hi"; }
|
||||
|
||||
const double g_double = 0;
|
||||
@ -113,10 +98,6 @@ void VoidTernary(int, char, bool) { g_done = true; }
|
||||
|
||||
int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
|
||||
|
||||
int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
|
||||
|
||||
void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
|
||||
|
||||
string Concat4(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4) {
|
||||
return string(s1) + s2 + s3 + s4;
|
||||
@ -175,388 +156,10 @@ string Concat10(const char* s1, const char* s2, const char* s3,
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
|
||||
}
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
Foo() : value_(123) {}
|
||||
|
||||
int Nullary() const { return value_; }
|
||||
|
||||
short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT
|
||||
|
||||
string Binary(const string& str, char c) const { return str + c; }
|
||||
|
||||
int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
|
||||
|
||||
int SumOf4(int a, int b, int c, int d) const {
|
||||
return a + b + c + d + value_;
|
||||
}
|
||||
|
||||
int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
|
||||
|
||||
int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
|
||||
|
||||
int SumOf6(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
|
||||
string Concat7(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
|
||||
}
|
||||
|
||||
string Concat8(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
|
||||
}
|
||||
|
||||
string Concat9(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
|
||||
}
|
||||
|
||||
string Concat10(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9,
|
||||
const char* s10) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
|
||||
}
|
||||
private:
|
||||
int value_;
|
||||
};
|
||||
|
||||
// Tests using Invoke() with a nullary function.
|
||||
TEST(InvokeTest, Nullary) {
|
||||
Action<int()> a = Invoke(Nullary); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a unary function.
|
||||
TEST(InvokeTest, Unary) {
|
||||
Action<bool(int)> a = Invoke(Unary); // NOLINT
|
||||
EXPECT_FALSE(a.Perform(make_tuple(1)));
|
||||
EXPECT_TRUE(a.Perform(make_tuple(-1)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a binary function.
|
||||
TEST(InvokeTest, Binary) {
|
||||
Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT
|
||||
const char* p = "Hello";
|
||||
EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a ternary function.
|
||||
TEST(InvokeTest, Ternary) {
|
||||
Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT
|
||||
EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 4-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes4Arguments) {
|
||||
Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT
|
||||
EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 5-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes5Arguments) {
|
||||
Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT
|
||||
EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 6-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes6Arguments) {
|
||||
Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT
|
||||
EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
|
||||
}
|
||||
|
||||
// A helper that turns the type of a C-string literal from const
|
||||
// char[N] to const char*.
|
||||
inline const char* CharPtr(const char* s) { return s; }
|
||||
|
||||
// Tests using Invoke() with a 7-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes7Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*)> a =
|
||||
Invoke(Concat7);
|
||||
EXPECT_EQ("1234567",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 8-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes8Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*)> a =
|
||||
Invoke(Concat8);
|
||||
EXPECT_EQ("12345678",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 9-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes9Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*)> a = Invoke(Concat9);
|
||||
EXPECT_EQ("123456789",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"), CharPtr("9"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 10-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes10Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*, const char*)> a = Invoke(Concat10);
|
||||
EXPECT_EQ("1234567890",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"), CharPtr("9"),
|
||||
CharPtr("0"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with functions with parameters declared as Unused.
|
||||
TEST(InvokeTest, FunctionWithUnusedParameters) {
|
||||
Action<int(int, int, double, const string&)> a1 =
|
||||
Invoke(SumOfFirst2);
|
||||
EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, CharPtr("hi"))));
|
||||
|
||||
Action<int(int, int, bool, int*)> a2 =
|
||||
Invoke(SumOfFirst2);
|
||||
EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with methods with parameters declared as Unused.
|
||||
TEST(InvokeTest, MethodWithUnusedParameters) {
|
||||
Foo foo;
|
||||
Action<int(string, bool, int, int)> a1 =
|
||||
Invoke(&foo, &Foo::SumOfLast2);
|
||||
EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
|
||||
|
||||
Action<int(char, double, int, int)> a2 =
|
||||
Invoke(&foo, &Foo::SumOfLast2);
|
||||
EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a functor.
|
||||
TEST(InvokeTest, Functor) {
|
||||
Action<int(short, char)> a = Invoke(plus<short>()); // NOLINT
|
||||
EXPECT_EQ(3, a.Perform(make_tuple(1, 2)));
|
||||
}
|
||||
|
||||
// Tests using Invoke(f) as an action of a compatible type.
|
||||
TEST(InvokeTest, FunctionWithCompatibleType) {
|
||||
Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT
|
||||
EXPECT_EQ(4321, a.Perform(make_tuple(4000, 300, 20, true)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with an object pointer and a method pointer.
|
||||
|
||||
// Tests using Invoke() with a nullary method.
|
||||
TEST(InvokeMethodTest, Nullary) {
|
||||
Foo foo;
|
||||
Action<int()> a = Invoke(&foo, &Foo::Nullary); // NOLINT
|
||||
EXPECT_EQ(123, a.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a unary method.
|
||||
TEST(InvokeMethodTest, Unary) {
|
||||
Foo foo;
|
||||
Action<short(long)> a = Invoke(&foo, &Foo::Unary); // NOLINT
|
||||
EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a binary method.
|
||||
TEST(InvokeMethodTest, Binary) {
|
||||
Foo foo;
|
||||
Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
|
||||
string s("Hell");
|
||||
EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a ternary method.
|
||||
TEST(InvokeMethodTest, Ternary) {
|
||||
Foo foo;
|
||||
Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary); // NOLINT
|
||||
EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, 1)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 4-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
|
||||
Foo foo;
|
||||
Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4); // NOLINT
|
||||
EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 5-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
|
||||
Foo foo;
|
||||
Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5); // NOLINT
|
||||
EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 6-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
|
||||
Foo foo;
|
||||
Action<int(int, int, int, int, int, int)> a = // NOLINT
|
||||
Invoke(&foo, &Foo::SumOf6);
|
||||
EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 7-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*)> a =
|
||||
Invoke(&foo, &Foo::Concat7);
|
||||
EXPECT_EQ("1234567",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 8-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*)> a =
|
||||
Invoke(&foo, &Foo::Concat8);
|
||||
EXPECT_EQ("12345678",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 9-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*)> a = Invoke(&foo, &Foo::Concat9);
|
||||
EXPECT_EQ("123456789",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"), CharPtr("9"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 10-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
|
||||
EXPECT_EQ("1234567890",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"), CharPtr("9"),
|
||||
CharPtr("0"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke(f) as an action of a compatible type.
|
||||
TEST(InvokeMethodTest, MethodWithCompatibleType) {
|
||||
Foo foo;
|
||||
Action<long(int, short, char, bool)> a = // NOLINT
|
||||
Invoke(&foo, &Foo::SumOf4);
|
||||
EXPECT_EQ(4444, a.Perform(make_tuple(4000, 300, 20, true)));
|
||||
}
|
||||
|
||||
// Tests ByRef().
|
||||
|
||||
// Tests that ReferenceWrapper<T> is copyable.
|
||||
TEST(ByRefTest, IsCopyable) {
|
||||
const string s1 = "Hi";
|
||||
const string s2 = "Hello";
|
||||
|
||||
::testing::internal::ReferenceWrapper<const string> ref_wrapper = ByRef(s1);
|
||||
const string& r1 = ref_wrapper;
|
||||
EXPECT_EQ(&s1, &r1);
|
||||
|
||||
// Assigns a new value to ref_wrapper.
|
||||
ref_wrapper = ByRef(s2);
|
||||
const string& r2 = ref_wrapper;
|
||||
EXPECT_EQ(&s2, &r2);
|
||||
|
||||
::testing::internal::ReferenceWrapper<const string> ref_wrapper1 = ByRef(s1);
|
||||
// Copies ref_wrapper1 to ref_wrapper.
|
||||
ref_wrapper = ref_wrapper1;
|
||||
const string& r3 = ref_wrapper;
|
||||
EXPECT_EQ(&s1, &r3);
|
||||
}
|
||||
|
||||
// Tests using ByRef() on a const value.
|
||||
TEST(ByRefTest, ConstValue) {
|
||||
const int n = 0;
|
||||
// int& ref = ByRef(n); // This shouldn't compile - we have a
|
||||
// negative compilation test to catch it.
|
||||
const int& const_ref = ByRef(n);
|
||||
EXPECT_EQ(&n, &const_ref);
|
||||
}
|
||||
|
||||
// Tests using ByRef() on a non-const value.
|
||||
TEST(ByRefTest, NonConstValue) {
|
||||
int n = 0;
|
||||
|
||||
// ByRef(n) can be used as either an int&,
|
||||
int& ref = ByRef(n);
|
||||
EXPECT_EQ(&n, &ref);
|
||||
|
||||
// or a const int&.
|
||||
const int& const_ref = ByRef(n);
|
||||
EXPECT_EQ(&n, &const_ref);
|
||||
}
|
||||
|
||||
struct Base {
|
||||
bool operator==(const Base&) { return true; }
|
||||
};
|
||||
|
||||
struct Derived : public Base {
|
||||
bool operator==(const Derived&) { return true; }
|
||||
};
|
||||
|
||||
// Tests explicitly specifying the type when using ByRef().
|
||||
TEST(ByRefTest, ExplicitType) {
|
||||
int n = 0;
|
||||
const int& r1 = ByRef<const int>(n);
|
||||
EXPECT_EQ(&n, &r1);
|
||||
|
||||
// ByRef<char>(n); // This shouldn't compile - we have a negative
|
||||
// compilation test to catch it.
|
||||
|
||||
|
||||
Derived d;
|
||||
Derived& r2 = ByRef<Derived>(d);
|
||||
EXPECT_EQ(&d, &r2);
|
||||
|
||||
const Derived& r3 = ByRef<const Derived>(d);
|
||||
EXPECT_EQ(&d, &r3);
|
||||
|
||||
Base& r4 = ByRef<Base>(d);
|
||||
EXPECT_EQ(&d, &r4);
|
||||
|
||||
const Base& r5 = ByRef<const Base>(d);
|
||||
EXPECT_EQ(&d, &r5);
|
||||
|
||||
// The following shouldn't compile - we have a negative compilation
|
||||
// test for it.
|
||||
//
|
||||
// Base b;
|
||||
// ByRef<Derived>(b);
|
||||
}
|
||||
|
||||
// Tests that Google Mock prints expression ByRef(x) as a reference to x.
|
||||
TEST(ByRefTest, PrintsCorrectly) {
|
||||
int n = 42;
|
||||
::std::stringstream expected, actual;
|
||||
testing::internal::UniversalPrinter<const int&>::Print(n, &expected);
|
||||
testing::internal::UniversalPrint(ByRef(n), &actual);
|
||||
EXPECT_EQ(expected.str(), actual.str());
|
||||
}
|
||||
|
||||
// Tests InvokeArgument<N>(...).
|
||||
|
||||
// Tests using InvokeArgument with a nullary function.
|
||||
@ -674,23 +277,11 @@ TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
|
||||
EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
|
||||
}
|
||||
|
||||
// Tests using WithoutArgs with an action that takes no argument.
|
||||
TEST(WithoutArgsTest, NoArg) {
|
||||
Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple(2)));
|
||||
}
|
||||
|
||||
// Tests using WithArgs and WithArg with an action that takes 1 argument.
|
||||
// Tests using WithArgs and with an action that takes 1 argument.
|
||||
TEST(WithArgsTest, OneArg) {
|
||||
Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT
|
||||
EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
|
||||
EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
|
||||
|
||||
// Also tests the synonym WithArg.
|
||||
Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT
|
||||
EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
|
||||
EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
|
||||
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 2 arguments.
|
||||
@ -1383,56 +974,6 @@ TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {
|
||||
EXPECT_EQ(55, a.Perform(empty));
|
||||
}
|
||||
|
||||
TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {
|
||||
const Action<int(int)> a = ReturnArg<0>();
|
||||
EXPECT_EQ(5, a.Perform(make_tuple(5)));
|
||||
}
|
||||
|
||||
TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {
|
||||
const Action<bool(bool, bool, bool)> a = ReturnArg<0>();
|
||||
EXPECT_TRUE(a.Perform(make_tuple(true, false, false)));
|
||||
}
|
||||
|
||||
TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {
|
||||
const Action<string(int, int, string, int)> a = ReturnArg<2>();
|
||||
EXPECT_EQ("seven", a.Perform(make_tuple(5, 6, string("seven"), 8)));
|
||||
}
|
||||
|
||||
TEST(SaveArgActionTest, WorksForSameType) {
|
||||
int result = 0;
|
||||
const Action<void(int n)> a1 = SaveArg<0>(&result);
|
||||
a1.Perform(make_tuple(5));
|
||||
EXPECT_EQ(5, result);
|
||||
}
|
||||
|
||||
TEST(SaveArgActionTest, WorksForCompatibleType) {
|
||||
int result = 0;
|
||||
const Action<void(bool, char)> a1 = SaveArg<1>(&result);
|
||||
a1.Perform(make_tuple(true, 'a'));
|
||||
EXPECT_EQ('a', result);
|
||||
}
|
||||
|
||||
TEST(SetArgRefereeActionTest, WorksForSameType) {
|
||||
int value = 0;
|
||||
const Action<void(int&)> a1 = SetArgReferee<0>(1);
|
||||
a1.Perform(tuple<int&>(value));
|
||||
EXPECT_EQ(1, value);
|
||||
}
|
||||
|
||||
TEST(SetArgRefereeActionTest, WorksForCompatibleType) {
|
||||
int value = 0;
|
||||
const Action<void(int, int&)> a1 = SetArgReferee<1>('a');
|
||||
a1.Perform(tuple<int, int&>(0, value));
|
||||
EXPECT_EQ('a', value);
|
||||
}
|
||||
|
||||
TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {
|
||||
int value = 0;
|
||||
const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');
|
||||
a1.Perform(tuple<bool, int, int&, const char*>(true, 0, value, "hi"));
|
||||
EXPECT_EQ('a', value);
|
||||
}
|
||||
|
||||
class NullaryConstructorClass {
|
||||
public:
|
||||
NullaryConstructorClass() : value_(123) {}
|
||||
@ -1497,64 +1038,6 @@ TEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
|
||||
delete c;
|
||||
}
|
||||
|
||||
// A class that can be used to verify that its destructor is called: it will set
|
||||
// the bool provided to the constructor to true when destroyed.
|
||||
class DeletionTester {
|
||||
public:
|
||||
explicit DeletionTester(bool* is_deleted)
|
||||
: is_deleted_(is_deleted) {
|
||||
// Make sure the bit is set to false.
|
||||
*is_deleted_ = false;
|
||||
}
|
||||
|
||||
~DeletionTester() {
|
||||
*is_deleted_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool* is_deleted_;
|
||||
};
|
||||
|
||||
TEST(DeleteArgActionTest, OneArg) {
|
||||
bool is_deleted = false;
|
||||
DeletionTester* t = new DeletionTester(&is_deleted);
|
||||
const Action<void(DeletionTester*)> a1 = DeleteArg<0>(); // NOLINT
|
||||
EXPECT_FALSE(is_deleted);
|
||||
a1.Perform(make_tuple(t));
|
||||
EXPECT_TRUE(is_deleted);
|
||||
}
|
||||
|
||||
TEST(DeleteArgActionTest, TenArgs) {
|
||||
bool is_deleted = false;
|
||||
DeletionTester* t = new DeletionTester(&is_deleted);
|
||||
const Action<void(bool, int, int, const char*, bool,
|
||||
int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
|
||||
EXPECT_FALSE(is_deleted);
|
||||
a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
|
||||
EXPECT_TRUE(is_deleted);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
|
||||
TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {
|
||||
const Action<void(int n)> a = Throw('a');
|
||||
EXPECT_THROW(a.Perform(make_tuple(0)), char);
|
||||
}
|
||||
|
||||
class MyException {};
|
||||
|
||||
TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {
|
||||
const Action<double(char ch)> a = Throw(MyException());
|
||||
EXPECT_THROW(a.Perform(make_tuple('0')), MyException);
|
||||
}
|
||||
|
||||
TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
|
||||
const Action<double()> a = Throw(MyException());
|
||||
EXPECT_THROW(a.Perform(make_tuple()), MyException);
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// Tests that ACTION_TEMPLATE works when there is no value parameter.
|
||||
ACTION_TEMPLATE(CreateNew,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, T),
|
||||
|
796
test/gmock-more-actions_test.cc
Normal file
796
test/gmock-more-actions_test.cc
Normal file
@ -0,0 +1,796 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the built-in actions in gmock-more-actions.h.
|
||||
|
||||
#include <gmock/gmock-more-actions.h>
|
||||
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_more_actions_test {
|
||||
|
||||
using ::std::plus;
|
||||
using ::std::string;
|
||||
using ::std::tr1::get;
|
||||
using ::std::tr1::make_tuple;
|
||||
using ::std::tr1::tuple;
|
||||
using ::std::tr1::tuple_element;
|
||||
using testing::_;
|
||||
using testing::Action;
|
||||
using testing::ActionInterface;
|
||||
using testing::DeleteArg;
|
||||
using testing::Invoke;
|
||||
using testing::Return;
|
||||
using testing::ReturnArg;
|
||||
using testing::SaveArg;
|
||||
using testing::SetArgReferee;
|
||||
using testing::SetArgumentPointee;
|
||||
using testing::StaticAssertTypeEq;
|
||||
using testing::Unused;
|
||||
using testing::WithArg;
|
||||
using testing::WithoutArgs;
|
||||
|
||||
// Sample functions and functors for testing Invoke() and etc.
|
||||
int Nullary() { return 1; }
|
||||
|
||||
class NullaryFunctor {
|
||||
public:
|
||||
int operator()() { return 2; }
|
||||
};
|
||||
|
||||
bool g_done = false;
|
||||
void VoidNullary() { g_done = true; }
|
||||
|
||||
class VoidNullaryFunctor {
|
||||
public:
|
||||
void operator()() { g_done = true; }
|
||||
};
|
||||
|
||||
bool Unary(int x) { return x < 0; }
|
||||
|
||||
const char* Plus1(const char* s) { return s + 1; }
|
||||
|
||||
void VoidUnary(int n) { g_done = true; }
|
||||
|
||||
bool ByConstRef(const string& s) { return s == "Hi"; }
|
||||
|
||||
const double g_double = 0;
|
||||
bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
|
||||
|
||||
string ByNonConstRef(string& s) { return s += "+"; } // NOLINT
|
||||
|
||||
struct UnaryFunctor {
|
||||
int operator()(bool x) { return x ? 1 : -1; }
|
||||
};
|
||||
|
||||
const char* Binary(const char* input, short n) { return input + n; } // NOLINT
|
||||
|
||||
void VoidBinary(int, char) { g_done = true; }
|
||||
|
||||
int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
|
||||
|
||||
void VoidTernary(int, char, bool) { g_done = true; }
|
||||
|
||||
int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
|
||||
|
||||
int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
|
||||
|
||||
void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
|
||||
|
||||
string Concat4(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4) {
|
||||
return string(s1) + s2 + s3 + s4;
|
||||
}
|
||||
|
||||
int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
|
||||
|
||||
struct SumOf5Functor {
|
||||
int operator()(int a, int b, int c, int d, int e) {
|
||||
return a + b + c + d + e;
|
||||
}
|
||||
};
|
||||
|
||||
string Concat5(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5) {
|
||||
return string(s1) + s2 + s3 + s4 + s5;
|
||||
}
|
||||
|
||||
int SumOf6(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
|
||||
struct SumOf6Functor {
|
||||
int operator()(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
};
|
||||
|
||||
string Concat6(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6;
|
||||
}
|
||||
|
||||
string Concat7(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
|
||||
}
|
||||
|
||||
string Concat8(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
|
||||
}
|
||||
|
||||
string Concat9(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
|
||||
}
|
||||
|
||||
string Concat10(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9,
|
||||
const char* s10) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
|
||||
}
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
Foo() : value_(123) {}
|
||||
|
||||
int Nullary() const { return value_; }
|
||||
|
||||
short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT
|
||||
|
||||
string Binary(const string& str, char c) const { return str + c; }
|
||||
|
||||
int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
|
||||
|
||||
int SumOf4(int a, int b, int c, int d) const {
|
||||
return a + b + c + d + value_;
|
||||
}
|
||||
|
||||
int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
|
||||
|
||||
int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
|
||||
|
||||
int SumOf6(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
|
||||
string Concat7(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
|
||||
}
|
||||
|
||||
string Concat8(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
|
||||
}
|
||||
|
||||
string Concat9(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
|
||||
}
|
||||
|
||||
string Concat10(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9,
|
||||
const char* s10) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
|
||||
}
|
||||
private:
|
||||
int value_;
|
||||
};
|
||||
|
||||
// Tests using Invoke() with a nullary function.
|
||||
TEST(InvokeTest, Nullary) {
|
||||
Action<int()> a = Invoke(Nullary); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a unary function.
|
||||
TEST(InvokeTest, Unary) {
|
||||
Action<bool(int)> a = Invoke(Unary); // NOLINT
|
||||
EXPECT_FALSE(a.Perform(make_tuple(1)));
|
||||
EXPECT_TRUE(a.Perform(make_tuple(-1)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a binary function.
|
||||
TEST(InvokeTest, Binary) {
|
||||
Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT
|
||||
const char* p = "Hello";
|
||||
EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a ternary function.
|
||||
TEST(InvokeTest, Ternary) {
|
||||
Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT
|
||||
EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 4-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes4Arguments) {
|
||||
Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT
|
||||
EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 5-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes5Arguments) {
|
||||
Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT
|
||||
EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 6-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes6Arguments) {
|
||||
Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT
|
||||
EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
|
||||
}
|
||||
|
||||
// A helper that turns the type of a C-string literal from const
|
||||
// char[N] to const char*.
|
||||
inline const char* CharPtr(const char* s) { return s; }
|
||||
|
||||
// Tests using Invoke() with a 7-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes7Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*)> a =
|
||||
Invoke(Concat7);
|
||||
EXPECT_EQ("1234567",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 8-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes8Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*)> a =
|
||||
Invoke(Concat8);
|
||||
EXPECT_EQ("12345678",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 9-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes9Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*)> a = Invoke(Concat9);
|
||||
EXPECT_EQ("123456789",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"), CharPtr("9"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 10-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes10Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*, const char*)> a = Invoke(Concat10);
|
||||
EXPECT_EQ("1234567890",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"), CharPtr("9"),
|
||||
CharPtr("0"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with functions with parameters declared as Unused.
|
||||
TEST(InvokeTest, FunctionWithUnusedParameters) {
|
||||
Action<int(int, int, double, const string&)> a1 =
|
||||
Invoke(SumOfFirst2);
|
||||
EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, CharPtr("hi"))));
|
||||
|
||||
Action<int(int, int, bool, int*)> a2 =
|
||||
Invoke(SumOfFirst2);
|
||||
EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with methods with parameters declared as Unused.
|
||||
TEST(InvokeTest, MethodWithUnusedParameters) {
|
||||
Foo foo;
|
||||
Action<int(string, bool, int, int)> a1 =
|
||||
Invoke(&foo, &Foo::SumOfLast2);
|
||||
EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
|
||||
|
||||
Action<int(char, double, int, int)> a2 =
|
||||
Invoke(&foo, &Foo::SumOfLast2);
|
||||
EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a functor.
|
||||
TEST(InvokeTest, Functor) {
|
||||
Action<int(short, char)> a = Invoke(plus<short>()); // NOLINT
|
||||
EXPECT_EQ(3, a.Perform(make_tuple(1, 2)));
|
||||
}
|
||||
|
||||
// Tests using Invoke(f) as an action of a compatible type.
|
||||
TEST(InvokeTest, FunctionWithCompatibleType) {
|
||||
Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT
|
||||
EXPECT_EQ(4321, a.Perform(make_tuple(4000, 300, 20, true)));
|
||||
}
|
||||
|
||||
#if GMOCK_HAS_GOOGLE3_CALLBACK_
|
||||
|
||||
// Tests IgnoreResult(Invoke(result_callback)).
|
||||
TEST(InvokeTest, IgnoreResultOfResultCallback) {
|
||||
ResultCallback<int>* c = NewPermanentCallback(Nullary);
|
||||
Action<void()> a = IgnoreResult(Invoke(c));
|
||||
a.Perform(make_tuple());
|
||||
}
|
||||
|
||||
// Tests IgnoreResult(Invoke(result_callback4)).
|
||||
TEST(InvokeTest, IgnoreResultOfResultCallback4) {
|
||||
ResultCallback4<int, int, int, int, int>* c =
|
||||
NewPermanentCallback(SumOf4);
|
||||
Action<void(int, int, int, int)> a = IgnoreResult(Invoke(c));
|
||||
a.Perform(make_tuple(1, 2, 3, 4));
|
||||
}
|
||||
|
||||
#endif // GMOCK_HAS_GOOGLE3_CALLBACK_
|
||||
|
||||
// Tests using Invoke() with an object pointer and a method pointer.
|
||||
|
||||
// Tests using Invoke() with a nullary method.
|
||||
TEST(InvokeMethodTest, Nullary) {
|
||||
Foo foo;
|
||||
Action<int()> a = Invoke(&foo, &Foo::Nullary); // NOLINT
|
||||
EXPECT_EQ(123, a.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a unary method.
|
||||
TEST(InvokeMethodTest, Unary) {
|
||||
Foo foo;
|
||||
Action<short(long)> a = Invoke(&foo, &Foo::Unary); // NOLINT
|
||||
EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a binary method.
|
||||
TEST(InvokeMethodTest, Binary) {
|
||||
Foo foo;
|
||||
Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
|
||||
string s("Hell");
|
||||
EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a ternary method.
|
||||
TEST(InvokeMethodTest, Ternary) {
|
||||
Foo foo;
|
||||
Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary); // NOLINT
|
||||
EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, 1)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 4-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
|
||||
Foo foo;
|
||||
Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4); // NOLINT
|
||||
EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 5-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
|
||||
Foo foo;
|
||||
Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5); // NOLINT
|
||||
EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 6-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
|
||||
Foo foo;
|
||||
Action<int(int, int, int, int, int, int)> a = // NOLINT
|
||||
Invoke(&foo, &Foo::SumOf6);
|
||||
EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 7-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*)> a =
|
||||
Invoke(&foo, &Foo::Concat7);
|
||||
EXPECT_EQ("1234567",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 8-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*)> a =
|
||||
Invoke(&foo, &Foo::Concat8);
|
||||
EXPECT_EQ("12345678",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 9-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*)> a = Invoke(&foo, &Foo::Concat9);
|
||||
EXPECT_EQ("123456789",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"), CharPtr("9"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 10-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
|
||||
EXPECT_EQ("1234567890",
|
||||
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
CharPtr("7"), CharPtr("8"), CharPtr("9"),
|
||||
CharPtr("0"))));
|
||||
}
|
||||
|
||||
// Tests using Invoke(f) as an action of a compatible type.
|
||||
TEST(InvokeMethodTest, MethodWithCompatibleType) {
|
||||
Foo foo;
|
||||
Action<long(int, short, char, bool)> a = // NOLINT
|
||||
Invoke(&foo, &Foo::SumOf4);
|
||||
EXPECT_EQ(4444, a.Perform(make_tuple(4000, 300, 20, true)));
|
||||
}
|
||||
|
||||
#if GMOCK_HAS_GOOGLE3_CALLBACK_
|
||||
|
||||
// We don't have dedicated tests to verify that Invoke(callback) and
|
||||
// InvokeWithoutArgs(callback) delete the callback argument. Instead,
|
||||
// we rely on the heap checker linked in this test program to do that.
|
||||
|
||||
// Tests that Invoke(non-permanent-callback) kills the process.
|
||||
TEST(InvokeCallbackDeathTest, RejectsNonPermanentCallback) {
|
||||
EXPECT_DEATH({
|
||||
Action<int()> a = Invoke(NewCallback(Nullary)); // NOLINT
|
||||
}, "");
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a nullary callback.
|
||||
TEST(InvokeCallbackTest, Nullary) {
|
||||
// Tests using Invoke(callback) as an action of the exact type.
|
||||
Action<int()> a = Invoke(NewPermanentCallback(Nullary)); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple()));
|
||||
|
||||
// Tests using Invoke(callback) as an action of a compatible type.
|
||||
Action<bool()> a2 = Invoke(NewPermanentCallback(Nullary)); // NOLINT
|
||||
EXPECT_TRUE(a2.Perform(make_tuple()));
|
||||
|
||||
// Tests using Invoke() on a callback that returns void.
|
||||
Action<void()> a3 = Invoke(NewPermanentCallback(VoidNullary)); // NOLINT
|
||||
g_done = false;
|
||||
a3.Perform(make_tuple());
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a unary callback.
|
||||
TEST(InvokeCallbackTest, Unary) {
|
||||
// Tests using Invoke(callback1) as an action of the exact type.
|
||||
Action<bool(int)> a = Invoke(NewPermanentCallback(Unary)); // NOLINT
|
||||
EXPECT_FALSE(a.Perform(make_tuple(1)));
|
||||
EXPECT_TRUE(a.Perform(make_tuple(-1)));
|
||||
|
||||
// Tests using Invoke(callback1) as an action of a compatible type.
|
||||
Action<int(long)> a2 = Invoke(NewPermanentCallback(Unary)); // NOLINT
|
||||
EXPECT_EQ(0, a2.Perform(make_tuple(1L)));
|
||||
EXPECT_EQ(1, a2.Perform(make_tuple(-1L)));
|
||||
|
||||
// Tests using Invoke() on a callback that returns void.
|
||||
Action<void(char)> a3 = Invoke(NewPermanentCallback(VoidUnary)); // NOLINT
|
||||
g_done = false;
|
||||
a3.Perform(make_tuple('a'));
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a binary callback.
|
||||
TEST(InvokeCallbackTest, Binary) {
|
||||
// Tests using Invoke(callback2) as an action of the exact type.
|
||||
Action<const char*(const char*, short)> a = // NOLINT
|
||||
Invoke(NewPermanentCallback(Binary));
|
||||
const char* p = "Hello";
|
||||
EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
|
||||
|
||||
// Tests using Invoke(callback2) as an action of a compatible type.
|
||||
Action<bool(char*, int)> a2 = // NOLINT
|
||||
Invoke(NewPermanentCallback(Binary));
|
||||
char str[] = "Hello";
|
||||
EXPECT_TRUE(a2.Perform(make_tuple(str, 2)));
|
||||
|
||||
// Tests using Invoke() on a callback that returns void.
|
||||
Action<void(char, char)> a3 =
|
||||
Invoke(NewPermanentCallback(VoidBinary)); // NOLINT
|
||||
g_done = false;
|
||||
a3.Perform(make_tuple('a', 'b'));
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a ternary callback.
|
||||
TEST(InvokeCallbackTest, Ternary) {
|
||||
// Tests using Invoke(callback3) as an action of the exact type.
|
||||
Action<int(int, char, short)> a = // NOLINT
|
||||
Invoke(NewPermanentCallback(Ternary));
|
||||
EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
|
||||
|
||||
// Tests using Invoke(callback3) as an action of a compatible type.
|
||||
Action<long(char, int, int)> a2 = // NOLINT
|
||||
Invoke(NewPermanentCallback(Ternary));
|
||||
EXPECT_EQ(6, a2.Perform(make_tuple('\1', 2, 3)));
|
||||
|
||||
// Tests using Invoke() on a callback that returns void.
|
||||
Action<void(char, char, bool)> a3 =
|
||||
Invoke(NewPermanentCallback(VoidTernary)); // NOLINT
|
||||
g_done = false;
|
||||
a3.Perform(make_tuple('a', 'b', true));
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 4-argument callback.
|
||||
TEST(InvokeCallbackTest, CallbackThatTakes4Arguments) {
|
||||
// Tests using Invoke(callback4) as an action of the exact type.
|
||||
Action<int(int, int, int, int)> a = // NOLINT
|
||||
Invoke(NewPermanentCallback(SumOf4));
|
||||
EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
|
||||
|
||||
// Tests using Invoke(callback4) as an action of a compatible type.
|
||||
Action<long(int, short, char, bool)> a2 = // NOLINT
|
||||
Invoke(NewPermanentCallback(SumOf4));
|
||||
EXPECT_EQ(4321, a2.Perform(make_tuple(4000, 300, 20, true)));
|
||||
|
||||
// Tests using Invoke() on a callback that returns void.
|
||||
Action<void(char, char, double, double)> a3 =
|
||||
Invoke(NewPermanentCallback(VoidFunctionWithFourArguments)); // NOLINT
|
||||
g_done = false;
|
||||
a3.Perform(make_tuple('a', 'b', 0, 1));
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
#endif // GMOCK_HAS_GOOGLE3_CALLBACK_
|
||||
|
||||
// Tests using WithoutArgs with an action that takes no argument.
|
||||
TEST(WithoutArgsTest, NoArg) {
|
||||
Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple(2)));
|
||||
}
|
||||
|
||||
// Tests using WithArg with an action that takes 1 argument.
|
||||
TEST(WithArgTest, OneArg) {
|
||||
Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT
|
||||
EXPECT_TRUE(b.Perform(make_tuple(1.5, -1)));
|
||||
EXPECT_FALSE(b.Perform(make_tuple(1.5, 1)));
|
||||
}
|
||||
|
||||
TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {
|
||||
const Action<int(int)> a = ReturnArg<0>();
|
||||
EXPECT_EQ(5, a.Perform(make_tuple(5)));
|
||||
}
|
||||
|
||||
TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {
|
||||
const Action<bool(bool, bool, bool)> a = ReturnArg<0>();
|
||||
EXPECT_TRUE(a.Perform(make_tuple(true, false, false)));
|
||||
}
|
||||
|
||||
TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {
|
||||
const Action<string(int, int, string, int)> a = ReturnArg<2>();
|
||||
EXPECT_EQ("seven", a.Perform(make_tuple(5, 6, string("seven"), 8)));
|
||||
}
|
||||
|
||||
TEST(SaveArgActionTest, WorksForSameType) {
|
||||
int result = 0;
|
||||
const Action<void(int n)> a1 = SaveArg<0>(&result);
|
||||
a1.Perform(make_tuple(5));
|
||||
EXPECT_EQ(5, result);
|
||||
}
|
||||
|
||||
TEST(SaveArgActionTest, WorksForCompatibleType) {
|
||||
int result = 0;
|
||||
const Action<void(bool, char)> a1 = SaveArg<1>(&result);
|
||||
a1.Perform(make_tuple(true, 'a'));
|
||||
EXPECT_EQ('a', result);
|
||||
}
|
||||
|
||||
TEST(SetArgRefereeActionTest, WorksForSameType) {
|
||||
int value = 0;
|
||||
const Action<void(int&)> a1 = SetArgReferee<0>(1);
|
||||
a1.Perform(tuple<int&>(value));
|
||||
EXPECT_EQ(1, value);
|
||||
}
|
||||
|
||||
TEST(SetArgRefereeActionTest, WorksForCompatibleType) {
|
||||
int value = 0;
|
||||
const Action<void(int, int&)> a1 = SetArgReferee<1>('a');
|
||||
a1.Perform(tuple<int, int&>(0, value));
|
||||
EXPECT_EQ('a', value);
|
||||
}
|
||||
|
||||
TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {
|
||||
int value = 0;
|
||||
const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');
|
||||
a1.Perform(tuple<bool, int, int&, const char*>(true, 0, value, "hi"));
|
||||
EXPECT_EQ('a', value);
|
||||
}
|
||||
|
||||
// A class that can be used to verify that its destructor is called: it will set
|
||||
// the bool provided to the constructor to true when destroyed.
|
||||
class DeletionTester {
|
||||
public:
|
||||
explicit DeletionTester(bool* is_deleted)
|
||||
: is_deleted_(is_deleted) {
|
||||
// Make sure the bit is set to false.
|
||||
*is_deleted_ = false;
|
||||
}
|
||||
|
||||
~DeletionTester() {
|
||||
*is_deleted_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool* is_deleted_;
|
||||
};
|
||||
|
||||
TEST(DeleteArgActionTest, OneArg) {
|
||||
bool is_deleted = false;
|
||||
DeletionTester* t = new DeletionTester(&is_deleted);
|
||||
const Action<void(DeletionTester*)> a1 = DeleteArg<0>(); // NOLINT
|
||||
EXPECT_FALSE(is_deleted);
|
||||
a1.Perform(make_tuple(t));
|
||||
EXPECT_TRUE(is_deleted);
|
||||
}
|
||||
|
||||
TEST(DeleteArgActionTest, TenArgs) {
|
||||
bool is_deleted = false;
|
||||
DeletionTester* t = new DeletionTester(&is_deleted);
|
||||
const Action<void(bool, int, int, const char*, bool,
|
||||
int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
|
||||
EXPECT_FALSE(is_deleted);
|
||||
a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
|
||||
EXPECT_TRUE(is_deleted);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
|
||||
TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {
|
||||
const Action<void(int n)> a = Throw('a');
|
||||
EXPECT_THROW(a.Perform(make_tuple(0)), char);
|
||||
}
|
||||
|
||||
class MyException {};
|
||||
|
||||
TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {
|
||||
const Action<double(char ch)> a = Throw(MyException());
|
||||
EXPECT_THROW(a.Perform(make_tuple('0')), MyException);
|
||||
}
|
||||
|
||||
TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
|
||||
const Action<double()> a = Throw(MyException());
|
||||
EXPECT_THROW(a.Perform(make_tuple()), MyException);
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
|
||||
// pointed to by the N-th (0-based) argument to values in range [first, last).
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArray) {
|
||||
typedef void MyFunction(bool, int*, char*);
|
||||
int numbers[] = { 1, 2, 3 };
|
||||
Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
|
||||
|
||||
int n[4] = {};
|
||||
int* pn = n;
|
||||
char ch[4] = {};
|
||||
char* pch = ch;
|
||||
a.Perform(make_tuple(true, pn, pch));
|
||||
EXPECT_EQ(1, n[0]);
|
||||
EXPECT_EQ(2, n[1]);
|
||||
EXPECT_EQ(3, n[2]);
|
||||
EXPECT_EQ(0, n[3]);
|
||||
EXPECT_EQ('\0', ch[0]);
|
||||
EXPECT_EQ('\0', ch[1]);
|
||||
EXPECT_EQ('\0', ch[2]);
|
||||
EXPECT_EQ('\0', ch[3]);
|
||||
|
||||
// Tests first and last are iterators.
|
||||
std::string letters = "abc";
|
||||
a = SetArrayArgument<2>(letters.begin(), letters.end());
|
||||
std::fill_n(n, 4, 0);
|
||||
std::fill_n(ch, 4, '\0');
|
||||
a.Perform(make_tuple(true, pn, pch));
|
||||
EXPECT_EQ(0, n[0]);
|
||||
EXPECT_EQ(0, n[1]);
|
||||
EXPECT_EQ(0, n[2]);
|
||||
EXPECT_EQ(0, n[3]);
|
||||
EXPECT_EQ('a', ch[0]);
|
||||
EXPECT_EQ('b', ch[1]);
|
||||
EXPECT_EQ('c', ch[2]);
|
||||
EXPECT_EQ('\0', ch[3]);
|
||||
}
|
||||
|
||||
// Tests SetArrayArgument<N>(first, last) where first == last.
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
|
||||
typedef void MyFunction(bool, int*);
|
||||
int numbers[] = { 1, 2, 3 };
|
||||
Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
|
||||
|
||||
int n[4] = {};
|
||||
int* pn = n;
|
||||
a.Perform(make_tuple(true, pn));
|
||||
EXPECT_EQ(0, n[0]);
|
||||
EXPECT_EQ(0, n[1]);
|
||||
EXPECT_EQ(0, n[2]);
|
||||
EXPECT_EQ(0, n[3]);
|
||||
}
|
||||
|
||||
// Tests SetArrayArgument<N>(first, last) where *first is convertible
|
||||
// (but not equal) to the argument type.
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
|
||||
typedef void MyFunction(bool, char*);
|
||||
int codes[] = { 97, 98, 99 };
|
||||
Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
|
||||
|
||||
char ch[4] = {};
|
||||
char* pch = ch;
|
||||
a.Perform(make_tuple(true, pch));
|
||||
EXPECT_EQ('a', ch[0]);
|
||||
EXPECT_EQ('b', ch[1]);
|
||||
EXPECT_EQ('c', ch[2]);
|
||||
EXPECT_EQ('\0', ch[3]);
|
||||
}
|
||||
|
||||
// Test SetArrayArgument<N>(first, last) with iterator as argument.
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
|
||||
typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
|
||||
std::string letters = "abc";
|
||||
Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
|
||||
|
||||
std::string s;
|
||||
a.Perform(make_tuple(true, back_inserter(s)));
|
||||
EXPECT_EQ(letters, s);
|
||||
}
|
||||
|
||||
} // namespace gmock_generated_actions_test
|
||||
} // namespace testing
|
Loading…
x
Reference in New Issue
Block a user