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
41b9b0b5
Commit
41b9b0b5
authored
Jul 01, 2009
by
zhanyong.wan
Browse files
Implements Expectation, ExpectationSet, and After for specifying expectation orders.
parent
4019819d
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
606 additions
and
100 deletions
+606
-100
include/gmock/gmock-spec-builders.h
include/gmock/gmock-spec-builders.h
+270
-80
src/gmock-spec-builders.cc
src/gmock-spec-builders.cc
+16
-18
test/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
...
@@ -49,13 +49,13 @@
...
@@ -49,13 +49,13 @@
// .With(multi-argument-matchers)
// .With(multi-argument-matchers)
// .Times(cardinality)
// .Times(cardinality)
// .InSequence(sequences)
// .InSequence(sequences)
// .After(expectations)
// .WillOnce(action)
// .WillOnce(action)
// .WillRepeatedly(action)
// .WillRepeatedly(action)
// .RetiresOnSaturation();
// .RetiresOnSaturation();
//
//
// where all clauses are optional, .InSequence() and .WillOnce() can
// where all clauses are optional, and .InSequence()/.After()/
// appear any number of times, and .Times() can be omitted only if
// .WillOnce() can appear any number of times.
// .WillOnce() or .WillRepeatedly() is present.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
...
@@ -76,22 +76,30 @@
...
@@ -76,22 +76,30 @@
namespace
testing
{
namespace
testing
{
// An abstract handle of an expectation.
class
Expectation
;
// A set of expectation handles.
class
ExpectationSet
;
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// and MUST NOT BE USED IN USER CODE!!!
// and MUST NOT BE USED IN USER CODE!!!
namespace
internal
{
namespace
internal
{
template
<
typename
F
>
// Implements a mock function.
class
FunctionMocker
;
template
<
typename
F
>
class
FunctionMocker
;
// Base class for expectations.
// Base class for expectations.
class
ExpectationBase
;
class
ExpectationBase
;
// Implements an expectation.
template
<
typename
F
>
class
TypedExpectation
;
// Helper class for testing the Expectation class template.
// Helper class for testing the Expectation class template.
class
ExpectationTester
;
class
ExpectationTester
;
// Base class for function mockers.
// Base class for function mockers.
template
<
typename
F
>
template
<
typename
F
>
class
FunctionMockerBase
;
class
FunctionMockerBase
;
// Protects the mock object registry (in class Mock), all function
// Protects the mock object registry (in class Mock), all function
// mockers, and all expectations.
// mockers, and all expectations.
...
@@ -232,7 +240,8 @@ class DefaultActionSpec {
...
@@ -232,7 +240,8 @@ class DefaultActionSpec {
Clause
last_clause_
;
Clause
last_clause_
;
};
// class DefaultActionSpec
};
// class DefaultActionSpec
// Possible reactions on uninteresting calls.
// Possible reactions on uninteresting calls. TODO(wan@google.com):
// rename the enum values to the kFoo style.
enum
CallReaction
{
enum
CallReaction
{
ALLOW
,
ALLOW
,
WARN
,
WARN
,
...
@@ -327,31 +336,166 @@ class Mock {
...
@@ -327,31 +336,166 @@ class Mock {
static
void
UnregisterLocked
(
internal
::
UntypedFunctionMockerBase
*
mocker
);
static
void
UnregisterLocked
(
internal
::
UntypedFunctionMockerBase
*
mocker
);
};
// class Mock
};
// class Mock
// An abstract handle of an expectation. Useful in the .After()
// clause of EXPECT_CALL() for setting the (partial) order of
// expectations. The syntax:
//
// Expectation e1 = EXPECT_CALL(...)...;
// EXPECT_CALL(...).After(e1)...;
//
// sets two expectations where the latter can only be matched after
// the former has been satisfied.
//
// Notes:
// - This class is copyable and has value semantics.
// - Constness is shallow: a const Expectation object itself cannot
// be modified, but the mutable methods of the ExpectationBase
// object it references can be called via expectation_base().
class
Expectation
{
public:
// Constructs a null object that doesn't reference any expectation.
Expectation
()
{}
// This single-argument ctor must not be explicit, in order to support the
// Expectation e = EXPECT_CALL(...);
// syntax.
//
// A TypedExpectation object stores its pre-requisites as
// Expectation objects, and needs to call the non-const Retire()
// method on the ExpectationBase objects they reference. Therefore
// Expectation must receive a *non-const* reference to the
// ExpectationBase object.
Expectation
(
internal
::
ExpectationBase
&
exp
);
// NOLINT
// The compiler-generated copy ctor and operator= work exactly as
// intended, so we don't need to define our own.
// Returns true iff rhs references the same expectation as this object does.
bool
operator
==
(
const
Expectation
&
rhs
)
const
{
return
expectation_base_
==
rhs
.
expectation_base_
;
}
bool
operator
!=
(
const
Expectation
&
rhs
)
const
{
return
!
(
*
this
==
rhs
);
}
private:
friend
class
ExpectationSet
;
friend
class
Sequence
;
friend
class
::
testing
::
internal
::
ExpectationBase
;
template
<
typename
F
>
friend
class
::
testing
::
internal
::
FunctionMockerBase
;
template
<
typename
F
>
friend
class
::
testing
::
internal
::
TypedExpectation
;
// This comparator is needed for putting Expectation objects into a set.
class
Less
{
public:
bool
operator
()(
const
Expectation
&
lhs
,
const
Expectation
&
rhs
)
const
{
return
lhs
.
expectation_base_
.
get
()
<
rhs
.
expectation_base_
.
get
();
}
};
typedef
::
std
::
set
<
Expectation
,
Less
>
Set
;
Expectation
(
const
internal
::
linked_ptr
<
internal
::
ExpectationBase
>&
expectation_base
)
:
expectation_base_
(
expectation_base
)
{}
// Returns the expectation this object references.
const
internal
::
linked_ptr
<
internal
::
ExpectationBase
>&
expectation_base
()
const
{
return
expectation_base_
;
}
// A linked_ptr that co-owns the expectation this handle references.
internal
::
linked_ptr
<
internal
::
ExpectationBase
>
expectation_base_
;
};
// A set of expectation handles. Useful in the .After() clause of
// EXPECT_CALL() for setting the (partial) order of expectations. The
// syntax:
//
// ExpectationSet es;
// es += EXPECT_CALL(...)...;
// es += EXPECT_CALL(...)...;
// EXPECT_CALL(...).After(es)...;
//
// sets three expectations where the last one can only be matched
// after the first two have both been satisfied.
//
// This class is copyable and has value semantics.
class
ExpectationSet
{
public:
// A bidirectional iterator that can read a const element in the set.
typedef
Expectation
::
Set
::
const_iterator
const_iterator
;
// An object stored in the set. This is an alias of Expectation.
typedef
Expectation
::
Set
::
value_type
value_type
;
// Constructs an empty set.
ExpectationSet
()
{}
// This single-argument ctor must not be explicit, in order to support the
// ExpectationSet es = EXPECT_CALL(...);
// syntax.
ExpectationSet
(
internal
::
ExpectationBase
&
exp
)
{
// NOLINT
*
this
+=
Expectation
(
exp
);
}
// This single-argument ctor implements implicit conversion from
// Expectation and thus must not be explicit. This allows either an
// Expectation or an ExpectationSet to be used in .After().
ExpectationSet
(
const
Expectation
&
e
)
{
// NOLINT
*
this
+=
e
;
}
// The compiler-generator ctor and operator= works exactly as
// intended, so we don't need to define our own.
// Returns true iff rhs contains the same set of Expectation objects
// as this does.
bool
operator
==
(
const
ExpectationSet
&
rhs
)
const
{
return
expectations_
==
rhs
.
expectations_
;
}
bool
operator
!=
(
const
ExpectationSet
&
rhs
)
const
{
return
!
(
*
this
==
rhs
);
}
// Implements the syntax
// expectation_set += EXPECT_CALL(...);
ExpectationSet
&
operator
+=
(
const
Expectation
&
e
)
{
expectations_
.
insert
(
e
);
return
*
this
;
}
int
size
()
const
{
return
static_cast
<
int
>
(
expectations_
.
size
());
}
const_iterator
begin
()
const
{
return
expectations_
.
begin
();
}
const_iterator
end
()
const
{
return
expectations_
.
end
();
}
private:
Expectation
::
Set
expectations_
;
};
// Sequence objects are used by a user to specify the relative order
// Sequence objects are used by a user to specify the relative order
// in which the expectations should match. They are copyable (we rely
// in which the expectations should match. They are copyable (we rely
// on the compiler-defined copy constructor and assignment operator).
// on the compiler-defined copy constructor and assignment operator).
class
Sequence
{
class
Sequence
{
public:
public:
// Constructs an empty sequence.
// Constructs an empty sequence.
Sequence
()
Sequence
()
:
last_expectation_
(
new
Expectation
)
{}
:
last_expectation_
(
new
internal
::
linked_ptr
<
internal
::
ExpectationBase
>
(
NULL
))
{}
// Adds an expectation to this sequence. The caller must ensure
// Adds an expectation to this sequence. The caller must ensure
// that no other thread is accessing this Sequence object.
// that no other thread is accessing this Sequence object.
void
AddExpectation
(
void
AddExpectation
(
const
Expectation
&
expectation
)
const
;
const
internal
::
linked_ptr
<
internal
::
ExpectationBase
>&
expectation
)
const
;
private:
private:
// The last expectation in this sequence. We use a nested
// The last expectation in this sequence. We use a linked_ptr here
// linked_ptr here because:
// because Sequence objects are copyable and we want the copies to
// - Sequence objects are copyable, and we want the copies to act
// be aliases. The linked_ptr allows the copies to co-own and share
// as aliases. The outer linked_ptr allows the copies to co-own
// the same Expectation object.
// and share the same state.
internal
::
linked_ptr
<
Expectation
>
last_expectation_
;
// - An Expectation object is co-owned (via linked_ptr) by its
// FunctionMocker and its successors (other Expectation objects).
// Hence the inner linked_ptr.
internal
::
linked_ptr
<
internal
::
linked_ptr
<
internal
::
ExpectationBase
>
>
last_expectation_
;
};
// class Sequence
};
// class Sequence
// An object of this type causes all EXPECT_CALL() statements
// An object of this type causes all EXPECT_CALL() statements
...
@@ -431,9 +575,7 @@ class ExpectationBase {
...
@@ -431,9 +575,7 @@ class ExpectationBase {
// L >= g_gmock_mutex
// L >= g_gmock_mutex
virtual
void
DescribeCallCountTo
(
::
std
::
ostream
*
os
)
const
=
0
;
virtual
void
DescribeCallCountTo
(
::
std
::
ostream
*
os
)
const
=
0
;
protected:
protected:
typedef
std
::
set
<
linked_ptr
<
ExpectationBase
>
,
friend
class
::
testing
::
Expectation
;
LinkedPtrLessThan
<
ExpectationBase
>
>
ExpectationBaseSet
;
enum
Clause
{
enum
Clause
{
// Don't change the order of the enum members!
// Don't change the order of the enum members!
...
@@ -441,11 +583,16 @@ class ExpectationBase {
...
@@ -441,11 +583,16 @@ class ExpectationBase {
kWith
,
kWith
,
kTimes
,
kTimes
,
kInSequence
,
kInSequence
,
kAfter
,
kWillOnce
,
kWillOnce
,
kWillRepeatedly
,
kWillRepeatedly
,
kRetiresOnSaturation
,
kRetiresOnSaturation
,
};
};
// Returns an Expectation object that references and co-owns this
// expectation.
virtual
Expectation
GetHandle
()
=
0
;
// Asserts that the EXPECT_CALL() statement has the given property.
// Asserts that the EXPECT_CALL() statement has the given property.
void
AssertSpecProperty
(
bool
property
,
const
string
&
failure_message
)
const
{
void
AssertSpecProperty
(
bool
property
,
const
string
&
failure_message
)
const
{
Assert
(
property
,
file_
,
line_
,
failure_message
);
Assert
(
property
,
file_
,
line_
,
failure_message
);
...
@@ -518,7 +665,7 @@ class ExpectationBase {
...
@@ -518,7 +665,7 @@ class ExpectationBase {
// 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
FindUnsatisfiedPrerequisites
(
Expectation
Base
Set
*
result
)
const
;
void
FindUnsatisfiedPrerequisites
(
ExpectationSet
*
result
)
const
;
// Returns the number this expectation has been invoked.
// Returns the number this expectation has been invoked.
// L >= g_gmock_mutex
// L >= g_gmock_mutex
...
@@ -539,7 +686,7 @@ class ExpectationBase {
...
@@ -539,7 +686,7 @@ class ExpectationBase {
friend
class
::
testing
::
internal
::
ExpectationTester
;
friend
class
::
testing
::
internal
::
ExpectationTester
;
template
<
typename
Function
>
template
<
typename
Function
>
friend
class
Expectation
;
friend
class
Typed
Expectation
;
// This group of fields are part of the spec and won't change after
// This group of fields are part of the spec and won't change after
// an EXPECT_CALL() statement finishes.
// an EXPECT_CALL() statement finishes.
...
@@ -548,11 +695,13 @@ class ExpectationBase {
...
@@ -548,11 +695,13 @@ class ExpectationBase {
// True iff the cardinality is specified explicitly.
// True iff the cardinality is specified explicitly.
bool
cardinality_specified_
;
bool
cardinality_specified_
;
Cardinality
cardinality_
;
// The cardinality of the expectation.
Cardinality
cardinality_
;
// The cardinality of the expectation.
// The immediate pre-requisites of this expectation. We use
// The immediate pre-requisites (i.e. expectations that must be
// linked_ptr in the set because we want an Expectation object to be
// satisfied before this expectation can be matched) of this
// co-owned by its FunctionMocker and its successors. This allows
// expectation. We use linked_ptr in the set because we want an
// multiple mock objects to be deleted at different times.
// Expectation object to be co-owned by its FunctionMocker and its
ExpectationBaseSet
immediate_prerequisites_
;
// successors. This allows multiple mock objects to be deleted at
// different times.
ExpectationSet
immediate_prerequisites_
;
// This group of fields are the current state of the expectation,
// This group of fields are the current state of the expectation,
// and can change as the mock function is called.
// and can change as the mock function is called.
...
@@ -562,13 +711,13 @@ class ExpectationBase {
...
@@ -562,13 +711,13 @@ class ExpectationBase {
// Impements an expectation for the given function type.
// Impements an expectation for the given function type.
template
<
typename
F
>
template
<
typename
F
>
class
Expectation
:
public
ExpectationBase
{
class
Typed
Expectation
:
public
ExpectationBase
{
public:
public:
typedef
typename
Function
<
F
>::
ArgumentTuple
ArgumentTuple
;
typedef
typename
Function
<
F
>::
ArgumentTuple
ArgumentTuple
;
typedef
typename
Function
<
F
>::
ArgumentMatcherTuple
ArgumentMatcherTuple
;
typedef
typename
Function
<
F
>::
ArgumentMatcherTuple
ArgumentMatcherTuple
;
typedef
typename
Function
<
F
>::
Result
Result
;
typedef
typename
Function
<
F
>::
Result
Result
;
Expectation
(
FunctionMockerBase
<
F
>*
owner
,
const
char
*
file
,
int
line
,
Typed
Expectation
(
FunctionMockerBase
<
F
>*
owner
,
const
char
*
file
,
int
line
,
const
ArgumentMatcherTuple
&
m
)
const
ArgumentMatcherTuple
&
m
)
:
ExpectationBase
(
file
,
line
),
:
ExpectationBase
(
file
,
line
),
owner_
(
owner
),
owner_
(
owner
),
...
@@ -584,14 +733,14 @@ class Expectation : public ExpectationBase {
...
@@ -584,14 +733,14 @@ class Expectation : public ExpectationBase {
last_clause_
(
kNone
),
last_clause_
(
kNone
),
action_count_checked_
(
false
)
{}
action_count_checked_
(
false
)
{}
virtual
~
Expectation
()
{
virtual
~
Typed
Expectation
()
{
// Check the validity of the action count if it hasn't been done
// Check the validity of the action count if it hasn't been done
// yet (for example, if the expectation was never used).
// yet (for example, if the expectation was never used).
CheckActionCountIfNotDone
();
CheckActionCountIfNotDone
();
}
}
// Implements the .With() clause.
// Implements the .With() clause.
Expectation
&
With
(
const
Matcher
<
const
ArgumentTuple
&>&
m
)
{
Typed
Expectation
&
With
(
const
Matcher
<
const
ArgumentTuple
&>&
m
)
{
if
(
last_clause_
==
kWith
)
{
if
(
last_clause_
==
kWith
)
{
ExpectSpecProperty
(
false
,
ExpectSpecProperty
(
false
,
".With() cannot appear "
".With() cannot appear "
...
@@ -608,7 +757,7 @@ class Expectation : public ExpectationBase {
...
@@ -608,7 +757,7 @@ class Expectation : public ExpectationBase {
}
}
// Implements the .Times() clause.
// Implements the .Times() clause.
Expectation
&
Times
(
const
Cardinality
&
cardinality
)
{
Typed
Expectation
&
Times
(
const
Cardinality
&
cardinality
)
{
if
(
last_clause_
==
kTimes
)
{
if
(
last_clause_
==
kTimes
)
{
ExpectSpecProperty
(
false
,
ExpectSpecProperty
(
false
,
".Times() cannot appear "
".Times() cannot appear "
...
@@ -626,40 +775,70 @@ class Expectation : public ExpectationBase {
...
@@ -626,40 +775,70 @@ class Expectation : public ExpectationBase {
}
}
// Implements the .Times() clause.
// Implements the .Times() clause.
Expectation
&
Times
(
int
n
)
{
Typed
Expectation
&
Times
(
int
n
)
{
return
Times
(
Exactly
(
n
));
return
Times
(
Exactly
(
n
));
}
}
// Implements the .InSequence() clause.
// Implements the .InSequence() clause.
Expectation
&
InSequence
(
const
Sequence
&
s
)
{
Typed
Expectation
&
InSequence
(
const
Sequence
&
s
)
{
ExpectSpecProperty
(
last_clause_
<=
kInSequence
,
ExpectSpecProperty
(
last_clause_
<=
kInSequence
,
".InSequence() cannot appear after .
WillOnce
(),"
".InSequence() cannot appear after .
After
(),"
" .WillRepeatedly(), or "
"
.WillOnce(),
.WillRepeatedly(), or "
".RetiresOnSaturation()."
);
".RetiresOnSaturation()."
);
last_clause_
=
kInSequence
;
last_clause_
=
kInSequence
;
s
.
AddExpectation
(
owner_
->
GetLinkedExpectationBase
(
this
));
s
.
AddExpectation
(
GetHandle
(
));
return
*
this
;
return
*
this
;
}
}
Expectation
&
InSequence
(
const
Sequence
&
s1
,
const
Sequence
&
s2
)
{
Typed
Expectation
&
InSequence
(
const
Sequence
&
s1
,
const
Sequence
&
s2
)
{
return
InSequence
(
s1
).
InSequence
(
s2
);
return
InSequence
(
s1
).
InSequence
(
s2
);
}
}
Expectation
&
InSequence
(
const
Sequence
&
s1
,
const
Sequence
&
s2
,
Typed
Expectation
&
InSequence
(
const
Sequence
&
s1
,
const
Sequence
&
s2
,
const
Sequence
&
s3
)
{
const
Sequence
&
s3
)
{
return
InSequence
(
s1
,
s2
).
InSequence
(
s3
);
return
InSequence
(
s1
,
s2
).
InSequence
(
s3
);
}
}
Expectation
&
InSequence
(
const
Sequence
&
s1
,
const
Sequence
&
s2
,
Typed
Expectation
&
InSequence
(
const
Sequence
&
s1
,
const
Sequence
&
s2
,
const
Sequence
&
s3
,
const
Sequence
&
s4
)
{
const
Sequence
&
s3
,
const
Sequence
&
s4
)
{
return
InSequence
(
s1
,
s2
,
s3
).
InSequence
(
s4
);
return
InSequence
(
s1
,
s2
,
s3
).
InSequence
(
s4
);
}
}
Expectation
&
InSequence
(
const
Sequence
&
s1
,
const
Sequence
&
s2
,
Typed
Expectation
&
InSequence
(
const
Sequence
&
s1
,
const
Sequence
&
s2
,
const
Sequence
&
s3
,
const
Sequence
&
s4
,
const
Sequence
&
s3
,
const
Sequence
&
s4
,
const
Sequence
&
s5
)
{
const
Sequence
&
s5
)
{
return
InSequence
(
s1
,
s2
,
s3
,
s4
).
InSequence
(
s5
);
return
InSequence
(
s1
,
s2
,
s3
,
s4
).
InSequence
(
s5
);
}
}
// Implements that .After() clause.
TypedExpectation
&
After
(
const
ExpectationSet
&
s
)
{
ExpectSpecProperty
(
last_clause_
<=
kAfter
,
".After() cannot appear after .WillOnce(),"
" .WillRepeatedly(), or "
".RetiresOnSaturation()."
);
last_clause_
=
kAfter
;
for
(
ExpectationSet
::
const_iterator
it
=
s
.
begin
();
it
!=
s
.
end
();
++
it
)
{
immediate_prerequisites_
+=
*
it
;
}
return
*
this
;
}
TypedExpectation
&
After
(
const
ExpectationSet
&
s1
,
const
ExpectationSet
&
s2
)
{
return
After
(
s1
).
After
(
s2
);
}
TypedExpectation
&
After
(
const
ExpectationSet
&
s1
,
const
ExpectationSet
&
s2
,
const
ExpectationSet
&
s3
)
{
return
After
(
s1
,
s2
).
After
(
s3
);
}
TypedExpectation
&
After
(
const
ExpectationSet
&
s1
,
const
ExpectationSet
&
s2
,
const
ExpectationSet
&
s3
,
const
ExpectationSet
&
s4
)
{
return
After
(
s1
,
s2
,
s3
).
After
(
s4
);
}
TypedExpectation
&
After
(
const
ExpectationSet
&
s1
,
const
ExpectationSet
&
s2
,
const
ExpectationSet
&
s3
,
const
ExpectationSet
&
s4
,
const
ExpectationSet
&
s5
)
{
return
After
(
s1
,
s2
,
s3
,
s4
).
After
(
s5
);
}
// Implements the .WillOnce() clause.
// Implements the .WillOnce() clause.
Expectation
&
WillOnce
(
const
Action
<
F
>&
action
)
{
Typed
Expectation
&
WillOnce
(
const
Action
<
F
>&
action
)
{
ExpectSpecProperty
(
last_clause_
<=
kWillOnce
,
ExpectSpecProperty
(
last_clause_
<=
kWillOnce
,
".WillOnce() cannot appear after "
".WillOnce() cannot appear after "
".WillRepeatedly() or .RetiresOnSaturation()."
);
".WillRepeatedly() or .RetiresOnSaturation()."
);
...
@@ -673,7 +852,7 @@ class Expectation : public ExpectationBase {
...
@@ -673,7 +852,7 @@ class Expectation : public ExpectationBase {
}
}
// Implements the .WillRepeatedly() clause.
// Implements the .WillRepeatedly() clause.
Expectation
&
WillRepeatedly
(
const
Action
<
F
>&
action
)
{
Typed
Expectation
&
WillRepeatedly
(
const
Action
<
F
>&
action
)
{
if
(
last_clause_
==
kWillRepeatedly
)
{
if
(
last_clause_
==
kWillRepeatedly
)
{
ExpectSpecProperty
(
false
,
ExpectSpecProperty
(
false
,
".WillRepeatedly() cannot appear "
".WillRepeatedly() cannot appear "
...
@@ -698,7 +877,7 @@ class Expectation : public ExpectationBase {
...
@@ -698,7 +877,7 @@ class Expectation : public ExpectationBase {
}
}
// Implements the .RetiresOnSaturation() clause.
// Implements the .RetiresOnSaturation() clause.
Expectation
&
RetiresOnSaturation
()
{
Typed
Expectation
&
RetiresOnSaturation
()
{
ExpectSpecProperty
(
last_clause_
<
kRetiresOnSaturation
,
ExpectSpecProperty
(
last_clause_
<
kRetiresOnSaturation
,
".RetiresOnSaturation() cannot appear "
".RetiresOnSaturation() cannot appear "
"more than once."
);
"more than once."
);
...
@@ -756,6 +935,12 @@ class Expectation : public ExpectationBase {
...
@@ -756,6 +935,12 @@ class Expectation : public ExpectationBase {
template
<
typename
Function
>
template
<
typename
Function
>
friend
class
FunctionMockerBase
;
friend
class
FunctionMockerBase
;
// Returns an Expectation object that references and co-owns this
// expectation.
virtual
Expectation
GetHandle
()
{
return
owner_
->
GetHandleOf
(
this
);
}
// The following methods will be called only after the EXPECT_CALL()
// The following methods will be called only after the EXPECT_CALL()
// statement finishes and when the current thread holds
// statement finishes and when the current thread holds
// g_gmock_mutex.
// g_gmock_mutex.
...
@@ -807,12 +992,12 @@ class Expectation : public ExpectationBase {
...
@@ -807,12 +992,12 @@ class Expectation : public ExpectationBase {
*
os
<<
" Expected: all pre-requisites are satisfied
\n
"
*
os
<<
" Expected: all pre-requisites are satisfied
\n
"
<<
" Actual: the following immediate pre-requisites "
<<
" Actual: the following immediate pre-requisites "
<<
"are not satisfied:
\n
"
;
<<
"are not satisfied:
\n
"
;
Expectation
Base
Set
unsatisfied_prereqs
;
ExpectationSet
unsatisfied_prereqs
;
FindUnsatisfiedPrerequisites
(
&
unsatisfied_prereqs
);
FindUnsatisfiedPrerequisites
(
&
unsatisfied_prereqs
);
int
i
=
0
;
int
i
=
0
;
for
(
Expectation
Base
Set
::
const_iterator
it
=
unsatisfied_prereqs
.
begin
();
for
(
ExpectationSet
::
const_iterator
it
=
unsatisfied_prereqs
.
begin
();
it
!=
unsatisfied_prereqs
.
end
();
++
it
)
{
it
!=
unsatisfied_prereqs
.
end
();
++
it
)
{
(
*
it
)
->
DescribeLocationTo
(
os
);
it
->
expectation_base
(
)
->
DescribeLocationTo
(
os
);
*
os
<<
"pre-requisite #"
<<
i
++
<<
"
\n
"
;
*
os
<<
"pre-requisite #"
<<
i
++
<<
"
\n
"
;
}
}
*
os
<<
" (end of pre-requisites)
\n
"
;
*
os
<<
" (end of pre-requisites)
\n
"
;
...
@@ -957,7 +1142,7 @@ class Expectation : public ExpectationBase {
...
@@ -957,7 +1142,7 @@ class Expectation : public ExpectationBase {
Clause
last_clause_
;
Clause
last_clause_
;
mutable
bool
action_count_checked_
;
// Under mutex_.
mutable
bool
action_count_checked_
;
// Under mutex_.
mutable
Mutex
mutex_
;
// Protects action_count_checked_.
mutable
Mutex
mutex_
;
// Protects action_count_checked_.
};
// class Expectation
};
// class
Typed
Expectation
// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for
// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for
// specifying the default behavior of, or expectation on, a mock
// specifying the default behavior of, or expectation on, a mock
...
@@ -992,7 +1177,7 @@ class MockSpec {
...
@@ -992,7 +1177,7 @@ class MockSpec {
// Adds a new expectation spec to the function mocker and returns
// Adds a new expectation spec to the function mocker and returns
// the newly created spec.
// the newly created spec.
internal
::
Expectation
<
F
>&
InternalExpectedAt
(
internal
::
Typed
Expectation
<
F
>&
InternalExpectedAt
(
const
char
*
file
,
int
line
,
const
char
*
obj
,
const
char
*
call
)
{
const
char
*
file
,
int
line
,
const
char
*
obj
,
const
char
*
call
)
{
LogWithLocation
(
internal
::
INFO
,
file
,
line
,
LogWithLocation
(
internal
::
INFO
,
file
,
line
,
string
(
"EXPECT_CALL("
)
+
obj
+
", "
+
call
+
") invoked"
);
string
(
"EXPECT_CALL("
)
+
obj
+
", "
+
call
+
") invoked"
);
...
@@ -1247,18 +1432,18 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
...
@@ -1247,18 +1432,18 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Adds and returns an expectation spec for this mock function.
// Adds and returns an expectation spec for this mock function.
// L < g_gmock_mutex
// L < g_gmock_mutex
Expectation
<
F
>&
AddNewExpectation
(
Typed
Expectation
<
F
>&
AddNewExpectation
(
const
char
*
file
,
int
line
,
const
char
*
file
,
int
line
,
const
ArgumentMatcherTuple
&
m
)
{
const
ArgumentMatcherTuple
&
m
)
{
Mock
::
RegisterUseByOnCallOrExpectCall
(
MockObject
(),
file
,
line
);
Mock
::
RegisterUseByOnCallOrExpectCall
(
MockObject
(),
file
,
line
);
const
linked_ptr
<
Expectation
<
F
>
>
expectation
(
const
linked_ptr
<
Typed
Expectation
<
F
>
>
expectation
(
new
Expectation
<
F
>
(
this
,
file
,
line
,
m
));
new
Typed
Expectation
<
F
>
(
this
,
file
,
line
,
m
));
expectations_
.
push_back
(
expectation
);
expectations_
.
push_back
(
expectation
);
// Adds this expectation into the implicit sequence if there is one.
// Adds this expectation into the implicit sequence if there is one.
Sequence
*
const
implicit_sequence
=
g_gmock_implicit_sequence
.
get
();
Sequence
*
const
implicit_sequence
=
g_gmock_implicit_sequence
.
get
();
if
(
implicit_sequence
!=
NULL
)
{
if
(
implicit_sequence
!=
NULL
)
{
implicit_sequence
->
AddExpectation
(
expectation
);
implicit_sequence
->
AddExpectation
(
Expectation
(
expectation
)
)
;
}
}
return
*
expectation
;
return
*
expectation
;
...
@@ -1268,22 +1453,23 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
...
@@ -1268,22 +1453,23 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// being described on this function mocker.
// being described on this function mocker.
MockSpec
<
F
>&
current_spec
()
{
return
current_spec_
;
}
MockSpec
<
F
>&
current_spec
()
{
return
current_spec_
;
}
private:
private:
template
<
typename
Func
>
friend
class
Expectation
;
template
<
typename
Func
>
friend
class
Typed
Expectation
;
typedef
std
::
vector
<
internal
::
linked_ptr
<
Expectation
<
F
>
>
>
Expectations
;
typedef
std
::
vector
<
internal
::
linked_ptr
<
TypedExpectation
<
F
>
>
>
TypedExpectations
;
//
G
et
s the internal::linked_ptr<
Expectation
Base>
object that co-owns
'
exp
'.
//
R
et
urns an
Expectation object that
references and
co-owns exp
,
internal
::
linked_ptr
<
ExpectationBase
>
GetLinkedExpectationBase
(
// which must be an expectation on this mock function.
Expectation
<
F
>*
exp
)
{
Expectation
GetHandleOf
(
Typed
Expectation
<
F
>*
exp
)
{
for
(
typename
Expectations
::
const_iterator
it
=
expectations_
.
begin
();
for
(
typename
Typed
Expectations
::
const_iterator
it
=
expectations_
.
begin
();
it
!=
expectations_
.
end
();
++
it
)
{
it
!=
expectations_
.
end
();
++
it
)
{
if
(
it
->
get
()
==
exp
)
{
if
(
it
->
get
()
==
exp
)
{
return
*
it
;
return
Expectation
(
*
it
)
;
}
}
}
}
Assert
(
false
,
__FILE__
,
__LINE__
,
"Cannot find expectation."
);
Assert
(
false
,
__FILE__
,
__LINE__
,
"Cannot find expectation."
);
return
internal
::
linked_ptr
<
Expectation
Base
>
(
NULL
);
return
Expectation
(
);
// The above statement is just to make the code compile, and will
// The above statement is just to make the code compile, and will
// never be executed.
// never be executed.
}
}
...
@@ -1330,7 +1516,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
...
@@ -1330,7 +1516,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// mock function) and excessive locking could cause a dead lock.
// mock function) and excessive locking could cause a dead lock.
// L < g_gmock_mutex
// L < g_gmock_mutex
bool
FindMatchingExpectationAndAction
(
bool
FindMatchingExpectationAndAction
(
const
ArgumentTuple
&
args
,
Expectation
<
F
>**
exp
,
Action
<
F
>*
action
,
const
ArgumentTuple
&
args
,
Typed
Expectation
<
F
>**
exp
,
Action
<
F
>*
action
,
bool
*
is_excessive
,
::
std
::
ostream
*
what
,
::
std
::
ostream
*
why
)
{
bool
*
is_excessive
,
::
std
::
ostream
*
what
,
::
std
::
ostream
*
why
)
{
MutexLock
l
(
&
g_gmock_mutex
);
MutexLock
l
(
&
g_gmock_mutex
);
*
exp
=
this
->
FindMatchingExpectationLocked
(
args
);
*
exp
=
this
->
FindMatchingExpectationLocked
(
args
);
...
@@ -1351,13 +1537,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
...
@@ -1351,13 +1537,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Returns the expectation that matches the arguments, or NULL if no
// Returns the expectation that matches the arguments, or NULL if no
// expectation matches them.
// expectation matches them.
// L >= g_gmock_mutex
// L >= g_gmock_mutex
Expectation
<
F
>*
FindMatchingExpectationLocked
(
Typed
Expectation
<
F
>*
FindMatchingExpectationLocked
(
const
ArgumentTuple
&
args
)
const
{
const
ArgumentTuple
&
args
)
const
{
g_gmock_mutex
.
AssertHeld
();
g_gmock_mutex
.
AssertHeld
();
for
(
typename
Expectations
::
const_reverse_iterator
it
=
for
(
typename
Typed
Expectations
::
const_reverse_iterator
it
=
expectations_
.
rbegin
();
expectations_
.
rbegin
();
it
!=
expectations_
.
rend
();
++
it
)
{
it
!=
expectations_
.
rend
();
++
it
)
{
Expectation
<
F
>*
const
exp
=
it
->
get
();
Typed
Expectation
<
F
>*
const
exp
=
it
->
get
();
if
(
exp
->
ShouldHandleArguments
(
args
))
{
if
(
exp
->
ShouldHandleArguments
(
args
))
{
return
exp
;
return
exp
;
}
}
...
@@ -1415,7 +1601,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
...
@@ -1415,7 +1601,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// All default action specs for this function mocker.
// All default action specs for this function mocker.
std
::
vector
<
DefaultActionSpec
<
F
>
>
default_actions_
;
std
::
vector
<
DefaultActionSpec
<
F
>
>
default_actions_
;
// All expectations for this function mocker.
// All expectations for this function mocker.
Expectations
expectations_
;
Typed
Expectations
expectations_
;
// There is no generally useful and implementable semantics of
// There is no generally useful and implementable semantics of
// copying a mock object, so copying a mock is usually a user error.
// copying a mock object, so copying a mock is usually a user error.
...
@@ -1446,9 +1632,9 @@ template <typename F>
...
@@ -1446,9 +1632,9 @@ template <typename F>
bool
FunctionMockerBase
<
F
>::
VerifyAndClearExpectationsLocked
()
{
bool
FunctionMockerBase
<
F
>::
VerifyAndClearExpectationsLocked
()
{
g_gmock_mutex
.
AssertHeld
();
g_gmock_mutex
.
AssertHeld
();
bool
expectations_met
=
true
;
bool
expectations_met
=
true
;
for
(
typename
Expectations
::
const_iterator
it
=
expectations_
.
begin
();
for
(
typename
Typed
Expectations
::
const_iterator
it
=
expectations_
.
begin
();
it
!=
expectations_
.
end
();
++
it
)
{
it
!=
expectations_
.
end
();
++
it
)
{
Expectation
<
F
>*
const
exp
=
it
->
get
();
Typed
Expectation
<
F
>*
const
exp
=
it
->
get
();
if
(
exp
->
IsOverSaturated
())
{
if
(
exp
->
IsOverSaturated
())
{
// There was an upper-bound violation. Since the error was
// There was an upper-bound violation. Since the error was
...
@@ -1532,7 +1718,7 @@ typename Function<F>::Result FunctionMockerBase<F>::InvokeWith(
...
@@ -1532,7 +1718,7 @@ typename Function<F>::Result FunctionMockerBase<F>::InvokeWith(
::
std
::
stringstream
why
;
::
std
::
stringstream
why
;
::
std
::
stringstream
loc
;
::
std
::
stringstream
loc
;
Action
<
F
>
action
;
Action
<
F
>
action
;
Expectation
<
F
>*
exp
;
Typed
Expectation
<
F
>*
exp
;
// The FindMatchingExpectationAndAction() function acquires and
// The FindMatchingExpectationAndAction() function acquires and
// releases g_gmock_mutex.
// releases g_gmock_mutex.
...
@@ -1605,6 +1791,10 @@ using internal::MockSpec;
...
@@ -1605,6 +1791,10 @@ using internal::MockSpec;
template
<
typename
T
>
template
<
typename
T
>
inline
const
T
&
Const
(
const
T
&
x
)
{
return
x
;
}
inline
const
T
&
Const
(
const
T
&
x
)
{
return
x
;
}
// Constructs an Expectation object that references and co-owns exp.
inline
Expectation
::
Expectation
(
internal
::
ExpectationBase
&
exp
)
// NOLINT
:
expectation_base_
(
exp
.
GetHandle
().
expectation_base
())
{}
}
// namespace testing
}
// namespace testing
// A separate macro is required to avoid compile errors when the name
// A separate macro is required to avoid compile errors when the name
...
...
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