Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
a42cdf2a
Commit
a42cdf2a
authored
Dec 03, 2018
by
Abseil Team
Committed by
Gennadiy Civil
Dec 03, 2018
Browse files
Googletest export
Replace pump'd Args() matcher with variadic templates. PiperOrigin-RevId: 223794430
parent
8fbf9d16
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
233 additions
and
655 deletions
+233
-655
googlemock/include/gmock/gmock-generated-matchers.h
googlemock/include/gmock/gmock-generated-matchers.h
+0
-337
googlemock/include/gmock/gmock-generated-matchers.h.pump
googlemock/include/gmock/gmock-generated-matchers.h.pump
+0
-163
googlemock/include/gmock/gmock-matchers.h
googlemock/include/gmock/gmock-matchers.h
+84
-0
googlemock/test/gmock-generated-matchers_test.cc
googlemock/test/gmock-generated-matchers_test.cc
+0
-152
googlemock/test/gmock-matchers_test.cc
googlemock/test/gmock-matchers_test.cc
+149
-3
No files found.
googlemock/include/gmock/gmock-generated-matchers.h
View file @
a42cdf2a
...
...
@@ -47,343 +47,6 @@
#include <vector>
#include "gmock/gmock-matchers.h"
namespace
testing
{
namespace
internal
{
// The type of the i-th (0-based) field of Tuple.
#define GMOCK_FIELD_TYPE_(Tuple, i) \
typename ::std::tuple_element<i, Tuple>::type
// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
// tuple of type Tuple. It has two members:
//
// type: a tuple type whose i-th field is the ki-th field of Tuple.
// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
//
// For example, in class TupleFields<std::tuple<bool, char, int>, 2, 0>,
// we have:
//
// type is std::tuple<int, bool>, and
// GetSelectedFields(std::make_tuple(true, 'a', 42)) is (42, true).
template
<
class
Tuple
,
int
k0
=
-
1
,
int
k1
=
-
1
,
int
k2
=
-
1
,
int
k3
=
-
1
,
int
k4
=
-
1
,
int
k5
=
-
1
,
int
k6
=
-
1
,
int
k7
=
-
1
,
int
k8
=
-
1
,
int
k9
=
-
1
>
class
TupleFields
;
// This generic version is used when there are 10 selectors.
template
<
class
Tuple
,
int
k0
,
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
int
k6
,
int
k7
,
int
k8
,
int
k9
>
class
TupleFields
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k1
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k2
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k3
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k4
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k5
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k6
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k7
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k8
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k9
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
),
std
::
get
<
k1
>
(
t
),
std
::
get
<
k2
>
(
t
),
std
::
get
<
k3
>
(
t
),
std
::
get
<
k4
>
(
t
),
std
::
get
<
k5
>
(
t
),
std
::
get
<
k6
>
(
t
),
std
::
get
<
k7
>
(
t
),
std
::
get
<
k8
>
(
t
),
std
::
get
<
k9
>
(
t
));
}
};
// The following specialization is used for 0 ~ 9 selectors.
template
<
class
Tuple
>
class
TupleFields
<
Tuple
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
>
{
public:
typedef
::
std
::
tuple
<>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
/* t */
)
{
return
type
();
}
};
template
<
class
Tuple
,
int
k0
>
class
TupleFields
<
Tuple
,
k0
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
>
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
));
}
};
template
<
class
Tuple
,
int
k0
,
int
k1
>
class
TupleFields
<
Tuple
,
k0
,
k1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
>
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k1
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
),
std
::
get
<
k1
>
(
t
));
}
};
template
<
class
Tuple
,
int
k0
,
int
k1
,
int
k2
>
class
TupleFields
<
Tuple
,
k0
,
k1
,
k2
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
>
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k1
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k2
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
),
std
::
get
<
k1
>
(
t
),
std
::
get
<
k2
>
(
t
));
}
};
template
<
class
Tuple
,
int
k0
,
int
k1
,
int
k2
,
int
k3
>
class
TupleFields
<
Tuple
,
k0
,
k1
,
k2
,
k3
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
>
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k1
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k2
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k3
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
),
std
::
get
<
k1
>
(
t
),
std
::
get
<
k2
>
(
t
),
std
::
get
<
k3
>
(
t
));
}
};
template
<
class
Tuple
,
int
k0
,
int
k1
,
int
k2
,
int
k3
,
int
k4
>
class
TupleFields
<
Tuple
,
k0
,
k1
,
k2
,
k3
,
k4
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
>
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k1
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k2
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k3
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k4
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
),
std
::
get
<
k1
>
(
t
),
std
::
get
<
k2
>
(
t
),
std
::
get
<
k3
>
(
t
),
std
::
get
<
k4
>
(
t
));
}
};
template
<
class
Tuple
,
int
k0
,
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
>
class
TupleFields
<
Tuple
,
k0
,
k1
,
k2
,
k3
,
k4
,
k5
,
-
1
,
-
1
,
-
1
,
-
1
>
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k1
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k2
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k3
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k4
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k5
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
),
std
::
get
<
k1
>
(
t
),
std
::
get
<
k2
>
(
t
),
std
::
get
<
k3
>
(
t
),
std
::
get
<
k4
>
(
t
),
std
::
get
<
k5
>
(
t
));
}
};
template
<
class
Tuple
,
int
k0
,
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
int
k6
>
class
TupleFields
<
Tuple
,
k0
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
-
1
,
-
1
,
-
1
>
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k1
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k2
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k3
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k4
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k5
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k6
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
),
std
::
get
<
k1
>
(
t
),
std
::
get
<
k2
>
(
t
),
std
::
get
<
k3
>
(
t
),
std
::
get
<
k4
>
(
t
),
std
::
get
<
k5
>
(
t
),
std
::
get
<
k6
>
(
t
));
}
};
template
<
class
Tuple
,
int
k0
,
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
int
k6
,
int
k7
>
class
TupleFields
<
Tuple
,
k0
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
-
1
,
-
1
>
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k1
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k2
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k3
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k4
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k5
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k6
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k7
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
),
std
::
get
<
k1
>
(
t
),
std
::
get
<
k2
>
(
t
),
std
::
get
<
k3
>
(
t
),
std
::
get
<
k4
>
(
t
),
std
::
get
<
k5
>
(
t
),
std
::
get
<
k6
>
(
t
),
std
::
get
<
k7
>
(
t
));
}
};
template
<
class
Tuple
,
int
k0
,
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
int
k6
,
int
k7
,
int
k8
>
class
TupleFields
<
Tuple
,
k0
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
-
1
>
{
public:
typedef
::
std
::
tuple
<
GMOCK_FIELD_TYPE_
(
Tuple
,
k0
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k1
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k2
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k3
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k4
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k5
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k6
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k7
),
GMOCK_FIELD_TYPE_
(
Tuple
,
k8
)
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
std
::
get
<
k0
>
(
t
),
std
::
get
<
k1
>
(
t
),
std
::
get
<
k2
>
(
t
),
std
::
get
<
k3
>
(
t
),
std
::
get
<
k4
>
(
t
),
std
::
get
<
k5
>
(
t
),
std
::
get
<
k6
>
(
t
),
std
::
get
<
k7
>
(
t
),
std
::
get
<
k8
>
(
t
));
}
};
#undef GMOCK_FIELD_TYPE_
// Implements the Args() matcher.
template
<
class
ArgsTuple
,
int
k0
=
-
1
,
int
k1
=
-
1
,
int
k2
=
-
1
,
int
k3
=
-
1
,
int
k4
=
-
1
,
int
k5
=
-
1
,
int
k6
=
-
1
,
int
k7
=
-
1
,
int
k8
=
-
1
,
int
k9
=
-
1
>
class
ArgsMatcherImpl
:
public
MatcherInterface
<
ArgsTuple
>
{
public:
// ArgsTuple may have top-level const or reference modifiers.
typedef
GTEST_REMOVE_REFERENCE_AND_CONST_
(
ArgsTuple
)
RawArgsTuple
;
typedef
typename
internal
::
TupleFields
<
RawArgsTuple
,
k0
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
k9
>::
type
SelectedArgs
;
typedef
Matcher
<
const
SelectedArgs
&>
MonomorphicInnerMatcher
;
template
<
typename
InnerMatcher
>
explicit
ArgsMatcherImpl
(
const
InnerMatcher
&
inner_matcher
)
:
inner_matcher_
(
SafeMatcherCast
<
const
SelectedArgs
&>
(
inner_matcher
))
{}
virtual
bool
MatchAndExplain
(
ArgsTuple
args
,
MatchResultListener
*
listener
)
const
{
const
SelectedArgs
&
selected_args
=
GetSelectedArgs
(
args
);
if
(
!
listener
->
IsInterested
())
return
inner_matcher_
.
Matches
(
selected_args
);
PrintIndices
(
listener
->
stream
());
*
listener
<<
"are "
<<
PrintToString
(
selected_args
);
StringMatchResultListener
inner_listener
;
const
bool
match
=
inner_matcher_
.
MatchAndExplain
(
selected_args
,
&
inner_listener
);
PrintIfNotEmpty
(
inner_listener
.
str
(),
listener
->
stream
());
return
match
;
}
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"are a tuple "
;
PrintIndices
(
os
);
inner_matcher_
.
DescribeTo
(
os
);
}
virtual
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"are a tuple "
;
PrintIndices
(
os
);
inner_matcher_
.
DescribeNegationTo
(
os
);
}
private:
static
SelectedArgs
GetSelectedArgs
(
ArgsTuple
args
)
{
return
TupleFields
<
RawArgsTuple
,
k0
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
k9
>::
GetSelectedFields
(
args
);
}
// Prints the indices of the selected fields.
static
void
PrintIndices
(
::
std
::
ostream
*
os
)
{
*
os
<<
"whose fields ("
;
const
int
indices
[
10
]
=
{
k0
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
k9
};
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
if
(
indices
[
i
]
<
0
)
break
;
if
(
i
>=
1
)
*
os
<<
", "
;
*
os
<<
"#"
<<
indices
[
i
];
}
*
os
<<
") "
;
}
const
MonomorphicInnerMatcher
inner_matcher_
;
GTEST_DISALLOW_ASSIGN_
(
ArgsMatcherImpl
);
};
template
<
class
InnerMatcher
,
int
k0
=
-
1
,
int
k1
=
-
1
,
int
k2
=
-
1
,
int
k3
=
-
1
,
int
k4
=
-
1
,
int
k5
=
-
1
,
int
k6
=
-
1
,
int
k7
=
-
1
,
int
k8
=
-
1
,
int
k9
=
-
1
>
class
ArgsMatcher
{
public:
explicit
ArgsMatcher
(
const
InnerMatcher
&
inner_matcher
)
:
inner_matcher_
(
inner_matcher
)
{}
template
<
typename
ArgsTuple
>
operator
Matcher
<
ArgsTuple
>
()
const
{
return
MakeMatcher
(
new
ArgsMatcherImpl
<
ArgsTuple
,
k0
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
k9
>
(
inner_matcher_
));
}
private:
const
InnerMatcher
inner_matcher_
;
GTEST_DISALLOW_ASSIGN_
(
ArgsMatcher
);
};
}
// namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
// fields of it matches a_matcher. C++ doesn't support default
// arguments for function templates, so we have to overload it.
template
<
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
>
(
matcher
);
}
template
<
int
k1
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
>
(
matcher
);
}
template
<
int
k1
,
int
k2
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
>
(
matcher
);
}
template
<
int
k1
,
int
k2
,
int
k3
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
>
(
matcher
);
}
template
<
int
k1
,
int
k2
,
int
k3
,
int
k4
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
>
(
matcher
);
}
template
<
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
>
(
matcher
);
}
template
<
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
int
k6
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
>
(
matcher
);
}
template
<
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
int
k6
,
int
k7
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
>
(
matcher
);
}
template
<
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
int
k6
,
int
k7
,
int
k8
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
>
(
matcher
);
}
template
<
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
int
k6
,
int
k7
,
int
k8
,
int
k9
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
k9
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
k9
>
(
matcher
);
}
template
<
int
k1
,
int
k2
,
int
k3
,
int
k4
,
int
k5
,
int
k6
,
int
k7
,
int
k8
,
int
k9
,
int
k10
,
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
k9
,
k10
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
k9
,
k10
>
(
matcher
);
}
}
// namespace testing
// The MATCHER* family of macros can be used in a namespace scope to
// define custom matchers easily.
//
...
...
googlemock/include/gmock/gmock-generated-matchers.h.pump
View file @
a42cdf2a
...
...
@@ -49,169 +49,6 @@ $$ }} This line fixes auto-indentation of the following code in Emacs.
#include <vector>
#include "gmock/gmock-matchers.h"
namespace
testing
{
namespace
internal
{
$
range
i
0.
.
n
-
1
// The type of the i-th (0-based) field of Tuple.
#define GMOCK_FIELD_TYPE_(Tuple, i) \
typename ::std::tuple_element<i, Tuple>::type
// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
// tuple of type Tuple. It has two members:
//
// type: a tuple type whose i-th field is the ki-th field of Tuple.
// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
//
// For example, in class TupleFields<std::tuple<bool, char, int>, 2, 0>,
// we have:
//
// type is std::tuple<int, bool>, and
// GetSelectedFields(std::make_tuple(true, 'a', 42)) is (42, true).
template
<
class
Tuple
$
for
i
[[,
int
k
$
i
=
-
1
]]>
class
TupleFields
;
// This generic version is used when there are $n selectors.
template
<
class
Tuple
$
for
i
[[,
int
k
$
i
]]>
class
TupleFields
{
public:
typedef
::
std
::
tuple
<
$
for
i
,
[[
GMOCK_FIELD_TYPE_
(
Tuple
,
k
$
i
)]]
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
t
)
{
return
type
(
$
for
i
,
[[
std
::
get
<
k
$
i
>
(
t
)]]);
}
};
// The following specialization is used for 0 ~ $(n-1) selectors.
$
for
i
[[
$$
}}
}
$
range
j
0.
.
i
-
1
$
range
k
0.
.
n
-
1
template
<
class
Tuple
$
for
j
[[,
int
k
$
j
]]>
class
TupleFields
<
Tuple
,
$
for
k
,
[[
$
if
k
<
i
[[
k
$
k
]]
$
else
[[
-
1
]]]]
>
{
public:
typedef
::
std
::
tuple
<
$
for
j
,
[[
GMOCK_FIELD_TYPE_
(
Tuple
,
k
$
j
)]]
>
type
;
static
type
GetSelectedFields
(
const
Tuple
&
$
if
i
==
0
[[
/* t */
]]
$
else
[[
t
]])
{
return
type
(
$
for
j
,
[[
std
::
get
<
k
$
j
>
(
t
)]]);
}
};
]]
#undef GMOCK_FIELD_TYPE_
// Implements the Args() matcher.
$
var
ks
=
[[
$
for
i
,
[[
k
$
i
]]]]
template
<
class
ArgsTuple
$
for
i
[[,
int
k
$
i
=
-
1
]]>
class
ArgsMatcherImpl
:
public
MatcherInterface
<
ArgsTuple
>
{
public:
// ArgsTuple may have top-level const or reference modifiers.
typedef
GTEST_REMOVE_REFERENCE_AND_CONST_
(
ArgsTuple
)
RawArgsTuple
;
typedef
typename
internal
::
TupleFields
<
RawArgsTuple
,
$
ks
>::
type
SelectedArgs
;
typedef
Matcher
<
const
SelectedArgs
&>
MonomorphicInnerMatcher
;
template
<
typename
InnerMatcher
>
explicit
ArgsMatcherImpl
(
const
InnerMatcher
&
inner_matcher
)
:
inner_matcher_
(
SafeMatcherCast
<
const
SelectedArgs
&>
(
inner_matcher
))
{}
virtual
bool
MatchAndExplain
(
ArgsTuple
args
,
MatchResultListener
*
listener
)
const
{
const
SelectedArgs
&
selected_args
=
GetSelectedArgs
(
args
);
if
(
!
listener
->
IsInterested
())
return
inner_matcher_
.
Matches
(
selected_args
);
PrintIndices
(
listener
->
stream
());
*
listener
<<
"are "
<<
PrintToString
(
selected_args
);
StringMatchResultListener
inner_listener
;
const
bool
match
=
inner_matcher_
.
MatchAndExplain
(
selected_args
,
&
inner_listener
);
PrintIfNotEmpty
(
inner_listener
.
str
(),
listener
->
stream
());
return
match
;
}
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"are a tuple "
;
PrintIndices
(
os
);
inner_matcher_
.
DescribeTo
(
os
);
}
virtual
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"are a tuple "
;
PrintIndices
(
os
);
inner_matcher_
.
DescribeNegationTo
(
os
);
}
private:
static
SelectedArgs
GetSelectedArgs
(
ArgsTuple
args
)
{
return
TupleFields
<
RawArgsTuple
,
$
ks
>::
GetSelectedFields
(
args
);
}
// Prints the indices of the selected fields.
static
void
PrintIndices
(
::
std
::
ostream
*
os
)
{
*
os
<<
"whose fields ("
;
const
int
indices
[
$
n
]
=
{
$
ks
};
for
(
int
i
=
0
;
i
<
$
n
;
i
++
)
{
if
(
indices
[
i
]
<
0
)
break
;
if
(
i
>=
1
)
*
os
<<
", "
;
*
os
<<
"#"
<<
indices
[
i
];
}
*
os
<<
") "
;
}
const
MonomorphicInnerMatcher
inner_matcher_
;
GTEST_DISALLOW_ASSIGN_
(
ArgsMatcherImpl
);
};
template
<
class
InnerMatcher
$
for
i
[[,
int
k
$
i
=
-
1
]]>
class
ArgsMatcher
{
public:
explicit
ArgsMatcher
(
const
InnerMatcher
&
inner_matcher
)
:
inner_matcher_
(
inner_matcher
)
{}
template
<
typename
ArgsTuple
>
operator
Matcher
<
ArgsTuple
>
()
const
{
return
MakeMatcher
(
new
ArgsMatcherImpl
<
ArgsTuple
,
$
ks
>
(
inner_matcher_
));
}
private:
const
InnerMatcher
inner_matcher_
;
GTEST_DISALLOW_ASSIGN_
(
ArgsMatcher
);
};
}
// namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
// fields of it matches a_matcher. C++ doesn't support default
// arguments for function templates, so we have to overload it.
$
range
i
0.
.
n
$
for
i
[[
$
range
j
1.
.
i
template
<
$
for
j
[[
int
k
$
j
,
]]
typename
InnerMatcher
>
inline
internal
::
ArgsMatcher
<
InnerMatcher
$
for
j
[[,
k
$
j
]]
>
Args
(
const
InnerMatcher
&
matcher
)
{
return
internal
::
ArgsMatcher
<
InnerMatcher
$
for
j
[[,
k
$
j
]]
>
(
matcher
);
}
]]
}
// namespace testing
$$
}
// This Pump meta comment fixes auto-indentation in Emacs. It will not
$$
// show up in the generated code.
// The MATCHER* family of macros can be used in a namespace scope to
// define custom matchers easily.
//
...
...
googlemock/include/gmock/gmock-matchers.h
View file @
a42cdf2a
...
...
@@ -3424,6 +3424,80 @@ class AnyCastMatcher {
};
}
// namespace any_cast_matcher
// Implements the Args() matcher.
template
<
class
ArgsTuple
,
size_t
...
k
>
class
ArgsMatcherImpl
:
public
MatcherInterface
<
ArgsTuple
>
{
public:
using
RawArgsTuple
=
typename
std
::
decay
<
ArgsTuple
>::
type
;
using
SelectedArgs
=
std
::
tuple
<
typename
std
::
tuple_element
<
k
,
RawArgsTuple
>::
type
...
>
;
using
MonomorphicInnerMatcher
=
Matcher
<
const
SelectedArgs
&>
;
template
<
typename
InnerMatcher
>
explicit
ArgsMatcherImpl
(
const
InnerMatcher
&
inner_matcher
)
:
inner_matcher_
(
SafeMatcherCast
<
const
SelectedArgs
&>
(
inner_matcher
))
{}
bool
MatchAndExplain
(
ArgsTuple
args
,
MatchResultListener
*
listener
)
const
override
{
// Workaround spurious C4100 on MSVC<=15.7 when k is empty.
(
void
)
args
;
const
SelectedArgs
&
selected_args
=
std
::
forward_as_tuple
(
std
::
get
<
k
>
(
args
)...);
if
(
!
listener
->
IsInterested
())
return
inner_matcher_
.
Matches
(
selected_args
);
PrintIndices
(
listener
->
stream
());
*
listener
<<
"are "
<<
PrintToString
(
selected_args
);
StringMatchResultListener
inner_listener
;
const
bool
match
=
inner_matcher_
.
MatchAndExplain
(
selected_args
,
&
inner_listener
);
PrintIfNotEmpty
(
inner_listener
.
str
(),
listener
->
stream
());
return
match
;
}
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
override
{
*
os
<<
"are a tuple "
;
PrintIndices
(
os
);
inner_matcher_
.
DescribeTo
(
os
);
}
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
override
{
*
os
<<
"are a tuple "
;
PrintIndices
(
os
);
inner_matcher_
.
DescribeNegationTo
(
os
);
}
private:
// Prints the indices of the selected fields.
static
void
PrintIndices
(
::
std
::
ostream
*
os
)
{
*
os
<<
"whose fields ("
;
const
char
*
sep
=
""
;
// Workaround spurious C4189 on MSVC<=15.7 when k is empty.
(
void
)
sep
;
const
char
*
dummy
[]
=
{
""
,
(
*
os
<<
sep
<<
"#"
<<
k
,
sep
=
", "
)...};
(
void
)
dummy
;
*
os
<<
") "
;
}
MonomorphicInnerMatcher
inner_matcher_
;
};
template
<
class
InnerMatcher
,
size_t
...
k
>
class
ArgsMatcher
{
public:
explicit
ArgsMatcher
(
InnerMatcher
inner_matcher
)
:
inner_matcher_
(
std
::
move
(
inner_matcher
))
{}
template
<
typename
ArgsTuple
>
operator
Matcher
<
ArgsTuple
>
()
const
{
// NOLINT
return
MakeMatcher
(
new
ArgsMatcherImpl
<
ArgsTuple
,
k
...
>
(
inner_matcher_
));
}
private:
InnerMatcher
inner_matcher_
;
};
}
// namespace internal
// ElementsAreArray(iterator_first, iterator_last)
...
...
@@ -4371,6 +4445,16 @@ internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf(
matchers
...);
}
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
// fields of it matches a_matcher. C++ doesn't support default
// arguments for function templates, so we have to overload it.
template
<
size_t
...
k
,
typename
InnerMatcher
>
internal
::
ArgsMatcher
<
typename
std
::
decay
<
InnerMatcher
>::
type
,
k
...
>
Args
(
InnerMatcher
&&
matcher
)
{
return
internal
::
ArgsMatcher
<
typename
std
::
decay
<
InnerMatcher
>::
type
,
k
...
>
(
std
::
forward
<
InnerMatcher
>
(
matcher
));
}
// AllArgs(m) is a synonym of m. This is useful in
//
// EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq()));
...
...
googlemock/test/gmock-generated-matchers_test.cc
View file @
a42cdf2a
...
...
@@ -112,154 +112,6 @@ std::string Explain(const MatcherType& m, const Value& x) {
return
ss
.
str
();
}
// Tests Args<k0, ..., kn>(m).
TEST
(
ArgsTest
,
AcceptsZeroTemplateArg
)
{
const
std
::
tuple
<
int
,
bool
>
t
(
5
,
true
);
EXPECT_THAT
(
t
,
Args
<>
(
Eq
(
std
::
tuple
<>
())));
EXPECT_THAT
(
t
,
Not
(
Args
<>
(
Ne
(
std
::
tuple
<>
()))));
}
TEST
(
ArgsTest
,
AcceptsOneTemplateArg
)
{
const
std
::
tuple
<
int
,
bool
>
t
(
5
,
true
);
EXPECT_THAT
(
t
,
Args
<
0
>
(
Eq
(
std
::
make_tuple
(
5
))));
EXPECT_THAT
(
t
,
Args
<
1
>
(
Eq
(
std
::
make_tuple
(
true
))));
EXPECT_THAT
(
t
,
Not
(
Args
<
1
>
(
Eq
(
std
::
make_tuple
(
false
)))));
}
TEST
(
ArgsTest
,
AcceptsTwoTemplateArgs
)
{
const
std
::
tuple
<
short
,
int
,
long
>
t
(
4
,
5
,
6L
);
// NOLINT
EXPECT_THAT
(
t
,
(
Args
<
0
,
1
>
(
Lt
())));
EXPECT_THAT
(
t
,
(
Args
<
1
,
2
>
(
Lt
())));
EXPECT_THAT
(
t
,
Not
(
Args
<
0
,
2
>
(
Gt
())));
}
TEST
(
ArgsTest
,
AcceptsRepeatedTemplateArgs
)
{
const
std
::
tuple
<
short
,
int
,
long
>
t
(
4
,
5
,
6L
);
// NOLINT
EXPECT_THAT
(
t
,
(
Args
<
0
,
0
>
(
Eq
())));
EXPECT_THAT
(
t
,
Not
(
Args
<
1
,
1
>
(
Ne
())));
}
TEST
(
ArgsTest
,
AcceptsDecreasingTemplateArgs
)
{
const
std
::
tuple
<
short
,
int
,
long
>
t
(
4
,
5
,
6L
);
// NOLINT
EXPECT_THAT
(
t
,
(
Args
<
2
,
0
>
(
Gt
())));
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
,
""
)
{
return
std
::
get
<
0
>
(
arg
)
+
std
::
get
<
1
>
(
arg
)
+
std
::
get
<
2
>
(
arg
)
==
0
;
}
TEST
(
ArgsTest
,
AcceptsMoreTemplateArgsThanArityOfOriginalTuple
)
{
EXPECT_THAT
(
std
::
make_tuple
(
-
1
,
2
),
(
Args
<
0
,
0
,
1
>
(
SumIsZero
())));
EXPECT_THAT
(
std
::
make_tuple
(
1
,
2
),
Not
(
Args
<
0
,
0
,
1
>
(
SumIsZero
())));
}
TEST
(
ArgsTest
,
CanBeNested
)
{
const
std
::
tuple
<
short
,
int
,
long
,
int
>
t
(
4
,
5
,
6L
,
6
);
// NOLINT
EXPECT_THAT
(
t
,
(
Args
<
1
,
2
,
3
>
(
Args
<
1
,
2
>
(
Eq
()))));
EXPECT_THAT
(
t
,
(
Args
<
0
,
1
,
3
>
(
Args
<
0
,
2
>
(
Lt
()))));
}
TEST
(
ArgsTest
,
CanMatchTupleByValue
)
{
typedef
std
::
tuple
<
char
,
int
,
int
>
Tuple3
;
const
Matcher
<
Tuple3
>
m
=
Args
<
1
,
2
>
(
Lt
());
EXPECT_TRUE
(
m
.
Matches
(
Tuple3
(
'a'
,
1
,
2
)));
EXPECT_FALSE
(
m
.
Matches
(
Tuple3
(
'b'
,
2
,
2
)));
}
TEST
(
ArgsTest
,
CanMatchTupleByReference
)
{
typedef
std
::
tuple
<
char
,
char
,
int
>
Tuple3
;
const
Matcher
<
const
Tuple3
&>
m
=
Args
<
0
,
1
>
(
Lt
());
EXPECT_TRUE
(
m
.
Matches
(
Tuple3
(
'a'
,
'b'
,
2
)));
EXPECT_FALSE
(
m
.
Matches
(
Tuple3
(
'b'
,
'b'
,
2
)));
}
// Validates that arg is printed as str.
MATCHER_P
(
PrintsAs
,
str
,
""
)
{
return
testing
::
PrintToString
(
arg
)
==
str
;
}
TEST
(
ArgsTest
,
AcceptsTenTemplateArgs
)
{
EXPECT_THAT
(
std
::
make_tuple
(
0
,
1L
,
2
,
3L
,
4
,
5
,
6
,
7
,
8
,
9
),
(
Args
<
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
>
(
PrintsAs
(
"(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)"
))));
EXPECT_THAT
(
std
::
make_tuple
(
0
,
1L
,
2
,
3L
,
4
,
5
,
6
,
7
,
8
,
9
),
Not
(
Args
<
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
>
(
PrintsAs
(
"(0, 8, 7, 6, 5, 4, 3, 2, 1, 0)"
))));
}
TEST
(
ArgsTest
,
DescirbesSelfCorrectly
)
{
const
Matcher
<
std
::
tuple
<
int
,
bool
,
char
>
>
m
=
Args
<
2
,
0
>
(
Lt
());
EXPECT_EQ
(
"are a tuple whose fields (#2, #0) are a pair where "
"the first < the second"
,
Describe
(
m
));
}
TEST
(
ArgsTest
,
DescirbesNestedArgsCorrectly
)
{
const
Matcher
<
const
std
::
tuple
<
int
,
bool
,
char
,
int
>&>
m
=
Args
<
0
,
2
,
3
>
(
Args
<
2
,
0
>
(
Lt
()));
EXPECT_EQ
(
"are a tuple whose fields (#0, #2, #3) are a tuple "
"whose fields (#2, #0) are a pair where the first < the second"
,
Describe
(
m
));
}
TEST
(
ArgsTest
,
DescribesNegationCorrectly
)
{
const
Matcher
<
std
::
tuple
<
int
,
char
>
>
m
=
Args
<
1
,
0
>
(
Gt
());
EXPECT_EQ
(
"are a tuple whose fields (#1, #0) aren't a pair "
"where the first > the second"
,
DescribeNegation
(
m
));
}
TEST
(
ArgsTest
,
ExplainsMatchResultWithoutInnerExplanation
)
{
const
Matcher
<
std
::
tuple
<
bool
,
int
,
int
>
>
m
=
Args
<
1
,
2
>
(
Eq
());
EXPECT_EQ
(
"whose fields (#1, #2) are (42, 42)"
,
Explain
(
m
,
std
::
make_tuple
(
false
,
42
,
42
)));
EXPECT_EQ
(
"whose fields (#1, #2) are (42, 43)"
,
Explain
(
m
,
std
::
make_tuple
(
false
,
42
,
43
)));
}
// For testing Args<>'s explanation.
class
LessThanMatcher
:
public
MatcherInterface
<
std
::
tuple
<
char
,
int
>
>
{
public:
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{}
virtual
bool
MatchAndExplain
(
std
::
tuple
<
char
,
int
>
value
,
MatchResultListener
*
listener
)
const
{
const
int
diff
=
std
::
get
<
0
>
(
value
)
-
std
::
get
<
1
>
(
value
);
if
(
diff
>
0
)
{
*
listener
<<
"where the first value is "
<<
diff
<<
" more than the second"
;
}
return
diff
<
0
;
}
};
Matcher
<
std
::
tuple
<
char
,
int
>
>
LessThan
()
{
return
MakeMatcher
(
new
LessThanMatcher
);
}
TEST
(
ArgsTest
,
ExplainsMatchResultWithInnerExplanation
)
{
const
Matcher
<
std
::
tuple
<
char
,
int
,
int
>
>
m
=
Args
<
0
,
2
>
(
LessThan
());
EXPECT_EQ
(
"whose fields (#0, #2) are ('a' (97, 0x61), 42), "
"where the first value is 55 more than the second"
,
Explain
(
m
,
std
::
make_tuple
(
'a'
,
42
,
42
)));
EXPECT_EQ
(
"whose fields (#0, #2) are ('
\\
0', 43)"
,
Explain
(
m
,
std
::
make_tuple
(
'\0'
,
42
,
43
)));
}
// For testing ExplainMatchResultTo().
class
GreaterThanMatcher
:
public
MatcherInterface
<
int
>
{
public:
...
...
@@ -1288,10 +1140,6 @@ TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) {
}
// namespace adl_test
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#if GTEST_LANG_CXX11
TEST
(
AllOfTest
,
WorksOnMoveOnlyType
)
{
...
...
googlemock/test/gmock-matchers_test.cc
View file @
a42cdf2a
...
...
@@ -32,6 +32,14 @@
//
// This file tests some commonly used argument matchers.
// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
// possible loss of data and C4100, unreferenced local parameter
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4244)
# pragma warning(disable:4100)
#endif
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-matchers.h"
...
...
@@ -6748,8 +6756,6 @@ TEST(AnyWithTest, ExplainsSelf) {
EXPECT_THAT
(
Explain
(
m
,
SampleAnyType
(
2
)),
"whose value 2 doesn't match"
);
}
#if GTEST_LANG_CXX11
TEST
(
PointeeTest
,
WorksOnMoveOnlyType
)
{
std
::
unique_ptr
<
int
>
p
(
new
int
(
3
));
EXPECT_THAT
(
p
,
Pointee
(
Eq
(
3
)));
...
...
@@ -6762,7 +6768,147 @@ TEST(NotTest, WorksOnMoveOnlyType) {
EXPECT_THAT
(
p
,
Not
(
Pointee
(
Eq
(
2
))));
}
#endif // GTEST_LANG_CXX11
// Tests Args<k0, ..., kn>(m).
TEST
(
ArgsTest
,
AcceptsZeroTemplateArg
)
{
const
std
::
tuple
<
int
,
bool
>
t
(
5
,
true
);
EXPECT_THAT
(
t
,
Args
<>
(
Eq
(
std
::
tuple
<>
())));
EXPECT_THAT
(
t
,
Not
(
Args
<>
(
Ne
(
std
::
tuple
<>
()))));
}
TEST
(
ArgsTest
,
AcceptsOneTemplateArg
)
{
const
std
::
tuple
<
int
,
bool
>
t
(
5
,
true
);
EXPECT_THAT
(
t
,
Args
<
0
>
(
Eq
(
std
::
make_tuple
(
5
))));
EXPECT_THAT
(
t
,
Args
<
1
>
(
Eq
(
std
::
make_tuple
(
true
))));
EXPECT_THAT
(
t
,
Not
(
Args
<
1
>
(
Eq
(
std
::
make_tuple
(
false
)))));
}
TEST
(
ArgsTest
,
AcceptsTwoTemplateArgs
)
{
const
std
::
tuple
<
short
,
int
,
long
>
t
(
4
,
5
,
6L
);
// NOLINT
EXPECT_THAT
(
t
,
(
Args
<
0
,
1
>
(
Lt
())));
EXPECT_THAT
(
t
,
(
Args
<
1
,
2
>
(
Lt
())));
EXPECT_THAT
(
t
,
Not
(
Args
<
0
,
2
>
(
Gt
())));
}
TEST
(
ArgsTest
,
AcceptsRepeatedTemplateArgs
)
{
const
std
::
tuple
<
short
,
int
,
long
>
t
(
4
,
5
,
6L
);
// NOLINT
EXPECT_THAT
(
t
,
(
Args
<
0
,
0
>
(
Eq
())));
EXPECT_THAT
(
t
,
Not
(
Args
<
1
,
1
>
(
Ne
())));
}
TEST
(
ArgsTest
,
AcceptsDecreasingTemplateArgs
)
{
const
std
::
tuple
<
short
,
int
,
long
>
t
(
4
,
5
,
6L
);
// NOLINT
EXPECT_THAT
(
t
,
(
Args
<
2
,
0
>
(
Gt
())));
EXPECT_THAT
(
t
,
Not
(
Args
<
2
,
1
>
(
Lt
())));
}
MATCHER
(
SumIsZero
,
""
)
{
return
std
::
get
<
0
>
(
arg
)
+
std
::
get
<
1
>
(
arg
)
+
std
::
get
<
2
>
(
arg
)
==
0
;
}
TEST
(
ArgsTest
,
AcceptsMoreTemplateArgsThanArityOfOriginalTuple
)
{
EXPECT_THAT
(
std
::
make_tuple
(
-
1
,
2
),
(
Args
<
0
,
0
,
1
>
(
SumIsZero
())));
EXPECT_THAT
(
std
::
make_tuple
(
1
,
2
),
Not
(
Args
<
0
,
0
,
1
>
(
SumIsZero
())));
}
TEST
(
ArgsTest
,
CanBeNested
)
{
const
std
::
tuple
<
short
,
int
,
long
,
int
>
t
(
4
,
5
,
6L
,
6
);
// NOLINT
EXPECT_THAT
(
t
,
(
Args
<
1
,
2
,
3
>
(
Args
<
1
,
2
>
(
Eq
()))));
EXPECT_THAT
(
t
,
(
Args
<
0
,
1
,
3
>
(
Args
<
0
,
2
>
(
Lt
()))));
}
TEST
(
ArgsTest
,
CanMatchTupleByValue
)
{
typedef
std
::
tuple
<
char
,
int
,
int
>
Tuple3
;
const
Matcher
<
Tuple3
>
m
=
Args
<
1
,
2
>
(
Lt
());
EXPECT_TRUE
(
m
.
Matches
(
Tuple3
(
'a'
,
1
,
2
)));
EXPECT_FALSE
(
m
.
Matches
(
Tuple3
(
'b'
,
2
,
2
)));
}
TEST
(
ArgsTest
,
CanMatchTupleByReference
)
{
typedef
std
::
tuple
<
char
,
char
,
int
>
Tuple3
;
const
Matcher
<
const
Tuple3
&>
m
=
Args
<
0
,
1
>
(
Lt
());
EXPECT_TRUE
(
m
.
Matches
(
Tuple3
(
'a'
,
'b'
,
2
)));
EXPECT_FALSE
(
m
.
Matches
(
Tuple3
(
'b'
,
'b'
,
2
)));
}
// Validates that arg is printed as str.
MATCHER_P
(
PrintsAs
,
str
,
""
)
{
return
testing
::
PrintToString
(
arg
)
==
str
;
}
TEST
(
ArgsTest
,
AcceptsTenTemplateArgs
)
{
EXPECT_THAT
(
std
::
make_tuple
(
0
,
1L
,
2
,
3L
,
4
,
5
,
6
,
7
,
8
,
9
),
(
Args
<
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
>
(
PrintsAs
(
"(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)"
))));
EXPECT_THAT
(
std
::
make_tuple
(
0
,
1L
,
2
,
3L
,
4
,
5
,
6
,
7
,
8
,
9
),
Not
(
Args
<
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
>
(
PrintsAs
(
"(0, 8, 7, 6, 5, 4, 3, 2, 1, 0)"
))));
}
TEST
(
ArgsTest
,
DescirbesSelfCorrectly
)
{
const
Matcher
<
std
::
tuple
<
int
,
bool
,
char
>
>
m
=
Args
<
2
,
0
>
(
Lt
());
EXPECT_EQ
(
"are a tuple whose fields (#2, #0) are a pair where "
"the first < the second"
,
Describe
(
m
));
}
TEST
(
ArgsTest
,
DescirbesNestedArgsCorrectly
)
{
const
Matcher
<
const
std
::
tuple
<
int
,
bool
,
char
,
int
>&>
m
=
Args
<
0
,
2
,
3
>
(
Args
<
2
,
0
>
(
Lt
()));
EXPECT_EQ
(
"are a tuple whose fields (#0, #2, #3) are a tuple "
"whose fields (#2, #0) are a pair where the first < the second"
,
Describe
(
m
));
}
TEST
(
ArgsTest
,
DescribesNegationCorrectly
)
{
const
Matcher
<
std
::
tuple
<
int
,
char
>
>
m
=
Args
<
1
,
0
>
(
Gt
());
EXPECT_EQ
(
"are a tuple whose fields (#1, #0) aren't a pair "
"where the first > the second"
,
DescribeNegation
(
m
));
}
TEST
(
ArgsTest
,
ExplainsMatchResultWithoutInnerExplanation
)
{
const
Matcher
<
std
::
tuple
<
bool
,
int
,
int
>
>
m
=
Args
<
1
,
2
>
(
Eq
());
EXPECT_EQ
(
"whose fields (#1, #2) are (42, 42)"
,
Explain
(
m
,
std
::
make_tuple
(
false
,
42
,
42
)));
EXPECT_EQ
(
"whose fields (#1, #2) are (42, 43)"
,
Explain
(
m
,
std
::
make_tuple
(
false
,
42
,
43
)));
}
// For testing Args<>'s explanation.
class
LessThanMatcher
:
public
MatcherInterface
<
std
::
tuple
<
char
,
int
>
>
{
public:
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{}
virtual
bool
MatchAndExplain
(
std
::
tuple
<
char
,
int
>
value
,
MatchResultListener
*
listener
)
const
{
const
int
diff
=
std
::
get
<
0
>
(
value
)
-
std
::
get
<
1
>
(
value
);
if
(
diff
>
0
)
{
*
listener
<<
"where the first value is "
<<
diff
<<
" more than the second"
;
}
return
diff
<
0
;
}
};
Matcher
<
std
::
tuple
<
char
,
int
>
>
LessThan
()
{
return
MakeMatcher
(
new
LessThanMatcher
);
}
TEST
(
ArgsTest
,
ExplainsMatchResultWithInnerExplanation
)
{
const
Matcher
<
std
::
tuple
<
char
,
int
,
int
>
>
m
=
Args
<
0
,
2
>
(
LessThan
());
EXPECT_EQ
(
"whose fields (#0, #2) are ('a' (97, 0x61), 42), "
"where the first value is 55 more than the second"
,
Explain
(
m
,
std
::
make_tuple
(
'a'
,
42
,
42
)));
EXPECT_EQ
(
"whose fields (#0, #2) are ('
\\
0', 43)"
,
Explain
(
m
,
std
::
make_tuple
(
'\0'
,
42
,
43
)));
}
}
// namespace gmock_matchers_test
}
// namespace testing
#ifdef _MSC_VER
# pragma warning(pop)
#endif
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