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
f5e1ce5b
Commit
f5e1ce5b
authored
Sep 16, 2009
by
zhanyong.wan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds new matcher Pair(). Replaces GMOCK_CHECK_ with GTEST_CHECK_ (by Vlad Losev).
parent
c53b3dca
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
219 additions
and
140 deletions
+219
-140
gmock-matchers.h
include/gmock/gmock-matchers.h
+101
-1
gmock-port.h
include/gmock/internal/gmock-port.h
+0
-50
gmock-spec-builders.cc
src/gmock-spec-builders.cc
+2
-2
gmock-matchers_test.cc
test/gmock-matchers_test.cc
+115
-29
gmock-port_test.cc
test/gmock-port_test.cc
+1
-58
No files found.
include/gmock/gmock-matchers.h
View file @
f5e1ce5b
...
...
@@ -1623,7 +1623,7 @@ struct CallableTraits<ResType(*)(ArgType)> {
typedef
ResType
(
*
StorageType
)(
ArgType
);
static
void
CheckIsValid
(
ResType
(
*
f
)(
ArgType
))
{
G
MOCK
_CHECK_
(
f
!=
NULL
)
G
TEST
_CHECK_
(
f
!=
NULL
)
<<
"NULL function pointer is passed into ResultOf()."
;
}
template
<
typename
T
>
...
...
@@ -1934,6 +1934,94 @@ class KeyMatcher {
const
M
matcher_for_key_
;
};
// Implements Pair(first_matcher, second_matcher) for the given argument pair
// type with its two matchers. See Pair() function below.
template
<
typename
PairType
>
class
PairMatcherImpl
:
public
MatcherInterface
<
PairType
>
{
public
:
typedef
GMOCK_REMOVE_CONST_
(
GMOCK_REMOVE_REFERENCE_
(
PairType
))
RawPairType
;
typedef
typename
RawPairType
::
first_type
FirstType
;
typedef
typename
RawPairType
::
second_type
SecondType
;
template
<
typename
FirstMatcher
,
typename
SecondMatcher
>
PairMatcherImpl
(
FirstMatcher
first_matcher
,
SecondMatcher
second_matcher
)
:
first_matcher_
(
testing
::
SafeMatcherCast
<
const
FirstType
&>
(
first_matcher
)),
second_matcher_
(
testing
::
SafeMatcherCast
<
const
SecondType
&>
(
second_matcher
))
{
}
// Returns true iff 'a_pair.first' matches first_matcher and 'a_pair.second'
// matches second_matcher.
virtual
bool
Matches
(
PairType
a_pair
)
const
{
return
first_matcher_
.
Matches
(
a_pair
.
first
)
&&
second_matcher_
.
Matches
(
a_pair
.
second
);
}
// Describes what this matcher does.
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"has a first field that "
;
first_matcher_
.
DescribeTo
(
os
);
*
os
<<
", and has a second field that "
;
second_matcher_
.
DescribeTo
(
os
);
}
// Describes what the negation of this matcher does.
virtual
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"has a first field that "
;
first_matcher_
.
DescribeNegationTo
(
os
);
*
os
<<
", or has a second field that "
;
second_matcher_
.
DescribeNegationTo
(
os
);
}
// Explains why 'a_pair' matches, or doesn't match, this matcher.
virtual
void
ExplainMatchResultTo
(
PairType
a_pair
,
::
std
::
ostream
*
os
)
const
{
::
std
::
stringstream
ss1
;
first_matcher_
.
ExplainMatchResultTo
(
a_pair
.
first
,
&
ss1
);
internal
::
string
s1
=
ss1
.
str
();
if
(
s1
!=
""
)
{
s1
=
"the first field "
+
s1
;
}
::
std
::
stringstream
ss2
;
second_matcher_
.
ExplainMatchResultTo
(
a_pair
.
second
,
&
ss2
);
internal
::
string
s2
=
ss2
.
str
();
if
(
s2
!=
""
)
{
s2
=
"the second field "
+
s2
;
}
*
os
<<
s1
;
if
(
s1
!=
""
&&
s2
!=
""
)
{
*
os
<<
", and "
;
}
*
os
<<
s2
;
}
private
:
const
Matcher
<
const
FirstType
&>
first_matcher_
;
const
Matcher
<
const
SecondType
&>
second_matcher_
;
};
// Implements polymorphic Pair(first_matcher, second_matcher).
template
<
typename
FirstMatcher
,
typename
SecondMatcher
>
class
PairMatcher
{
public
:
PairMatcher
(
FirstMatcher
first_matcher
,
SecondMatcher
second_matcher
)
:
first_matcher_
(
first_matcher
),
second_matcher_
(
second_matcher
)
{}
template
<
typename
PairType
>
operator
Matcher
<
PairType
>
()
const
{
return
MakeMatcher
(
new
PairMatcherImpl
<
PairType
>
(
first_matcher_
,
second_matcher_
));
}
private
:
const
FirstMatcher
first_matcher_
;
const
SecondMatcher
second_matcher_
;
};
// Implements ElementsAre() and ElementsAreArray().
template
<
typename
Container
>
class
ElementsAreMatcherImpl
:
public
MatcherInterface
<
Container
>
{
...
...
@@ -2632,6 +2720,18 @@ inline internal::KeyMatcher<M> Key(M inner_matcher) {
return
internal
::
KeyMatcher
<
M
>
(
inner_matcher
);
}
// Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field
// matches first_matcher and whose 'second' field matches second_matcher. For
// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used
// to match a std::map<int, string> that contains exactly one element whose key
// is >= 5 and whose value equals "foo".
template
<
typename
FirstMatcher
,
typename
SecondMatcher
>
inline
internal
::
PairMatcher
<
FirstMatcher
,
SecondMatcher
>
Pair
(
FirstMatcher
first_matcher
,
SecondMatcher
second_matcher
)
{
return
internal
::
PairMatcher
<
FirstMatcher
,
SecondMatcher
>
(
first_matcher
,
second_matcher
);
}
// Returns a predicate that is satisfied by anything that matches the
// given matcher.
template
<
typename
M
>
...
...
include/gmock/internal/gmock-port.h
View file @
f5e1ce5b
...
...
@@ -214,56 +214,6 @@ typedef ::wstring wstring;
typedef
::
std
::
wstring
wstring
;
#endif // GTEST_HAS_GLOBAL_WSTRING
// Prints the file location in the format native to the compiler.
inline
void
FormatFileLocation
(
const
char
*
file
,
int
line
,
::
std
::
ostream
*
os
)
{
if
(
file
==
NULL
)
file
=
"unknown file"
;
if
(
line
<
0
)
{
*
os
<<
file
<<
":"
;
}
else
{
#if _MSC_VER
*
os
<<
file
<<
"("
<<
line
<<
"):"
;
#else
*
os
<<
file
<<
":"
<<
line
<<
":"
;
#endif
}
}
// INTERNAL IMPLEMENTATION - DO NOT USE.
//
// GMOCK_CHECK_ is an all mode assert. It aborts the program if the condition
// is not satisfied.
// Synopsys:
// GMOCK_CHECK_(boolean_condition);
// or
// GMOCK_CHECK_(boolean_condition) << "Additional message";
//
// This checks the condition and if the condition is not satisfied
// it prints message about the condition violation, including the
// condition itself, plus additional message streamed into it, if any,
// and then it aborts the program. It aborts the program irrespective of
// whether it is built in the debug mode or not.
class
GMockCheckProvider
{
public
:
GMockCheckProvider
(
const
char
*
condition
,
const
char
*
file
,
int
line
)
{
FormatFileLocation
(
file
,
line
,
&::
std
::
cerr
);
::
std
::
cerr
<<
" ERROR: Condition "
<<
condition
<<
" failed. "
;
}
~
GMockCheckProvider
()
{
::
std
::
cerr
<<
::
std
::
endl
;
posix
::
Abort
();
}
::
std
::
ostream
&
GetStream
()
{
return
::
std
::
cerr
;
}
};
#define GMOCK_CHECK_(condition) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (condition) \
; \
else \
::testing::internal::GMockCheckProvider(\
#condition, __FILE__, __LINE__).GetStream()
}
// namespace internal
}
// namespace testing
...
...
src/gmock-spec-builders.cc
View file @
f5e1ce5b
...
...
@@ -203,8 +203,8 @@ class MockObjectRegistry {
// This can help the user identify the leaked object.
std
::
cout
<<
"
\n
"
;
const
MockObjectState
&
state
=
it
->
second
;
internal
::
FormatFileLocation
(
state
.
first_used_file
,
state
.
first_used_line
,
&
std
::
cout
);
std
::
cout
<<
internal
::
FormatFileLocation
(
state
.
first_used_file
,
state
.
first_used_line
);
std
::
cout
<<
" ERROR: this mock object"
;
if
(
state
.
first_used_test
!=
""
)
{
std
::
cout
<<
" (used in test "
<<
state
.
first_used_test_case
<<
"."
...
...
test/gmock-matchers_test.cc
View file @
f5e1ce5b
...
...
@@ -42,6 +42,7 @@
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
...
...
@@ -91,6 +92,7 @@ using testing::NanSensitiveFloatEq;
using
testing
::
Ne
;
using
testing
::
Not
;
using
testing
::
NotNull
;
using
testing
::
Pair
;
using
testing
::
Pointee
;
using
testing
::
PolymorphicMatcher
;
using
testing
::
Property
;
...
...
@@ -126,6 +128,35 @@ using testing::MatchesRegex;
using
testing
::
internal
::
RE
;
#endif // GMOCK_HAS_REGEX
// For testing ExplainMatchResultTo().
class
GreaterThanMatcher
:
public
MatcherInterface
<
int
>
{
public
:
explicit
GreaterThanMatcher
(
int
rhs
)
:
rhs_
(
rhs
)
{}
virtual
bool
Matches
(
int
lhs
)
const
{
return
lhs
>
rhs_
;
}
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"is greater than "
<<
rhs_
;
}
virtual
void
ExplainMatchResultTo
(
int
lhs
,
::
std
::
ostream
*
os
)
const
{
const
int
diff
=
lhs
-
rhs_
;
if
(
diff
>
0
)
{
*
os
<<
"is "
<<
diff
<<
" more than "
<<
rhs_
;
}
else
if
(
diff
==
0
)
{
*
os
<<
"is the same as "
<<
rhs_
;
}
else
{
*
os
<<
"is "
<<
-
diff
<<
" less than "
<<
rhs_
;
}
}
private
:
const
int
rhs_
;
};
Matcher
<
int
>
GreaterThan
(
int
n
)
{
return
MakeMatcher
(
new
GreaterThanMatcher
(
n
));
}
// Returns the description of the given matcher.
template
<
typename
T
>
string
Describe
(
const
Matcher
<
T
>&
m
)
{
...
...
@@ -899,6 +930,90 @@ TEST(KeyTest, InsideContainsUsingMultimap) {
EXPECT_THAT
(
container
,
Not
(
Contains
(
Key
(
3
))));
}
TEST
(
PairTest
,
Typing
)
{
// Test verifies the following type conversions can be compiled.
Matcher
<
const
std
::
pair
<
const
char
*
,
int
>&>
m1
=
Pair
(
"foo"
,
42
);
Matcher
<
const
std
::
pair
<
const
char
*
,
int
>
>
m2
=
Pair
(
"foo"
,
42
);
Matcher
<
std
::
pair
<
const
char
*
,
int
>
>
m3
=
Pair
(
"foo"
,
42
);
Matcher
<
std
::
pair
<
int
,
const
std
::
string
>
>
m4
=
Pair
(
25
,
"42"
);
Matcher
<
std
::
pair
<
const
std
::
string
,
int
>
>
m5
=
Pair
(
"25"
,
42
);
}
TEST
(
PairTest
,
CanDescribeSelf
)
{
Matcher
<
const
std
::
pair
<
std
::
string
,
int
>&>
m1
=
Pair
(
"foo"
,
42
);
EXPECT_EQ
(
"has a first field that is equal to
\"
foo
\"
"
", and has a second field that is equal to 42"
,
Describe
(
m1
));
EXPECT_EQ
(
"has a first field that is not equal to
\"
foo
\"
"
", or has a second field that is not equal to 42"
,
DescribeNegation
(
m1
));
// Double and triple negation (1 or 2 times not and description of negation).
Matcher
<
const
std
::
pair
<
int
,
int
>&>
m2
=
Not
(
Pair
(
Not
(
13
),
42
));
EXPECT_EQ
(
"has a first field that is not equal to 13"
", and has a second field that is equal to 42"
,
DescribeNegation
(
m2
));
}
TEST
(
PairTest
,
CanExplainMatchResultTo
)
{
const
Matcher
<
std
::
pair
<
int
,
int
>
>
m0
=
Pair
(
0
,
0
);
EXPECT_EQ
(
""
,
Explain
(
m0
,
std
::
make_pair
(
25
,
42
)));
const
Matcher
<
std
::
pair
<
int
,
int
>
>
m1
=
Pair
(
GreaterThan
(
0
),
0
);
EXPECT_EQ
(
"the first field is 25 more than 0"
,
Explain
(
m1
,
std
::
make_pair
(
25
,
42
)));
const
Matcher
<
std
::
pair
<
int
,
int
>
>
m2
=
Pair
(
0
,
GreaterThan
(
0
));
EXPECT_EQ
(
"the second field is 42 more than 0"
,
Explain
(
m2
,
std
::
make_pair
(
25
,
42
)));
const
Matcher
<
std
::
pair
<
int
,
int
>
>
m3
=
Pair
(
GreaterThan
(
0
),
GreaterThan
(
0
));
EXPECT_EQ
(
"the first field is 25 more than 0"
", and the second field is 42 more than 0"
,
Explain
(
m3
,
std
::
make_pair
(
25
,
42
)));
}
TEST
(
PairTest
,
MatchesCorrectly
)
{
std
::
pair
<
int
,
std
::
string
>
p
(
25
,
"foo"
);
// Both fields match.
EXPECT_THAT
(
p
,
Pair
(
25
,
"foo"
));
EXPECT_THAT
(
p
,
Pair
(
Ge
(
20
),
HasSubstr
(
"o"
)));
// 'first' doesnt' match, but 'second' matches.
EXPECT_THAT
(
p
,
Not
(
Pair
(
42
,
"foo"
)));
EXPECT_THAT
(
p
,
Not
(
Pair
(
Lt
(
25
),
"foo"
)));
// 'first' matches, but 'second' doesn't match.
EXPECT_THAT
(
p
,
Not
(
Pair
(
25
,
"bar"
)));
EXPECT_THAT
(
p
,
Not
(
Pair
(
25
,
Not
(
"foo"
))));
// Neither field matches.
EXPECT_THAT
(
p
,
Not
(
Pair
(
13
,
"bar"
)));
EXPECT_THAT
(
p
,
Not
(
Pair
(
Lt
(
13
),
HasSubstr
(
"a"
))));
}
TEST
(
PairTest
,
SafelyCastsInnerMatchers
)
{
Matcher
<
int
>
is_positive
=
Gt
(
0
);
Matcher
<
int
>
is_negative
=
Lt
(
0
);
std
::
pair
<
char
,
bool
>
p
(
'a'
,
true
);
EXPECT_THAT
(
p
,
Pair
(
is_positive
,
_
));
EXPECT_THAT
(
p
,
Not
(
Pair
(
is_negative
,
_
)));
EXPECT_THAT
(
p
,
Pair
(
_
,
is_positive
));
EXPECT_THAT
(
p
,
Not
(
Pair
(
_
,
is_negative
)));
}
TEST
(
PairTest
,
InsideContainsUsingMap
)
{
std
::
map
<
int
,
std
::
string
>
container
;
container
.
insert
(
std
::
make_pair
(
1
,
"foo"
));
container
.
insert
(
std
::
make_pair
(
2
,
"bar"
));
container
.
insert
(
std
::
make_pair
(
4
,
"baz"
));
EXPECT_THAT
(
container
,
Contains
(
Pair
(
1
,
"foo"
)));
EXPECT_THAT
(
container
,
Contains
(
Pair
(
1
,
_
)));
EXPECT_THAT
(
container
,
Contains
(
Pair
(
_
,
"foo"
)));
EXPECT_THAT
(
container
,
Not
(
Contains
(
Pair
(
3
,
_
))));
}
// Tests StartsWith(s).
TEST
(
StartsWithTest
,
MatchesStringWithGivenPrefix
)
{
...
...
@@ -2150,35 +2265,6 @@ TEST(PointeeTest, CanDescribeSelf) {
DescribeNegation
(
m
));
}
// For testing ExplainMatchResultTo().
class
GreaterThanMatcher
:
public
MatcherInterface
<
int
>
{
public
:
explicit
GreaterThanMatcher
(
int
rhs
)
:
rhs_
(
rhs
)
{}
virtual
bool
Matches
(
int
lhs
)
const
{
return
lhs
>
rhs_
;
}
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"is greater than "
<<
rhs_
;
}
virtual
void
ExplainMatchResultTo
(
int
lhs
,
::
std
::
ostream
*
os
)
const
{
const
int
diff
=
lhs
-
rhs_
;
if
(
diff
>
0
)
{
*
os
<<
"is "
<<
diff
<<
" more than "
<<
rhs_
;
}
else
if
(
diff
==
0
)
{
*
os
<<
"is the same as "
<<
rhs_
;
}
else
{
*
os
<<
"is "
<<
-
diff
<<
" less than "
<<
rhs_
;
}
}
private
:
const
int
rhs_
;
};
Matcher
<
int
>
GreaterThan
(
int
n
)
{
return
MakeMatcher
(
new
GreaterThanMatcher
(
n
));
}
TEST
(
PointeeTest
,
CanExplainMatchResult
)
{
const
Matcher
<
const
string
*>
m
=
Pointee
(
StartsWith
(
"Hi"
));
...
...
test/gmock-port_test.cc
View file @
f5e1ce5b
...
...
@@ -36,61 +36,4 @@
#include <gmock/internal/gmock-port.h>
#include <gtest/gtest.h>
TEST
(
GmockCheckSyntaxTest
,
BehavesLikeASingleStatement
)
{
if
(
false
)
GMOCK_CHECK_
(
false
)
<<
"This should never be executed; "
"It's a compilation test only."
;
if
(
true
)
GMOCK_CHECK_
(
true
);
else
;
if
(
false
)
;
else
GMOCK_CHECK_
(
true
)
<<
""
;
}
TEST
(
GmockCheckSyntaxTest
,
WorksWithSwitch
)
{
switch
(
0
)
{
case
1
:
break
;
default
:
GMOCK_CHECK_
(
true
);
}
switch
(
0
)
case
0
:
GMOCK_CHECK_
(
true
)
<<
"Check failed in switch case"
;
}
TEST
(
GmockCheckDeathTest
,
DiesWithCorrectOutputOnFailure
)
{
const
bool
a_false_condition
=
false
;
// MSVC and gcc use different formats to print source file locations.
// Google Mock's failure messages use the same format as used by the
// compiler, in order for the IDE to recognize them. Therefore we look
// for different patterns here depending on the compiler.
const
char
regex
[]
=
#ifdef _MSC_VER
"gmock-port_test
\\
.cc
\\
(
\\
d+
\\
):"
#else
"gmock-port_test
\\
.cc:[0-9]+"
#endif // _MSC_VER
".*a_false_condition.*Extra info"
;
EXPECT_DEATH_IF_SUPPORTED
(
GMOCK_CHECK_
(
a_false_condition
)
<<
"Extra info"
,
regex
);
}
#if GTEST_HAS_DEATH_TEST
TEST
(
GmockCheckDeathTest
,
LivesSilentlyOnSuccess
)
{
EXPECT_EXIT
({
GMOCK_CHECK_
(
true
)
<<
"Extra info"
;
::
std
::
cerr
<<
"Success
\n
"
;
exit
(
0
);
},
::
testing
::
ExitedWithCode
(
0
),
"Success"
);
}
#endif // GTEST_HAS_DEATH_TEST
// This file intentionally contains no test at this moment.
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