Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
1afe1c79
Commit
1afe1c79
authored
Jul 21, 2009
by
zhanyong.wan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds the ReturnArg<k>() action (by Tim Hockin); refactors gmock-matchers.h (by Zhanyong Wan).
parent
387bdd55
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
249 additions
and
444 deletions
+249
-444
gmock-generated-actions.h
include/gmock/gmock-generated-actions.h
+7
-0
gmock-generated-actions.h.pump
include/gmock/gmock-generated-actions.h.pump
+8
-1
gmock-generated-matchers.h
include/gmock/gmock-generated-matchers.h
+1
-221
gmock-generated-matchers.h.pump
include/gmock/gmock-generated-matchers.h.pump
+2
-222
gmock-matchers.h
include/gmock/gmock-matchers.h
+215
-0
gmock-generated-actions_test.cc
test/gmock-generated-actions_test.cc
+16
-0
No files found.
include/gmock/gmock-generated-actions.h
View file @
1afe1c79
...
@@ -2441,6 +2441,13 @@ ACTION_TEMPLATE(InvokeArgument,
...
@@ -2441,6 +2441,13 @@ ACTION_TEMPLATE(InvokeArgument,
::
std
::
tr1
::
get
<
k
>
(
args
),
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
p6
,
p7
,
p8
,
p9
);
::
std
::
tr1
::
get
<
k
>
(
args
),
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
p6
,
p7
,
p8
,
p9
);
}
}
// Action ReturnArg<k>() returns the k-th argument of the mock function.
ACTION_TEMPLATE
(
ReturnArg
,
HAS_1_TEMPLATE_PARAMS
(
int
,
k
),
AND_0_VALUE_PARAMS
())
{
return
std
::
tr1
::
get
<
k
>
(
args
);
}
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
// mock function to *pointer.
// mock function to *pointer.
ACTION_TEMPLATE
(
SaveArg
,
ACTION_TEMPLATE
(
SaveArg
,
...
...
include/gmock/gmock-generated-actions.h.pump
View file @
1afe1c79
$$
-*-
mode
:
c
++
;
-*-
$$
-*-
mode
:
c
++
;
-*-
$$
This
is
a
Pump
source
file
.
Please
use
Pump
to
convert
it
to
$$
This
is
a
Pump
source
file
.
Please
use
Pump
to
convert
it
to
$$
gmock
-
generated
-
variadic
-
actions
.
h
.
$$
gmock
-
generated
-
actions
.
h
.
$$
$$
$
var
n
=
10
$$
The
maximum
arity
we
support
.
$
var
n
=
10
$$
The
maximum
arity
we
support
.
$$
}}
This
meta
comment
fixes
auto
-
indentation
in
editors
.
$$
}}
This
meta
comment
fixes
auto
-
indentation
in
editors
.
...
@@ -940,6 +940,13 @@ ACTION_TEMPLATE(InvokeArgument,
...
@@ -940,6 +940,13 @@ ACTION_TEMPLATE(InvokeArgument,
]]
]]
// Action ReturnArg<k>() returns the k-th argument of the mock function.
ACTION_TEMPLATE
(
ReturnArg
,
HAS_1_TEMPLATE_PARAMS
(
int
,
k
),
AND_0_VALUE_PARAMS
())
{
return
std
::
tr1
::
get
<
k
>
(
args
);
}
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
// mock function to *pointer.
// mock function to *pointer.
ACTION_TEMPLATE
(
SaveArg
,
ACTION_TEMPLATE
(
SaveArg
,
...
...
include/gmock/gmock-generated-matchers.h
View file @
1afe1c79
...
@@ -290,163 +290,7 @@ class ArgsMatcher {
...
@@ -290,163 +290,7 @@ class ArgsMatcher {
const
InnerMatcher
inner_matcher_
;
const
InnerMatcher
inner_matcher_
;
};
};
// Implements ElementsAre() and ElementsAreArray().
// Implements ElementsAre() of 1-10 arguments.
template
<
typename
Container
>
class
ElementsAreMatcherImpl
:
public
MatcherInterface
<
Container
>
{
public
:
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
Container
))
RawContainer
;
typedef
internal
::
StlContainerView
<
RawContainer
>
View
;
typedef
typename
View
::
type
StlContainer
;
typedef
typename
View
::
const_reference
StlContainerReference
;
typedef
typename
StlContainer
::
value_type
Element
;
// Constructs the matcher from a sequence of element values or
// element matchers.
template
<
typename
InputIter
>
ElementsAreMatcherImpl
(
InputIter
first
,
size_t
count
)
{
matchers_
.
reserve
(
count
);
InputIter
it
=
first
;
for
(
size_t
i
=
0
;
i
!=
count
;
++
i
,
++
it
)
{
matchers_
.
push_back
(
MatcherCast
<
const
Element
&>
(
*
it
));
}
}
// Returns true iff 'container' matches.
virtual
bool
Matches
(
Container
container
)
const
{
StlContainerReference
stl_container
=
View
::
ConstReference
(
container
);
if
(
stl_container
.
size
()
!=
count
())
return
false
;
typename
StlContainer
::
const_iterator
it
=
stl_container
.
begin
();
for
(
size_t
i
=
0
;
i
!=
count
();
++
it
,
++
i
)
{
if
(
!
matchers_
[
i
].
Matches
(
*
it
))
return
false
;
}
return
true
;
}
// Describes what this matcher does.
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
if
(
count
()
==
0
)
{
*
os
<<
"is empty"
;
}
else
if
(
count
()
==
1
)
{
*
os
<<
"has 1 element that "
;
matchers_
[
0
].
DescribeTo
(
os
);
}
else
{
*
os
<<
"has "
<<
Elements
(
count
())
<<
" where
\n
"
;
for
(
size_t
i
=
0
;
i
!=
count
();
++
i
)
{
*
os
<<
"element "
<<
i
<<
" "
;
matchers_
[
i
].
DescribeTo
(
os
);
if
(
i
+
1
<
count
())
{
*
os
<<
",
\n
"
;
}
}
}
}
// Describes what the negation of this matcher does.
virtual
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
if
(
count
()
==
0
)
{
*
os
<<
"is not empty"
;
return
;
}
*
os
<<
"does not have "
<<
Elements
(
count
())
<<
", or
\n
"
;
for
(
size_t
i
=
0
;
i
!=
count
();
++
i
)
{
*
os
<<
"element "
<<
i
<<
" "
;
matchers_
[
i
].
DescribeNegationTo
(
os
);
if
(
i
+
1
<
count
())
{
*
os
<<
", or
\n
"
;
}
}
}
// Explains why 'container' matches, or doesn't match, this matcher.
virtual
void
ExplainMatchResultTo
(
Container
container
,
::
std
::
ostream
*
os
)
const
{
StlContainerReference
stl_container
=
View
::
ConstReference
(
container
);
if
(
Matches
(
container
))
{
// We need to explain why *each* element matches (the obvious
// ones can be skipped).
bool
reason_printed
=
false
;
typename
StlContainer
::
const_iterator
it
=
stl_container
.
begin
();
for
(
size_t
i
=
0
;
i
!=
count
();
++
it
,
++
i
)
{
::
std
::
stringstream
ss
;
matchers_
[
i
].
ExplainMatchResultTo
(
*
it
,
&
ss
);
const
string
s
=
ss
.
str
();
if
(
!
s
.
empty
())
{
if
(
reason_printed
)
{
*
os
<<
",
\n
"
;
}
*
os
<<
"element "
<<
i
<<
" "
<<
s
;
reason_printed
=
true
;
}
}
}
else
{
// We need to explain why the container doesn't match.
const
size_t
actual_count
=
stl_container
.
size
();
if
(
actual_count
!=
count
())
{
// 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
)
{
*
os
<<
"has "
<<
Elements
(
actual_count
);
}
return
;
}
// The container has the right size but at least one element
// doesn't match expectation. We need to find this element and
// explain why it doesn't match.
typename
StlContainer
::
const_iterator
it
=
stl_container
.
begin
();
for
(
size_t
i
=
0
;
i
!=
count
();
++
it
,
++
i
)
{
if
(
matchers_
[
i
].
Matches
(
*
it
))
{
continue
;
}
*
os
<<
"element "
<<
i
<<
" doesn't match"
;
::
std
::
stringstream
ss
;
matchers_
[
i
].
ExplainMatchResultTo
(
*
it
,
&
ss
);
const
string
s
=
ss
.
str
();
if
(
!
s
.
empty
())
{
*
os
<<
" ("
<<
s
<<
")"
;
}
return
;
}
}
}
private
:
static
Message
Elements
(
size_t
count
)
{
return
Message
()
<<
count
<<
(
count
==
1
?
" element"
:
" elements"
);
}
size_t
count
()
const
{
return
matchers_
.
size
();
}
std
::
vector
<
Matcher
<
const
Element
&>
>
matchers_
;
};
// Implements ElementsAre() of 0-10 arguments.
class
ElementsAreMatcher0
{
public
:
ElementsAreMatcher0
()
{}
template
<
typename
Container
>
operator
Matcher
<
Container
>
()
const
{
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
Container
))
RawContainer
;
typedef
typename
internal
::
StlContainerView
<
RawContainer
>::
type
::
value_type
Element
;
const
Matcher
<
const
Element
&>*
const
matchers
=
NULL
;
return
MakeMatcher
(
new
ElementsAreMatcherImpl
<
Container
>
(
matchers
,
0
));
}
};
template
<
typename
T1
>
template
<
typename
T1
>
class
ElementsAreMatcher1
{
class
ElementsAreMatcher1
{
...
@@ -788,28 +632,6 @@ class ElementsAreMatcher10 {
...
@@ -788,28 +632,6 @@ class ElementsAreMatcher10 {
const
T10
&
e10_
;
const
T10
&
e10_
;
};
};
// Implements ElementsAreArray().
template
<
typename
T
>
class
ElementsAreArrayMatcher
{
public
:
ElementsAreArrayMatcher
(
const
T
*
first
,
size_t
count
)
:
first_
(
first
),
count_
(
count
)
{}
template
<
typename
Container
>
operator
Matcher
<
Container
>
()
const
{
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
Container
))
RawContainer
;
typedef
typename
internal
::
StlContainerView
<
RawContainer
>::
type
::
value_type
Element
;
return
MakeMatcher
(
new
ElementsAreMatcherImpl
<
Container
>
(
first_
,
count_
));
}
private
:
const
T
*
const
first_
;
const
size_t
count_
;
};
}
// namespace internal
}
// namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
...
@@ -1169,48 +991,6 @@ ElementsAreArray(const T (&array)[N]) {
...
@@ -1169,48 +991,6 @@ ElementsAreArray(const T (&array)[N]) {
// 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.
namespace
testing
{
namespace
internal
{
// Constants denoting interpolations in a matcher description string.
const
int
kTupleInterpolation
=
-
1
;
// "%(*)s"
const
int
kPercentInterpolation
=
-
2
;
// "%%"
const
int
kInvalidInterpolation
=
-
3
;
// "%" followed by invalid text
// Records the location and content of an interpolation.
struct
Interpolation
{
Interpolation
(
const
char
*
start
,
const
char
*
end
,
int
param
)
:
start_pos
(
start
),
end_pos
(
end
),
param_index
(
param
)
{}
// Points to the start of the interpolation (the '%' character).
const
char
*
start_pos
;
// Points to the first character after the interpolation.
const
char
*
end_pos
;
// 0-based index of the interpolated matcher parameter;
// kTupleInterpolation for "%(*)s"; kPercentInterpolation for "%%".
int
param_index
;
};
typedef
::
std
::
vector
<
Interpolation
>
Interpolations
;
// Parses a matcher description string and returns a vector of
// interpolations that appear in the string; generates non-fatal
// failures iff 'description' is an invalid matcher description.
// 'param_names' is a NULL-terminated array of parameter names in the
// order they appear in the MATCHER_P*() parameter list.
Interpolations
ValidateMatcherDescription
(
const
char
*
param_names
[],
const
char
*
description
);
// Returns the actual matcher description, given the matcher name,
// user-supplied description template string, interpolations in the
// string, and the printed values of the matcher parameters.
string
FormatMatcherDescription
(
const
char
*
matcher_name
,
const
char
*
description
,
const
Interpolations
&
interp
,
const
Strings
&
param_values
);
}
// namespace internal
}
// namespace testing
#define MATCHER(name, description)\
#define MATCHER(name, description)\
class name##Matcher {\
class name##Matcher {\
public:\
public:\
...
...
include/gmock/gmock-generated-matchers.h.pump
View file @
1afe1c79
$$
-*-
mode
:
c
++
;
-*-
$$
-*-
mode
:
c
++
;
-*-
$$
This
is
a
Pump
source
file
.
Please
use
Pump
to
convert
it
to
$$
This
is
a
Pump
source
file
.
Please
use
Pump
to
convert
it
to
$$
gmock
-
generated
-
variadic
-
actions
.
h
.
$$
gmock
-
generated
-
actions
.
h
.
$$
$$
$
var
n
=
10
$$
The
maximum
arity
we
support
.
$
var
n
=
10
$$
The
maximum
arity
we
support
.
$$
}}
This
line
fixes
auto
-
indentation
of
the
following
code
in
Emacs
.
$$
}}
This
line
fixes
auto
-
indentation
of
the
following
code
in
Emacs
.
...
@@ -173,163 +173,7 @@ class ArgsMatcher {
...
@@ -173,163 +173,7 @@ class ArgsMatcher {
const
InnerMatcher
inner_matcher_
;
const
InnerMatcher
inner_matcher_
;
};
};
// Implements ElementsAre() and ElementsAreArray().
// Implements ElementsAre() of 1-$n arguments.
template
<
typename
Container
>
class
ElementsAreMatcherImpl
:
public
MatcherInterface
<
Container
>
{
public
:
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
Container
))
RawContainer
;
typedef
internal
::
StlContainerView
<
RawContainer
>
View
;
typedef
typename
View
::
type
StlContainer
;
typedef
typename
View
::
const_reference
StlContainerReference
;
typedef
typename
StlContainer
::
value_type
Element
;
// Constructs the matcher from a sequence of element values or
// element matchers.
template
<
typename
InputIter
>
ElementsAreMatcherImpl
(
InputIter
first
,
size_t
count
)
{
matchers_
.
reserve
(
count
);
InputIter
it
=
first
;
for
(
size_t
i
=
0
;
i
!=
count
;
++
i
,
++
it
)
{
matchers_
.
push_back
(
MatcherCast
<
const
Element
&>
(
*
it
));
}
}
// Returns true iff 'container' matches.
virtual
bool
Matches
(
Container
container
)
const
{
StlContainerReference
stl_container
=
View
::
ConstReference
(
container
);
if
(
stl_container
.
size
()
!=
count
())
return
false
;
typename
StlContainer
::
const_iterator
it
=
stl_container
.
begin
();
for
(
size_t
i
=
0
;
i
!=
count
();
++
it
,
++
i
)
{
if
(
!
matchers_
[
i
].
Matches
(
*
it
))
return
false
;
}
return
true
;
}
// Describes what this matcher does.
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
if
(
count
()
==
0
)
{
*
os
<<
"is empty"
;
}
else
if
(
count
()
==
1
)
{
*
os
<<
"has 1 element that "
;
matchers_
[
0
].
DescribeTo
(
os
);
}
else
{
*
os
<<
"has "
<<
Elements
(
count
())
<<
" where
\n
"
;
for
(
size_t
i
=
0
;
i
!=
count
();
++
i
)
{
*
os
<<
"element "
<<
i
<<
" "
;
matchers_
[
i
].
DescribeTo
(
os
);
if
(
i
+
1
<
count
())
{
*
os
<<
",
\n
"
;
}
}
}
}
// Describes what the negation of this matcher does.
virtual
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
if
(
count
()
==
0
)
{
*
os
<<
"is not empty"
;
return
;
}
*
os
<<
"does not have "
<<
Elements
(
count
())
<<
", or
\n
"
;
for
(
size_t
i
=
0
;
i
!=
count
();
++
i
)
{
*
os
<<
"element "
<<
i
<<
" "
;
matchers_
[
i
].
DescribeNegationTo
(
os
);
if
(
i
+
1
<
count
())
{
*
os
<<
", or
\n
"
;
}
}
}
// Explains why 'container' matches, or doesn't match, this matcher.
virtual
void
ExplainMatchResultTo
(
Container
container
,
::
std
::
ostream
*
os
)
const
{
StlContainerReference
stl_container
=
View
::
ConstReference
(
container
);
if
(
Matches
(
container
))
{
// We need to explain why *each* element matches (the obvious
// ones can be skipped).
bool
reason_printed
=
false
;
typename
StlContainer
::
const_iterator
it
=
stl_container
.
begin
();
for
(
size_t
i
=
0
;
i
!=
count
();
++
it
,
++
i
)
{
::
std
::
stringstream
ss
;
matchers_
[
i
].
ExplainMatchResultTo
(
*
it
,
&
ss
);
const
string
s
=
ss
.
str
();
if
(
!
s
.
empty
())
{
if
(
reason_printed
)
{
*
os
<<
",
\n
"
;
}
*
os
<<
"element "
<<
i
<<
" "
<<
s
;
reason_printed
=
true
;
}
}
}
else
{
// We need to explain why the container doesn't match.
const
size_t
actual_count
=
stl_container
.
size
();
if
(
actual_count
!=
count
())
{
// 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
)
{
*
os
<<
"has "
<<
Elements
(
actual_count
);
}
return
;
}
// The container has the right size but at least one element
// doesn't match expectation. We need to find this element and
// explain why it doesn't match.
typename
StlContainer
::
const_iterator
it
=
stl_container
.
begin
();
for
(
size_t
i
=
0
;
i
!=
count
();
++
it
,
++
i
)
{
if
(
matchers_
[
i
].
Matches
(
*
it
))
{
continue
;
}
*
os
<<
"element "
<<
i
<<
" doesn't match"
;
::
std
::
stringstream
ss
;
matchers_
[
i
].
ExplainMatchResultTo
(
*
it
,
&
ss
);
const
string
s
=
ss
.
str
();
if
(
!
s
.
empty
())
{
*
os
<<
" ("
<<
s
<<
")"
;
}
return
;
}
}
}
private
:
static
Message
Elements
(
size_t
count
)
{
return
Message
()
<<
count
<<
(
count
==
1
?
" element"
:
" elements"
);
}
size_t
count
()
const
{
return
matchers_
.
size
();
}
std
::
vector
<
Matcher
<
const
Element
&>
>
matchers_
;
};
// Implements ElementsAre() of 0-10 arguments.
class
ElementsAreMatcher0
{
public
:
ElementsAreMatcher0
()
{}
template
<
typename
Container
>
operator
Matcher
<
Container
>
()
const
{
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
Container
))
RawContainer
;
typedef
typename
internal
::
StlContainerView
<
RawContainer
>::
type
::
value_type
Element
;
const
Matcher
<
const
Element
&>*
const
matchers
=
NULL
;
return
MakeMatcher
(
new
ElementsAreMatcherImpl
<
Container
>
(
matchers
,
0
));
}
};
$
range
i
1.
.
n
$
range
i
1.
.
n
...
@@ -369,28 +213,6 @@ $for j [[
...
@@ -369,28 +213,6 @@ $for j [[
]]
]]
// Implements ElementsAreArray().
template
<
typename
T
>
class
ElementsAreArrayMatcher
{
public
:
ElementsAreArrayMatcher
(
const
T
*
first
,
size_t
count
)
:
first_
(
first
),
count_
(
count
)
{}
template
<
typename
Container
>
operator
Matcher
<
Container
>
()
const
{
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
Container
))
RawContainer
;
typedef
typename
internal
::
StlContainerView
<
RawContainer
>::
type
::
value_type
Element
;
return
MakeMatcher
(
new
ElementsAreMatcherImpl
<
Container
>
(
first_
,
count_
));
}
private
:
const
T
*
const
first_
;
const
size_t
count_
;
};
}
// namespace internal
}
// namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
...
@@ -625,48 +447,6 @@ $$ // show up in the generated code.
...
@@ -625,48 +447,6 @@ $$ // show up in the generated code.
// 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.
namespace
testing
{
namespace
internal
{
// Constants denoting interpolations in a matcher description string.
const
int
kTupleInterpolation
=
-
1
;
// "%(*)s"
const
int
kPercentInterpolation
=
-
2
;
// "%%"
const
int
kInvalidInterpolation
=
-
3
;
// "%" followed by invalid text
// Records the location and content of an interpolation.
struct
Interpolation
{
Interpolation
(
const
char
*
start
,
const
char
*
end
,
int
param
)
:
start_pos
(
start
),
end_pos
(
end
),
param_index
(
param
)
{}
// Points to the start of the interpolation (the '%' character).
const
char
*
start_pos
;
// Points to the first character after the interpolation.
const
char
*
end_pos
;
// 0-based index of the interpolated matcher parameter;
// kTupleInterpolation for "%(*)s"; kPercentInterpolation for "%%".
int
param_index
;
};
typedef
::
std
::
vector
<
Interpolation
>
Interpolations
;
// Parses a matcher description string and returns a vector of
// interpolations that appear in the string; generates non-fatal
// failures iff 'description' is an invalid matcher description.
// 'param_names' is a NULL-terminated array of parameter names in the
// order they appear in the MATCHER_P*() parameter list.
Interpolations
ValidateMatcherDescription
(
const
char
*
param_names
[],
const
char
*
description
);
// Returns the actual matcher description, given the matcher name,
// user-supplied description template string, interpolations in the
// string, and the printed values of the matcher parameters.
string
FormatMatcherDescription
(
const
char
*
matcher_name
,
const
char
*
description
,
const
Interpolations
&
interp
,
const
Strings
&
param_values
);
}
// namespace internal
}
// namespace testing
$
range
i
0.
.
n
$
range
i
0.
.
n
$
for
i
$
for
i
...
...
include/gmock/gmock-matchers.h
View file @
1afe1c79
...
@@ -1925,6 +1925,221 @@ class KeyMatcher {
...
@@ -1925,6 +1925,221 @@ class KeyMatcher {
const
M
matcher_for_key_
;
const
M
matcher_for_key_
;
};
};
// Implements ElementsAre() and ElementsAreArray().
template
<
typename
Container
>
class
ElementsAreMatcherImpl
:
public
MatcherInterface
<
Container
>
{
public
:
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
Container
))
RawContainer
;
typedef
internal
::
StlContainerView
<
RawContainer
>
View
;
typedef
typename
View
::
type
StlContainer
;
typedef
typename
View
::
const_reference
StlContainerReference
;
typedef
typename
StlContainer
::
value_type
Element
;
// Constructs the matcher from a sequence of element values or
// element matchers.
template
<
typename
InputIter
>
ElementsAreMatcherImpl
(
InputIter
first
,
size_t
count
)
{
matchers_
.
reserve
(
count
);
InputIter
it
=
first
;
for
(
size_t
i
=
0
;
i
!=
count
;
++
i
,
++
it
)
{
matchers_
.
push_back
(
MatcherCast
<
const
Element
&>
(
*
it
));
}
}
// Returns true iff 'container' matches.
virtual
bool
Matches
(
Container
container
)
const
{
StlContainerReference
stl_container
=
View
::
ConstReference
(
container
);
if
(
stl_container
.
size
()
!=
count
())
return
false
;
typename
StlContainer
::
const_iterator
it
=
stl_container
.
begin
();
for
(
size_t
i
=
0
;
i
!=
count
();
++
it
,
++
i
)
{
if
(
!
matchers_
[
i
].
Matches
(
*
it
))
return
false
;
}
return
true
;
}
// Describes what this matcher does.
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
if
(
count
()
==
0
)
{
*
os
<<
"is empty"
;
}
else
if
(
count
()
==
1
)
{
*
os
<<
"has 1 element that "
;
matchers_
[
0
].
DescribeTo
(
os
);
}
else
{
*
os
<<
"has "
<<
Elements
(
count
())
<<
" where
\n
"
;
for
(
size_t
i
=
0
;
i
!=
count
();
++
i
)
{
*
os
<<
"element "
<<
i
<<
" "
;
matchers_
[
i
].
DescribeTo
(
os
);
if
(
i
+
1
<
count
())
{
*
os
<<
",
\n
"
;
}
}
}
}
// Describes what the negation of this matcher does.
virtual
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
if
(
count
()
==
0
)
{
*
os
<<
"is not empty"
;
return
;
}
*
os
<<
"does not have "
<<
Elements
(
count
())
<<
", or
\n
"
;
for
(
size_t
i
=
0
;
i
!=
count
();
++
i
)
{
*
os
<<
"element "
<<
i
<<
" "
;
matchers_
[
i
].
DescribeNegationTo
(
os
);
if
(
i
+
1
<
count
())
{
*
os
<<
", or
\n
"
;
}
}
}
// Explains why 'container' matches, or doesn't match, this matcher.
virtual
void
ExplainMatchResultTo
(
Container
container
,
::
std
::
ostream
*
os
)
const
{
StlContainerReference
stl_container
=
View
::
ConstReference
(
container
);
if
(
Matches
(
container
))
{
// We need to explain why *each* element matches (the obvious
// ones can be skipped).
bool
reason_printed
=
false
;
typename
StlContainer
::
const_iterator
it
=
stl_container
.
begin
();
for
(
size_t
i
=
0
;
i
!=
count
();
++
it
,
++
i
)
{
::
std
::
stringstream
ss
;
matchers_
[
i
].
ExplainMatchResultTo
(
*
it
,
&
ss
);
const
string
s
=
ss
.
str
();
if
(
!
s
.
empty
())
{
if
(
reason_printed
)
{
*
os
<<
",
\n
"
;
}
*
os
<<
"element "
<<
i
<<
" "
<<
s
;
reason_printed
=
true
;
}
}
}
else
{
// We need to explain why the container doesn't match.
const
size_t
actual_count
=
stl_container
.
size
();
if
(
actual_count
!=
count
())
{
// 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
)
{
*
os
<<
"has "
<<
Elements
(
actual_count
);
}
return
;
}
// The container has the right size but at least one element
// doesn't match expectation. We need to find this element and
// explain why it doesn't match.
typename
StlContainer
::
const_iterator
it
=
stl_container
.
begin
();
for
(
size_t
i
=
0
;
i
!=
count
();
++
it
,
++
i
)
{
if
(
matchers_
[
i
].
Matches
(
*
it
))
{
continue
;
}
*
os
<<
"element "
<<
i
<<
" doesn't match"
;
::
std
::
stringstream
ss
;
matchers_
[
i
].
ExplainMatchResultTo
(
*
it
,
&
ss
);
const
string
s
=
ss
.
str
();
if
(
!
s
.
empty
())
{
*
os
<<
" ("
<<
s
<<
")"
;
}
return
;
}
}
}
private
:
static
Message
Elements
(
size_t
count
)
{
return
Message
()
<<
count
<<
(
count
==
1
?
" element"
:
" elements"
);
}
size_t
count
()
const
{
return
matchers_
.
size
();
}
std
::
vector
<
Matcher
<
const
Element
&>
>
matchers_
;
};
// Implements ElementsAre() of 0 arguments.
class
ElementsAreMatcher0
{
public
:
ElementsAreMatcher0
()
{}
template
<
typename
Container
>
operator
Matcher
<
Container
>
()
const
{
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
Container
))
RawContainer
;
typedef
typename
internal
::
StlContainerView
<
RawContainer
>::
type
::
value_type
Element
;
const
Matcher
<
const
Element
&>*
const
matchers
=
NULL
;
return
MakeMatcher
(
new
ElementsAreMatcherImpl
<
Container
>
(
matchers
,
0
));
}
};
// Implements ElementsAreArray().
template
<
typename
T
>
class
ElementsAreArrayMatcher
{
public
:
ElementsAreArrayMatcher
(
const
T
*
first
,
size_t
count
)
:
first_
(
first
),
count_
(
count
)
{}
template
<
typename
Container
>
operator
Matcher
<
Container
>
()
const
{
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
Container
))
RawContainer
;
typedef
typename
internal
::
StlContainerView
<
RawContainer
>::
type
::
value_type
Element
;
return
MakeMatcher
(
new
ElementsAreMatcherImpl
<
Container
>
(
first_
,
count_
));
}
private
:
const
T
*
const
first_
;
const
size_t
count_
;
};
// Constants denoting interpolations in a matcher description string.
const
int
kTupleInterpolation
=
-
1
;
// "%(*)s"
const
int
kPercentInterpolation
=
-
2
;
// "%%"
const
int
kInvalidInterpolation
=
-
3
;
// "%" followed by invalid text
// Records the location and content of an interpolation.
struct
Interpolation
{
Interpolation
(
const
char
*
start
,
const
char
*
end
,
int
param
)
:
start_pos
(
start
),
end_pos
(
end
),
param_index
(
param
)
{}
// Points to the start of the interpolation (the '%' character).
const
char
*
start_pos
;
// Points to the first character after the interpolation.
const
char
*
end_pos
;
// 0-based index of the interpolated matcher parameter;
// kTupleInterpolation for "%(*)s"; kPercentInterpolation for "%%".
int
param_index
;
};
typedef
::
std
::
vector
<
Interpolation
>
Interpolations
;
// Parses a matcher description string and returns a vector of
// interpolations that appear in the string; generates non-fatal
// failures iff 'description' is an invalid matcher description.
// 'param_names' is a NULL-terminated array of parameter names in the
// order they appear in the MATCHER_P*() parameter list.
Interpolations
ValidateMatcherDescription
(
const
char
*
param_names
[],
const
char
*
description
);
// Returns the actual matcher description, given the matcher name,
// user-supplied description template string, interpolations in the
// string, and the printed values of the matcher parameters.
string
FormatMatcherDescription
(
const
char
*
matcher_name
,
const
char
*
description
,
const
Interpolations
&
interp
,
const
Strings
&
param_values
);
}
// namespace internal
}
// namespace internal
// Implements MatcherCast().
// Implements MatcherCast().
...
...
test/gmock-generated-actions_test.cc
View file @
1afe1c79
...
@@ -59,6 +59,7 @@ using testing::DoAll;
...
@@ -59,6 +59,7 @@ using testing::DoAll;
using
testing
::
Invoke
;
using
testing
::
Invoke
;
using
testing
::
InvokeArgument
;
using
testing
::
InvokeArgument
;
using
testing
::
Return
;
using
testing
::
Return
;
using
testing
::
ReturnArg
;
using
testing
::
ReturnNew
;
using
testing
::
ReturnNew
;
using
testing
::
SaveArg
;
using
testing
::
SaveArg
;
using
testing
::
SetArgReferee
;
using
testing
::
SetArgReferee
;
...
@@ -1382,6 +1383,21 @@ TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {
...
@@ -1382,6 +1383,21 @@ TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {
EXPECT_EQ
(
55
,
a
.
Perform
(
empty
));
EXPECT_EQ
(
55
,
a
.
Perform
(
empty
));
}
}
TEST
(
ReturnArgActionTest
,
WorksForOneArgIntArg0
)
{
const
Action
<
int
(
int
)
>
a
=
ReturnArg
<
0
>
();
EXPECT_EQ
(
5
,
a
.
Perform
(
make_tuple
(
5
)));
}
TEST
(
ReturnArgActionTest
,
WorksForMultiArgBoolArg0
)
{
const
Action
<
bool
(
bool
,
bool
,
bool
)
>
a
=
ReturnArg
<
0
>
();
EXPECT_TRUE
(
a
.
Perform
(
make_tuple
(
true
,
false
,
false
)));
}
TEST
(
ReturnArgActionTest
,
WorksForMultiArgStringArg2
)
{
const
Action
<
string
(
int
,
int
,
string
,
int
)
>
a
=
ReturnArg
<
2
>
();
EXPECT_EQ
(
"seven"
,
a
.
Perform
(
make_tuple
(
5
,
6
,
string
(
"seven"
),
8
)));
}
TEST
(
SaveArgActionTest
,
WorksForSameType
)
{
TEST
(
SaveArgActionTest
,
WorksForSameType
)
{
int
result
=
0
;
int
result
=
0
;
const
Action
<
void
(
int
n
)
>
a1
=
SaveArg
<
0
>
(
&
result
);
const
Action
<
void
(
int
n
)
>
a1
=
SaveArg
<
0
>
(
&
result
);
...
...
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