Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
326aa564
Commit
326aa564
authored
Jan 09, 2009
by
shiqian
Browse files
Implements the ACTION* macros.
parent
44a8cf19
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
1518 additions
and
0 deletions
+1518
-0
include/gmock/gmock-generated-actions.h
include/gmock/gmock-generated-actions.h
+972
-0
include/gmock/gmock-generated-actions.h.pump
include/gmock/gmock-generated-actions.h.pump
+208
-0
test/gmock-generated-actions_test.cc
test/gmock-generated-actions_test.cc
+338
-0
No files found.
include/gmock/gmock-generated-actions.h
View file @
326aa564
...
...
@@ -971,6 +971,126 @@ class DoBothAction {
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
// function. For example, if such an action only uses the second
// argument, it can be used in any mock function that takes >= 2
// arguments where the type of the second argument is compatible.
//
// Therefore, the action implementation must be prepared to take more
// arguments than it needs. The ExcessiveArg type is used to
// represent those excessive arguments. In order to keep the compiler
// error messages tractable, we define it in the testing namespace
// instead of testing::internal. However, this is an INTERNAL TYPE
// and subject to change without notice, so a user MUST NOT USE THIS
// TYPE DIRECTLY.
struct
ExcessiveArg
{};
// A helper class needed for implementing the ACTION* macros.
template
<
typename
Result
,
class
Impl
>
class
ActionHelper
{
public:
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
());
}
template
<
typename
A0
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
());
}
template
<
typename
A0
,
typename
A1
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
,
A1
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
get
<
1
>
(
args
),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
());
}
template
<
typename
A0
,
typename
A1
,
typename
A2
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
,
A1
,
A2
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
get
<
1
>
(
args
),
get
<
2
>
(
args
),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
());
}
template
<
typename
A0
,
typename
A1
,
typename
A2
,
typename
A3
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
,
A1
,
A2
,
A3
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
get
<
1
>
(
args
),
get
<
2
>
(
args
),
get
<
3
>
(
args
),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
());
}
template
<
typename
A0
,
typename
A1
,
typename
A2
,
typename
A3
,
typename
A4
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
,
A1
,
A2
,
A3
,
A4
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
get
<
1
>
(
args
),
get
<
2
>
(
args
),
get
<
3
>
(
args
),
get
<
4
>
(
args
),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
());
}
template
<
typename
A0
,
typename
A1
,
typename
A2
,
typename
A3
,
typename
A4
,
typename
A5
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
,
A1
,
A2
,
A3
,
A4
,
A5
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
get
<
1
>
(
args
),
get
<
2
>
(
args
),
get
<
3
>
(
args
),
get
<
4
>
(
args
),
get
<
5
>
(
args
),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
());
}
template
<
typename
A0
,
typename
A1
,
typename
A2
,
typename
A3
,
typename
A4
,
typename
A5
,
typename
A6
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
,
A1
,
A2
,
A3
,
A4
,
A5
,
A6
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
get
<
1
>
(
args
),
get
<
2
>
(
args
),
get
<
3
>
(
args
),
get
<
4
>
(
args
),
get
<
5
>
(
args
),
get
<
6
>
(
args
),
ExcessiveArg
(),
ExcessiveArg
(),
ExcessiveArg
());
}
template
<
typename
A0
,
typename
A1
,
typename
A2
,
typename
A3
,
typename
A4
,
typename
A5
,
typename
A6
,
typename
A7
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
,
A1
,
A2
,
A3
,
A4
,
A5
,
A6
,
A7
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
get
<
1
>
(
args
),
get
<
2
>
(
args
),
get
<
3
>
(
args
),
get
<
4
>
(
args
),
get
<
5
>
(
args
),
get
<
6
>
(
args
),
get
<
7
>
(
args
),
ExcessiveArg
(),
ExcessiveArg
());
}
template
<
typename
A0
,
typename
A1
,
typename
A2
,
typename
A3
,
typename
A4
,
typename
A5
,
typename
A6
,
typename
A7
,
typename
A8
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
,
A1
,
A2
,
A3
,
A4
,
A5
,
A6
,
A7
,
A8
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
get
<
1
>
(
args
),
get
<
2
>
(
args
),
get
<
3
>
(
args
),
get
<
4
>
(
args
),
get
<
5
>
(
args
),
get
<
6
>
(
args
),
get
<
7
>
(
args
),
get
<
8
>
(
args
),
ExcessiveArg
());
}
template
<
typename
A0
,
typename
A1
,
typename
A2
,
typename
A3
,
typename
A4
,
typename
A5
,
typename
A6
,
typename
A7
,
typename
A8
,
typename
A9
>
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
A0
,
A1
,
A2
,
A3
,
A4
,
A5
,
A6
,
A7
,
A8
,
A9
>&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
get
<
0
>
(
args
),
get
<
1
>
(
args
),
get
<
2
>
(
args
),
get
<
3
>
(
args
),
get
<
4
>
(
args
),
get
<
5
>
(
args
),
get
<
6
>
(
args
),
get
<
7
>
(
args
),
get
<
8
>
(
args
),
get
<
9
>
(
args
));
}
};
}
// namespace internal
// Various overloads for Invoke().
...
...
@@ -1326,4 +1446,856 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
}
// namespace testing
// The ACTION* family of macros can be used in a namespace scope to
// define custom actions easily. The syntax:
//
// ACTION(name) { statements; }
//
// will define an action with the given name that executes the
// statements. The value returned by the statements will be used as
// the return value of the action. Inside the statements, you can
// refer to the K-th (0-based) argument of the mock function by
// 'argK', and refer to its type by 'argK_type'. For example:
//
// ACTION(IncrementArg1) {
// arg1_type temp = arg1;
// return ++(*temp);
// }
//
// allows you to write
//
// ...WillOnce(IncrementArg1());
//
// You can also refer to the entire argument tuple and its type by
// 'args' and 'args_type', and refer to the mock function type and its
// return type by 'function_type' and 'return_type'.
//
// Note that you don't need to specify the types of the mock function
// arguments. However rest assured that your code is still type-safe:
// you'll get a compiler error if *arg1 doesn't support the ++
// operator, or if the type of ++(*arg1) isn't compatible with the
// mock function's return type, for example.
//
// Sometimes you'll want to parameterize the action. For that you can use
// another macro:
//
// ACTION_P(name, param_name) { statements; }
//
// For example:
//
// ACTION_P(Add, n) { return arg0 + n; }
//
// will allow you to write:
//
// ...WillOnce(Add(5));
//
// Note that you don't need to provide the type of the parameter
// either. If you need to reference the type of a parameter named
// 'foo', you can write 'foo_type'. For example, in the body of
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
// of 'n'.
//
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support
// multi-parameter actions.
//
// For the purpose of typing, you can view
//
// ACTION_Pk(Foo, p1, ..., pk) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
//
// In particular, you can provide the template type arguments
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
// although usually you can rely on the compiler to infer the types
// for you automatically. You can assign the result of expression
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
// pk_type>. This can be useful when composing actions.
//
// You can also overload actions with different numbers of parameters:
//
// ACTION_P(Plus, a) { ... }
// ACTION_P2(Plus, a, b) { ... }
//
// While it's tempting to always use the ACTION* macros when defining
// a new action, you should also consider implementing ActionInterface
// or using MakePolymorphicAction() instead, especially if you need to
// use the action a lot. While these approaches require more work,
// they give you more control on the types of the mock function
// arguments and the action parameters, which in general leads to
// better compiler error messages that pay off in the long run. They
// also allow overloading actions based on parameter types (as opposed
// to just based on the number of parameters).
//
// CAVEAT:
//
// ACTION*() can only be used in a namespace scope. The reason is
// that C++ doesn't yet allow function-local types to be used to
// instantiate templates. The up-coming C++0x standard will fix this.
// Once that's done, we'll consider supporting using ACTION*() inside
// a function.
//
// MORE INFORMATION:
//
// To learn more about using these macros, please search for 'ACTION'
// on http://code.google.com/p/googlemock/wiki/CookBook.
#define ACTION(name)\
class name##Action {\
public:\
name##Action() {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl() {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>());\
}\
};\
inline name##Action name() {\
return name##Action();\
}\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##Action::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P(name, p0)\
template <typename p0##_type>\
class name##ActionP {\
public:\
name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
explicit gmock_Impl(p0##_type gmock_p0) : p0(gmock_p0) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0));\
}\
const p0##_type p0;\
};\
template <typename p0##_type>\
inline name##ActionP<p0##_type> name(p0##_type p0) {\
return name##ActionP<p0##_type>(p0);\
}\
template <typename p0##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP<p0##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P2(name, p0, p1)\
template <typename p0##_type, typename p1##_type>\
class name##ActionP2 {\
public:\
name##ActionP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
p1(gmock_p1) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
p1(gmock_p1) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
const p1##_type p1;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0, p1));\
}\
const p0##_type p0;\
const p1##_type p1;\
};\
template <typename p0##_type, typename p1##_type>\
inline name##ActionP2<p0##_type, p1##_type> name(p0##_type p0, \
p1##_type p1) {\
return name##ActionP2<p0##_type, p1##_type>(p0, p1);\
}\
template <typename p0##_type, typename p1##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP2<p0##_type, p1##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P3(name, p0, p1, p2)\
template <typename p0##_type, typename p1##_type, typename p2##_type>\
class name##ActionP3 {\
public:\
name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2));\
}\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type>\
inline name##ActionP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \
p1##_type p1, p2##_type p2) {\
return name##ActionP3<p0##_type, p1##_type, p2##_type>(p0, p1, p2);\
}\
template <typename p0##_type, typename p1##_type, typename p2##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP3<p0##_type, p1##_type, p2##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P4(name, p0, p1, p2, p3)\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type>\
class name##ActionP4 {\
public:\
name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \
p2(gmock_p2), p3(gmock_p3) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3));\
}\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type>\
inline name##ActionP4<p0##_type, p1##_type, p2##_type, \
p3##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \
p3##_type p3) {\
return name##ActionP4<p0##_type, p1##_type, p2##_type, p3##_type>(p0, p1, \
p2, p3);\
}\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP4<p0##_type, p1##_type, p2##_type, p3##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P5(name, p0, p1, p2, p3, p4)\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type>\
class name##ActionP5 {\
public:\
name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, \
p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), \
p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4));\
}\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type>\
inline name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
p4##_type p4) {\
return name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type>(p0, p1, p2, p3, p4);\
}\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P6(name, p0, p1, p2, p3, p4, p5)\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type>\
class name##ActionP6 {\
public:\
name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5));\
}\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type>\
inline name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \
p3##_type p3, p4##_type p4, p5##_type p5) {\
return name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5);\
}\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P7(name, p0, p1, p2, p3, p4, p5, p6)\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type>\
class name##ActionP7 {\
public:\
name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \
p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \
p6(gmock_p6) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
const p6##_type p6;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \
p6));\
}\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
const p6##_type p6;\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type>\
inline name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type> name(p0##_type p0, p1##_type p1, \
p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \
p6##_type p6) {\
return name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, p6);\
}\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P8(name, p0, p1, p2, p3, p4, p5, p6, p7)\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type>\
class name##ActionP8 {\
public:\
name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, \
p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
p7(gmock_p7) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), \
p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), \
p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
const p6##_type p6;\
const p7##_type p7;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \
p6, p7));\
}\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
const p6##_type p6;\
const p7##_type p7;\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type>\
inline name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type> name(p0##_type p0, \
p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \
p6##_type p6, p7##_type p7) {\
return name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, p3, p4, p5, \
p6, p7);\
}\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type, p7##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8)\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type, typename p8##_type>\
class name##ActionP9 {\
public:\
name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
p8(gmock_p8) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, \
p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
p7(gmock_p7), p8(gmock_p8) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
const p6##_type p6;\
const p7##_type p7;\
const p8##_type p8;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \
p6, p7, p8));\
}\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
const p6##_type p6;\
const p7##_type p7;\
const p8##_type p8;\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type, typename p8##_type>\
inline name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type, \
p8##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \
p8##_type p8) {\
return name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type, p8##_type>(p0, p1, p2, \
p3, p4, p5, p6, p7, p8);\
}\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type, typename p8##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type, p7##_type, p8##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#define ACTION_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type, typename p8##_type, \
typename p9##_type>\
class name##ActionP10 {\
public:\
name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \
p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
arg9_type arg9) const;\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
const p6##_type p6;\
const p7##_type p7;\
const p8##_type p8;\
const p9##_type p9;\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \
p6, p7, p8, p9));\
}\
const p0##_type p0;\
const p1##_type p1;\
const p2##_type p2;\
const p3##_type p3;\
const p4##_type p4;\
const p5##_type p5;\
const p6##_type p6;\
const p7##_type p7;\
const p8##_type p8;\
const p9##_type p9;\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type, typename p8##_type, \
typename p9##_type>\
inline name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
p9##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \
p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \
p9##_type p9) {\
return name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>(p0, \
p1, p2, p3, p4, p5, p6, p7, p8, p9);\
}\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type, typename p8##_type, \
typename p9##_type>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>::\
gmock_Impl<F>::gmock_PerformImpl(const args_type& args, \
arg0_type arg0, arg1_type arg1, arg2_type arg2, arg3_type arg3, \
arg4_type arg4, arg5_type arg5, arg6_type arg6, arg7_type arg7, \
arg8_type arg8, arg9_type arg9) const
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
include/gmock/gmock-generated-actions.h.pump
View file @
326aa564
...
...
@@ -395,6 +395,49 @@ class DoBothAction {
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
// function. For example, if such an action only uses the second
// argument, it can be used in any mock function that takes >= 2
// arguments where the type of the second argument is compatible.
//
// Therefore, the action implementation must be prepared to take more
// arguments than it needs. The ExcessiveArg type is used to
// represent those excessive arguments. In order to keep the compiler
// error messages tractable, we define it in the testing namespace
// instead of testing::internal. However, this is an INTERNAL TYPE
// and subject to change without notice, so a user MUST NOT USE THIS
// TYPE DIRECTLY.
struct
ExcessiveArg
{};
// A helper class needed for implementing the ACTION* macros.
template
<
typename
Result
,
class
Impl
>
class
ActionHelper
{
public:
$
range
i
0.
.
n
$
for
i
[[
$
var
template
=
[[
$
if
i
==
0
[[]]
$
else
[[
$
range
j
0.
.
i
-
1
template
<
$
for
j
,
[[
typename
A
$
j
]]>
]]]]
$
range
j
0.
.
i
-
1
$
var
As
=
[[
$
for
j
,
[[
A
$
j
]]]]
$
var
as
=
[[
$
for
j
,
[[
get
<
$
j
>(
args
)]]]]
$
range
k
1.
.
n
-
i
$
var
eas
=
[[
$
for
k
,
[[
ExcessiveArg
()]]]]
$
var
arg_list
=
[[
$
if
(
i
==
0
)
|
(
i
==
n
)
[[
$
as
$
eas
]]
$
else
[[
$
as
,
$
eas
]]]]
$
template
static
Result
Perform
(
Impl
*
impl
,
const
::
std
::
tr1
::
tuple
<
$
As
>
&
args
)
{
using
::
std
::
tr1
::
get
;
return
impl
->
gmock_PerformImpl
(
args
,
$
arg_list
);
}
]]
};
}
// namespace internal
// Various overloads for Invoke().
...
...
@@ -564,4 +607,169 @@ $range j2 2..i
}
// namespace testing
// The ACTION* family of macros can be used in a namespace scope to
// define custom actions easily. The syntax:
//
// ACTION(name) { statements; }
//
// will define an action with the given name that executes the
// statements. The value returned by the statements will be used as
// the return value of the action. Inside the statements, you can
// refer to the K-th (0-based) argument of the mock function by
// 'argK', and refer to its type by 'argK_type'. For example:
//
// ACTION(IncrementArg1) {
// arg1_type temp = arg1;
// return ++(*temp);
// }
//
// allows you to write
//
// ...WillOnce(IncrementArg1());
//
// You can also refer to the entire argument tuple and its type by
// 'args' and 'args_type', and refer to the mock function type and its
// return type by 'function_type' and 'return_type'.
//
// Note that you don't need to specify the types of the mock function
// arguments. However rest assured that your code is still type-safe:
// you'll get a compiler error if *arg1 doesn't support the ++
// operator, or if the type of ++(*arg1) isn't compatible with the
// mock function's return type, for example.
//
// Sometimes you'll want to parameterize the action. For that you can use
// another macro:
//
// ACTION_P(name, param_name) { statements; }
//
// For example:
//
// ACTION_P(Add, n) { return arg0 + n; }
//
// will allow you to write:
//
// ...WillOnce(Add(5));
//
// Note that you don't need to provide the type of the parameter
// either. If you need to reference the type of a parameter named
// 'foo', you can write 'foo_type'. For example, in the body of
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
// of 'n'.
//
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support
// multi-parameter actions.
//
// For the purpose of typing, you can view
//
// ACTION_Pk(Foo, p1, ..., pk) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
//
// In particular, you can provide the template type arguments
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
// although usually you can rely on the compiler to infer the types
// for you automatically. You can assign the result of expression
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
// pk_type>. This can be useful when composing actions.
//
// You can also overload actions with different numbers of parameters:
//
// ACTION_P(Plus, a) { ... }
// ACTION_P2(Plus, a, b) { ... }
//
// While it's tempting to always use the ACTION* macros when defining
// a new action, you should also consider implementing ActionInterface
// or using MakePolymorphicAction() instead, especially if you need to
// use the action a lot. While these approaches require more work,
// they give you more control on the types of the mock function
// arguments and the action parameters, which in general leads to
// better compiler error messages that pay off in the long run. They
// also allow overloading actions based on parameter types (as opposed
// to just based on the number of parameters).
//
// CAVEAT:
//
// ACTION*() can only be used in a namespace scope. The reason is
// that C++ doesn't yet allow function-local types to be used to
// instantiate templates. The up-coming C++0x standard will fix this.
// Once that's done, we'll consider supporting using ACTION*() inside
// a function.
//
// MORE INFORMATION:
//
// To learn more about using these macros, please search for 'ACTION'
// on http://code.google.com/p/googlemock/wiki/CookBook.
$
range
i
0.
.
n
$
for
i
[[
$
var
template
=
[[
$
if
i
==
0
[[]]
$
else
[[
$
range
j
0.
.
i
-
1
template
<
$
for
j
,
[[
typename
p
$
j
##
_type
]]>
\
]]]]
$
var
class_name
=
[[
name
##
Action
[[
$
if
i
==
0
[[]]
$
elif
i
==
1
[[
P
]]
$
else
[[
P
$
i
]]]]]]
$
range
j
0.
.
i
-
1
$
var
ctor_param_list
=
[[
$
for
j
,
[[
p
$
j
##
_type
gmock_p
$
j
]]]]
$
var
param_types_and_names
=
[[
$
for
j
,
[[
p
$
j
##
_type
p
$
j
]]]]
$
var
inits
=
[[
$
if
i
==
0
[[]]
$
else
[[
:
$
for
j
,
[[
p
$
j
(
gmock_p
$
j
)]]]]]]
$
var
const_param_field_decls
=
[[
$
for
j
[[
const
p
$
j
##
_type
p
$
j
;
\
]]]]
$
var
const_param_field_decls2
=
[[
$
for
j
[[
const
p
$
j
##
_type
p
$
j
;
\
]]]]
$
var
params
=
[[
$
for
j
,
[[
p
$
j
]]]]
$
var
param_types
=
[[
$
if
i
==
0
[[]]
$
else
[[
<
$
for
j
,
[[
p
$
j
##
_type
]]
>
]]]]
$
range
k
0.
.
n
-
1
$
var
typename_arg_types
=
[[
$
for
k
,
[[
typename
arg
$
k
[[]]
_type
]]]]
$
var
arg_types_and_names
=
[[
$
for
k
,
[[
arg
$
k
[[]]
_type
arg
$
k
]]]]
$
var
macro_name
=
[[
$
if
i
==
0
[[
ACTION
]]
$
elif
i
==
1
[[
ACTION_P
]]
$
else
[[
ACTION_P
$
i
]]]]
#define $macro_name(name$for j [[, p$j]])\$template
class
$
class_name
{
\
public
:
\
$
class_name
(
$
ctor_param_list
)
$
inits
{}
\
template
<
typename
F
>
\
class
gmock_Impl
:
public
::
testing
::
ActionInterface
<
F
>
{
\
public
:
\
typedef
F
function_type
;
\
typedef
typename
::
testing
::
internal
::
Function
<
F
>::
Result
return_type
;
\
typedef
typename
::
testing
::
internal
::
Function
<
F
>::
ArgumentTuple
\
args_type
;
\
[[
$
if
i
==
1
[[
explicit
]]]]
gmock_Impl
(
$
ctor_param_list
)
$
inits
{}
\
virtual
return_type
Perform
(
const
args_type
&
args
)
{
\
return
::
testing
::
internal
::
ActionHelper
<
return_type
,
gmock_Impl
>::
\
Perform
(
this
,
args
);
\
}
\
template
<
$
typename_arg_types
>
\
return_type
gmock_PerformImpl
(
const
args_type
&
args
,
[[]]
$
arg_types_and_names
)
const
;
\$
const_param_field_decls
};
\
template
<
typename
F
>
operator
::
testing
::
Action
<
F
>
()
const
{
\
return
::
testing
::
Action
<
F
>
(
new
gmock_Impl
<
F
>
(
$
params
));
\
}
\$
const_param_field_decls2
};
\$
template
inline
$
class_name
$
param_types
name
(
$
param_types_and_names
)
{
\
return
$
class_name
$
param_types
(
$
params
);
\
}\$
template
template
<
typename
F
>
\
template
<
$
typename_arg_types
>
\
typename
::
testing
::
internal
::
Function
<
F
>
::
Result
\
$
class_name
$
param_types
::
\
gmock_Impl
<
F
>::
gmock_PerformImpl
(
const
args_type
&
args
,
[[]]
$
arg_types_and_names
)
const
]]
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
test/gmock-generated-actions_test.cc
View file @
326aa564
...
...
@@ -58,6 +58,7 @@ using testing::Invoke;
using
testing
::
InvokeArgument
;
using
testing
::
Return
;
using
testing
::
SetArgumentPointee
;
using
testing
::
StaticAssertTypeEq
;
using
testing
::
Unused
;
using
testing
::
WithArg
;
using
testing
::
WithArgs
;
...
...
@@ -942,5 +943,342 @@ TEST(DoAllTest, TenActions) {
EXPECT_EQ
(
'g'
,
g
);
}
// Tests the ACTION*() macro family.
// Tests that ACTION() can define an action that doesn't reference the
// mock function arguments.
ACTION
(
Return5
)
{
return
5
;
}
TEST
(
ActionMacroTest
,
WorksWhenNotReferencingArguments
)
{
Action
<
double
()
>
a1
=
Return5
();
EXPECT_DOUBLE_EQ
(
5
,
a1
.
Perform
(
make_tuple
()));
Action
<
int
(
double
,
bool
)
>
a2
=
Return5
();
EXPECT_EQ
(
5
,
a2
.
Perform
(
make_tuple
(
1
,
true
)));
}
// Tests that ACTION() can define an action that returns void.
ACTION
(
IncrementArg1
)
{
(
*
arg1
)
++
;
}
TEST
(
ActionMacroTest
,
WorksWhenReturningVoid
)
{
Action
<
void
(
int
,
int
*
)
>
a1
=
IncrementArg1
();
int
n
=
0
;
a1
.
Perform
(
make_tuple
(
5
,
&
n
));
EXPECT_EQ
(
1
,
n
);
}
// Tests that the body of ACTION() can reference the type of the
// argument.
ACTION
(
IncrementArg2
)
{
StaticAssertTypeEq
<
int
*
,
arg2_type
>
();
arg2_type
temp
=
arg2
;
(
*
temp
)
++
;
}
TEST
(
ActionMacroTest
,
CanReferenceArgumentType
)
{
Action
<
void
(
int
,
bool
,
int
*
)
>
a1
=
IncrementArg2
();
int
n
=
0
;
a1
.
Perform
(
make_tuple
(
5
,
false
,
&
n
));
EXPECT_EQ
(
1
,
n
);
}
// Tests that the body of ACTION() can reference the argument tuple
// via args_type and args.
ACTION
(
Sum2
)
{
StaticAssertTypeEq
<
::
std
::
tr1
::
tuple
<
int
,
char
,
int
*>
,
args_type
>
();
args_type
args_copy
=
args
;
return
get
<
0
>
(
args_copy
)
+
get
<
1
>
(
args_copy
);
}
TEST
(
ActionMacroTest
,
CanReferenceArgumentTuple
)
{
Action
<
int
(
int
,
char
,
int
*
)
>
a1
=
Sum2
();
int
dummy
=
0
;
EXPECT_EQ
(
11
,
a1
.
Perform
(
make_tuple
(
5
,
static_cast
<
char
>
(
6
),
&
dummy
)));
}
// Tests that the body of ACTION() can reference the mock function
// type.
int
Dummy
(
bool
flag
)
{
return
flag
?
1
:
0
;
}
ACTION
(
InvokeDummy
)
{
StaticAssertTypeEq
<
int
(
bool
),
function_type
>
();
function_type
*
fp
=
&
Dummy
;
return
(
*
fp
)(
true
);
}
TEST
(
ActionMacroTest
,
CanReferenceMockFunctionType
)
{
Action
<
int
(
bool
)
>
a1
=
InvokeDummy
();
EXPECT_EQ
(
1
,
a1
.
Perform
(
make_tuple
(
true
)));
EXPECT_EQ
(
1
,
a1
.
Perform
(
make_tuple
(
false
)));
}
// Tests that the body of ACTION() can reference the mock function's
// return type.
ACTION
(
InvokeDummy2
)
{
StaticAssertTypeEq
<
int
,
return_type
>
();
return_type
result
=
Dummy
(
true
);
return
result
;
}
TEST
(
ActionMacroTest
,
CanReferenceMockFunctionReturnType
)
{
Action
<
int
(
bool
)
>
a1
=
InvokeDummy2
();
EXPECT_EQ
(
1
,
a1
.
Perform
(
make_tuple
(
true
)));
EXPECT_EQ
(
1
,
a1
.
Perform
(
make_tuple
(
false
)));
}
// Tests that ACTION() can be used in a namespace.
namespace
action_test
{
ACTION
(
Sum
)
{
return
arg0
+
arg1
;
}
}
// namespace action_test
TEST
(
ActionMacroTest
,
WorksInNamespace
)
{
Action
<
int
(
int
,
int
)
>
a1
=
action_test
::
Sum
();
EXPECT_EQ
(
3
,
a1
.
Perform
(
make_tuple
(
1
,
2
)));
}
// Tests that the same ACTION definition works for mock functions with
// different argument numbers.
ACTION
(
PlusTwo
)
{
return
arg0
+
2
;
}
TEST
(
ActionMacroTest
,
WorksForDifferentArgumentNumbers
)
{
Action
<
int
(
int
)
>
a1
=
PlusTwo
();
EXPECT_EQ
(
4
,
a1
.
Perform
(
make_tuple
(
2
)));
Action
<
double
(
float
,
void
*
)
>
a2
=
PlusTwo
();
int
dummy
;
EXPECT_DOUBLE_EQ
(
6
,
a2
.
Perform
(
make_tuple
(
4.0
f
,
&
dummy
)));
}
// Tests that ACTION_P can define a parameterized action.
ACTION_P
(
Plus
,
n
)
{
return
arg0
+
n
;
}
TEST
(
ActionPMacroTest
,
DefinesParameterizedAction
)
{
Action
<
int
(
int
m
,
bool
t
)
>
a1
=
Plus
(
9
);
EXPECT_EQ
(
10
,
a1
.
Perform
(
make_tuple
(
1
,
true
)));
}
// Tests that the body of ACTION_P can reference the argument types
// and the parameter type.
ACTION_P
(
TypedPlus
,
n
)
{
arg0_type
t1
=
arg0
;
n_type
t2
=
n
;
return
t1
+
t2
;
}
TEST
(
ActionPMacroTest
,
CanReferenceArgumentAndParameterTypes
)
{
Action
<
int
(
char
m
,
bool
t
)
>
a1
=
TypedPlus
(
9
);
EXPECT_EQ
(
10
,
a1
.
Perform
(
make_tuple
(
static_cast
<
char
>
(
1
),
true
)));
}
// Tests that a parameterized action can be used in any mock function
// whose type is compatible.
TEST
(
ActionPMacroTest
,
WorksInCompatibleMockFunction
)
{
Action
<
std
::
string
(
const
std
::
string
&
s
)
>
a1
=
Plus
(
"tail"
);
const
std
::
string
re
=
"re"
;
EXPECT_EQ
(
"retail"
,
a1
.
Perform
(
make_tuple
(
re
)));
}
// Tests that we can use ACTION*() to define actions overloaded on the
// number of parameters.
ACTION
(
OverloadedAction
)
{
return
arg0
?
arg1
:
"hello"
;
}
ACTION_P
(
OverloadedAction
,
default_value
)
{
return
arg0
?
arg1
:
default_value
;
}
ACTION_P2
(
OverloadedAction
,
true_value
,
false_value
)
{
return
arg0
?
true_value
:
false_value
;
}
TEST
(
ActionMacroTest
,
CanDefineOverloadedActions
)
{
typedef
Action
<
const
char
*
(
bool
,
const
char
*
)
>
MyAction
;
const
MyAction
a1
=
OverloadedAction
();
EXPECT_STREQ
(
"hello"
,
a1
.
Perform
(
make_tuple
(
false
,
"world"
)));
EXPECT_STREQ
(
"world"
,
a1
.
Perform
(
make_tuple
(
true
,
"world"
)));
const
MyAction
a2
=
OverloadedAction
(
"hi"
);
EXPECT_STREQ
(
"hi"
,
a2
.
Perform
(
make_tuple
(
false
,
"world"
)));
EXPECT_STREQ
(
"world"
,
a2
.
Perform
(
make_tuple
(
true
,
"world"
)));
const
MyAction
a3
=
OverloadedAction
(
"hi"
,
"you"
);
EXPECT_STREQ
(
"hi"
,
a3
.
Perform
(
make_tuple
(
true
,
"world"
)));
EXPECT_STREQ
(
"you"
,
a3
.
Perform
(
make_tuple
(
false
,
"world"
)));
}
// Tests ACTION_Pn where n >= 3.
ACTION_P3
(
Plus
,
m
,
n
,
k
)
{
return
arg0
+
m
+
n
+
k
;
}
TEST
(
ActionPnMacroTest
,
WorksFor3Parameters
)
{
Action
<
double
(
int
m
,
bool
t
)
>
a1
=
Plus
(
100
,
20
,
3.4
);
EXPECT_DOUBLE_EQ
(
3123.4
,
a1
.
Perform
(
make_tuple
(
3000
,
true
)));
Action
<
std
::
string
(
const
std
::
string
&
s
)
>
a2
=
Plus
(
"tail"
,
"-"
,
">"
);
const
std
::
string
re
=
"re"
;
EXPECT_EQ
(
"retail->"
,
a2
.
Perform
(
make_tuple
(
re
)));
}
ACTION_P4
(
Plus
,
p0
,
p1
,
p2
,
p3
)
{
return
arg0
+
p0
+
p1
+
p2
+
p3
;
}
TEST
(
ActionPnMacroTest
,
WorksFor4Parameters
)
{
Action
<
int
(
int
)
>
a1
=
Plus
(
1
,
2
,
3
,
4
);
EXPECT_EQ
(
10
+
1
+
2
+
3
+
4
,
a1
.
Perform
(
make_tuple
(
10
)));
}
ACTION_P5
(
Plus
,
p0
,
p1
,
p2
,
p3
,
p4
)
{
return
arg0
+
p0
+
p1
+
p2
+
p3
+
p4
;
}
TEST
(
ActionPnMacroTest
,
WorksFor5Parameters
)
{
Action
<
int
(
int
)
>
a1
=
Plus
(
1
,
2
,
3
,
4
,
5
);
EXPECT_EQ
(
10
+
1
+
2
+
3
+
4
+
5
,
a1
.
Perform
(
make_tuple
(
10
)));
}
ACTION_P6
(
Plus
,
p0
,
p1
,
p2
,
p3
,
p4
,
p5
)
{
return
arg0
+
p0
+
p1
+
p2
+
p3
+
p4
+
p5
;
}
TEST
(
ActionPnMacroTest
,
WorksFor6Parameters
)
{
Action
<
int
(
int
)
>
a1
=
Plus
(
1
,
2
,
3
,
4
,
5
,
6
);
EXPECT_EQ
(
10
+
1
+
2
+
3
+
4
+
5
+
6
,
a1
.
Perform
(
make_tuple
(
10
)));
}
ACTION_P7
(
Plus
,
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
p6
)
{
return
arg0
+
p0
+
p1
+
p2
+
p3
+
p4
+
p5
+
p6
;
}
TEST
(
ActionPnMacroTest
,
WorksFor7Parameters
)
{
Action
<
int
(
int
)
>
a1
=
Plus
(
1
,
2
,
3
,
4
,
5
,
6
,
7
);
EXPECT_EQ
(
10
+
1
+
2
+
3
+
4
+
5
+
6
+
7
,
a1
.
Perform
(
make_tuple
(
10
)));
}
ACTION_P8
(
Plus
,
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
p6
,
p7
)
{
return
arg0
+
p0
+
p1
+
p2
+
p3
+
p4
+
p5
+
p6
+
p7
;
}
TEST
(
ActionPnMacroTest
,
WorksFor8Parameters
)
{
Action
<
int
(
int
)
>
a1
=
Plus
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
);
EXPECT_EQ
(
10
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
,
a1
.
Perform
(
make_tuple
(
10
)));
}
ACTION_P9
(
Plus
,
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
p6
,
p7
,
p8
)
{
return
arg0
+
p0
+
p1
+
p2
+
p3
+
p4
+
p5
+
p6
+
p7
+
p8
;
}
TEST
(
ActionPnMacroTest
,
WorksFor9Parameters
)
{
Action
<
int
(
int
)
>
a1
=
Plus
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
);
EXPECT_EQ
(
10
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
,
a1
.
Perform
(
make_tuple
(
10
)));
}
ACTION_P10
(
Plus
,
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
p6
,
p7
,
p8
,
last_param
)
{
arg0_type
t0
=
arg0
;
last_param_type
t9
=
last_param
;
return
t0
+
p0
+
p1
+
p2
+
p3
+
p4
+
p5
+
p6
+
p7
+
p8
+
t9
;
}
TEST
(
ActionPnMacroTest
,
WorksFor10Parameters
)
{
Action
<
int
(
int
)
>
a1
=
Plus
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
);
EXPECT_EQ
(
10
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
,
a1
.
Perform
(
make_tuple
(
10
)));
}
// Tests that the action body can promote the parameter types.
ACTION_P2
(
PadArgument
,
prefix
,
suffix
)
{
// The following lines promote the two parameters to desired types.
std
::
string
prefix_str
(
prefix
);
char
suffix_char
(
suffix
);
return
prefix_str
+
arg0
+
suffix_char
;
}
TEST
(
ActionPnMacroTest
,
SimpleTypePromotion
)
{
Action
<
std
::
string
(
const
char
*
)
>
no_promo
=
PadArgument
(
std
::
string
(
"foo"
),
'r'
);
Action
<
std
::
string
(
const
char
*
)
>
promo
=
PadArgument
(
"foo"
,
static_cast
<
int
>
(
'r'
));
EXPECT_EQ
(
"foobar"
,
no_promo
.
Perform
(
make_tuple
(
"ba"
)));
EXPECT_EQ
(
"foobar"
,
promo
.
Perform
(
make_tuple
(
"ba"
)));
}
// Tests that we can partially restrict parameter types using a
// straight-forward pattern.
// Defines a generic action that doesn't restrict the types of its
// parameters.
ACTION_P3
(
ConcatImpl
,
a
,
b
,
c
)
{
std
::
stringstream
ss
;
ss
<<
a
<<
b
<<
c
;
return
ss
.
str
();
}
// Next, we try to restrict that either the first parameter is a
// string, or the second parameter is an int.
// Defines a partially specialized wrapper that restricts the first
// parameter to std::string.
template
<
typename
T1
,
typename
T2
>
// ConcatImplActionP3 is the class template ACTION_P3 uses to
// implement ConcatImpl. We shouldn't change the name as this
// pattern requires the user to use it directly.
ConcatImplActionP3
<
std
::
string
,
T1
,
T2
>
Concat
(
const
std
::
string
&
a
,
T1
b
,
T2
c
)
{
if
(
true
)
{
// This branch verifies that ConcatImpl() can be invoked without
// explicit template arguments.
return
ConcatImpl
(
a
,
b
,
c
);
}
else
{
// This branch verifies that ConcatImpl() can also be invoked with
// explicit template arguments. It doesn't really need to be
// executed as this is a compile-time verification.
return
ConcatImpl
<
std
::
string
,
T1
,
T2
>
(
a
,
b
,
c
);
}
}
// Defines another partially specialized wrapper that restricts the
// second parameter to int.
template
<
typename
T1
,
typename
T2
>
ConcatImplActionP3
<
T1
,
int
,
T2
>
Concat
(
T1
a
,
int
b
,
T2
c
)
{
return
ConcatImpl
(
a
,
b
,
c
);
}
TEST
(
ActionPnMacroTest
,
CanPartiallyRestrictParameterTypes
)
{
Action
<
const
std
::
string
()
>
a1
=
Concat
(
"Hello"
,
"1"
,
2
);
EXPECT_EQ
(
"Hello12"
,
a1
.
Perform
(
make_tuple
()));
a1
=
Concat
(
1
,
2
,
3
);
EXPECT_EQ
(
"123"
,
a1
.
Perform
(
make_tuple
()));
}
// Verifies the type of an ACTION*.
ACTION
(
DoFoo
)
{}
ACTION_P
(
DoFoo
,
p
)
{}
ACTION_P2
(
DoFoo
,
p0
,
p1
)
{}
TEST
(
ActionPnMacroTest
,
TypesAreCorrect
)
{
// DoFoo() must be assignable to a DoFooAction variable.
DoFooAction
a0
=
DoFoo
();
// DoFoo(1) must be assignable to a DoFooActionP variable.
DoFooActionP
<
int
>
a1
=
DoFoo
(
1
);
// DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk
// variable, and so on.
DoFooActionP2
<
int
,
char
>
a2
=
DoFoo
(
1
,
'2'
);
PlusActionP3
<
int
,
int
,
char
>
a3
=
Plus
(
1
,
2
,
'3'
);
PlusActionP4
<
int
,
int
,
int
,
char
>
a4
=
Plus
(
1
,
2
,
3
,
'4'
);
PlusActionP5
<
int
,
int
,
int
,
int
,
char
>
a5
=
Plus
(
1
,
2
,
3
,
4
,
'5'
);
PlusActionP6
<
int
,
int
,
int
,
int
,
int
,
char
>
a6
=
Plus
(
1
,
2
,
3
,
4
,
5
,
'6'
);
PlusActionP7
<
int
,
int
,
int
,
int
,
int
,
int
,
char
>
a7
=
Plus
(
1
,
2
,
3
,
4
,
5
,
6
,
'7'
);
PlusActionP8
<
int
,
int
,
int
,
int
,
int
,
int
,
int
,
char
>
a8
=
Plus
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
'8'
);
PlusActionP9
<
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
char
>
a9
=
Plus
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
'9'
);
PlusActionP10
<
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
char
>
a10
=
Plus
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
'0'
);
}
}
// namespace gmock_generated_actions_test
}
// namespace testing
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment