mirror of
https://github.com/google/googletest.git
synced 2025-03-10 09:16:48 +00:00
Implements the new matcher API.
This commit is contained in:
parent
7f8eb725b5
commit
821133180c
@ -229,8 +229,9 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
|||||||
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
|
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
|
||||||
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
|
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
|
||||||
|
|
||||||
virtual bool Matches(ArgsTuple args) const {
|
virtual bool MatchAndExplain(ArgsTuple args,
|
||||||
return inner_matcher_.Matches(GetSelectedArgs(args));
|
MatchResultListener* listener) const {
|
||||||
|
return inner_matcher_.MatchAndExplain(GetSelectedArgs(args), listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void DescribeTo(::std::ostream* os) const {
|
virtual void DescribeTo(::std::ostream* os) const {
|
||||||
@ -243,11 +244,6 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
|||||||
inner_matcher_.DescribeNegationTo(os);
|
inner_matcher_.DescribeNegationTo(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void ExplainMatchResultTo(ArgsTuple args,
|
|
||||||
::std::ostream* os) const {
|
|
||||||
inner_matcher_.ExplainMatchResultTo(GetSelectedArgs(args), os);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
|
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
|
||||||
return TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5, k6, k7, k8,
|
return TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5, k6, k7, k8,
|
||||||
@ -852,14 +848,19 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
// The MATCHER* family of macros can be used in a namespace scope to
|
// The MATCHER* family of macros can be used in a namespace scope to
|
||||||
// define custom matchers easily. The syntax:
|
// define custom matchers easily.
|
||||||
|
//
|
||||||
|
// Basic Usage
|
||||||
|
// ===========
|
||||||
|
//
|
||||||
|
// The syntax
|
||||||
//
|
//
|
||||||
// MATCHER(name, description_string) { statements; }
|
// MATCHER(name, description_string) { statements; }
|
||||||
//
|
//
|
||||||
// will define a matcher with the given name that executes the
|
// defines a matcher with the given name that executes the statements,
|
||||||
// statements, which must return a bool to indicate if the match
|
// which must return a bool to indicate if the match succeeds. Inside
|
||||||
// succeeds. Inside the statements, you can refer to the value being
|
// the statements, you can refer to the value being matched by 'arg',
|
||||||
// matched by 'arg', and refer to its type by 'arg_type'.
|
// and refer to its type by 'arg_type'.
|
||||||
//
|
//
|
||||||
// The description string documents what the matcher does, and is used
|
// The description string documents what the matcher does, and is used
|
||||||
// to generate the failure message when the match fails. Since a
|
// to generate the failure message when the match fails. Since a
|
||||||
@ -892,6 +893,9 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
// where the description "is even" is automatically calculated from the
|
// where the description "is even" is automatically calculated from the
|
||||||
// matcher name IsEven.
|
// matcher name IsEven.
|
||||||
//
|
//
|
||||||
|
// Argument Type
|
||||||
|
// =============
|
||||||
|
//
|
||||||
// Note that the type of the value being matched (arg_type) is
|
// Note that the type of the value being matched (arg_type) is
|
||||||
// determined by the context in which you use the matcher and is
|
// determined by the context in which you use the matcher and is
|
||||||
// supplied to you by the compiler, so you don't need to worry about
|
// supplied to you by the compiler, so you don't need to worry about
|
||||||
@ -902,6 +906,9 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
|
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
|
||||||
// 'arg_type' will be unsigned long; and so on.
|
// 'arg_type' will be unsigned long; and so on.
|
||||||
//
|
//
|
||||||
|
// Parameterizing Matchers
|
||||||
|
// =======================
|
||||||
|
//
|
||||||
// Sometimes you'll want to parameterize the matcher. For that you
|
// Sometimes you'll want to parameterize the matcher. For that you
|
||||||
// can use another macro:
|
// can use another macro:
|
||||||
//
|
//
|
||||||
@ -932,6 +939,9 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to
|
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to
|
||||||
// support multi-parameter matchers.
|
// support multi-parameter matchers.
|
||||||
//
|
//
|
||||||
|
// Describing Parameterized Matchers
|
||||||
|
// =================================
|
||||||
|
//
|
||||||
// When defining a parameterized matcher, you can use Python-style
|
// When defining a parameterized matcher, you can use Python-style
|
||||||
// interpolations in the description string to refer to the parameter
|
// interpolations in the description string to refer to the parameter
|
||||||
// values. We support the following syntax currently:
|
// values. We support the following syntax currently:
|
||||||
@ -964,6 +974,9 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
//
|
//
|
||||||
// Expected: in closed range (4, 6)
|
// Expected: in closed range (4, 6)
|
||||||
//
|
//
|
||||||
|
// Types of Matcher Parameters
|
||||||
|
// ===========================
|
||||||
|
//
|
||||||
// For the purpose of typing, you can view
|
// For the purpose of typing, you can view
|
||||||
//
|
//
|
||||||
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
|
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
|
||||||
@ -991,23 +1004,44 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
// matcher you will see the value of the referenced object but not its
|
// matcher you will see the value of the referenced object but not its
|
||||||
// address.
|
// address.
|
||||||
//
|
//
|
||||||
|
// Explaining Match Results
|
||||||
|
// ========================
|
||||||
|
//
|
||||||
|
// Sometimes the matcher description alone isn't enough to explain why
|
||||||
|
// the match has failed or succeeded. For example, when expecting a
|
||||||
|
// long string, it can be very helpful to also print the diff between
|
||||||
|
// the expected string and the actual one. To achieve that, you can
|
||||||
|
// optionally stream additional information to a special variable
|
||||||
|
// named result_listener, whose type is a pointer to class
|
||||||
|
// MatchResultListener:
|
||||||
|
//
|
||||||
|
// MATCHER_P(EqualsLongString, str, "") {
|
||||||
|
// if (arg == str) return true;
|
||||||
|
//
|
||||||
|
// *result_listener << "the difference: "
|
||||||
|
/// << DiffStrings(str, arg);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Overloading Matchers
|
||||||
|
// ====================
|
||||||
|
//
|
||||||
// You can overload matchers with different numbers of parameters:
|
// You can overload matchers with different numbers of parameters:
|
||||||
//
|
//
|
||||||
// MATCHER_P(Blah, a, description_string1) { ... }
|
// MATCHER_P(Blah, a, description_string1) { ... }
|
||||||
// MATCHER_P2(Blah, a, b, description_string2) { ... }
|
// MATCHER_P2(Blah, a, b, description_string2) { ... }
|
||||||
//
|
//
|
||||||
// While it's tempting to always use the MATCHER* macros when defining
|
// Caveats
|
||||||
// a new matcher, you should also consider implementing
|
// =======
|
||||||
// MatcherInterface or using MakePolymorphicMatcher() instead,
|
|
||||||
// especially if you need to use the matcher a lot. While these
|
|
||||||
// approaches require more work, they give you more control on the
|
|
||||||
// types of the value being matched and the matcher parameters, which
|
|
||||||
// in general leads to better compiler error messages that pay off in
|
|
||||||
// the long run. They also allow overloading matchers based on
|
|
||||||
// parameter types (as opposed to just based on the number of
|
|
||||||
// parameters).
|
|
||||||
//
|
//
|
||||||
// CAVEAT:
|
// When defining a new matcher, you should also consider implementing
|
||||||
|
// MatcherInterface or using MakePolymorphicMatcher(). These
|
||||||
|
// approaches require more work than the MATCHER* macros, but also
|
||||||
|
// give you more control on the types of the value being matched and
|
||||||
|
// the matcher parameters, which may leads to better compiler error
|
||||||
|
// messages when the matcher is used wrong. They also allow
|
||||||
|
// overloading matchers based on parameter types (as opposed to just
|
||||||
|
// based on the number of parameters).
|
||||||
//
|
//
|
||||||
// MATCHER*() can only be used in a namespace scope. The reason is
|
// MATCHER*() can only be used in a namespace scope. The reason is
|
||||||
// that C++ doesn't yet allow function-local types to be used to
|
// that C++ doesn't yet allow function-local types to be used to
|
||||||
@ -1015,7 +1049,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
// Once that's done, we'll consider supporting using MATCHER*() inside
|
// Once that's done, we'll consider supporting using MATCHER*() inside
|
||||||
// a function.
|
// a function.
|
||||||
//
|
//
|
||||||
// MORE INFORMATION:
|
// More Information
|
||||||
|
// ================
|
||||||
//
|
//
|
||||||
// To learn more about using these macros, please search for 'MATCHER'
|
// To learn more about using these macros, please search for 'MATCHER'
|
||||||
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
||||||
@ -1028,7 +1063,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
public:\
|
public:\
|
||||||
gmock_Impl(const ::testing::internal::Interpolations& gmock_interp)\
|
gmock_Impl(const ::testing::internal::Interpolations& gmock_interp)\
|
||||||
: gmock_interp_(gmock_interp) {}\
|
: gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1058,8 +1094,10 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
return name##Matcher();\
|
return name##Matcher();\
|
||||||
}\
|
}\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##Matcher::\
|
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P(name, p0, description)\
|
#define MATCHER_P(name, p0, description)\
|
||||||
template <typename p0##_type>\
|
template <typename p0##_type>\
|
||||||
@ -1071,7 +1109,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
explicit gmock_Impl(p0##_type gmock_p0, \
|
explicit gmock_Impl(p0##_type gmock_p0, \
|
||||||
const ::testing::internal::Interpolations& gmock_interp)\
|
const ::testing::internal::Interpolations& gmock_interp)\
|
||||||
: p0(gmock_p0), gmock_interp_(gmock_interp) {}\
|
: p0(gmock_p0), gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1105,8 +1144,10 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
}\
|
}\
|
||||||
template <typename p0##_type>\
|
template <typename p0##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP<p0##_type>::\
|
bool name##MatcherP<p0##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P2(name, p0, p1, description)\
|
#define MATCHER_P2(name, p0, p1, description)\
|
||||||
template <typename p0##_type, typename p1##_type>\
|
template <typename p0##_type, typename p1##_type>\
|
||||||
@ -1118,7 +1159,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
|
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
|
||||||
const ::testing::internal::Interpolations& gmock_interp)\
|
const ::testing::internal::Interpolations& gmock_interp)\
|
||||||
: p0(gmock_p0), p1(gmock_p1), gmock_interp_(gmock_interp) {}\
|
: p0(gmock_p0), p1(gmock_p1), gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1156,8 +1198,11 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
}\
|
}\
|
||||||
template <typename p0##_type, typename p1##_type>\
|
template <typename p0##_type, typename p1##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP2<p0##_type, p1##_type>::\
|
bool name##MatcherP2<p0##_type, \
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
p1##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P3(name, p0, p1, p2, description)\
|
#define MATCHER_P3(name, p0, p1, p2, description)\
|
||||||
template <typename p0##_type, typename p1##_type, typename p2##_type>\
|
template <typename p0##_type, typename p1##_type, typename p2##_type>\
|
||||||
@ -1170,7 +1215,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
const ::testing::internal::Interpolations& gmock_interp)\
|
const ::testing::internal::Interpolations& gmock_interp)\
|
||||||
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
|
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
|
||||||
gmock_interp_(gmock_interp) {}\
|
gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1211,8 +1257,11 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
}\
|
}\
|
||||||
template <typename p0##_type, typename p1##_type, typename p2##_type>\
|
template <typename p0##_type, typename p1##_type, typename p2##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP3<p0##_type, p1##_type, p2##_type>::\
|
bool name##MatcherP3<p0##_type, p1##_type, \
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
p2##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P4(name, p0, p1, p2, p3, description)\
|
#define MATCHER_P4(name, p0, p1, p2, p3, description)\
|
||||||
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||||
@ -1227,7 +1276,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
const ::testing::internal::Interpolations& gmock_interp)\
|
const ::testing::internal::Interpolations& gmock_interp)\
|
||||||
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
||||||
gmock_interp_(gmock_interp) {}\
|
gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1275,8 +1325,11 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||||
typename p3##_type>\
|
typename p3##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP4<p0##_type, p1##_type, p2##_type, p3##_type>::\
|
bool name##MatcherP4<p0##_type, p1##_type, p2##_type, \
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
p3##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)\
|
#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)\
|
||||||
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||||
@ -1291,7 +1344,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
const ::testing::internal::Interpolations& gmock_interp)\
|
const ::testing::internal::Interpolations& gmock_interp)\
|
||||||
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
||||||
p4(gmock_p4), gmock_interp_(gmock_interp) {}\
|
p4(gmock_p4), gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1342,8 +1396,11 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||||
typename p3##_type, typename p4##_type>\
|
typename p3##_type, typename p4##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type>::\
|
bool name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
p4##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description)\
|
#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description)\
|
||||||
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||||
@ -1358,7 +1415,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
const ::testing::internal::Interpolations& gmock_interp)\
|
const ::testing::internal::Interpolations& gmock_interp)\
|
||||||
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
||||||
p4(gmock_p4), p5(gmock_p5), gmock_interp_(gmock_interp) {}\
|
p4(gmock_p4), p5(gmock_p5), gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1412,8 +1470,10 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
typename p3##_type, typename p4##_type, typename p5##_type>\
|
typename p3##_type, typename p4##_type, typename p5##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
bool name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
||||||
p5##_type>::\
|
p5##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description)\
|
#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description)\
|
||||||
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||||
@ -1431,7 +1491,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
||||||
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
|
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
|
||||||
gmock_interp_(gmock_interp) {}\
|
gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1493,8 +1554,10 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
typename p6##_type>\
|
typename p6##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
bool name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
||||||
p5##_type, p6##_type>::\
|
p5##_type, p6##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description)\
|
#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description)\
|
||||||
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||||
@ -1512,7 +1575,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
||||||
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
|
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
|
||||||
gmock_interp_(gmock_interp) {}\
|
gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1579,8 +1643,11 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
typename p6##_type, typename p7##_type>\
|
typename p6##_type, typename p7##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
bool name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
||||||
p5##_type, p6##_type, p7##_type>::\
|
p5##_type, p6##_type, \
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
p7##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description)\
|
#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description)\
|
||||||
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||||
@ -1598,7 +1665,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
||||||
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
|
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
|
||||||
p8(gmock_p8), gmock_interp_(gmock_interp) {}\
|
p8(gmock_p8), gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1668,8 +1736,11 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
typename p6##_type, typename p7##_type, typename p8##_type>\
|
typename p6##_type, typename p7##_type, typename p8##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
bool name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
|
||||||
p5##_type, p6##_type, p7##_type, p8##_type>::\
|
p5##_type, p6##_type, p7##_type, \
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
p8##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description)\
|
#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description)\
|
||||||
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
template <typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||||
@ -1689,7 +1760,8 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
: p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
|
||||||
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
|
p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
|
||||||
p8(gmock_p8), p9(gmock_p9), gmock_interp_(gmock_interp) {}\
|
p8(gmock_p8), p9(gmock_p9), gmock_interp_(gmock_interp) {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -1763,7 +1835,10 @@ ElementsAreArray(const T (&array)[N]) {
|
|||||||
typename p9##_type>\
|
typename p9##_type>\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \
|
bool name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \
|
||||||
p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>::\
|
p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
p9##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||||
|
@ -116,8 +116,9 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
|||||||
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
|
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
|
||||||
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
|
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
|
||||||
|
|
||||||
virtual bool Matches(ArgsTuple args) const {
|
virtual bool MatchAndExplain(ArgsTuple args,
|
||||||
return inner_matcher_.Matches(GetSelectedArgs(args));
|
MatchResultListener* listener) const {
|
||||||
|
return inner_matcher_.MatchAndExplain(GetSelectedArgs(args), listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void DescribeTo(::std::ostream* os) const {
|
virtual void DescribeTo(::std::ostream* os) const {
|
||||||
@ -130,11 +131,6 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
|||||||
inner_matcher_.DescribeNegationTo(os);
|
inner_matcher_.DescribeNegationTo(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void ExplainMatchResultTo(ArgsTuple args,
|
|
||||||
::std::ostream* os) const {
|
|
||||||
inner_matcher_.ExplainMatchResultTo(GetSelectedArgs(args), os);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
|
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
|
||||||
return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args);
|
return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args);
|
||||||
@ -301,14 +297,19 @@ $$ // show up in the generated code.
|
|||||||
|
|
||||||
|
|
||||||
// The MATCHER* family of macros can be used in a namespace scope to
|
// The MATCHER* family of macros can be used in a namespace scope to
|
||||||
// define custom matchers easily. The syntax:
|
// define custom matchers easily.
|
||||||
|
//
|
||||||
|
// Basic Usage
|
||||||
|
// ===========
|
||||||
|
//
|
||||||
|
// The syntax
|
||||||
//
|
//
|
||||||
// MATCHER(name, description_string) { statements; }
|
// MATCHER(name, description_string) { statements; }
|
||||||
//
|
//
|
||||||
// will define a matcher with the given name that executes the
|
// defines a matcher with the given name that executes the statements,
|
||||||
// statements, which must return a bool to indicate if the match
|
// which must return a bool to indicate if the match succeeds. Inside
|
||||||
// succeeds. Inside the statements, you can refer to the value being
|
// the statements, you can refer to the value being matched by 'arg',
|
||||||
// matched by 'arg', and refer to its type by 'arg_type'.
|
// and refer to its type by 'arg_type'.
|
||||||
//
|
//
|
||||||
// The description string documents what the matcher does, and is used
|
// The description string documents what the matcher does, and is used
|
||||||
// to generate the failure message when the match fails. Since a
|
// to generate the failure message when the match fails. Since a
|
||||||
@ -341,6 +342,9 @@ $$ // show up in the generated code.
|
|||||||
// where the description "is even" is automatically calculated from the
|
// where the description "is even" is automatically calculated from the
|
||||||
// matcher name IsEven.
|
// matcher name IsEven.
|
||||||
//
|
//
|
||||||
|
// Argument Type
|
||||||
|
// =============
|
||||||
|
//
|
||||||
// Note that the type of the value being matched (arg_type) is
|
// Note that the type of the value being matched (arg_type) is
|
||||||
// determined by the context in which you use the matcher and is
|
// determined by the context in which you use the matcher and is
|
||||||
// supplied to you by the compiler, so you don't need to worry about
|
// supplied to you by the compiler, so you don't need to worry about
|
||||||
@ -351,6 +355,9 @@ $$ // show up in the generated code.
|
|||||||
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
|
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
|
||||||
// 'arg_type' will be unsigned long; and so on.
|
// 'arg_type' will be unsigned long; and so on.
|
||||||
//
|
//
|
||||||
|
// Parameterizing Matchers
|
||||||
|
// =======================
|
||||||
|
//
|
||||||
// Sometimes you'll want to parameterize the matcher. For that you
|
// Sometimes you'll want to parameterize the matcher. For that you
|
||||||
// can use another macro:
|
// can use another macro:
|
||||||
//
|
//
|
||||||
@ -381,6 +388,9 @@ $$ // show up in the generated code.
|
|||||||
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
|
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
|
||||||
// support multi-parameter matchers.
|
// support multi-parameter matchers.
|
||||||
//
|
//
|
||||||
|
// Describing Parameterized Matchers
|
||||||
|
// =================================
|
||||||
|
//
|
||||||
// When defining a parameterized matcher, you can use Python-style
|
// When defining a parameterized matcher, you can use Python-style
|
||||||
// interpolations in the description string to refer to the parameter
|
// interpolations in the description string to refer to the parameter
|
||||||
// values. We support the following syntax currently:
|
// values. We support the following syntax currently:
|
||||||
@ -413,6 +423,9 @@ $$ // show up in the generated code.
|
|||||||
//
|
//
|
||||||
// Expected: in closed range (4, 6)
|
// Expected: in closed range (4, 6)
|
||||||
//
|
//
|
||||||
|
// Types of Matcher Parameters
|
||||||
|
// ===========================
|
||||||
|
//
|
||||||
// For the purpose of typing, you can view
|
// For the purpose of typing, you can view
|
||||||
//
|
//
|
||||||
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
|
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
|
||||||
@ -440,23 +453,44 @@ $$ // show up in the generated code.
|
|||||||
// matcher you will see the value of the referenced object but not its
|
// matcher you will see the value of the referenced object but not its
|
||||||
// address.
|
// address.
|
||||||
//
|
//
|
||||||
|
// Explaining Match Results
|
||||||
|
// ========================
|
||||||
|
//
|
||||||
|
// Sometimes the matcher description alone isn't enough to explain why
|
||||||
|
// the match has failed or succeeded. For example, when expecting a
|
||||||
|
// long string, it can be very helpful to also print the diff between
|
||||||
|
// the expected string and the actual one. To achieve that, you can
|
||||||
|
// optionally stream additional information to a special variable
|
||||||
|
// named result_listener, whose type is a pointer to class
|
||||||
|
// MatchResultListener:
|
||||||
|
//
|
||||||
|
// MATCHER_P(EqualsLongString, str, "") {
|
||||||
|
// if (arg == str) return true;
|
||||||
|
//
|
||||||
|
// *result_listener << "the difference: "
|
||||||
|
/// << DiffStrings(str, arg);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Overloading Matchers
|
||||||
|
// ====================
|
||||||
|
//
|
||||||
// You can overload matchers with different numbers of parameters:
|
// You can overload matchers with different numbers of parameters:
|
||||||
//
|
//
|
||||||
// MATCHER_P(Blah, a, description_string1) { ... }
|
// MATCHER_P(Blah, a, description_string1) { ... }
|
||||||
// MATCHER_P2(Blah, a, b, description_string2) { ... }
|
// MATCHER_P2(Blah, a, b, description_string2) { ... }
|
||||||
//
|
//
|
||||||
// While it's tempting to always use the MATCHER* macros when defining
|
// Caveats
|
||||||
// a new matcher, you should also consider implementing
|
// =======
|
||||||
// MatcherInterface or using MakePolymorphicMatcher() instead,
|
|
||||||
// especially if you need to use the matcher a lot. While these
|
|
||||||
// approaches require more work, they give you more control on the
|
|
||||||
// types of the value being matched and the matcher parameters, which
|
|
||||||
// in general leads to better compiler error messages that pay off in
|
|
||||||
// the long run. They also allow overloading matchers based on
|
|
||||||
// parameter types (as opposed to just based on the number of
|
|
||||||
// parameters).
|
|
||||||
//
|
//
|
||||||
// CAVEAT:
|
// When defining a new matcher, you should also consider implementing
|
||||||
|
// MatcherInterface or using MakePolymorphicMatcher(). These
|
||||||
|
// approaches require more work than the MATCHER* macros, but also
|
||||||
|
// give you more control on the types of the value being matched and
|
||||||
|
// the matcher parameters, which may leads to better compiler error
|
||||||
|
// messages when the matcher is used wrong. They also allow
|
||||||
|
// overloading matchers based on parameter types (as opposed to just
|
||||||
|
// based on the number of parameters).
|
||||||
//
|
//
|
||||||
// MATCHER*() can only be used in a namespace scope. The reason is
|
// MATCHER*() can only be used in a namespace scope. The reason is
|
||||||
// that C++ doesn't yet allow function-local types to be used to
|
// that C++ doesn't yet allow function-local types to be used to
|
||||||
@ -464,7 +498,8 @@ $$ // show up in the generated code.
|
|||||||
// Once that's done, we'll consider supporting using MATCHER*() inside
|
// Once that's done, we'll consider supporting using MATCHER*() inside
|
||||||
// a function.
|
// a function.
|
||||||
//
|
//
|
||||||
// MORE INFORMATION:
|
// More Information
|
||||||
|
// ================
|
||||||
//
|
//
|
||||||
// To learn more about using these macros, please search for 'MATCHER'
|
// To learn more about using these macros, please search for 'MATCHER'
|
||||||
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
||||||
@ -510,7 +545,8 @@ $var param_field_decls2 = [[$for j
|
|||||||
public:\
|
public:\
|
||||||
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
|
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
|
||||||
$impl_inits {}\
|
$impl_inits {}\
|
||||||
virtual bool Matches(arg_type arg) const;\
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
const ::testing::internal::Strings& gmock_printed_params = \
|
const ::testing::internal::Strings& gmock_printed_params = \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
@ -540,8 +576,10 @@ $var param_field_decls2 = [[$for j
|
|||||||
return $class_name$param_types($params);\
|
return $class_name$param_types($params);\
|
||||||
}\$template
|
}\$template
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
bool $class_name$param_types::\
|
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
gmock_Impl<arg_type>::Matches(arg_type arg) const
|
arg_type arg,\
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1004,13 +1004,13 @@ class TypedExpectation : public ExpectationBase {
|
|||||||
if (!TupleMatches(matchers_, args)) {
|
if (!TupleMatches(matchers_, args)) {
|
||||||
DescribeMatchFailureTupleTo(matchers_, args, os);
|
DescribeMatchFailureTupleTo(matchers_, args, os);
|
||||||
}
|
}
|
||||||
if (!extra_matcher_.Matches(args)) {
|
StringMatchResultListener listener;
|
||||||
|
if (!extra_matcher_.MatchAndExplain(args, &listener)) {
|
||||||
*os << " Expected args: ";
|
*os << " Expected args: ";
|
||||||
extra_matcher_.DescribeTo(os);
|
extra_matcher_.DescribeTo(os);
|
||||||
*os << "\n Actual: don't match";
|
*os << "\n Actual: don't match";
|
||||||
|
|
||||||
internal::ExplainMatchResultAsNeededTo<const ArgumentTuple&>(
|
internal::StreamInParensAsNeeded(listener.str(), os);
|
||||||
extra_matcher_, args, os);
|
|
||||||
*os << "\n";
|
*os << "\n";
|
||||||
}
|
}
|
||||||
} else if (!AllPrerequisitesAreSatisfied()) {
|
} else if (!AllPrerequisitesAreSatisfied()) {
|
||||||
|
@ -136,6 +136,16 @@ TEST(ArgsTest, AcceptsDecreasingTemplateArgs) {
|
|||||||
EXPECT_THAT(t, Not(Args<2, 1>(Lt())));
|
EXPECT_THAT(t, Not(Args<2, 1>(Lt())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The MATCHER*() macros trigger warning C4100 (unreferenced formal
|
||||||
|
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||||
|
// the macro definition, as the warnings are generated when the macro
|
||||||
|
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||||
|
// we suppress them here.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4100)
|
||||||
|
#endif
|
||||||
|
|
||||||
MATCHER(SumIsZero, "") {
|
MATCHER(SumIsZero, "") {
|
||||||
return get<0>(arg) + get<1>(arg) + get<2>(arg) == 0;
|
return get<0>(arg) + get<1>(arg) + get<2>(arg) == 0;
|
||||||
}
|
}
|
||||||
@ -553,6 +563,44 @@ TEST(MatcherMacroTest, Works) {
|
|||||||
EXPECT_EQ("", Explain(m, 7));
|
EXPECT_EQ("", Explain(m, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests explaining match result in a MATCHER* macro.
|
||||||
|
|
||||||
|
MATCHER(IsEven2, "is even") {
|
||||||
|
if ((arg % 2) == 0) {
|
||||||
|
// Verifies that we can stream to result_listener, a listener
|
||||||
|
// supplied by the MATCHER macro implicitly.
|
||||||
|
*result_listener << "OK";
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
*result_listener << "% 2 == " << (arg % 2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MATCHER_P2(EqSumOf, x, y, "") {
|
||||||
|
if (arg == (x + y)) {
|
||||||
|
*result_listener << "OK";
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Verifies that we can stream to the underlying stream of
|
||||||
|
// result_listener.
|
||||||
|
if (result_listener->stream() != NULL) {
|
||||||
|
*result_listener->stream() << "diff == " << (x + y - arg);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MatcherMacroTest, CanExplainMatchResult) {
|
||||||
|
const Matcher<int> m1 = IsEven2();
|
||||||
|
EXPECT_EQ("OK", Explain(m1, 4));
|
||||||
|
EXPECT_EQ("% 2 == 1", Explain(m1, 5));
|
||||||
|
|
||||||
|
const Matcher<int> m2 = EqSumOf(1, 2);
|
||||||
|
EXPECT_EQ("OK", Explain(m2, 3));
|
||||||
|
EXPECT_EQ("diff == -1", Explain(m2, 4));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that the description string supplied to MATCHER() must be
|
// Tests that the description string supplied to MATCHER() must be
|
||||||
// valid.
|
// valid.
|
||||||
|
|
||||||
@ -1052,4 +1100,8 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
|
|||||||
EXPECT_THAT(a, Contains(Not(Contains(5))));
|
EXPECT_THAT(a, Contains(Not(Contains(5))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -88,6 +88,7 @@ using testing::Matcher;
|
|||||||
using testing::MatcherCast;
|
using testing::MatcherCast;
|
||||||
using testing::MatcherInterface;
|
using testing::MatcherInterface;
|
||||||
using testing::Matches;
|
using testing::Matches;
|
||||||
|
using testing::MatchResultListener;
|
||||||
using testing::NanSensitiveDoubleEq;
|
using testing::NanSensitiveDoubleEq;
|
||||||
using testing::NanSensitiveFloatEq;
|
using testing::NanSensitiveFloatEq;
|
||||||
using testing::Ne;
|
using testing::Ne;
|
||||||
@ -200,10 +201,39 @@ class EvenMatcherImpl : public MatcherInterface<int> {
|
|||||||
// two methods is optional.
|
// two methods is optional.
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(MatcherInterfaceTest, CanBeImplemented) {
|
TEST(MatcherInterfaceTest, CanBeImplementedUsingDeprecatedAPI) {
|
||||||
EvenMatcherImpl m;
|
EvenMatcherImpl m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests implementing a monomorphic matcher using MatchAndExplain().
|
||||||
|
|
||||||
|
class NewEvenMatcherImpl : public MatcherInterface<int> {
|
||||||
|
public:
|
||||||
|
virtual bool MatchAndExplain(int x, MatchResultListener* listener) const {
|
||||||
|
const bool match = x % 2 == 0;
|
||||||
|
// Verifies that we can stream to a listener directly.
|
||||||
|
*listener << "value % " << 2;
|
||||||
|
if (listener->stream() != NULL) {
|
||||||
|
// Verifies that we can stream to a listener's underlying stream
|
||||||
|
// too.
|
||||||
|
*listener->stream() << " == " << (x % 2);
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DescribeTo(::std::ostream* os) const {
|
||||||
|
*os << "is an even number";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(MatcherInterfaceTest, CanBeImplementedUsingNewAPI) {
|
||||||
|
Matcher<int> m = MakeMatcher(new NewEvenMatcherImpl);
|
||||||
|
EXPECT_TRUE(m.Matches(2));
|
||||||
|
EXPECT_FALSE(m.Matches(3));
|
||||||
|
EXPECT_EQ("value % 2 == 0", Explain(m, 2));
|
||||||
|
EXPECT_EQ("value % 2 == 1", Explain(m, 3));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests default-constructing a matcher.
|
// Tests default-constructing a matcher.
|
||||||
TEST(MatcherTest, CanBeDefaultConstructed) {
|
TEST(MatcherTest, CanBeDefaultConstructed) {
|
||||||
Matcher<double> m;
|
Matcher<double> m;
|
||||||
@ -252,6 +282,18 @@ TEST(MatcherTest, CanDescribeItself) {
|
|||||||
Describe(Matcher<int>(new EvenMatcherImpl)));
|
Describe(Matcher<int>(new EvenMatcherImpl)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests Matcher<T>::MatchAndExplain().
|
||||||
|
TEST(MatcherTest, MatchAndExplain) {
|
||||||
|
Matcher<int> m = GreaterThan(0);
|
||||||
|
::testing::internal::StringMatchResultListener listener1;
|
||||||
|
EXPECT_TRUE(m.MatchAndExplain(42, &listener1));
|
||||||
|
EXPECT_EQ("is 42 more than 0", listener1.str());
|
||||||
|
|
||||||
|
::testing::internal::StringMatchResultListener listener2;
|
||||||
|
EXPECT_FALSE(m.MatchAndExplain(-9, &listener2));
|
||||||
|
EXPECT_EQ("is 9 less than 0", listener2.str());
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that a C-string literal can be implicitly converted to a
|
// Tests that a C-string literal can be implicitly converted to a
|
||||||
// Matcher<string> or Matcher<const string&>.
|
// Matcher<string> or Matcher<const string&>.
|
||||||
TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) {
|
TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) {
|
||||||
@ -284,8 +326,8 @@ TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) {
|
|||||||
Matcher<int> m = MakeMatcher(dummy_impl);
|
Matcher<int> m = MakeMatcher(dummy_impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that MakePolymorphicMatcher() constructs a polymorphic
|
// Tests that MakePolymorphicMatcher() can construct a polymorphic
|
||||||
// matcher from its implementation.
|
// matcher from its implementation using the old API.
|
||||||
const int bar = 1;
|
const int bar = 1;
|
||||||
class ReferencesBarOrIsZeroImpl {
|
class ReferencesBarOrIsZeroImpl {
|
||||||
public:
|
public:
|
||||||
@ -308,7 +350,7 @@ PolymorphicMatcher<ReferencesBarOrIsZeroImpl> ReferencesBarOrIsZero() {
|
|||||||
return MakePolymorphicMatcher(ReferencesBarOrIsZeroImpl());
|
return MakePolymorphicMatcher(ReferencesBarOrIsZeroImpl());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MakePolymorphicMatcherTest, ConstructsMatcherFromImpl) {
|
TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingOldAPI) {
|
||||||
// Using a polymorphic matcher to match a reference type.
|
// Using a polymorphic matcher to match a reference type.
|
||||||
Matcher<const int&> m1 = ReferencesBarOrIsZero();
|
Matcher<const int&> m1 = ReferencesBarOrIsZero();
|
||||||
EXPECT_TRUE(m1.Matches(0));
|
EXPECT_TRUE(m1.Matches(0));
|
||||||
@ -324,6 +366,58 @@ TEST(MakePolymorphicMatcherTest, ConstructsMatcherFromImpl) {
|
|||||||
EXPECT_EQ("bar or zero", Describe(m2));
|
EXPECT_EQ("bar or zero", Describe(m2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests implementing a polymorphic matcher using MatchAndExplain().
|
||||||
|
|
||||||
|
class PolymorphicIsEvenImpl {
|
||||||
|
public:
|
||||||
|
void DescribeTo(::std::ostream* os) const { *os << "is even"; }
|
||||||
|
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
*os << "is odd";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool MatchAndExplain(const PolymorphicIsEvenImpl& /* impl */,
|
||||||
|
T x, MatchResultListener* listener) {
|
||||||
|
// Verifies that we can stream to the listener directly.
|
||||||
|
*listener << "% " << 2;
|
||||||
|
if (listener->stream() != NULL) {
|
||||||
|
// Verifies that we can stream to the listener's underlying stream
|
||||||
|
// too.
|
||||||
|
*listener->stream() << " == " << (x % 2);
|
||||||
|
}
|
||||||
|
return (x % 2) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolymorphicMatcher<PolymorphicIsEvenImpl> PolymorphicIsEven() {
|
||||||
|
return MakePolymorphicMatcher(PolymorphicIsEvenImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingNewAPI) {
|
||||||
|
// Using PolymorphicIsEven() as a Matcher<int>.
|
||||||
|
const Matcher<int> m1 = PolymorphicIsEven();
|
||||||
|
EXPECT_TRUE(m1.Matches(42));
|
||||||
|
EXPECT_FALSE(m1.Matches(43));
|
||||||
|
EXPECT_EQ("is even", Describe(m1));
|
||||||
|
|
||||||
|
const Matcher<int> not_m1 = Not(m1);
|
||||||
|
EXPECT_EQ("is odd", Describe(not_m1));
|
||||||
|
|
||||||
|
EXPECT_EQ("% 2 == 0", Explain(m1, 42));
|
||||||
|
|
||||||
|
// Using PolymorphicIsEven() as a Matcher<char>.
|
||||||
|
const Matcher<char> m2 = PolymorphicIsEven();
|
||||||
|
EXPECT_TRUE(m2.Matches('\x42'));
|
||||||
|
EXPECT_FALSE(m2.Matches('\x43'));
|
||||||
|
EXPECT_EQ("is even", Describe(m2));
|
||||||
|
|
||||||
|
const Matcher<char> not_m2 = Not(m2);
|
||||||
|
EXPECT_EQ("is odd", Describe(not_m2));
|
||||||
|
|
||||||
|
EXPECT_EQ("% 2 == 0", Explain(m2, '\x42'));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that MatcherCast<T>(m) works when m is a polymorphic matcher.
|
// Tests that MatcherCast<T>(m) works when m is a polymorphic matcher.
|
||||||
TEST(MatcherCastTest, FromPolymorphicMatcher) {
|
TEST(MatcherCastTest, FromPolymorphicMatcher) {
|
||||||
Matcher<int> m = MatcherCast<int>(Eq(5));
|
Matcher<int> m = MatcherCast<int>(Eq(5));
|
||||||
@ -1050,21 +1144,26 @@ TEST(PairTest, CanDescribeSelf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(PairTest, CanExplainMatchResultTo) {
|
TEST(PairTest, CanExplainMatchResultTo) {
|
||||||
const Matcher<std::pair<int, int> > m0 = Pair(0, 0);
|
// If neither field matches, Pair() should explain about the first
|
||||||
EXPECT_EQ("", Explain(m0, std::make_pair(25, 42)));
|
// field.
|
||||||
|
const Matcher<std::pair<int, int> > m = Pair(GreaterThan(0), GreaterThan(0));
|
||||||
|
EXPECT_EQ("the first field is 1 less than 0",
|
||||||
|
Explain(m, std::make_pair(-1, -2)));
|
||||||
|
|
||||||
const Matcher<std::pair<int, int> > m1 = Pair(GreaterThan(0), 0);
|
// If the first field matches but the second doesn't, Pair() should
|
||||||
EXPECT_EQ("the first field is 25 more than 0",
|
// explain about the second field.
|
||||||
Explain(m1, std::make_pair(25, 42)));
|
EXPECT_EQ("the second field is 2 less than 0",
|
||||||
|
Explain(m, std::make_pair(1, -2)));
|
||||||
|
|
||||||
const Matcher<std::pair<int, int> > m2 = Pair(0, GreaterThan(0));
|
// If the first field doesn't match but the second does, Pair()
|
||||||
EXPECT_EQ("the second field is 42 more than 0",
|
// should explain about the first field.
|
||||||
Explain(m2, std::make_pair(25, 42)));
|
EXPECT_EQ("the first field is 1 less than 0",
|
||||||
|
Explain(m, std::make_pair(-1, 2)));
|
||||||
|
|
||||||
const Matcher<std::pair<int, int> > m3 = Pair(GreaterThan(0), GreaterThan(0));
|
// If both fields match, Pair() should explain about them both.
|
||||||
EXPECT_EQ("the first field is 25 more than 0"
|
EXPECT_EQ("the first field is 1 more than 0"
|
||||||
", and the second field is 42 more than 0",
|
", and the second field is 2 more than 0",
|
||||||
Explain(m3, std::make_pair(25, 42)));
|
Explain(m, std::make_pair(1, 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PairTest, MatchesCorrectly) {
|
TEST(PairTest, MatchesCorrectly) {
|
||||||
@ -3335,6 +3434,16 @@ TEST(ValidateMatcherDescriptionTest,
|
|||||||
ElementsAre());
|
ElementsAre());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The MATCHER*() macros trigger warning C4100 (unreferenced formal
|
||||||
|
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||||
|
// the macro definition, as the warnings are generated when the macro
|
||||||
|
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||||
|
// we suppress them here.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4100)
|
||||||
|
#endif
|
||||||
|
|
||||||
// We use MATCHER_P3() to define a matcher for testing
|
// We use MATCHER_P3() to define a matcher for testing
|
||||||
// ValidateMatcherDescription(); otherwise we'll end up with much
|
// ValidateMatcherDescription(); otherwise we'll end up with much
|
||||||
// plumbing code. This is not circular as
|
// plumbing code. This is not circular as
|
||||||
@ -3345,6 +3454,10 @@ MATCHER_P3(EqInterpolation, start, end, index, "equals Interpolation%(*)s") {
|
|||||||
arg.param_index == index;
|
arg.param_index == index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST(ValidateMatcherDescriptionTest, AcceptsPercentInterpolation) {
|
TEST(ValidateMatcherDescriptionTest, AcceptsPercentInterpolation) {
|
||||||
const char* params[] = { "foo", NULL };
|
const char* params[] = { "foo", NULL };
|
||||||
const char* const desc = "one %%";
|
const char* const desc = "one %%";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user