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
41b9b0b5
Commit
41b9b0b5
authored
Jul 01, 2009
by
zhanyong.wan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implements Expectation, ExpectationSet, and After for specifying expectation orders.
parent
4019819d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
336 additions
and
20 deletions
+336
-20
gmock-spec-builders.h
include/gmock/gmock-spec-builders.h
+0
-0
gmock-spec-builders.cc
src/gmock-spec-builders.cc
+16
-18
gmock-spec-builders_test.cc
test/gmock-spec-builders_test.cc
+320
-2
No files found.
include/gmock/gmock-spec-builders.h
View file @
41b9b0b5
This diff is collapsed.
Click to expand it.
src/gmock-spec-builders.cc
View file @
41b9b0b5
...
@@ -82,11 +82,9 @@ void ExpectationBase::RetireAllPreRequisites() {
...
@@ -82,11 +82,9 @@ void ExpectationBase::RetireAllPreRequisites() {
return
;
return
;
}
}
for
(
ExpectationBaseSet
::
const_iterator
it
=
for
(
ExpectationSet
::
const_iterator
it
=
immediate_prerequisites_
.
begin
();
immediate_prerequisites_
.
begin
();
it
!=
immediate_prerequisites_
.
end
();
++
it
)
{
it
!=
immediate_prerequisites_
.
end
();
ExpectationBase
*
const
prerequisite
=
it
->
expectation_base
().
get
();
++
it
)
{
ExpectationBase
*
const
prerequisite
=
(
*
it
).
get
();
if
(
!
prerequisite
->
is_retired
())
{
if
(
!
prerequisite
->
is_retired
())
{
prerequisite
->
RetireAllPreRequisites
();
prerequisite
->
RetireAllPreRequisites
();
prerequisite
->
Retire
();
prerequisite
->
Retire
();
...
@@ -99,10 +97,10 @@ void ExpectationBase::RetireAllPreRequisites() {
...
@@ -99,10 +97,10 @@ void ExpectationBase::RetireAllPreRequisites() {
// L >= g_gmock_mutex
// L >= g_gmock_mutex
bool
ExpectationBase
::
AllPrerequisitesAreSatisfied
()
const
{
bool
ExpectationBase
::
AllPrerequisitesAreSatisfied
()
const
{
g_gmock_mutex
.
AssertHeld
();
g_gmock_mutex
.
AssertHeld
();
for
(
Expectation
Base
Set
::
const_iterator
it
=
immediate_prerequisites_
.
begin
();
for
(
ExpectationSet
::
const_iterator
it
=
immediate_prerequisites_
.
begin
();
it
!=
immediate_prerequisites_
.
end
();
++
it
)
{
it
!=
immediate_prerequisites_
.
end
();
++
it
)
{
if
(
!
(
*
it
)
->
IsSatisfied
(
)
||
if
(
!
(
it
->
expectation_base
()
->
IsSatisfied
()
)
||
!
(
*
it
)
->
AllPrerequisitesAreSatisfied
(
))
!
(
it
->
expectation_base
()
->
AllPrerequisitesAreSatisfied
()
))
return
false
;
return
false
;
}
}
return
true
;
return
true
;
...
@@ -111,21 +109,21 @@ bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
...
@@ -111,21 +109,21 @@ bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
// Adds unsatisfied pre-requisites of this expectation to 'result'.
// Adds unsatisfied pre-requisites of this expectation to 'result'.
// L >= g_gmock_mutex
// L >= g_gmock_mutex
void
ExpectationBase
::
FindUnsatisfiedPrerequisites
(
void
ExpectationBase
::
FindUnsatisfiedPrerequisites
(
Expectation
Base
Set
*
result
)
const
{
ExpectationSet
*
result
)
const
{
g_gmock_mutex
.
AssertHeld
();
g_gmock_mutex
.
AssertHeld
();
for
(
Expectation
Base
Set
::
const_iterator
it
=
immediate_prerequisites_
.
begin
();
for
(
ExpectationSet
::
const_iterator
it
=
immediate_prerequisites_
.
begin
();
it
!=
immediate_prerequisites_
.
end
();
++
it
)
{
it
!=
immediate_prerequisites_
.
end
();
++
it
)
{
if
(
(
*
it
)
->
IsSatisfied
())
{
if
(
it
->
expectation_base
(
)
->
IsSatisfied
())
{
// If *it is satisfied and has a call count of 0, some of its
// If *it is satisfied and has a call count of 0, some of its
// pre-requisites may not be satisfied yet.
// pre-requisites may not be satisfied yet.
if
(
(
*
it
)
->
call_count_
==
0
)
{
if
(
it
->
expectation_base
(
)
->
call_count_
==
0
)
{
(
*
it
)
->
FindUnsatisfiedPrerequisites
(
result
);
it
->
expectation_base
(
)
->
FindUnsatisfiedPrerequisites
(
result
);
}
}
}
else
{
}
else
{
// Now that we know *it is unsatisfied, we are not so interested
// Now that we know *it is unsatisfied, we are not so interested
// in whether its pre-requisites are satisfied. Therefore we
// in whether its pre-requisites are satisfied. Therefore we
// don't recursively call FindUnsatisfiedPrerequisites() here.
// don't recursively call FindUnsatisfiedPrerequisites() here.
result
->
insert
(
*
it
)
;
*
result
+=
*
it
;
}
}
}
}
}
}
...
@@ -421,11 +419,11 @@ void Mock::ClearDefaultActionsLocked(void* mock_obj) {
...
@@ -421,11 +419,11 @@ void Mock::ClearDefaultActionsLocked(void* mock_obj) {
}
}
// Adds an expectation to a sequence.
// Adds an expectation to a sequence.
void
Sequence
::
AddExpectation
(
void
Sequence
::
AddExpectation
(
const
Expectation
&
expectation
)
const
{
const
internal
::
linked_ptr
<
internal
::
ExpectationBase
>&
expectation
)
const
{
if
(
*
last_expectation_
!=
expectation
)
{
if
(
*
last_expectation_
!=
expectation
)
{
if
(
*
last_expectation_
!=
NULL
)
{
if
(
last_expectation_
->
expectation_base
()
!=
NULL
)
{
expectation
->
immediate_prerequisites_
.
insert
(
*
last_expectation_
);
expectation
.
expectation_base
()
->
immediate_prerequisites_
+=
*
last_expectation_
;
}
}
*
last_expectation_
=
expectation
;
*
last_expectation_
=
expectation
;
}
}
...
...
test/gmock-spec-builders_test.cc
View file @
41b9b0b5
...
@@ -71,6 +71,9 @@ using testing::CardinalityInterface;
...
@@ -71,6 +71,9 @@ using testing::CardinalityInterface;
using
testing
::
Const
;
using
testing
::
Const
;
using
testing
::
DoAll
;
using
testing
::
DoAll
;
using
testing
::
DoDefault
;
using
testing
::
DoDefault
;
using
testing
::
Eq
;
using
testing
::
Expectation
;
using
testing
::
ExpectationSet
;
using
testing
::
GMOCK_FLAG
(
verbose
);
using
testing
::
GMOCK_FLAG
(
verbose
);
using
testing
::
Gt
;
using
testing
::
Gt
;
using
testing
::
InSequence
;
using
testing
::
InSequence
;
...
@@ -80,13 +83,13 @@ using testing::IsSubstring;
...
@@ -80,13 +83,13 @@ using testing::IsSubstring;
using
testing
::
Lt
;
using
testing
::
Lt
;
using
testing
::
Message
;
using
testing
::
Message
;
using
testing
::
Mock
;
using
testing
::
Mock
;
using
testing
::
Ne
;
using
testing
::
Return
;
using
testing
::
Return
;
using
testing
::
Sequence
;
using
testing
::
Sequence
;
using
testing
::
internal
::
g_gmock_mutex
;
using
testing
::
internal
::
g_gmock_mutex
;
using
testing
::
internal
::
kErrorVerbosity
;
using
testing
::
internal
::
kErrorVerbosity
;
using
testing
::
internal
::
kInfoVerbosity
;
using
testing
::
internal
::
kInfoVerbosity
;
using
testing
::
internal
::
kWarningVerbosity
;
using
testing
::
internal
::
kWarningVerbosity
;
using
testing
::
internal
::
Expectation
;
using
testing
::
internal
::
ExpectationTester
;
using
testing
::
internal
::
ExpectationTester
;
using
testing
::
internal
::
string
;
using
testing
::
internal
::
string
;
...
@@ -345,7 +348,22 @@ TEST(ExpectCallSyntaxTest, InSequenceCanAppearMultipleTimes) {
...
@@ -345,7 +348,22 @@ TEST(ExpectCallSyntaxTest, InSequenceCanAppearMultipleTimes) {
a
.
DoA
(
1
);
a
.
DoA
(
1
);
}
}
TEST
(
ExpectCallSyntaxTest
,
InSequenceMustBeBeforeWill
)
{
TEST
(
ExpectCallSyntaxTest
,
InSequenceMustBeBeforeAfter
)
{
MockA
a
;
Sequence
s
;
Expectation
e
=
EXPECT_CALL
(
a
,
DoA
(
1
))
.
Times
(
AnyNumber
());
EXPECT_NONFATAL_FAILURE
({
// NOLINT
EXPECT_CALL
(
a
,
DoA
(
2
))
.
After
(
e
)
.
InSequence
(
s
);
},
".InSequence() cannot appear after "
);
a
.
DoA
(
2
);
}
TEST
(
ExpectCallSyntaxTest
,
InSequenceMustBeBeforeWillOnce
)
{
MockA
a
;
MockA
a
;
Sequence
s
;
Sequence
s
;
...
@@ -358,6 +376,20 @@ TEST(ExpectCallSyntaxTest, InSequenceMustBeBeforeWill) {
...
@@ -358,6 +376,20 @@ TEST(ExpectCallSyntaxTest, InSequenceMustBeBeforeWill) {
a
.
DoA
(
1
);
a
.
DoA
(
1
);
}
}
TEST
(
ExpectCallSyntaxTest
,
AfterMustBeBeforeWillOnce
)
{
MockA
a
;
Expectation
e
=
EXPECT_CALL
(
a
,
DoA
(
1
));
EXPECT_NONFATAL_FAILURE
({
EXPECT_CALL
(
a
,
DoA
(
2
))
.
WillOnce
(
Return
())
.
After
(
e
);
},
".After() cannot appear after "
);
a
.
DoA
(
1
);
a
.
DoA
(
2
);
}
TEST
(
ExpectCallSyntaxTest
,
WillIsOptional
)
{
TEST
(
ExpectCallSyntaxTest
,
WillIsOptional
)
{
MockA
a
;
MockA
a
;
...
@@ -1248,6 +1280,292 @@ TEST(SequenceTest, Retirement) {
...
@@ -1248,6 +1280,292 @@ TEST(SequenceTest, Retirement) {
a
.
DoA
(
1
);
a
.
DoA
(
1
);
}
}
// Tests Expectation.
TEST
(
ExpectationTest
,
ConstrutorsWork
)
{
MockA
a
;
Expectation
e1
;
// Default ctor.
Expectation
e2
=
EXPECT_CALL
(
a
,
DoA
(
1
));
// Ctor from EXPECT_CALL.
Expectation
e3
=
e2
;
// Copy ctor.
EXPECT_THAT
(
e1
,
Ne
(
e2
));
EXPECT_THAT
(
e2
,
Eq
(
e3
));
a
.
DoA
(
1
);
}
TEST
(
ExpectationTest
,
AssignmentWorks
)
{
MockA
a
;
Expectation
e1
;
Expectation
e2
=
EXPECT_CALL
(
a
,
DoA
(
1
));
EXPECT_THAT
(
e1
,
Ne
(
e2
));
e1
=
e2
;
EXPECT_THAT
(
e1
,
Eq
(
e2
));
a
.
DoA
(
1
);
}
// Tests ExpectationSet.
TEST
(
ExpectationSetTest
,
MemberTypesAreCorrect
)
{
::
testing
::
StaticAssertTypeEq
<
Expectation
,
ExpectationSet
::
value_type
>
();
}
TEST
(
ExpectationSetTest
,
ConstructorsWork
)
{
MockA
a
;
Expectation
e1
;
const
Expectation
e2
;
ExpectationSet
es1
;
// Default ctor.
ExpectationSet
es2
=
EXPECT_CALL
(
a
,
DoA
(
1
));
// Ctor from EXPECT_CALL.
ExpectationSet
es3
=
e1
;
// Ctor from Expectation.
ExpectationSet
es4
(
e1
);
// Ctor from Expectation; alternative syntax.
ExpectationSet
es5
=
e2
;
// Ctor from const Expectation.
ExpectationSet
es6
(
e2
);
// Ctor from const Expectation; alternative syntax.
ExpectationSet
es7
=
es2
;
// Copy ctor.
EXPECT_EQ
(
0
,
es1
.
size
());
EXPECT_EQ
(
1
,
es2
.
size
());
EXPECT_EQ
(
1
,
es3
.
size
());
EXPECT_EQ
(
1
,
es4
.
size
());
EXPECT_EQ
(
1
,
es5
.
size
());
EXPECT_EQ
(
1
,
es6
.
size
());
EXPECT_EQ
(
1
,
es7
.
size
());
EXPECT_THAT
(
es3
,
Ne
(
es2
));
EXPECT_THAT
(
es4
,
Eq
(
es3
));
EXPECT_THAT
(
es5
,
Eq
(
es4
));
EXPECT_THAT
(
es6
,
Eq
(
es5
));
EXPECT_THAT
(
es7
,
Eq
(
es2
));
a
.
DoA
(
1
);
}
TEST
(
ExpectationSetTest
,
AssignmentWorks
)
{
ExpectationSet
es1
;
ExpectationSet
es2
=
Expectation
();
es1
=
es2
;
EXPECT_EQ
(
1
,
es1
.
size
());
EXPECT_THAT
(
*
(
es1
.
begin
()),
Eq
(
Expectation
()));
EXPECT_THAT
(
es1
,
Eq
(
es2
));
}
TEST
(
ExpectationSetTest
,
InsertionWorks
)
{
ExpectationSet
es1
;
Expectation
e1
;
es1
+=
e1
;
EXPECT_EQ
(
1
,
es1
.
size
());
EXPECT_THAT
(
*
(
es1
.
begin
()),
Eq
(
e1
));
MockA
a
;
Expectation
e2
=
EXPECT_CALL
(
a
,
DoA
(
1
));
es1
+=
e2
;
EXPECT_EQ
(
2
,
es1
.
size
());
ExpectationSet
::
const_iterator
it1
=
es1
.
begin
();
ExpectationSet
::
const_iterator
it2
=
it1
;
++
it2
;
EXPECT_TRUE
(
*
it1
==
e1
||
*
it2
==
e1
);
// e1 must be in the set.
EXPECT_TRUE
(
*
it1
==
e2
||
*
it2
==
e2
);
// e2 must be in the set too.
a
.
DoA
(
1
);
}
TEST
(
ExpectationSetTest
,
SizeWorks
)
{
ExpectationSet
es
;
EXPECT_EQ
(
0
,
es
.
size
());
es
+=
Expectation
();
EXPECT_EQ
(
1
,
es
.
size
());
MockA
a
;
es
+=
EXPECT_CALL
(
a
,
DoA
(
1
));
EXPECT_EQ
(
2
,
es
.
size
());
a
.
DoA
(
1
);
}
TEST
(
ExpectationSetTest
,
IsEnumerable
)
{
ExpectationSet
es
;
EXPECT_THAT
(
es
.
begin
(),
Eq
(
es
.
end
()));
es
+=
Expectation
();
ExpectationSet
::
const_iterator
it
=
es
.
begin
();
EXPECT_THAT
(
it
,
Ne
(
es
.
end
()));
EXPECT_THAT
(
*
it
,
Eq
(
Expectation
()));
++
it
;
EXPECT_THAT
(
it
,
Eq
(
es
.
end
()));
}
// Tests the .After() clause.
TEST
(
AfterTest
,
SucceedsWhenPartialOrderIsSatisfied
)
{
MockA
a
;
ExpectationSet
es
;
es
+=
EXPECT_CALL
(
a
,
DoA
(
1
));
es
+=
EXPECT_CALL
(
a
,
DoA
(
2
));
EXPECT_CALL
(
a
,
DoA
(
3
))
.
After
(
es
);
a
.
DoA
(
1
);
a
.
DoA
(
2
);
a
.
DoA
(
3
);
}
TEST
(
AfterTest
,
SucceedsWhenTotalOrderIsSatisfied
)
{
MockA
a
;
MockB
b
;
// The following also verifies that const Expectation objects work
// too. Do not remove the const modifiers.
const
Expectation
e1
=
EXPECT_CALL
(
a
,
DoA
(
1
));
const
Expectation
e2
=
EXPECT_CALL
(
b
,
DoB
())
.
Times
(
2
)
.
After
(
e1
);
EXPECT_CALL
(
a
,
DoA
(
2
)).
After
(
e2
);
a
.
DoA
(
1
);
b
.
DoB
();
b
.
DoB
();
a
.
DoA
(
2
);
}
// Calls must be in strict order when specified so.
TEST
(
AfterTest
,
CallsMustBeInStrictOrderWhenSpecifiedSo
)
{
MockA
a
;
MockB
b
;
Expectation
e1
=
EXPECT_CALL
(
a
,
DoA
(
1
));
Expectation
e2
=
EXPECT_CALL
(
b
,
DoB
())
.
Times
(
2
)
.
After
(
e1
);
EXPECT_CALL
(
a
,
ReturnResult
(
2
))
.
After
(
e2
)
.
WillOnce
(
Return
(
Result
()));
a
.
DoA
(
1
);
// If a call to ReturnResult() violates the specified order, no
// matching expectation will be found, and thus the default action
// will be done. Since the return type of ReturnResult() is not a
// built-in type, gmock won't know what to return and will thus
// abort the program. Therefore a death test can tell us whether
// gmock catches the order violation correctly.
//
// gtest and gmock print messages to stdout, which isn't captured by
// death tests. Therefore we have to match with an empty regular
// expression in all the EXPECT_DEATH()s.
EXPECT_DEATH
(
a
.
ReturnResult
(
2
),
""
);
b
.
DoB
();
EXPECT_DEATH
(
a
.
ReturnResult
(
2
),
""
);
b
.
DoB
();
a
.
ReturnResult
(
2
);
}
// Calls must satisfy the partial order when specified so.
TEST
(
AfterTest
,
CallsMustSatisfyPartialOrderWhenSpecifiedSo
)
{
MockA
a
;
Expectation
e
=
EXPECT_CALL
(
a
,
DoA
(
1
));
const
ExpectationSet
es
=
EXPECT_CALL
(
a
,
DoA
(
2
));
EXPECT_CALL
(
a
,
ReturnResult
(
3
))
.
After
(
e
,
es
)
.
WillOnce
(
Return
(
Result
()));
EXPECT_DEATH
(
a
.
ReturnResult
(
3
),
""
);
a
.
DoA
(
2
);
EXPECT_DEATH
(
a
.
ReturnResult
(
3
),
""
);
a
.
DoA
(
1
);
a
.
ReturnResult
(
3
);
}
// .After() can be combined with .InSequence().
TEST
(
AfterTest
,
CanBeUsedWithInSequence
)
{
MockA
a
;
Sequence
s
;
Expectation
e
=
EXPECT_CALL
(
a
,
DoA
(
1
));
EXPECT_CALL
(
a
,
DoA
(
2
)).
InSequence
(
s
);
EXPECT_CALL
(
a
,
ReturnResult
(
3
))
.
InSequence
(
s
).
After
(
e
)
.
WillOnce
(
Return
(
Result
()));
a
.
DoA
(
1
);
EXPECT_DEATH
(
a
.
ReturnResult
(
3
),
""
);
a
.
DoA
(
2
);
a
.
ReturnResult
(
3
);
}
// .After() can be called multiple times.
TEST
(
AfterTest
,
CanBeCalledManyTimes
)
{
MockA
a
;
Expectation
e1
=
EXPECT_CALL
(
a
,
DoA
(
1
));
Expectation
e2
=
EXPECT_CALL
(
a
,
DoA
(
2
));
Expectation
e3
=
EXPECT_CALL
(
a
,
DoA
(
3
));
EXPECT_CALL
(
a
,
DoA
(
4
))
.
After
(
e1
)
.
After
(
e2
)
.
After
(
e3
);
a
.
DoA
(
3
);
a
.
DoA
(
1
);
a
.
DoA
(
2
);
a
.
DoA
(
4
);
}
// .After() accepts up to 5 arguments.
TEST
(
AfterTest
,
AcceptsUpToFiveArguments
)
{
MockA
a
;
Expectation
e1
=
EXPECT_CALL
(
a
,
DoA
(
1
));
Expectation
e2
=
EXPECT_CALL
(
a
,
DoA
(
2
));
Expectation
e3
=
EXPECT_CALL
(
a
,
DoA
(
3
));
ExpectationSet
es1
=
EXPECT_CALL
(
a
,
DoA
(
4
));
ExpectationSet
es2
=
EXPECT_CALL
(
a
,
DoA
(
5
));
EXPECT_CALL
(
a
,
DoA
(
6
))
.
After
(
e1
,
e2
,
e3
,
es1
,
es2
);
a
.
DoA
(
5
);
a
.
DoA
(
2
);
a
.
DoA
(
4
);
a
.
DoA
(
1
);
a
.
DoA
(
3
);
a
.
DoA
(
6
);
}
// .After() allows input to contain duplicated Expectations.
TEST
(
AfterTest
,
AcceptsDuplicatedInput
)
{
MockA
a
;
Expectation
e1
=
EXPECT_CALL
(
a
,
DoA
(
1
));
Expectation
e2
=
EXPECT_CALL
(
a
,
DoA
(
2
));
ExpectationSet
es
;
es
+=
e1
;
es
+=
e2
;
EXPECT_CALL
(
a
,
ReturnResult
(
3
))
.
After
(
e1
,
e2
,
es
,
e1
)
.
WillOnce
(
Return
(
Result
()));
a
.
DoA
(
1
);
EXPECT_DEATH
(
a
.
ReturnResult
(
3
),
""
);
a
.
DoA
(
2
);
a
.
ReturnResult
(
3
);
}
// An Expectation added to an ExpectationSet after it has been used in
// an .After() has no effect.
TEST
(
AfterTest
,
ChangesToExpectationSetHaveNoEffectAfterwards
)
{
MockA
a
;
ExpectationSet
es1
=
EXPECT_CALL
(
a
,
DoA
(
1
));
Expectation
e2
=
EXPECT_CALL
(
a
,
DoA
(
2
));
EXPECT_CALL
(
a
,
DoA
(
3
))
.
After
(
es1
);
es1
+=
e2
;
a
.
DoA
(
1
);
a
.
DoA
(
3
);
a
.
DoA
(
2
);
}
// Tests that Google Mock correctly handles calls to mock functions
// Tests that Google Mock correctly handles calls to mock functions
// after a mock object owning one of their pre-requisites has died.
// after a mock object owning one of their pre-requisites has died.
...
...
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