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
f5e1ce5b
Commit
f5e1ce5b
authored
Sep 16, 2009
by
zhanyong.wan
Browse files
Adds new matcher Pair(). Replaces GMOCK_CHECK_ with GTEST_CHECK_ (by Vlad Losev).
parent
c53b3dca
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
219 additions
and
140 deletions
+219
-140
include/gmock/gmock-matchers.h
include/gmock/gmock-matchers.h
+101
-1
include/gmock/internal/gmock-port.h
include/gmock/internal/gmock-port.h
+0
-50
src/gmock-spec-builders.cc
src/gmock-spec-builders.cc
+2
-2
test/gmock-matchers_test.cc
test/gmock-matchers_test.cc
+115
-29
test/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