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
190e2cdd
Commit
190e2cdd
authored
Feb 27, 2018
by
Xiaoyi Zhang
Browse files
Add matcher for std::variant.
parent
ac34e6c9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
135 additions
and
0 deletions
+135
-0
googlemock/include/gmock/gmock-matchers.h
googlemock/include/gmock/gmock-matchers.h
+71
-0
googlemock/test/gmock-matchers_test.cc
googlemock/test/gmock-matchers_test.cc
+64
-0
No files found.
googlemock/include/gmock/gmock-matchers.h
View file @
190e2cdd
...
@@ -3623,6 +3623,66 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
...
@@ -3623,6 +3623,66 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
const
char
*
matcher_name
,
const
char
*
matcher_name
,
const
Strings
&
param_values
);
const
Strings
&
param_values
);
namespace
variant_matcher
{
// Overloads to allow VariantMatcher to do proper ADL lookup.
template
<
typename
T
>
void
holds_alternative
()
{}
template
<
typename
T
>
void
get
()
{}
// Implements a matcher that checks the value of a variant<> type variable.
template
<
typename
T
>
class
VariantMatcher
{
public:
explicit
VariantMatcher
(
::
testing
::
Matcher
<
const
T
&>
matcher
)
:
matcher_
(
internal
::
move
(
matcher
))
{}
template
<
typename
Variant
>
bool
MatchAndExplain
(
const
Variant
&
value
,
::
testing
::
MatchResultListener
*
listener
)
const
{
if
(
!
listener
->
IsInterested
())
{
return
holds_alternative
<
T
>
(
value
)
&&
matcher_
.
Matches
(
get
<
T
>
(
value
));
}
if
(
!
holds_alternative
<
T
>
(
value
))
{
*
listener
<<
"whose value is not of type '"
<<
GetTypeName
()
<<
"'"
;
return
false
;
}
const
T
&
elem
=
get
<
T
>
(
value
);
StringMatchResultListener
elem_listener
;
const
bool
match
=
matcher_
.
MatchAndExplain
(
elem
,
&
elem_listener
);
*
listener
<<
"whose value "
<<
PrintToString
(
elem
)
<<
(
match
?
" matches"
:
" doesn't match"
);
PrintIfNotEmpty
(
elem_listener
.
str
(),
listener
->
stream
());
return
match
;
}
void
DescribeTo
(
std
::
ostream
*
os
)
const
{
*
os
<<
"is a variant<> with value of type '"
<<
GetTypeName
()
<<
"' and the value "
;
matcher_
.
DescribeTo
(
os
);
}
void
DescribeNegationTo
(
std
::
ostream
*
os
)
const
{
*
os
<<
"is a variant<> with value of type other than '"
<<
GetTypeName
()
<<
"' or the value "
;
matcher_
.
DescribeNegationTo
(
os
);
}
private:
static
string
GetTypeName
()
{
#if GTEST_HAS_RTTI
return
internal
::
GetTypeName
<
T
>
();
#endif
return
"the element type"
;
}
const
::
testing
::
Matcher
<
const
T
&>
matcher_
;
};
}
// namespace variant_matcher
}
// namespace internal
}
// namespace internal
// ElementsAreArray(first, last)
// ElementsAreArray(first, last)
...
@@ -4397,6 +4457,17 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
...
@@ -4397,6 +4457,17 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
template
<
typename
InnerMatcher
>
template
<
typename
InnerMatcher
>
inline
InnerMatcher
AllArgs
(
const
InnerMatcher
&
matcher
)
{
return
matcher
;
}
inline
InnerMatcher
AllArgs
(
const
InnerMatcher
&
matcher
)
{
return
matcher
;
}
// Returns a matcher that matches the value of a variant<> type variable.
// The matcher implementation uses ADL to find the holds_alternative and get
// functions.
// It is compatible with std::variant.
template
<
typename
T
>
PolymorphicMatcher
<
internal
::
variant_matcher
::
VariantMatcher
<
T
>
>
VariantWith
(
const
Matcher
<
const
T
&>&
matcher
)
{
return
MakePolymorphicMatcher
(
internal
::
variant_matcher
::
VariantMatcher
<
T
>
(
matcher
));
}
// These macros allow using matchers to check values in Google Test
// These macros allow using matchers to check values in Google Test
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// succeed iff the value matches the matcher. If the assertion fails,
// succeed iff the value matches the matcher. If the assertion fails,
...
...
googlemock/test/gmock-matchers_test.cc
View file @
190e2cdd
...
@@ -5655,5 +5655,69 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) {
...
@@ -5655,5 +5655,69 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) {
EXPECT_THAT
(
lhs
,
UnorderedPointwise
(
m2
,
rhs
));
EXPECT_THAT
(
lhs
,
UnorderedPointwise
(
m2
,
rhs
));
}
}
class
SampleVariantIntString
{
public:
SampleVariantIntString
(
int
i
)
:
i_
(
i
),
has_int_
(
true
)
{}
SampleVariantIntString
(
const
std
::
string
&
s
)
:
s_
(
s
),
has_int_
(
false
)
{}
template
<
typename
T
>
friend
bool
holds_alternative
(
const
SampleVariantIntString
&
value
)
{
return
value
.
has_int_
==
internal
::
IsSame
<
T
,
int
>::
value
;
}
template
<
typename
T
>
friend
const
T
&
get
(
const
SampleVariantIntString
&
value
)
{
return
value
.
get_impl
(
static_cast
<
T
*>
(
NULL
));
}
private:
const
int
&
get_impl
(
int
*
)
const
{
return
i_
;
}
const
std
::
string
&
get_impl
(
std
::
string
*
)
const
{
return
s_
;
}
int
i_
;
std
::
string
s_
;
bool
has_int_
;
};
TEST
(
VariantTest
,
DescribesSelf
)
{
const
Matcher
<
SampleVariantIntString
>
m
=
VariantWith
<
int
>
(
Eq
(
1
));
EXPECT_THAT
(
Describe
(
m
),
ContainsRegex
(
"is a variant<> with value of type "
"'.*' and the value is equal to 1"
));
}
TEST
(
VariantTest
,
ExplainsSelf
)
{
const
Matcher
<
SampleVariantIntString
>
m
=
VariantWith
<
int
>
(
Eq
(
1
));
EXPECT_THAT
(
Explain
(
m
,
SampleVariantIntString
(
1
)),
ContainsRegex
(
"whose value 1"
));
EXPECT_THAT
(
Explain
(
m
,
SampleVariantIntString
(
"A"
)),
HasSubstr
(
"whose value is not of type '"
));
EXPECT_THAT
(
Explain
(
m
,
SampleVariantIntString
(
2
)),
"whose value 2 doesn't match"
);
}
TEST
(
VariantTest
,
FullMatch
)
{
Matcher
<
SampleVariantIntString
>
m
=
VariantWith
<
int
>
(
Eq
(
1
));
EXPECT_TRUE
(
m
.
Matches
(
SampleVariantIntString
(
1
)));
m
=
VariantWith
<
std
::
string
>
(
Eq
(
"1"
));
EXPECT_TRUE
(
m
.
Matches
(
SampleVariantIntString
(
"1"
)));
}
TEST
(
VariantTest
,
TypeDoesNotMatch
)
{
Matcher
<
SampleVariantIntString
>
m
=
VariantWith
<
int
>
(
Eq
(
1
));
EXPECT_FALSE
(
m
.
Matches
(
SampleVariantIntString
(
"1"
)));
m
=
VariantWith
<
std
::
string
>
(
Eq
(
"1"
));
EXPECT_FALSE
(
m
.
Matches
(
SampleVariantIntString
(
1
)));
}
TEST
(
VariantTest
,
InnerDoesNotMatch
)
{
Matcher
<
SampleVariantIntString
>
m
=
VariantWith
<
int
>
(
Eq
(
1
));
EXPECT_FALSE
(
m
.
Matches
(
SampleVariantIntString
(
2
)));
m
=
VariantWith
<
std
::
string
>
(
Eq
(
"1"
));
EXPECT_FALSE
(
m
.
Matches
(
SampleVariantIntString
(
"2"
)));
}
}
// namespace gmock_matchers_test
}
// namespace gmock_matchers_test
}
// namespace testing
}
// namespace testing
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment