Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
82113318
Commit
82113318
authored
Jan 08, 2010
by
zhanyong.wan
Browse files
Implements the new matcher API.
parent
7f8eb725
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
763 additions
and
425 deletions
+763
-425
include/gmock/gmock-generated-matchers.h
include/gmock/gmock-generated-matchers.h
+132
-57
include/gmock/gmock-generated-matchers.h.pump
include/gmock/gmock-generated-matchers.h.pump
+65
-27
include/gmock/gmock-matchers.h
include/gmock/gmock-matchers.h
+382
-322
include/gmock/gmock-spec-builders.h
include/gmock/gmock-spec-builders.h
+3
-3
test/gmock-generated-matchers_test.cc
test/gmock-generated-matchers_test.cc
+52
-0
test/gmock-matchers_test.cc
test/gmock-matchers_test.cc
+129
-16
No files found.
include/gmock/gmock-generated-matchers.h
View file @
82113318
...
@@ -229,8 +229,9 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
...
@@ -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> {
...
@@ -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]) {
...
@@ -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
// define
s
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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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]) {
...
@@ -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_
include/gmock/gmock-generated-matchers.h.pump
View file @
82113318
...
@@ -116,8 +116,9 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
...
@@ -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> {
...
@@ -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.
...
@@ -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
// define
s
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.
...
@@ -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.
...
@@ -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.
...
@@ -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.
...
@@ -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.
...
@@ -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.
...
@@ -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
...
@@ -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
...
@@ -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
]]
]]
...
...
include/gmock/gmock-matchers.h
View file @
82113318
This diff is collapsed.
Click to expand it.
include/gmock/gmock-spec-builders.h
View file @
82113318
...
@@ -1004,13 +1004,13 @@ class TypedExpectation : public ExpectationBase {
...
@@ -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
())
{
...
...
test/gmock-generated-matchers_test.cc
View file @
82113318
...
@@ -136,6 +136,16 @@ TEST(ArgsTest, AcceptsDecreasingTemplateArgs) {
...
@@ -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) {
...
@@ -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) {
...
@@ -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
test/gmock-matchers_test.cc
View file @
82113318
...
@@ -88,6 +88,7 @@ using testing::Matcher;
...
@@ -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> {
...
@@ -200,10 +201,39 @@ class EvenMatcherImpl : public MatcherInterface<int> {
// two methods is optional.
// two methods is optional.
};
};
TEST
(
MatcherInterfaceTest
,
CanBeImplemented
)
{
TEST
(
MatcherInterfaceTest
,
CanBeImplemented
UsingDeprecatedAPI
)
{
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) {
...
@@ -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) {
...
@@ -284,8 +326,8 @@ TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) {
Matcher
<
int
>
m
=
MakeMatcher
(
dummy_impl
);
Matcher
<
int
>
m
=
MakeMatcher
(
dummy_impl
);
}
}
// Tests that MakePolymorphicMatcher() construct
s
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() {
...
@@ -308,7 +350,7 @@ PolymorphicMatcher<ReferencesBarOrIsZeroImpl> ReferencesBarOrIsZero() {
return
MakePolymorphicMatcher
(
ReferencesBarOrIsZeroImpl
());
return
MakePolymorphicMatcher
(
ReferencesBarOrIsZeroImpl
());
}
}
TEST
(
MakePolymorphicMatcherTest
,
ConstructsMatcher
FromImpl
)
{
TEST
(
MakePolymorphicMatcherTest
,
ConstructsMatcher
UsingOldAPI
)
{
// 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) {
...
@@ -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) {
...
@@ -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
4
2 more than 0"
,
", and the second field is 2 more than 0"
,
Explain
(
m
3
,
std
::
make_pair
(
25
,
4
2
)));
Explain
(
m
,
std
::
make_pair
(
1
,
2
)));
}
}
TEST
(
PairTest
,
MatchesCorrectly
)
{
TEST
(
PairTest
,
MatchesCorrectly
)
{
...
@@ -3335,6 +3434,16 @@ TEST(ValidateMatcherDescriptionTest,
...
@@ -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") {
...
@@ -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 %%"
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment