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
a9f2368d
Unverified
Commit
a9f2368d
authored
Feb 27, 2018
by
Gennadiy Civil
Committed by
GitHub
Feb 27, 2018
Browse files
Merge pull request #1483 from gennadiycivil/master
gmock merging -2
parents
ce61dc54
ba40fd14
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
328 additions
and
123 deletions
+328
-123
googlemock/include/gmock/gmock-matchers.h
googlemock/include/gmock/gmock-matchers.h
+187
-44
googlemock/src/gmock-matchers.cc
googlemock/src/gmock-matchers.cc
+119
-77
googlemock/test/gmock_link_test.h
googlemock/test/gmock_link_test.h
+22
-2
No files found.
googlemock/include/gmock/gmock-matchers.h
View file @
a9f2368d
...
...
@@ -514,7 +514,7 @@ template <typename T, typename M>
class
MatcherCastImpl
{
public:
static
Matcher
<
T
>
Cast
(
const
M
&
polymorphic_matcher_or_value
)
{
// M can be a polymorhic matcher, in which case we want to use
// M can be a polymor
p
hic matcher, in which case we want to use
// its conversion operator to create Matcher<T>. Or it can be a value
// that should be passed to the Matcher<T>'s constructor.
//
...
...
@@ -3303,14 +3303,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
GTEST_API_
ElementMatcherPairs
FindMaxBipartiteMatching
(
const
MatchMatrix
&
g
);
GTEST_API_
bool
FindPairing
(
const
MatchMatrix
&
matrix
,
MatchResultListener
*
listener
);
struct
UnorderedMatcherRequire
{
enum
Flags
{
Superset
=
1
<<
0
,
Subset
=
1
<<
1
,
ExactMatch
=
Superset
|
Subset
,
};
};
// Untyped base class for implementing UnorderedElementsAre. By
// putting logic that's not specific to the element type here, we
// reduce binary bloat and increase compilation speed.
class
GTEST_API_
UnorderedElementsAreMatcherImplBase
{
protected:
explicit
UnorderedElementsAreMatcherImplBase
(
UnorderedMatcherRequire
::
Flags
matcher_flags
)
:
match_flags_
(
matcher_flags
)
{}
// A vector of matcher describers, one for each element matcher.
// Does not own the describers (and thus can be used only when the
// element matchers are alive).
...
...
@@ -3322,9 +3331,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
// Describes the negation of this UnorderedElementsAre matcher.
void
DescribeNegationToImpl
(
::
std
::
ostream
*
os
)
const
;
bool
VerifyAllElementsAndMatchersAreMatched
(
const
::
std
::
vector
<
std
::
string
>&
element_printouts
,
const
MatchMatrix
&
matrix
,
MatchResultListener
*
listener
)
const
;
bool
VerifyMatchMatrix
(
const
::
std
::
vector
<
std
::
string
>&
element_printouts
,
const
MatchMatrix
&
matrix
,
MatchResultListener
*
listener
)
const
;
bool
FindPairing
(
const
MatchMatrix
&
matrix
,
MatchResultListener
*
listener
)
const
;
MatcherDescriberVec
&
matcher_describers
()
{
return
matcher_describers_
;
...
...
@@ -3334,13 +3346,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
return
Message
()
<<
n
<<
" element"
<<
(
n
==
1
?
""
:
"s"
);
}
UnorderedMatcherRequire
::
Flags
match_flags
()
const
{
return
match_flags_
;
}
private:
UnorderedMatcherRequire
::
Flags
match_flags_
;
MatcherDescriberVec
matcher_describers_
;
GTEST_DISALLOW_ASSIGN_
(
UnorderedElementsAreMatcherImplBase
);
};
// Implements unordered ElementsAre and unordered ElementsAreArray.
// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
// IsSupersetOf.
template
<
typename
Container
>
class
UnorderedElementsAreMatcherImpl
:
public
MatcherInterface
<
Container
>
,
...
...
@@ -3353,10 +3369,10 @@ class UnorderedElementsAreMatcherImpl
typedef
typename
StlContainer
::
const_iterator
StlContainerConstIterator
;
typedef
typename
StlContainer
::
value_type
Element
;
// Constructs the matcher from a sequence of element values or
// element matchers.
template
<
typename
InputIter
>
UnorderedElementsAreMatcherImpl
(
InputIter
first
,
InputIter
last
)
{
UnorderedElementsAreMatcherImpl
(
UnorderedMatcherRequire
::
Flags
matcher_flags
,
InputIter
first
,
InputIter
last
)
:
UnorderedElementsAreMatcherImplBase
(
matcher_flags
)
{
for
(;
first
!=
last
;
++
first
)
{
matchers_
.
push_back
(
MatcherCast
<
const
Element
&>
(
*
first
));
matcher_describers
().
push_back
(
matchers_
.
back
().
GetDescriber
());
...
...
@@ -3377,34 +3393,32 @@ class UnorderedElementsAreMatcherImpl
MatchResultListener
*
listener
)
const
{
StlContainerReference
stl_container
=
View
::
ConstReference
(
container
);
::
std
::
vector
<
std
::
string
>
element_printouts
;
MatchMatrix
matrix
=
AnalyzeElements
(
stl_container
.
begin
(),
stl_container
.
end
(),
&
element_printouts
,
listener
);
MatchMatrix
matrix
=
AnalyzeElements
(
stl_container
.
begin
(),
stl_container
.
end
(),
&
element_printouts
,
listener
);
const
size_t
actual_count
=
matrix
.
LhsSize
();
if
(
actual_count
==
0
&&
matchers_
.
empty
())
{
if
(
matrix
.
LhsSize
()
==
0
&&
matrix
.
RhsSize
()
==
0
)
{
return
true
;
}
if
(
actual_count
!=
matchers_
.
size
())
{
// The element count doesn't match. If the container is empty,
// there's no need to explain anything as Google Mock already
// prints the empty container. Otherwise we just need to show
// how many elements there actually are.
if
(
actual_count
!=
0
&&
listener
->
IsInterested
())
{
*
listener
<<
"which has "
<<
Elements
(
actual_count
);
if
(
match_flags
()
==
UnorderedMatcherRequire
::
ExactMatch
)
{
if
(
matrix
.
LhsSize
()
!=
matrix
.
RhsSize
())
{
// The element count doesn't match. If the container is empty,
// there's no need to explain anything as Google Mock already
// prints the empty container. Otherwise we just need to show
// how many elements there actually are.
if
(
matrix
.
LhsSize
()
!=
0
&&
listener
->
IsInterested
())
{
*
listener
<<
"which has "
<<
Elements
(
matrix
.
LhsSize
());
}
return
false
;
}
return
false
;
}
return
VerifyAllElementsAndMatchersAreMatched
(
element_printouts
,
matrix
,
listener
)
&&
return
VerifyMatchMatrix
(
element_printouts
,
matrix
,
listener
)
&&
FindPairing
(
matrix
,
listener
);
}
private:
typedef
::
std
::
vector
<
Matcher
<
const
Element
&>
>
MatcherVec
;
template
<
typename
ElementIter
>
MatchMatrix
AnalyzeElements
(
ElementIter
elem_first
,
ElementIter
elem_last
,
::
std
::
vector
<
std
::
string
>*
element_printouts
,
...
...
@@ -3431,7 +3445,7 @@ class UnorderedElementsAreMatcherImpl
return
matrix
;
}
MatcherVec
matchers_
;
::
std
::
vector
<
Matcher
<
const
Element
&>
>
matchers_
;
GTEST_DISALLOW_ASSIGN_
(
UnorderedElementsAreMatcherImpl
);
};
...
...
@@ -3464,7 +3478,7 @@ class UnorderedElementsAreMatcher {
TransformTupleValues
(
CastAndAppendTransform
<
const
Element
&>
(),
matchers_
,
::
std
::
back_inserter
(
matchers
));
return
MakeMatcher
(
new
UnorderedElementsAreMatcherImpl
<
Container
>
(
matchers
.
begin
(),
matchers
.
end
()));
UnorderedMatcherRequire
::
ExactMatch
,
matchers
.
begin
(),
matchers
.
end
()));
}
private:
...
...
@@ -3497,24 +3511,23 @@ class ElementsAreMatcher {
GTEST_DISALLOW_ASSIGN_
(
ElementsAreMatcher
);
};
// Implements UnorderedElementsAreArray().
// Implements UnorderedElementsAreArray()
, IsSubsetOf(), and IsSupersetOf()
.
template
<
typename
T
>
class
UnorderedElementsAreArrayMatcher
{
public:
UnorderedElementsAreArrayMatcher
()
{}
template
<
typename
Iter
>
UnorderedElementsAreArrayMatcher
(
Iter
first
,
Iter
last
)
:
matchers_
(
first
,
last
)
{}
UnorderedElementsAreArrayMatcher
(
UnorderedMatcherRequire
::
Flags
match_flags
,
Iter
first
,
Iter
last
)
:
match_flags_
(
match_flags
),
matchers_
(
first
,
last
)
{}
template
<
typename
Container
>
operator
Matcher
<
Container
>
()
const
{
return
MakeMatcher
(
new
UnorderedElementsAreMatcherImpl
<
Container
>
(
matchers_
.
begin
(),
matchers_
.
end
()));
return
MakeMatcher
(
new
UnorderedElementsAreMatcherImpl
<
Container
>
(
match_flags_
,
matchers_
.
begin
(),
matchers_
.
end
()));
}
private:
UnorderedMatcherRequire
::
Flags
match_flags_
;
::
std
::
vector
<
T
>
matchers_
;
GTEST_DISALLOW_ASSIGN_
(
UnorderedElementsAreArrayMatcher
);
...
...
@@ -3625,7 +3638,7 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
}
// namespace internal
// ElementsAreArray(
first,
last)
// ElementsAreArray(
iterator_first, iterator_
last)
// ElementsAreArray(pointer, count)
// ElementsAreArray(array)
// ElementsAreArray(container)
...
...
@@ -3674,20 +3687,26 @@ ElementsAreArray(::std::initializer_list<T> xs) {
}
#endif
// UnorderedElementsAreArray(
first,
last)
// UnorderedElementsAreArray(
iterator_first, iterator_
last)
// UnorderedElementsAreArray(pointer, count)
// UnorderedElementsAreArray(array)
// UnorderedElementsAreArray(container)
// UnorderedElementsAreArray({ e1, e2, ..., en })
//
// The UnorderedElementsAreArray() functions are like
// ElementsAreArray(...), but allow matching the elements in any order.
// UnorderedElementsAreArray() verifies that a bijective mapping onto a
// collection of matchers exists.
//
// The matchers can be specified as an array, a pointer and count, a container,
// an initializer list, or an STL iterator range. In each of these cases, the
// underlying matchers can be either values or matchers.
template
<
typename
Iter
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
typename
::
std
::
iterator_traits
<
Iter
>::
value_type
>
UnorderedElementsAreArray
(
Iter
first
,
Iter
last
)
{
typedef
typename
::
std
::
iterator_traits
<
Iter
>::
value_type
T
;
return
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
(
first
,
last
);
return
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
(
internal
::
UnorderedMatcherRequire
::
ExactMatch
,
first
,
last
);
}
template
<
typename
T
>
...
...
@@ -3729,7 +3748,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) {
const
internal
::
AnythingMatcher
_
=
{};
// Creates a matcher that matches any value of the given type T.
template
<
typename
T
>
inline
Matcher
<
T
>
A
()
{
return
MakeMatcher
(
new
internal
::
AnyMatcherImpl
<
T
>
());
}
inline
Matcher
<
T
>
A
()
{
return
Matcher
<
T
>
(
new
internal
::
AnyMatcherImpl
<
T
>
());
}
// Creates a matcher that matches any value of the given type T.
template
<
typename
T
>
...
...
@@ -4299,6 +4320,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
return
internal
::
ContainsMatcher
<
M
>
(
matcher
);
}
// IsSupersetOf(iterator_first, iterator_last)
// IsSupersetOf(pointer, count)
// IsSupersetOf(array)
// IsSupersetOf(container)
// IsSupersetOf({e1, e2, ..., en})
//
// IsSupersetOf() verifies that a surjective partial mapping onto a collection
// of matchers exists. In other words, a container matches
// IsSupersetOf({e1, ..., en}) if and only if there is a permutation
// {y1, ..., yn} of some of the container's elements where y1 matches e1,
// ..., and yn matches en. Obviously, the size of the container must be >= n
// in order to have a match. Examples:
//
// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and
// 1 matches Ne(0).
// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches
// both Eq(1) and Lt(2). The reason is that different matchers must be used
// for elements in different slots of the container.
// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches
// Eq(1) and (the second) 1 matches Lt(2).
// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)
// Gt(1) and 3 matches (the second) Gt(1).
//
// The matchers can be specified as an array, a pointer and count, a container,
// an initializer list, or an STL iterator range. In each of these cases, the
// underlying matchers can be either values or matchers.
template
<
typename
Iter
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
typename
::
std
::
iterator_traits
<
Iter
>::
value_type
>
IsSupersetOf
(
Iter
first
,
Iter
last
)
{
typedef
typename
::
std
::
iterator_traits
<
Iter
>::
value_type
T
;
return
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
(
internal
::
UnorderedMatcherRequire
::
Superset
,
first
,
last
);
}
template
<
typename
T
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
IsSupersetOf
(
const
T
*
pointer
,
size_t
count
)
{
return
IsSupersetOf
(
pointer
,
pointer
+
count
);
}
template
<
typename
T
,
size_t
N
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
IsSupersetOf
(
const
T
(
&
array
)[
N
])
{
return
IsSupersetOf
(
array
,
N
);
}
template
<
typename
Container
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
typename
Container
::
value_type
>
IsSupersetOf
(
const
Container
&
container
)
{
return
IsSupersetOf
(
container
.
begin
(),
container
.
end
());
}
#if GTEST_HAS_STD_INITIALIZER_LIST_
template
<
typename
T
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
IsSupersetOf
(
::
std
::
initializer_list
<
T
>
xs
)
{
return
IsSupersetOf
(
xs
.
begin
(),
xs
.
end
());
}
#endif
// IsSubsetOf(iterator_first, iterator_last)
// IsSubsetOf(pointer, count)
// IsSubsetOf(array)
// IsSubsetOf(container)
// IsSubsetOf({e1, e2, ..., en})
//
// IsSubsetOf() verifies that an injective mapping onto a collection of matchers
// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and
// only if there is a subset of matchers {m1, ..., mk} which would match the
// container using UnorderedElementsAre. Obviously, the size of the container
// must be <= n in order to have a match. Examples:
//
// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).
// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1
// matches Lt(0).
// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both
// match Gt(0). The reason is that different matchers must be used for
// elements in different slots of the container.
//
// The matchers can be specified as an array, a pointer and count, a container,
// an initializer list, or an STL iterator range. In each of these cases, the
// underlying matchers can be either values or matchers.
template
<
typename
Iter
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
typename
::
std
::
iterator_traits
<
Iter
>::
value_type
>
IsSubsetOf
(
Iter
first
,
Iter
last
)
{
typedef
typename
::
std
::
iterator_traits
<
Iter
>::
value_type
T
;
return
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
(
internal
::
UnorderedMatcherRequire
::
Subset
,
first
,
last
);
}
template
<
typename
T
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
IsSubsetOf
(
const
T
*
pointer
,
size_t
count
)
{
return
IsSubsetOf
(
pointer
,
pointer
+
count
);
}
template
<
typename
T
,
size_t
N
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
IsSubsetOf
(
const
T
(
&
array
)[
N
])
{
return
IsSubsetOf
(
array
,
N
);
}
template
<
typename
Container
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
typename
Container
::
value_type
>
IsSubsetOf
(
const
Container
&
container
)
{
return
IsSubsetOf
(
container
.
begin
(),
container
.
end
());
}
#if GTEST_HAS_STD_INITIALIZER_LIST_
template
<
typename
T
>
inline
internal
::
UnorderedElementsAreArrayMatcher
<
T
>
IsSubsetOf
(
::
std
::
initializer_list
<
T
>
xs
)
{
return
IsSubsetOf
(
xs
.
begin
(),
xs
.
end
());
}
#endif
// Matches an STL-style container or a native array that contains only
// elements matching the given value or matcher.
//
...
...
googlemock/src/gmock-matchers.cc
View file @
a9f2368d
...
...
@@ -38,6 +38,7 @@
#include "gmock/gmock-generated-matchers.h"
#include <string.h>
#include <iostream>
#include <sstream>
#include <string>
...
...
@@ -181,8 +182,7 @@ class MaxBipartiteMatchState {
explicit
MaxBipartiteMatchState
(
const
MatchMatrix
&
graph
)
:
graph_
(
&
graph
),
left_
(
graph_
->
LhsSize
(),
kUnused
),
right_
(
graph_
->
RhsSize
(),
kUnused
)
{
}
right_
(
graph_
->
RhsSize
(),
kUnused
)
{}
// Returns the edges of a maximal match, each in the form {left, right}.
ElementMatcherPairs
Compute
()
{
...
...
@@ -239,10 +239,8 @@ class MaxBipartiteMatchState {
//
bool
TryAugment
(
size_t
ilhs
,
::
std
::
vector
<
char
>*
seen
)
{
for
(
size_t
irhs
=
0
;
irhs
<
graph_
->
RhsSize
();
++
irhs
)
{
if
((
*
seen
)[
irhs
])
continue
;
if
(
!
graph_
->
HasEdge
(
ilhs
,
irhs
))
continue
;
if
((
*
seen
)[
irhs
])
continue
;
if
(
!
graph_
->
HasEdge
(
ilhs
,
irhs
))
continue
;
// There's an available edge from ilhs to irhs.
(
*
seen
)[
irhs
]
=
1
;
// Next a search is performed to determine whether
...
...
@@ -285,8 +283,7 @@ class MaxBipartiteMatchState {
const
size_t
MaxBipartiteMatchState
::
kUnused
;
GTEST_API_
ElementMatcherPairs
FindMaxBipartiteMatching
(
const
MatchMatrix
&
g
)
{
GTEST_API_
ElementMatcherPairs
FindMaxBipartiteMatching
(
const
MatchMatrix
&
g
)
{
return
MaxBipartiteMatchState
(
g
).
Compute
();
}
...
...
@@ -295,7 +292,7 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
typedef
ElementMatcherPairs
::
const_iterator
Iter
;
::
std
::
ostream
&
os
=
*
stream
;
os
<<
"{"
;
const
char
*
sep
=
""
;
const
char
*
sep
=
""
;
for
(
Iter
it
=
pairs
.
begin
();
it
!=
pairs
.
end
();
++
it
)
{
os
<<
sep
<<
"
\n
("
<<
"element #"
<<
it
->
first
<<
", "
...
...
@@ -305,38 +302,6 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
os
<<
"
\n
}"
;
}
// Tries to find a pairing, and explains the result.
GTEST_API_
bool
FindPairing
(
const
MatchMatrix
&
matrix
,
MatchResultListener
*
listener
)
{
ElementMatcherPairs
matches
=
FindMaxBipartiteMatching
(
matrix
);
size_t
max_flow
=
matches
.
size
();
bool
result
=
(
max_flow
==
matrix
.
RhsSize
());
if
(
!
result
)
{
if
(
listener
->
IsInterested
())
{
*
listener
<<
"where no permutation of the elements can "
"satisfy all matchers, and the closest match is "
<<
max_flow
<<
" of "
<<
matrix
.
RhsSize
()
<<
" matchers with the pairings:
\n
"
;
LogElementMatcherPairVec
(
matches
,
listener
->
stream
());
}
return
false
;
}
if
(
matches
.
size
()
>
1
)
{
if
(
listener
->
IsInterested
())
{
const
char
*
sep
=
"where:
\n
"
;
for
(
size_t
mi
=
0
;
mi
<
matches
.
size
();
++
mi
)
{
*
listener
<<
sep
<<
" - element #"
<<
matches
[
mi
].
first
<<
" is matched by matcher #"
<<
matches
[
mi
].
second
;
sep
=
",
\n
"
;
}
}
}
return
true
;
}
bool
MatchMatrix
::
NextGraph
()
{
for
(
size_t
ilhs
=
0
;
ilhs
<
LhsSize
();
++
ilhs
)
{
for
(
size_t
irhs
=
0
;
irhs
<
RhsSize
();
++
irhs
)
{
...
...
@@ -362,7 +327,7 @@ void MatchMatrix::Randomize() {
std
::
string
MatchMatrix
::
DebugString
()
const
{
::
std
::
stringstream
ss
;
const
char
*
sep
=
""
;
const
char
*
sep
=
""
;
for
(
size_t
i
=
0
;
i
<
LhsSize
();
++
i
)
{
ss
<<
sep
;
for
(
size_t
j
=
0
;
j
<
RhsSize
();
++
j
)
{
...
...
@@ -375,44 +340,83 @@ std::string MatchMatrix::DebugString() const {
void
UnorderedElementsAreMatcherImplBase
::
DescribeToImpl
(
::
std
::
ostream
*
os
)
const
{
if
(
matcher_describers_
.
empty
())
{
*
os
<<
"is empty"
;
return
;
}
if
(
matcher_describers_
.
size
()
==
1
)
{
*
os
<<
"has "
<<
Elements
(
1
)
<<
" and that element "
;
matcher_describers_
[
0
]
->
DescribeTo
(
os
);
return
;
switch
(
match_flags
())
{
case
UnorderedMatcherRequire
::
ExactMatch
:
if
(
matcher_describers_
.
empty
())
{
*
os
<<
"is empty"
;
return
;
}
if
(
matcher_describers_
.
size
()
==
1
)
{
*
os
<<
"has "
<<
Elements
(
1
)
<<
" and that element "
;
matcher_describers_
[
0
]
->
DescribeTo
(
os
);
return
;
}
*
os
<<
"has "
<<
Elements
(
matcher_describers_
.
size
())
<<
" and there exists some permutation of elements such that:
\n
"
;
break
;
case
UnorderedMatcherRequire
::
Superset
:
*
os
<<
"a surjection from elements to requirements exists such that:
\n
"
;
break
;
case
UnorderedMatcherRequire
::
Subset
:
*
os
<<
"an injection from elements to requirements exists such that:
\n
"
;
break
;
}
*
os
<<
"has "
<<
Elements
(
matcher_describers_
.
size
())
<<
" and there exists some permutation of elements such that:
\n
"
;
const
char
*
sep
=
""
;
for
(
size_t
i
=
0
;
i
!=
matcher_describers_
.
size
();
++
i
)
{
*
os
<<
sep
<<
" - element #"
<<
i
<<
" "
;
*
os
<<
sep
;
if
(
match_flags
()
==
UnorderedMatcherRequire
::
ExactMatch
)
{
*
os
<<
" - element #"
<<
i
<<
" "
;
}
else
{
*
os
<<
" - an element "
;
}
matcher_describers_
[
i
]
->
DescribeTo
(
os
);
sep
=
", and
\n
"
;
if
(
match_flags
()
==
UnorderedMatcherRequire
::
ExactMatch
)
{
sep
=
", and
\n
"
;
}
else
{
sep
=
"
\n
"
;
}
}
}
void
UnorderedElementsAreMatcherImplBase
::
DescribeNegationToImpl
(
::
std
::
ostream
*
os
)
const
{
if
(
matcher_describers_
.
empty
())
{
*
os
<<
"isn't empty"
;
return
;
}
if
(
matcher_describers_
.
size
()
==
1
)
{
*
os
<<
"doesn't have "
<<
Elements
(
1
)
<<
", or has "
<<
Elements
(
1
)
<<
" that "
;
matcher_describers_
[
0
]
->
DescribeNegationTo
(
os
);
return
;
switch
(
match_flags
())
{
case
UnorderedMatcherRequire
::
ExactMatch
:
if
(
matcher_describers_
.
empty
())
{
*
os
<<
"isn't empty"
;
return
;
}
if
(
matcher_describers_
.
size
()
==
1
)
{
*
os
<<
"doesn't have "
<<
Elements
(
1
)
<<
", or has "
<<
Elements
(
1
)
<<
" that "
;
matcher_describers_
[
0
]
->
DescribeNegationTo
(
os
);
return
;
}
*
os
<<
"doesn't have "
<<
Elements
(
matcher_describers_
.
size
())
<<
", or there exists no permutation of elements such that:
\n
"
;
break
;
case
UnorderedMatcherRequire
::
Superset
:
*
os
<<
"no surjection from elements to requirements exists such that:
\n
"
;
break
;
case
UnorderedMatcherRequire
::
Subset
:
*
os
<<
"no injection from elements to requirements exists such that:
\n
"
;
break
;
}
*
os
<<
"doesn't have "
<<
Elements
(
matcher_describers_
.
size
())
<<
", or there exists no permutation of elements such that:
\n
"
;
const
char
*
sep
=
""
;
for
(
size_t
i
=
0
;
i
!=
matcher_describers_
.
size
();
++
i
)
{
*
os
<<
sep
<<
" - element #"
<<
i
<<
" "
;
*
os
<<
sep
;
if
(
match_flags
()
==
UnorderedMatcherRequire
::
ExactMatch
)
{
*
os
<<
" - element #"
<<
i
<<
" "
;
}
else
{
*
os
<<
" - an element "
;
}
matcher_describers_
[
i
]
->
DescribeTo
(
os
);
sep
=
", and
\n
"
;
if
(
match_flags
()
==
UnorderedMatcherRequire
::
ExactMatch
)
{
sep
=
", and
\n
"
;
}
else
{
sep
=
"
\n
"
;
}
}
}
...
...
@@ -421,10 +425,9 @@ void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
// and better error reporting.
// Returns false, writing an explanation to 'listener', if and only
// if the success criteria are not met.
bool
UnorderedElementsAreMatcherImplBase
::
VerifyAllElementsAndMatchersAreMatched
(
const
::
std
::
vector
<
std
::
string
>&
element_printouts
,
const
MatchMatrix
&
matrix
,
MatchResultListener
*
listener
)
const
{
bool
UnorderedElementsAreMatcherImplBase
::
VerifyMatchMatrix
(
const
::
std
::
vector
<
std
::
string
>&
element_printouts
,
const
MatchMatrix
&
matrix
,
MatchResultListener
*
listener
)
const
{
bool
result
=
true
;
::
std
::
vector
<
char
>
element_matched
(
matrix
.
LhsSize
(),
0
);
::
std
::
vector
<
char
>
matcher_matched
(
matrix
.
RhsSize
(),
0
);
...
...
@@ -437,12 +440,11 @@ bool UnorderedElementsAreMatcherImplBase::
}
}
{
if
(
match_flags
()
&
UnorderedMatcherRequire
::
Superset
)
{
const
char
*
sep
=
"where the following matchers don't match any elements:
\n
"
;
for
(
size_t
mi
=
0
;
mi
<
matcher_matched
.
size
();
++
mi
)
{
if
(
matcher_matched
[
mi
])
continue
;
if
(
matcher_matched
[
mi
])
continue
;
result
=
false
;
if
(
listener
->
IsInterested
())
{
*
listener
<<
sep
<<
"matcher #"
<<
mi
<<
": "
;
...
...
@@ -452,7 +454,7 @@ bool UnorderedElementsAreMatcherImplBase::
}
}
{
if
(
match_flags
()
&
UnorderedMatcherRequire
::
Subset
)
{
const
char
*
sep
=
"where the following elements don't match any matchers:
\n
"
;
const
char
*
outer_sep
=
""
;
...
...
@@ -460,8 +462,7 @@ bool UnorderedElementsAreMatcherImplBase::
outer_sep
=
"
\n
and "
;
}
for
(
size_t
ei
=
0
;
ei
<
element_matched
.
size
();
++
ei
)
{
if
(
element_matched
[
ei
])
continue
;
if
(
element_matched
[
ei
])
continue
;
result
=
false
;
if
(
listener
->
IsInterested
())
{
*
listener
<<
outer_sep
<<
sep
<<
"element #"
<<
ei
<<
": "
...
...
@@ -474,5 +475,46 @@ bool UnorderedElementsAreMatcherImplBase::
return
result
;
}
bool
UnorderedElementsAreMatcherImplBase
::
FindPairing
(
const
MatchMatrix
&
matrix
,
MatchResultListener
*
listener
)
const
{
ElementMatcherPairs
matches
=
FindMaxBipartiteMatching
(
matrix
);
size_t
max_flow
=
matches
.
size
();
if
((
match_flags
()
&
UnorderedMatcherRequire
::
Superset
)
&&
max_flow
<
matrix
.
RhsSize
())
{
if
(
listener
->
IsInterested
())
{
*
listener
<<
"where no permutation of the elements can satisfy all "
"matchers, and the closest match is "
<<
max_flow
<<
" of "
<<
matrix
.
RhsSize
()
<<
" matchers with the pairings:
\n
"
;
LogElementMatcherPairVec
(
matches
,
listener
->
stream
());
}
return
false
;
}
if
((
match_flags
()
&
UnorderedMatcherRequire
::
Subset
)
&&
max_flow
<
matrix
.
LhsSize
())
{
if
(
listener
->
IsInterested
())
{
*
listener
<<
"where not all elements can be matched, and the closest match is "
<<
max_flow
<<
" of "
<<
matrix
.
RhsSize
()
<<
" matchers with the pairings:
\n
"
;
LogElementMatcherPairVec
(
matches
,
listener
->
stream
());
}
return
false
;
}
if
(
matches
.
size
()
>
1
)
{
if
(
listener
->
IsInterested
())
{
const
char
*
sep
=
"where:
\n
"
;
for
(
size_t
mi
=
0
;
mi
<
matches
.
size
();
++
mi
)
{
*
listener
<<
sep
<<
" - element #"
<<
matches
[
mi
].
first
<<
" is matched by matcher #"
<<
matches
[
mi
].
second
;
sep
=
",
\n
"
;
}
}
}
return
true
;
}
}
// namespace internal
}
// namespace testing
googlemock/test/gmock_link_test.h
View file @
a9f2368d
...
...
@@ -120,13 +120,15 @@
# include <errno.h>
#endif
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
#include <iostream>
#include <vector>
#include "gtest/gtest.h"
#include "gtest/internal/gtest-port.h"
using
testing
::
_
;
using
testing
::
A
;
using
testing
::
Action
;
using
testing
::
AllOf
;
using
testing
::
AnyOf
;
using
testing
::
Assign
;
...
...
@@ -148,6 +150,8 @@ using testing::Invoke;
using
testing
::
InvokeArgument
;
using
testing
::
InvokeWithoutArgs
;
using
testing
::
IsNull
;
using
testing
::
IsSubsetOf
;
using
testing
::
IsSupersetOf
;
using
testing
::
Le
;
using
testing
::
Lt
;
using
testing
::
Matcher
;
...
...
@@ -592,6 +596,22 @@ TEST(LinkTest, TestMatcherElementsAreArray) {
ON_CALL
(
mock
,
VoidFromVector
(
ElementsAreArray
(
arr
))).
WillByDefault
(
Return
());
}
// Tests the linkage of the IsSubsetOf matcher.
TEST
(
LinkTest
,
TestMatcherIsSubsetOf
)
{
Mock
mock
;
char
arr
[]
=
{
'a'
,
'b'
};
ON_CALL
(
mock
,
VoidFromVector
(
IsSubsetOf
(
arr
))).
WillByDefault
(
Return
());
}
// Tests the linkage of the IsSupersetOf matcher.
TEST
(
LinkTest
,
TestMatcherIsSupersetOf
)
{
Mock
mock
;
char
arr
[]
=
{
'a'
,
'b'
};
ON_CALL
(
mock
,
VoidFromVector
(
IsSupersetOf
(
arr
))).
WillByDefault
(
Return
());
}
// Tests the linkage of the ContainerEq matcher.
TEST
(
LinkTest
,
TestMatcherContainerEq
)
{
Mock
mock
;
...
...
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