Partially implemented SafeMatcherCast (by Vlad Losev); updated the implementation of Not, AnyOf, and AllOf to use SafeMatcherCast (by Vlad Losev); implemented ACTION_TEMPLATE (by Zhanyong Wan); worked around bugs on Symbian (by Zhanyong Wan).
This commit is contained in:
parent
d955e83bee
commit
18490653e8
@ -1571,6 +1571,416 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
|
||||
arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_,\
|
||||
arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_
|
||||
|
||||
// Sometimes you want to give an action explicit template parameters
|
||||
// that cannot be inferred from its value parameters. ACTION() and
|
||||
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
|
||||
// and can be viewed as an extension to ACTION() and ACTION_P*().
|
||||
//
|
||||
// The syntax:
|
||||
//
|
||||
// ACTION_TEMPLATE(ActionName,
|
||||
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
|
||||
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
|
||||
//
|
||||
// defines an action template that takes m explicit template
|
||||
// parameters and n value parameters. name_i is the name of the i-th
|
||||
// template parameter, and kind_i specifies whether it's a typename,
|
||||
// an integral constant, or a template. p_i is the name of the i-th
|
||||
// value parameter.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
|
||||
// // function to type T and copies it to *output.
|
||||
// ACTION_TEMPLATE(DuplicateArg,
|
||||
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
|
||||
// AND_1_VALUE_PARAMS(output)) {
|
||||
// *output = T(std::tr1::get<k>(args));
|
||||
// }
|
||||
// ...
|
||||
// int n;
|
||||
// EXPECT_CALL(mock, Foo(_, _))
|
||||
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
|
||||
//
|
||||
// To create an instance of an action template, write:
|
||||
//
|
||||
// ActionName<t1, ..., t_m>(v1, ..., v_n)
|
||||
//
|
||||
// where the ts are the template arguments and the vs are the value
|
||||
// arguments. The value argument types are inferred by the compiler.
|
||||
// If you want to explicitly specify the value argument types, you can
|
||||
// provide additional template arguments:
|
||||
//
|
||||
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
|
||||
//
|
||||
// where u_i is the desired type of v_i.
|
||||
//
|
||||
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
|
||||
// number of value parameters, but not on the number of template
|
||||
// parameters. Without the restriction, the meaning of the following
|
||||
// is unclear:
|
||||
//
|
||||
// OverloadedAction<int, bool>(x);
|
||||
//
|
||||
// Are we using a single-template-parameter action where 'bool' refers
|
||||
// to the type of x, or are we using a two-template-parameter action
|
||||
// where the compiler is asked to infer the type of x?
|
||||
//
|
||||
// Implementation notes:
|
||||
//
|
||||
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
|
||||
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
|
||||
// implementing ACTION_TEMPLATE. The main trick we use is to create
|
||||
// new macro invocations when expanding a macro. For example, we have
|
||||
//
|
||||
// #define ACTION_TEMPLATE(name, template_params, value_params)
|
||||
// ... GMOCK_INTERNAL_DECL_##template_params ...
|
||||
//
|
||||
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
|
||||
// to expand to
|
||||
//
|
||||
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
|
||||
//
|
||||
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
|
||||
// preprocessor will continue to expand it to
|
||||
//
|
||||
// ... typename T ...
|
||||
//
|
||||
// This technique conforms to the C++ standard and is portable. It
|
||||
// allows us to implement action templates using O(N) code, where N is
|
||||
// the maximum number of template/value parameters supported. Without
|
||||
// using it, we'd have to devote O(N^2) amount of code to implement all
|
||||
// combinations of m and n.
|
||||
|
||||
// Declares the template parameters.
|
||||
#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0
|
||||
#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
|
||||
name1) kind0 name0, kind1 name1
|
||||
#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2) kind0 name0, kind1 name1, kind2 name2
|
||||
#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \
|
||||
kind3 name3
|
||||
#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \
|
||||
kind2 name2, kind3 name3, kind4 name4
|
||||
#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \
|
||||
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5
|
||||
#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
|
||||
name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \
|
||||
kind5 name5, kind6 name6
|
||||
#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
|
||||
kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \
|
||||
kind4 name4, kind5 name5, kind6 name6, kind7 name7
|
||||
#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
|
||||
kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \
|
||||
kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \
|
||||
kind8 name8
|
||||
#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
|
||||
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
|
||||
name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \
|
||||
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \
|
||||
kind6 name6, kind7 name7, kind8 name8, kind9 name9
|
||||
|
||||
// Lists the template parameters.
|
||||
#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0
|
||||
#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
|
||||
name1) name0, name1
|
||||
#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2) name0, name1, name2
|
||||
#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3) name0, name1, name2, name3
|
||||
#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \
|
||||
name4
|
||||
#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \
|
||||
name2, name3, name4, name5
|
||||
#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
|
||||
name6) name0, name1, name2, name3, name4, name5, name6
|
||||
#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
|
||||
kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7
|
||||
#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
|
||||
kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \
|
||||
name6, name7, name8
|
||||
#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
|
||||
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
|
||||
name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \
|
||||
name3, name4, name5, name6, name7, name8, name9
|
||||
|
||||
// Declares the types of value parameters.
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \
|
||||
typename p0##_type, typename p1##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \
|
||||
typename p0##_type, typename p1##_type, typename p2##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \
|
||||
typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \
|
||||
typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \
|
||||
typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6) , typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type, \
|
||||
typename p6##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type, \
|
||||
typename p6##_type, typename p7##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8) , 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
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8, p9) , 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
|
||||
|
||||
// Initializes the value parameters.
|
||||
#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\
|
||||
()
|
||||
#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\
|
||||
(p0##_type gmock_p0) : p0(gmock_p0)
|
||||
#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), p1(gmock_p1)
|
||||
#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, \
|
||||
p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2)
|
||||
#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\
|
||||
(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)
|
||||
#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\
|
||||
(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)
|
||||
#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\
|
||||
(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)
|
||||
#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\
|
||||
(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)
|
||||
#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\
|
||||
(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)
|
||||
#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8)\
|
||||
(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)
|
||||
#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9)\
|
||||
(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)
|
||||
|
||||
// Declares the fields for storing the value parameters.
|
||||
#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0; \
|
||||
p1##_type p1;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0; \
|
||||
p1##_type p1; p2##_type p2;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0; \
|
||||
p1##_type p1; p2##_type p2; p3##_type p3;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \
|
||||
p4) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \
|
||||
p5) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \
|
||||
p5##_type p5;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \
|
||||
p5##_type p5; p6##_type p6;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \
|
||||
p5##_type p5; p6##_type p6; p7##_type p7;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8) 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;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9) 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;
|
||||
|
||||
// Lists the value parameters.
|
||||
#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0
|
||||
#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1
|
||||
#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2
|
||||
#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3
|
||||
#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) p0, p1, \
|
||||
p2, p3, p4
|
||||
#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) p0, \
|
||||
p1, p2, p3, p4, p5
|
||||
#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6) p0, p1, p2, p3, p4, p5, p6
|
||||
#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7) p0, p1, p2, p3, p4, p5, p6, p7
|
||||
#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8) p0, p1, p2, p3, p4, p5, p6, p7, p8
|
||||
#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9) p0, p1, p2, p3, p4, p5, p6, p7, p8, p9
|
||||
|
||||
// Lists the value parameter types.
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) , p0##_type, \
|
||||
p1##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , p0##_type, \
|
||||
p1##_type, p2##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \
|
||||
p0##_type, p1##_type, p2##_type, p3##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \
|
||||
p0##_type, p1##_type, p2##_type, p3##_type, p4##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \
|
||||
p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \
|
||||
p6##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
||||
p5##_type, p6##_type, p7##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
||||
p5##_type, p6##_type, p7##_type, p8##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8, p9) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
||||
p5##_type, p6##_type, p7##_type, p8##_type, p9##_type
|
||||
|
||||
// Declares the value parameters.
|
||||
#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0
|
||||
#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0, \
|
||||
p1##_type p1
|
||||
#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0, \
|
||||
p1##_type p1, p2##_type p2
|
||||
#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0, \
|
||||
p1##_type p1, p2##_type p2, p3##_type p3
|
||||
#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \
|
||||
p4) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4
|
||||
#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \
|
||||
p5) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
|
||||
p5##_type p5
|
||||
#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
|
||||
p5##_type p5, p6##_type p6
|
||||
#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
|
||||
p5##_type p5, p6##_type p6, p7##_type p7
|
||||
#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8) 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
|
||||
#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9) 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
|
||||
|
||||
// The suffix of the class template implementing the action template.
|
||||
#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P
|
||||
#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2
|
||||
#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3
|
||||
#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4
|
||||
#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5
|
||||
#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6
|
||||
#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7
|
||||
#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7) P8
|
||||
#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8) P9
|
||||
#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9) P10
|
||||
|
||||
// The name of the class template implementing the action template.
|
||||
#define GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GMOCK_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
|
||||
|
||||
#define ACTION_TEMPLATE(name, template_params, value_params)\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
class GMOCK_ACTION_CLASS_(name, value_params) {\
|
||||
public:\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
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 GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
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;\
|
||||
GMOCK_INTERNAL_DEFN_##value_params\
|
||||
};\
|
||||
template <typename F> operator ::testing::Action<F>() const {\
|
||||
return ::testing::Action<F>(\
|
||||
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
|
||||
}\
|
||||
GMOCK_INTERNAL_DEFN_##value_params\
|
||||
};\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
inline GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
|
||||
GMOCK_INTERNAL_DECL_##value_params) {\
|
||||
return GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
|
||||
GMOCK_INTERNAL_LIST_##value_params);\
|
||||
}\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
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\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
|
||||
gmock_PerformImpl(\
|
||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||
|
||||
#define ACTION(name)\
|
||||
class name##Action {\
|
||||
public:\
|
||||
|
@ -3,6 +3,7 @@ $$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-variadic-actions.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
$$}} This meta comment fixes auto-indentation in editors.
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
@ -718,6 +719,239 @@ $for k [[,\
|
||||
arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
|
||||
|
||||
|
||||
// Sometimes you want to give an action explicit template parameters
|
||||
// that cannot be inferred from its value parameters. ACTION() and
|
||||
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
|
||||
// and can be viewed as an extension to ACTION() and ACTION_P*().
|
||||
//
|
||||
// The syntax:
|
||||
//
|
||||
// ACTION_TEMPLATE(ActionName,
|
||||
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
|
||||
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
|
||||
//
|
||||
// defines an action template that takes m explicit template
|
||||
// parameters and n value parameters. name_i is the name of the i-th
|
||||
// template parameter, and kind_i specifies whether it's a typename,
|
||||
// an integral constant, or a template. p_i is the name of the i-th
|
||||
// value parameter.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
|
||||
// // function to type T and copies it to *output.
|
||||
// ACTION_TEMPLATE(DuplicateArg,
|
||||
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
|
||||
// AND_1_VALUE_PARAMS(output)) {
|
||||
// *output = T(std::tr1::get<k>(args));
|
||||
// }
|
||||
// ...
|
||||
// int n;
|
||||
// EXPECT_CALL(mock, Foo(_, _))
|
||||
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
|
||||
//
|
||||
// To create an instance of an action template, write:
|
||||
//
|
||||
// ActionName<t1, ..., t_m>(v1, ..., v_n)
|
||||
//
|
||||
// where the ts are the template arguments and the vs are the value
|
||||
// arguments. The value argument types are inferred by the compiler.
|
||||
// If you want to explicitly specify the value argument types, you can
|
||||
// provide additional template arguments:
|
||||
//
|
||||
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
|
||||
//
|
||||
// where u_i is the desired type of v_i.
|
||||
//
|
||||
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
|
||||
// number of value parameters, but not on the number of template
|
||||
// parameters. Without the restriction, the meaning of the following
|
||||
// is unclear:
|
||||
//
|
||||
// OverloadedAction<int, bool>(x);
|
||||
//
|
||||
// Are we using a single-template-parameter action where 'bool' refers
|
||||
// to the type of x, or are we using a two-template-parameter action
|
||||
// where the compiler is asked to infer the type of x?
|
||||
//
|
||||
// Implementation notes:
|
||||
//
|
||||
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
|
||||
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
|
||||
// implementing ACTION_TEMPLATE. The main trick we use is to create
|
||||
// new macro invocations when expanding a macro. For example, we have
|
||||
//
|
||||
// #define ACTION_TEMPLATE(name, template_params, value_params)
|
||||
// ... GMOCK_INTERNAL_DECL_##template_params ...
|
||||
//
|
||||
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
|
||||
// to expand to
|
||||
//
|
||||
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
|
||||
//
|
||||
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
|
||||
// preprocessor will continue to expand it to
|
||||
//
|
||||
// ... typename T ...
|
||||
//
|
||||
// This technique conforms to the C++ standard and is portable. It
|
||||
// allows us to implement action templates using O(N) code, where N is
|
||||
// the maximum number of template/value parameters supported. Without
|
||||
// using it, we'd have to devote O(N^2) amount of code to implement all
|
||||
// combinations of m and n.
|
||||
|
||||
// Declares the template parameters.
|
||||
|
||||
$range j 1..n
|
||||
$for j [[
|
||||
$range m 0..j-1
|
||||
#define GMOCK_INTERNAL_DECL_HAS_$j[[]]
|
||||
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Lists the template parameters.
|
||||
|
||||
$for j [[
|
||||
$range m 0..j-1
|
||||
#define GMOCK_INTERNAL_LIST_HAS_$j[[]]
|
||||
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Declares the types of value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Initializes the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
|
||||
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Declares the fields for storing the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_DEFN_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Lists the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_LIST_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Lists the value parameter types.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Declares the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
|
||||
$for j, [[p$j##_type p$j]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// The suffix of the class template implementing the action template.
|
||||
$for i [[
|
||||
|
||||
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
|
||||
$if i==1 [[P]] $elif i>=2 [[P$i]]
|
||||
]]
|
||||
|
||||
|
||||
// The name of the class template implementing the action template.
|
||||
#define GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GMOCK_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
|
||||
|
||||
$range k 0..n-1
|
||||
|
||||
#define ACTION_TEMPLATE(name, template_params, value_params)\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
class GMOCK_ACTION_CLASS_(name, value_params) {\
|
||||
public:\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
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 GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
virtual return_type Perform(const args_type& args) {\
|
||||
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
|
||||
Perform(this, args);\
|
||||
}\
|
||||
template <$for k, [[typename arg$k[[]]_type]]>\
|
||||
return_type gmock_PerformImpl(const args_type& args[[]]
|
||||
$for k [[, arg$k[[]]_type arg$k]]) const;\
|
||||
GMOCK_INTERNAL_DEFN_##value_params\
|
||||
};\
|
||||
template <typename F> operator ::testing::Action<F>() const {\
|
||||
return ::testing::Action<F>(\
|
||||
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
|
||||
}\
|
||||
GMOCK_INTERNAL_DEFN_##value_params\
|
||||
};\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
inline GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
|
||||
GMOCK_INTERNAL_DECL_##value_params) {\
|
||||
return GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
|
||||
GMOCK_INTERNAL_LIST_##value_params);\
|
||||
}\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
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\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
|
||||
gmock_PerformImpl(\
|
||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||
|
||||
$for i
|
||||
|
||||
[[
|
||||
|
@ -171,7 +171,7 @@ class Matcher : public internal::MatcherBase<T> {
|
||||
explicit Matcher(const MatcherInterface<T>* impl)
|
||||
: internal::MatcherBase<T>(impl) {}
|
||||
|
||||
// Implicit constructor here allows ipeople to write
|
||||
// Implicit constructor here allows people to write
|
||||
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
|
||||
Matcher(T value); // NOLINT
|
||||
};
|
||||
@ -310,6 +310,39 @@ inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
|
||||
template <typename T, typename M>
|
||||
Matcher<T> MatcherCast(M m);
|
||||
|
||||
// TODO(vladl@google.com): Modify the implementation to reject casting
|
||||
// Matcher<int> to Matcher<double>.
|
||||
// Implements SafeMatcherCast().
|
||||
//
|
||||
// This overload handles polymorphic matchers only since monomorphic
|
||||
// matchers are handled by the next one.
|
||||
template <typename T, typename M>
|
||||
inline Matcher<T> SafeMatcherCast(M polymorphic_matcher) {
|
||||
return Matcher<T>(polymorphic_matcher);
|
||||
}
|
||||
|
||||
// This overload handles monomorphic matchers.
|
||||
//
|
||||
// In general, if type T can be implicitly converted to type U, we can
|
||||
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
|
||||
// contravariant): just keep a copy of the original Matcher<U>, convert the
|
||||
// argument from type T to U, and then pass it to the underlying Matcher<U>.
|
||||
// The only exception is when U is a reference and T is not, as the
|
||||
// underlying Matcher<U> may be interested in the argument's address, which
|
||||
// is not preserved in the conversion from T to U.
|
||||
template <typename T, typename U>
|
||||
Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) {
|
||||
// Enforce that T can be implicitly converted to U.
|
||||
GMOCK_COMPILE_ASSERT_((internal::ImplicitlyConvertible<T, U>::value),
|
||||
T_must_be_implicitly_convertible_to_U);
|
||||
// Enforce that we are not converting a non-reference type T to a reference
|
||||
// type U.
|
||||
GMOCK_COMPILE_ASSERT_(
|
||||
internal::is_reference<T>::value || !internal::is_reference<U>::value,
|
||||
cannot_convert_non_referentce_arg_to_reference);
|
||||
return MatcherCast<T>(matcher);
|
||||
}
|
||||
|
||||
// A<T>() returns a matcher that matches any value of type T.
|
||||
template <typename T>
|
||||
Matcher<T> A();
|
||||
@ -927,6 +960,10 @@ GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ne, !=, "not equal to");
|
||||
|
||||
#undef GMOCK_IMPLEMENT_COMPARISON2_MATCHER_
|
||||
|
||||
// TODO(vladl@google.com): Move Impl outside of NotMatcher and rename it
|
||||
// NotMatcherImpl to reduce compilation overhead and the size of the binary.
|
||||
// This also applies to BothOfMatcher::Impl and EitherOfMatcher::Impl.
|
||||
//
|
||||
// Implements the Not(m) matcher, which matches a value that doesn't
|
||||
// match matcher m.
|
||||
template <typename InnerMatcher>
|
||||
@ -945,7 +982,8 @@ class NotMatcher {
|
||||
template <typename T>
|
||||
class Impl : public MatcherInterface<T> {
|
||||
public:
|
||||
explicit Impl(const Matcher<T>& matcher) : matcher_(matcher) {}
|
||||
explicit Impl(InnerMatcher matcher)
|
||||
: matcher_(SafeMatcherCast<T>(matcher)) {}
|
||||
|
||||
virtual bool Matches(T x) const {
|
||||
return !matcher_.Matches(x);
|
||||
@ -990,8 +1028,9 @@ class BothOfMatcher {
|
||||
template <typename T>
|
||||
class Impl : public MatcherInterface<T> {
|
||||
public:
|
||||
Impl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
|
||||
: matcher1_(matcher1), matcher2_(matcher2) {}
|
||||
Impl(Matcher1 matcher1, Matcher2 matcher2)
|
||||
: matcher1_(SafeMatcherCast<T>(matcher1)),
|
||||
matcher2_(SafeMatcherCast<T>(matcher2)) {}
|
||||
|
||||
virtual bool Matches(T x) const {
|
||||
return matcher1_.Matches(x) && matcher2_.Matches(x);
|
||||
@ -1071,8 +1110,9 @@ class EitherOfMatcher {
|
||||
template <typename T>
|
||||
class Impl : public MatcherInterface<T> {
|
||||
public:
|
||||
Impl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
|
||||
: matcher1_(matcher1), matcher2_(matcher2) {}
|
||||
Impl(Matcher1 matcher1, Matcher2 matcher2)
|
||||
: matcher1_(SafeMatcherCast<T>(matcher1)),
|
||||
matcher2_(SafeMatcherCast<T>(matcher2)) {}
|
||||
|
||||
virtual bool Matches(T x) const {
|
||||
return matcher1_.Matches(x) || matcher2_.Matches(x);
|
||||
@ -1433,7 +1473,11 @@ class FieldMatcher {
|
||||
matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
void ExplainMatchResultTo(const Class& obj, ::std::ostream* os) const {
|
||||
// The first argument of ExplainMatchResultTo() is needed to help
|
||||
// Symbian's C++ compiler choose which overload to use. Its type is
|
||||
// true_type iff the Field() matcher is used to match a pointer.
|
||||
void ExplainMatchResultTo(false_type /* is_not_pointer */, const Class& obj,
|
||||
::std::ostream* os) const {
|
||||
::std::stringstream ss;
|
||||
matcher_.ExplainMatchResultTo(obj.*field_, &ss);
|
||||
const internal::string s = ss.str();
|
||||
@ -1442,9 +1486,13 @@ class FieldMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
void ExplainMatchResultTo(const Class* p, ::std::ostream* os) const {
|
||||
void ExplainMatchResultTo(true_type /* is_pointer */, const Class* p,
|
||||
::std::ostream* os) const {
|
||||
if (p != NULL) {
|
||||
ExplainMatchResultTo(*p, os);
|
||||
// Since *p has a field, it must be a class/struct/union type
|
||||
// and thus cannot be a pointer. Therefore we pass false_type()
|
||||
// as the first argument.
|
||||
ExplainMatchResultTo(false_type(), *p, os);
|
||||
}
|
||||
}
|
||||
private:
|
||||
@ -1452,18 +1500,12 @@ class FieldMatcher {
|
||||
const Matcher<const FieldType&> matcher_;
|
||||
};
|
||||
|
||||
// Explains the result of matching an object against a field matcher.
|
||||
template <typename Class, typename FieldType>
|
||||
// Explains the result of matching an object or pointer against a field matcher.
|
||||
template <typename Class, typename FieldType, typename T>
|
||||
void ExplainMatchResultTo(const FieldMatcher<Class, FieldType>& matcher,
|
||||
const Class& obj, ::std::ostream* os) {
|
||||
matcher.ExplainMatchResultTo(obj, os);
|
||||
}
|
||||
|
||||
// Explains the result of matching a pointer against a field matcher.
|
||||
template <typename Class, typename FieldType>
|
||||
void ExplainMatchResultTo(const FieldMatcher<Class, FieldType>& matcher,
|
||||
const Class* p, ::std::ostream* os) {
|
||||
matcher.ExplainMatchResultTo(p, os);
|
||||
const T& value, ::std::ostream* os) {
|
||||
matcher.ExplainMatchResultTo(
|
||||
typename ::testing::internal::is_pointer<T>::type(), value, os);
|
||||
}
|
||||
|
||||
// Implements the Property() matcher for matching a property
|
||||
@ -1501,7 +1543,11 @@ class PropertyMatcher {
|
||||
matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
void ExplainMatchResultTo(const Class& obj, ::std::ostream* os) const {
|
||||
// The first argument of ExplainMatchResultTo() is needed to help
|
||||
// Symbian's C++ compiler choose which overload to use. Its type is
|
||||
// true_type iff the Property() matcher is used to match a pointer.
|
||||
void ExplainMatchResultTo(false_type /* is_not_pointer */, const Class& obj,
|
||||
::std::ostream* os) const {
|
||||
::std::stringstream ss;
|
||||
matcher_.ExplainMatchResultTo((obj.*property_)(), &ss);
|
||||
const internal::string s = ss.str();
|
||||
@ -1510,9 +1556,13 @@ class PropertyMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
void ExplainMatchResultTo(const Class* p, ::std::ostream* os) const {
|
||||
void ExplainMatchResultTo(true_type /* is_pointer */, const Class* p,
|
||||
::std::ostream* os) const {
|
||||
if (p != NULL) {
|
||||
ExplainMatchResultTo(*p, os);
|
||||
// Since *p has a property method, it must be a
|
||||
// class/struct/union type and thus cannot be a pointer.
|
||||
// Therefore we pass false_type() as the first argument.
|
||||
ExplainMatchResultTo(false_type(), *p, os);
|
||||
}
|
||||
}
|
||||
private:
|
||||
@ -1520,18 +1570,13 @@ class PropertyMatcher {
|
||||
const Matcher<RefToConstProperty> matcher_;
|
||||
};
|
||||
|
||||
// Explains the result of matching an object against a property matcher.
|
||||
template <typename Class, typename PropertyType>
|
||||
// Explains the result of matching an object or pointer against a
|
||||
// property matcher.
|
||||
template <typename Class, typename PropertyType, typename T>
|
||||
void ExplainMatchResultTo(const PropertyMatcher<Class, PropertyType>& matcher,
|
||||
const Class& obj, ::std::ostream* os) {
|
||||
matcher.ExplainMatchResultTo(obj, os);
|
||||
}
|
||||
|
||||
// Explains the result of matching a pointer against a property matcher.
|
||||
template <typename Class, typename PropertyType>
|
||||
void ExplainMatchResultTo(const PropertyMatcher<Class, PropertyType>& matcher,
|
||||
const Class* p, ::std::ostream* os) {
|
||||
matcher.ExplainMatchResultTo(p, os);
|
||||
const T& value, ::std::ostream* os) {
|
||||
matcher.ExplainMatchResultTo(
|
||||
typename ::testing::internal::is_pointer<T>::type(), value, os);
|
||||
}
|
||||
|
||||
// Type traits specifying various features of different functors for ResultOf.
|
||||
|
@ -263,11 +263,10 @@ void PrintTo(const T& value, ::std::ostream* os) {
|
||||
//
|
||||
// For protocol messages, we want to give people a chance to
|
||||
// override Google Mock's format by defining a PrintTo() or
|
||||
// operator<<. For STL containers, we believe the Google Mock's
|
||||
// format is superior to what util/gtl/stl-logging.h offers.
|
||||
// Therefore we don't want it to be accidentally overridden by the
|
||||
// latter (even if the user includes stl-logging.h through other
|
||||
// headers indirectly, Google Mock's format will still be used).
|
||||
// operator<<. For STL containers, other formats can be
|
||||
// incompatible with Google Mock's format for the container
|
||||
// elements; therefore we check for container types here to ensure
|
||||
// that our format is used.
|
||||
DefaultPrintTo(IsContainerTest<T>(0), value, os);
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,11 @@ class DefaultActionSpec {
|
||||
: file_(file),
|
||||
line_(line),
|
||||
matchers_(matchers),
|
||||
extra_matcher_(_),
|
||||
// By default, extra_matcher_ should match anything. However,
|
||||
// we cannot initialize it with _ as that triggers a compiler
|
||||
// bug in Symbian's C++ compiler (cannot decide between two
|
||||
// overloaded constructors of Matcher<const ArgumentTuple&>).
|
||||
extra_matcher_(A<const ArgumentTuple&>()),
|
||||
last_clause_(NONE) {
|
||||
}
|
||||
|
||||
@ -576,7 +580,11 @@ class Expectation : public ExpectationBase {
|
||||
: ExpectationBase(file, line),
|
||||
owner_(owner),
|
||||
matchers_(m),
|
||||
extra_matcher_(_),
|
||||
// By default, extra_matcher_ should match anything. However,
|
||||
// we cannot initialize it with _ as that triggers a compiler
|
||||
// bug in Symbian's C++ compiler (cannot decide between two
|
||||
// overloaded constructors of Matcher<const ArgumentTuple&>).
|
||||
extra_matcher_(A<const ArgumentTuple&>()),
|
||||
repeated_action_specified_(false),
|
||||
repeated_action_(DoDefault()),
|
||||
retires_on_saturation_(false),
|
||||
|
@ -1495,5 +1495,157 @@ TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
|
||||
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// Tests that ACTION_TEMPLATE works when there is no value parameter.
|
||||
ACTION_TEMPLATE(CreateNew,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, T),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
return new T;
|
||||
}
|
||||
|
||||
TEST(ActionTemplateTest, WorksWithoutValueParam) {
|
||||
const Action<int*()> a = CreateNew<int>();
|
||||
int* p = a.Perform(make_tuple());
|
||||
delete p;
|
||||
}
|
||||
|
||||
// Tests that ACTION_TEMPLATE works when there are value parameters.
|
||||
ACTION_TEMPLATE(CreateNew,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, T),
|
||||
AND_1_VALUE_PARAMS(a0)) {
|
||||
return new T(a0);
|
||||
}
|
||||
|
||||
TEST(ActionTemplateTest, WorksWithValueParams) {
|
||||
const Action<int*()> a = CreateNew<int>(42);
|
||||
int* p = a.Perform(make_tuple());
|
||||
EXPECT_EQ(42, *p);
|
||||
delete p;
|
||||
}
|
||||
|
||||
// Tests that ACTION_TEMPLATE works for integral template parameters.
|
||||
ACTION_TEMPLATE(MyDeleteArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
delete std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Resets a bool variable in the destructor.
|
||||
class BoolResetter {
|
||||
public:
|
||||
explicit BoolResetter(bool* value) : value_(value) {}
|
||||
~BoolResetter() { *value_ = false; }
|
||||
private:
|
||||
bool* const value_;
|
||||
};
|
||||
|
||||
TEST(ActionTemplateTest, WorksForIntegralTemplateParams) {
|
||||
const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();
|
||||
int n = 0;
|
||||
bool b = true;
|
||||
BoolResetter* resetter = new BoolResetter(&b);
|
||||
a.Perform(make_tuple(&n, resetter));
|
||||
EXPECT_FALSE(b); // Verifies that resetter is deleted.
|
||||
}
|
||||
|
||||
// Tests that ACTION_TEMPLATES works for template template parameters.
|
||||
ACTION_TEMPLATE(ReturnSmartPointer,
|
||||
HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class,
|
||||
Pointer),
|
||||
AND_1_VALUE_PARAMS(pointee)) {
|
||||
return Pointer<pointee_type>(new pointee_type(pointee));
|
||||
}
|
||||
|
||||
TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) {
|
||||
using ::testing::internal::linked_ptr;
|
||||
const Action<linked_ptr<int>()> a = ReturnSmartPointer<linked_ptr>(42);
|
||||
linked_ptr<int> p = a.Perform(make_tuple());
|
||||
EXPECT_EQ(42, *p);
|
||||
}
|
||||
|
||||
// Tests that ACTION_TEMPLATE works for 10 template parameters.
|
||||
template <typename T1, typename T2, typename T3, int k4, bool k5,
|
||||
unsigned int k6, typename T7, typename T8, typename T9>
|
||||
struct GiantTemplate {
|
||||
public:
|
||||
explicit GiantTemplate(int a_value) : value(a_value) {}
|
||||
int value;
|
||||
};
|
||||
|
||||
ACTION_TEMPLATE(ReturnGiant,
|
||||
HAS_10_TEMPLATE_PARAMS(
|
||||
typename, T1,
|
||||
typename, T2,
|
||||
typename, T3,
|
||||
int, k4,
|
||||
bool, k5,
|
||||
unsigned int, k6,
|
||||
class, T7,
|
||||
class, T8,
|
||||
class, T9,
|
||||
template <typename T> class, T10),
|
||||
AND_1_VALUE_PARAMS(value)) {
|
||||
return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value);
|
||||
}
|
||||
|
||||
TEST(ActionTemplateTest, WorksFor10TemplateParameters) {
|
||||
using ::testing::internal::linked_ptr;
|
||||
typedef GiantTemplate<linked_ptr<int>, bool, double, 5,
|
||||
true, 6, char, unsigned, int> Giant;
|
||||
const Action<Giant()> a = ReturnGiant<
|
||||
int, bool, double, 5, true, 6, char, unsigned, int, linked_ptr>(42);
|
||||
Giant giant = a.Perform(make_tuple());
|
||||
EXPECT_EQ(42, giant.value);
|
||||
}
|
||||
|
||||
// Tests that ACTION_TEMPLATE works for 10 value parameters.
|
||||
ACTION_TEMPLATE(ReturnSum,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, Number),
|
||||
AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) {
|
||||
return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;
|
||||
}
|
||||
|
||||
TEST(ActionTemplateTest, WorksFor10ValueParameters) {
|
||||
const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
EXPECT_EQ(55, a.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded
|
||||
// on the number of value parameters.
|
||||
|
||||
ACTION(ReturnSum) { return 0; }
|
||||
|
||||
ACTION_P(ReturnSum, x) { return x; }
|
||||
|
||||
ACTION_TEMPLATE(ReturnSum,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, Number),
|
||||
AND_2_VALUE_PARAMS(v1, v2)) {
|
||||
return static_cast<Number>(v1) + v2;
|
||||
}
|
||||
|
||||
ACTION_TEMPLATE(ReturnSum,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, Number),
|
||||
AND_3_VALUE_PARAMS(v1, v2, v3)) {
|
||||
return static_cast<Number>(v1) + v2 + v3;
|
||||
}
|
||||
|
||||
ACTION_TEMPLATE(ReturnSum,
|
||||
HAS_2_TEMPLATE_PARAMS(typename, Number, int, k),
|
||||
AND_4_VALUE_PARAMS(v1, v2, v3, v4)) {
|
||||
return static_cast<Number>(v1) + v2 + v3 + v4 + k;
|
||||
}
|
||||
|
||||
TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {
|
||||
const Action<int()> a0 = ReturnSum();
|
||||
const Action<int()> a1 = ReturnSum(1);
|
||||
const Action<int()> a2 = ReturnSum<int>(1, 2);
|
||||
const Action<int()> a3 = ReturnSum<int>(1, 2, 3);
|
||||
const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);
|
||||
EXPECT_EQ(0, a0.Perform(make_tuple()));
|
||||
EXPECT_EQ(1, a1.Perform(make_tuple()));
|
||||
EXPECT_EQ(3, a2.Perform(make_tuple()));
|
||||
EXPECT_EQ(6, a3.Perform(make_tuple()));
|
||||
EXPECT_EQ(12345, a4.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
} // namespace gmock_generated_actions_test
|
||||
} // namespace testing
|
||||
|
@ -366,6 +366,76 @@ TEST(MatcherCastTest, FromSameType) {
|
||||
EXPECT_FALSE(m2.Matches(1));
|
||||
}
|
||||
|
||||
class Base {};
|
||||
class Derived : public Base {};
|
||||
|
||||
// Tests that SafeMatcherCast<T>(m) works when m is a polymorphic matcher.
|
||||
TEST(SafeMatcherCastTest, FromPolymorphicMatcher) {
|
||||
Matcher<char> m2 = SafeMatcherCast<char>(Eq(32));
|
||||
EXPECT_TRUE(m2.Matches(' '));
|
||||
EXPECT_FALSE(m2.Matches('\n'));
|
||||
}
|
||||
|
||||
// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<U> where T
|
||||
// can be implicitly converted to U.
|
||||
TEST(SafeMatcherCastTest, FromImplicitlyConvertibleType) {
|
||||
Matcher<double> m1 = DoubleEq(1.0);
|
||||
Matcher<int> m2 = SafeMatcherCast<int>(m1);
|
||||
EXPECT_TRUE(m2.Matches(1));
|
||||
EXPECT_FALSE(m2.Matches(2));
|
||||
}
|
||||
|
||||
// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<U> where T and U
|
||||
// are pointers or references to a derived and a base class, correspondingly.
|
||||
TEST(SafeMatcherCastTest, FromBaseClass) {
|
||||
Derived d, d2;
|
||||
Matcher<Base*> m1 = Eq(&d);
|
||||
Matcher<Derived*> m2 = SafeMatcherCast<Derived*>(m1);
|
||||
EXPECT_TRUE(m2.Matches(&d));
|
||||
EXPECT_FALSE(m2.Matches(&d2));
|
||||
|
||||
Matcher<Base&> m3 = Ref(d);
|
||||
Matcher<Derived&> m4 = SafeMatcherCast<Derived&>(m3);
|
||||
EXPECT_TRUE(m4.Matches(d));
|
||||
EXPECT_FALSE(m4.Matches(d2));
|
||||
}
|
||||
|
||||
// Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<const T&>.
|
||||
TEST(SafeMatcherCastTest, FromConstReferenceToReference) {
|
||||
int n = 0;
|
||||
Matcher<const int&> m1 = Ref(n);
|
||||
Matcher<int&> m2 = SafeMatcherCast<int&>(m1);
|
||||
int n1 = 0;
|
||||
EXPECT_TRUE(m2.Matches(n));
|
||||
EXPECT_FALSE(m2.Matches(n1));
|
||||
}
|
||||
|
||||
// Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>.
|
||||
TEST(SafeMatcherCastTest, FromNonReferenceToConstReference) {
|
||||
Matcher<int> m1 = Eq(0);
|
||||
Matcher<const int&> m2 = SafeMatcherCast<const int&>(m1);
|
||||
EXPECT_TRUE(m2.Matches(0));
|
||||
EXPECT_FALSE(m2.Matches(1));
|
||||
}
|
||||
|
||||
// Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<T>.
|
||||
TEST(SafeMatcherCastTest, FromNonReferenceToReference) {
|
||||
Matcher<int> m1 = Eq(0);
|
||||
Matcher<int&> m2 = SafeMatcherCast<int&>(m1);
|
||||
int n = 0;
|
||||
EXPECT_TRUE(m2.Matches(n));
|
||||
n = 1;
|
||||
EXPECT_FALSE(m2.Matches(n));
|
||||
}
|
||||
|
||||
// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<T>.
|
||||
TEST(SafeMatcherCastTest, FromSameType) {
|
||||
Matcher<int> m1 = Eq(0);
|
||||
Matcher<int> m2 = SafeMatcherCast<int>(m1);
|
||||
EXPECT_TRUE(m2.Matches(0));
|
||||
EXPECT_FALSE(m2.Matches(1));
|
||||
}
|
||||
|
||||
// Tests that A<T>() matches any value of type T.
|
||||
TEST(ATest, MatchesAnyValue) {
|
||||
// Tests a matcher for a value type.
|
||||
@ -626,9 +696,6 @@ TEST(RefTest, CanBeUsedAsMatcherForConstReference) {
|
||||
// used wherever Ref(base) can be used (Ref(derived) is a sub-type
|
||||
// of Ref(base), but not vice versa.
|
||||
|
||||
class Base {};
|
||||
class Derived : public Base {};
|
||||
|
||||
TEST(RefTest, IsCovariant) {
|
||||
Base base, base2;
|
||||
Derived derived;
|
||||
@ -1355,6 +1422,16 @@ TEST(NotTest, CanDescribeSelf) {
|
||||
EXPECT_EQ("is not equal to 5", Describe(m));
|
||||
}
|
||||
|
||||
// Tests that monomorphic matchers are safely cast by the Not matcher.
|
||||
TEST(NotTest, NotMatcherSafelyCastsMonomorphicMatchers) {
|
||||
// greater_than_5 is a monomorphic matcher.
|
||||
Matcher<int> greater_than_5 = Gt(5);
|
||||
|
||||
Matcher<const int&> m = Not(greater_than_5);
|
||||
Matcher<int&> m2 = Not(greater_than_5);
|
||||
Matcher<int&> m3 = Not(m);
|
||||
}
|
||||
|
||||
// Tests that AllOf(m1, ..., mn) matches any value that matches all of
|
||||
// the given matchers.
|
||||
TEST(AllOfTest, MatchesWhenAllMatch) {
|
||||
@ -1415,6 +1492,21 @@ TEST(AllOfTest, CanDescribeSelf) {
|
||||
"(is not equal to 7))))", Describe(m));
|
||||
}
|
||||
|
||||
// Tests that monomorphic matchers are safely cast by the AllOf matcher.
|
||||
TEST(AllOfTest, AllOfMatcherSafelyCastsMonomorphicMatchers) {
|
||||
// greater_than_5 and less_than_10 are monomorphic matchers.
|
||||
Matcher<int> greater_than_5 = Gt(5);
|
||||
Matcher<int> less_than_10 = Lt(10);
|
||||
|
||||
Matcher<const int&> m = AllOf(greater_than_5, less_than_10);
|
||||
Matcher<int&> m2 = AllOf(greater_than_5, less_than_10);
|
||||
Matcher<int&> m3 = AllOf(greater_than_5, m2);
|
||||
|
||||
// Tests that BothOf works when composing itself.
|
||||
Matcher<const int&> m4 = AllOf(greater_than_5, less_than_10, less_than_10);
|
||||
Matcher<int&> m5 = AllOf(greater_than_5, less_than_10, less_than_10);
|
||||
}
|
||||
|
||||
// Tests that AnyOf(m1, ..., mn) matches any value that matches at
|
||||
// least one of the given matchers.
|
||||
TEST(AnyOfTest, MatchesWhenAnyMatches) {
|
||||
@ -1473,6 +1565,21 @@ TEST(AnyOfTest, CanDescribeSelf) {
|
||||
Describe(m));
|
||||
}
|
||||
|
||||
// Tests that monomorphic matchers are safely cast by the AnyOf matcher.
|
||||
TEST(AnyOfTest, AnyOfMatcherSafelyCastsMonomorphicMatchers) {
|
||||
// greater_than_5 and less_than_10 are monomorphic matchers.
|
||||
Matcher<int> greater_than_5 = Gt(5);
|
||||
Matcher<int> less_than_10 = Lt(10);
|
||||
|
||||
Matcher<const int&> m = AnyOf(greater_than_5, less_than_10);
|
||||
Matcher<int&> m2 = AnyOf(greater_than_5, less_than_10);
|
||||
Matcher<int&> m3 = AnyOf(greater_than_5, m2);
|
||||
|
||||
// Tests that EitherOf works when composing itself.
|
||||
Matcher<const int&> m4 = AnyOf(greater_than_5, less_than_10, less_than_10);
|
||||
Matcher<int&> m5 = AnyOf(greater_than_5, less_than_10, less_than_10);
|
||||
}
|
||||
|
||||
// The following predicate function and predicate functor are for
|
||||
// testing the Truly(predicate) matcher.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user