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
88fc7d75
Commit
88fc7d75
authored
Apr 06, 2018
by
Gennadiy Civil
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
merging gmock-actions 2
parent
bee1d13f
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
216 additions
and
18 deletions
+216
-18
gmock-actions.h
googlemock/include/gmock/gmock-actions.h
+73
-17
gmock-actions_test.cc
googlemock/test/gmock-actions_test.cc
+143
-1
No files found.
googlemock/include/gmock/gmock-actions.h
View file @
88fc7d75
...
@@ -360,14 +360,20 @@ class Action {
...
@@ -360,14 +360,20 @@ class Action {
// Constructs a null Action. Needed for storing Action objects in
// Constructs a null Action. Needed for storing Action objects in
// STL containers.
// STL containers.
Action
()
:
impl_
(
NULL
)
{}
Action
()
{}
// Constructs an Action from its implementation. A NULL impl is
#if GTEST_LANG_CXX11
// used to represent the "do-default" action.
// Construct an Action from a specified callable.
explicit
Action
(
ActionInterface
<
F
>*
impl
)
:
impl_
(
impl
)
{}
// This cannot take std::function directly, because then Action would not be
// directly constructible from lambda (it would require two conversions).
template
<
typename
G
,
typename
=
typename
::
std
::
enable_if
<
::
std
::
is_constructible
<::
std
::
function
<
F
>
,
G
>::
value
>::
type
>
Action
(
G
&&
fun
)
:
fun_
(
::
std
::
forward
<
G
>
(
fun
))
{}
// NOLINT
#endif
// Co
py constructor
.
// Co
nstructs an Action from its implementation
.
Action
(
const
Action
&
action
)
:
impl_
(
action
.
impl_
)
{}
explicit
Action
(
ActionInterface
<
F
>*
impl
)
:
impl_
(
impl
)
{}
// This constructor allows us to turn an Action<Func> object into an
// This constructor allows us to turn an Action<Func> object into an
// Action<F>, as long as F's arguments can be implicitly converted
// Action<F>, as long as F's arguments can be implicitly converted
...
@@ -377,7 +383,13 @@ class Action {
...
@@ -377,7 +383,13 @@ class Action {
explicit
Action
(
const
Action
<
Func
>&
action
);
explicit
Action
(
const
Action
<
Func
>&
action
);
// Returns true iff this is the DoDefault() action.
// Returns true iff this is the DoDefault() action.
bool
IsDoDefault
()
const
{
return
impl_
.
get
()
==
NULL
;
}
bool
IsDoDefault
()
const
{
#if GTEST_LANG_CXX11
return
impl_
==
nullptr
&&
fun_
==
nullptr
;
#else
return
impl_
==
NULL
;
#endif
}
// Performs the action. Note that this method is const even though
// Performs the action. Note that this method is const even though
// the corresponding method in ActionInterface is not. The reason
// the corresponding method in ActionInterface is not. The reason
...
@@ -385,14 +397,15 @@ class Action {
...
@@ -385,14 +397,15 @@ class Action {
// another concrete action, not that the concrete action it binds to
// another concrete action, not that the concrete action it binds to
// cannot change state. (Think of the difference between a const
// cannot change state. (Think of the difference between a const
// pointer and a pointer to const.)
// pointer and a pointer to const.)
Result
Perform
(
const
ArgumentTuple
&
args
)
const
{
Result
Perform
(
ArgumentTuple
args
)
const
{
internal
::
Assert
(
if
(
IsDoDefault
())
{
!
IsDoDefault
(),
__FILE__
,
__LINE__
,
internal
::
IllegalDoDefault
(
__FILE__
,
__LINE__
);
"You are using DoDefault() inside a composite action like "
}
"DoAll() or WithArgs(). This is not supported for technical "
#if GTEST_LANG_CXX11
"reasons. Please instead spell out the default action, or "
if
(
fun_
!=
nullptr
)
{
"assign the default action to an Action variable and use "
return
internal
::
Apply
(
fun_
,
::
std
::
move
(
args
));
"the variable in various places."
);
}
#endif
return
impl_
->
Perform
(
args
);
return
impl_
->
Perform
(
args
);
}
}
...
@@ -400,6 +413,18 @@ class Action {
...
@@ -400,6 +413,18 @@ class Action {
template
<
typename
F1
,
typename
F2
>
template
<
typename
F1
,
typename
F2
>
friend
class
internal
::
ActionAdaptor
;
friend
class
internal
::
ActionAdaptor
;
template
<
typename
G
>
friend
class
Action
;
// In C++11, Action can be implemented either as a generic functor (through
// std::function), or legacy ActionInterface. In C++98, only ActionInterface
// is available. The invariants are as follows:
// * in C++98, impl_ is null iff this is the default action
// * in C++11, at most one of fun_ & impl_ may be nonnull; both are null iff
// this is the default action
#if GTEST_LANG_CXX11
::
std
::
function
<
F
>
fun_
;
#endif
internal
::
linked_ptr
<
ActionInterface
<
F
>
>
impl_
;
internal
::
linked_ptr
<
ActionInterface
<
F
>
>
impl_
;
};
};
...
@@ -531,6 +556,9 @@ struct ByMoveWrapper {
...
@@ -531,6 +556,9 @@ struct ByMoveWrapper {
// statement, and conversion of the result of Return to Action<T(U)> is a
// statement, and conversion of the result of Return to Action<T(U)> is a
// good place for that.
// good place for that.
//
//
// The real life example of the above scenario happens when an invocation
// of gtl::Container() is passed into Return.
//
template
<
typename
R
>
template
<
typename
R
>
class
ReturnAction
{
class
ReturnAction
{
public
:
public
:
...
@@ -750,7 +778,7 @@ class DoDefaultAction {
...
@@ -750,7 +778,7 @@ class DoDefaultAction {
// This template type conversion operator allows DoDefault() to be
// This template type conversion operator allows DoDefault() to be
// used in any function.
// used in any function.
template
<
typename
F
>
template
<
typename
F
>
operator
Action
<
F
>
()
const
{
return
Action
<
F
>
(
NULL
);
}
operator
Action
<
F
>
()
const
{
return
Action
<
F
>
(
);
}
// NOLINT
};
};
// Implements the Assign action to set a given pointer referent to a
// Implements the Assign action to set a given pointer referent to a
...
@@ -886,6 +914,28 @@ class InvokeMethodWithoutArgsAction {
...
@@ -886,6 +914,28 @@ class InvokeMethodWithoutArgsAction {
GTEST_DISALLOW_ASSIGN_
(
InvokeMethodWithoutArgsAction
);
GTEST_DISALLOW_ASSIGN_
(
InvokeMethodWithoutArgsAction
);
};
};
// Implements the InvokeWithoutArgs(callback) action.
template
<
typename
CallbackType
>
class
InvokeCallbackWithoutArgsAction
{
public
:
// The c'tor takes ownership of the callback.
explicit
InvokeCallbackWithoutArgsAction
(
CallbackType
*
callback
)
:
callback_
(
callback
)
{
callback
->
CheckIsRepeatable
();
// Makes sure the callback is permanent.
}
// This type conversion operator template allows Invoke(callback) to
// be used wherever the callback's return type can be implicitly
// converted to that of the mock function.
template
<
typename
Result
,
typename
ArgumentTuple
>
Result
Perform
(
const
ArgumentTuple
&
)
const
{
return
callback_
->
Run
();
}
private
:
const
internal
::
linked_ptr
<
CallbackType
>
callback_
;
GTEST_DISALLOW_ASSIGN_
(
InvokeCallbackWithoutArgsAction
);
};
// Implements the IgnoreResult(action) action.
// Implements the IgnoreResult(action) action.
template
<
typename
A
>
template
<
typename
A
>
class
IgnoreResultAction
{
class
IgnoreResultAction
{
...
@@ -1053,7 +1103,13 @@ typedef internal::IgnoredValue Unused;
...
@@ -1053,7 +1103,13 @@ typedef internal::IgnoredValue Unused;
template
<
typename
To
>
template
<
typename
To
>
template
<
typename
From
>
template
<
typename
From
>
Action
<
To
>::
Action
(
const
Action
<
From
>&
from
)
Action
<
To
>::
Action
(
const
Action
<
From
>&
from
)
:
impl_
(
new
internal
::
ActionAdaptor
<
To
,
From
>
(
from
))
{}
:
#if GTEST_LANG_CXX11
fun_
(
from
.
fun_
),
#endif
impl_
(
from
.
impl_
==
NULL
?
NULL
:
new
internal
::
ActionAdaptor
<
To
,
From
>
(
from
))
{
}
// Creates an action that returns 'value'. 'value' is passed by value
// Creates an action that returns 'value'. 'value' is passed by value
// instead of const reference - otherwise Return("string literal")
// instead of const reference - otherwise Return("string literal")
...
...
googlemock/test/gmock-actions_test.cc
View file @
88fc7d75
...
@@ -65,6 +65,7 @@ using testing::ReturnRef;
...
@@ -65,6 +65,7 @@ using testing::ReturnRef;
using
testing
::
ReturnRefOfCopy
;
using
testing
::
ReturnRefOfCopy
;
using
testing
::
SetArgPointee
;
using
testing
::
SetArgPointee
;
using
testing
::
SetArgumentPointee
;
using
testing
::
SetArgumentPointee
;
using
testing
::
Unused
;
using
testing
::
_
;
using
testing
::
_
;
using
testing
::
get
;
using
testing
::
get
;
using
testing
::
internal
::
BuiltInDefaultValue
;
using
testing
::
internal
::
BuiltInDefaultValue
;
...
@@ -705,6 +706,8 @@ class MockClass {
...
@@ -705,6 +706,8 @@ class MockClass {
MOCK_METHOD0
(
MakeUniqueBase
,
std
::
unique_ptr
<
Base
>
());
MOCK_METHOD0
(
MakeUniqueBase
,
std
::
unique_ptr
<
Base
>
());
MOCK_METHOD0
(
MakeVectorUnique
,
std
::
vector
<
std
::
unique_ptr
<
int
>>
());
MOCK_METHOD0
(
MakeVectorUnique
,
std
::
vector
<
std
::
unique_ptr
<
int
>>
());
MOCK_METHOD1
(
TakeUnique
,
int
(
std
::
unique_ptr
<
int
>
));
MOCK_METHOD1
(
TakeUnique
,
int
(
std
::
unique_ptr
<
int
>
));
MOCK_METHOD2
(
TakeUnique
,
int
(
const
std
::
unique_ptr
<
int
>&
,
std
::
unique_ptr
<
int
>
));
#endif
#endif
private
:
private
:
...
@@ -756,7 +759,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
...
@@ -756,7 +759,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
}
}
// Tests that DoDefault() returns the default value set by
// Tests that DoDefault() returns the default value set by
// DefaultValue<T>::Set() when it's not overrid
d
en by an ON_CALL().
// DefaultValue<T>::Set() when it's not overriden by an ON_CALL().
TEST
(
DoDefaultTest
,
ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne
)
{
TEST
(
DoDefaultTest
,
ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne
)
{
DefaultValue
<
int
>::
Set
(
1
);
DefaultValue
<
int
>::
Set
(
1
);
MockClass
mock
;
MockClass
mock
;
...
@@ -1411,6 +1414,145 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
...
@@ -1411,6 +1414,145 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
EXPECT_EQ
(
7
,
*
vresult
[
0
]);
EXPECT_EQ
(
7
,
*
vresult
[
0
]);
}
}
TEST
(
MockMethodTest
,
CanTakeMoveOnlyValue
)
{
MockClass
mock
;
auto
make
=
[](
int
i
)
{
return
std
::
unique_ptr
<
int
>
(
new
int
(
i
));
};
EXPECT_CALL
(
mock
,
TakeUnique
(
_
)).
WillRepeatedly
([](
std
::
unique_ptr
<
int
>
i
)
{
return
*
i
;
});
// DoAll() does not compile, since it would move from its arguments twice.
// EXPECT_CALL(mock, TakeUnique(_, _))
// .WillRepeatedly(DoAll(Invoke([](std::unique_ptr<int> j) {}),
// Return(1)));
EXPECT_CALL
(
mock
,
TakeUnique
(
testing
::
Pointee
(
7
)))
.
WillOnce
(
Return
(
-
7
))
.
RetiresOnSaturation
();
EXPECT_CALL
(
mock
,
TakeUnique
(
testing
::
IsNull
()))
.
WillOnce
(
Return
(
-
1
))
.
RetiresOnSaturation
();
EXPECT_EQ
(
5
,
mock
.
TakeUnique
(
make
(
5
)));
EXPECT_EQ
(
-
7
,
mock
.
TakeUnique
(
make
(
7
)));
EXPECT_EQ
(
7
,
mock
.
TakeUnique
(
make
(
7
)));
EXPECT_EQ
(
7
,
mock
.
TakeUnique
(
make
(
7
)));
EXPECT_EQ
(
-
1
,
mock
.
TakeUnique
({}));
// Some arguments are moved, some passed by reference.
auto
lvalue
=
make
(
6
);
EXPECT_CALL
(
mock
,
TakeUnique
(
_
,
_
))
.
WillOnce
([](
const
std
::
unique_ptr
<
int
>&
i
,
std
::
unique_ptr
<
int
>
j
)
{
return
*
i
*
*
j
;
});
EXPECT_EQ
(
42
,
mock
.
TakeUnique
(
lvalue
,
make
(
7
)));
// The unique_ptr can be saved by the action.
std
::
unique_ptr
<
int
>
saved
;
EXPECT_CALL
(
mock
,
TakeUnique
(
_
)).
WillOnce
([
&
saved
](
std
::
unique_ptr
<
int
>
i
)
{
saved
=
std
::
move
(
i
);
return
0
;
});
EXPECT_EQ
(
0
,
mock
.
TakeUnique
(
make
(
42
)));
EXPECT_EQ
(
42
,
*
saved
);
}
#endif // GTEST_HAS_STD_UNIQUE_PTR_
#endif // GTEST_HAS_STD_UNIQUE_PTR_
#if GTEST_LANG_CXX11
// Tests for std::function based action.
int
Add
(
int
val
,
int
&
ref
,
int
*
ptr
)
{
// NOLINT
int
result
=
val
+
ref
+
*
ptr
;
ref
=
42
;
*
ptr
=
43
;
return
result
;
}
int
Deref
(
std
::
unique_ptr
<
int
>
ptr
)
{
return
*
ptr
;
}
struct
Double
{
template
<
typename
T
>
T
operator
()(
T
t
)
{
return
2
*
t
;
}
};
std
::
unique_ptr
<
int
>
UniqueInt
(
int
i
)
{
return
std
::
unique_ptr
<
int
>
(
new
int
(
i
));
}
TEST
(
FunctorActionTest
,
ActionFromFunction
)
{
Action
<
int
(
int
,
int
&
,
int
*
)
>
a
=
&
Add
;
int
x
=
1
,
y
=
2
,
z
=
3
;
EXPECT_EQ
(
6
,
a
.
Perform
(
std
::
forward_as_tuple
(
x
,
y
,
&
z
)));
EXPECT_EQ
(
42
,
y
);
EXPECT_EQ
(
43
,
z
);
Action
<
int
(
std
::
unique_ptr
<
int
>
)
>
a1
=
&
Deref
;
EXPECT_EQ
(
7
,
a1
.
Perform
(
std
::
make_tuple
(
UniqueInt
(
7
))));
}
TEST
(
FunctorActionTest
,
ActionFromLambda
)
{
Action
<
int
(
bool
,
int
)
>
a1
=
[](
bool
b
,
int
i
)
{
return
b
?
i
:
0
;
};
EXPECT_EQ
(
5
,
a1
.
Perform
(
make_tuple
(
true
,
5
)));
EXPECT_EQ
(
0
,
a1
.
Perform
(
make_tuple
(
false
,
5
)));
std
::
unique_ptr
<
int
>
saved
;
Action
<
void
(
std
::
unique_ptr
<
int
>
)
>
a2
=
[
&
saved
](
std
::
unique_ptr
<
int
>
p
)
{
saved
=
std
::
move
(
p
);
};
a2
.
Perform
(
make_tuple
(
UniqueInt
(
5
)));
EXPECT_EQ
(
5
,
*
saved
);
}
TEST
(
FunctorActionTest
,
PolymorphicFunctor
)
{
Action
<
int
(
int
)
>
ai
=
Double
();
EXPECT_EQ
(
2
,
ai
.
Perform
(
make_tuple
(
1
)));
Action
<
double
(
double
)
>
ad
=
Double
();
// Double? Double double!
EXPECT_EQ
(
3.0
,
ad
.
Perform
(
make_tuple
(
1.5
)));
}
TEST
(
FunctorActionTest
,
TypeConversion
)
{
// Numeric promotions are allowed.
const
Action
<
bool
(
int
)
>
a1
=
[](
int
i
)
{
return
i
>
1
;
};
const
Action
<
int
(
bool
)
>
a2
=
Action
<
int
(
bool
)
>
(
a1
);
EXPECT_EQ
(
1
,
a1
.
Perform
(
make_tuple
(
42
)));
EXPECT_EQ
(
0
,
a2
.
Perform
(
make_tuple
(
42
)));
// Implicit constructors are allowed.
const
Action
<
bool
(
std
::
string
)
>
s1
=
[](
std
::
string
s
)
{
return
!
s
.
empty
();
};
const
Action
<
int
(
const
char
*
)
>
s2
=
Action
<
int
(
const
char
*
)
>
(
s1
);
EXPECT_EQ
(
0
,
s2
.
Perform
(
make_tuple
(
""
)));
EXPECT_EQ
(
1
,
s2
.
Perform
(
make_tuple
(
"hello"
)));
// Also between the lambda and the action itself.
const
Action
<
bool
(
std
::
string
)
>
x
=
[](
Unused
)
{
return
42
;
};
EXPECT_TRUE
(
x
.
Perform
(
make_tuple
(
"hello"
)));
}
TEST
(
FunctorActionTest
,
UnusedArguments
)
{
// Verify that users can ignore uninteresting arguments.
Action
<
int
(
int
,
std
::
unique_ptr
<
int
>
,
const
int
&
)
>
a
=
[](
int
i
,
Unused
,
Unused
)
{
return
2
*
i
;
};
EXPECT_EQ
(
6
,
a
.
Perform
(
make_tuple
(
3
,
UniqueInt
(
7
),
9
)));
}
// Test that basic built-in actions work with move-only arguments.
// TODO(rburny): Currently, almost all ActionInterface-based actions will not
// work, even if they only try to use other, copyable arguments. Implement them
// if necessary (but note that DoAll cannot work on non-copyable types anyway -
// so maybe it's better to make users use lambdas instead.
TEST
(
MoveOnlyArgumentsTest
,
ReturningActions
)
{
Action
<
int
(
std
::
unique_ptr
<
int
>
)
>
a
=
Return
(
1
);
EXPECT_EQ
(
1
,
a
.
Perform
(
make_tuple
(
nullptr
)));
a
=
testing
::
WithoutArgs
([]()
{
return
7
;
});
EXPECT_EQ
(
7
,
a
.
Perform
(
make_tuple
(
nullptr
)));
Action
<
void
(
std
::
unique_ptr
<
int
>
,
int
*
)
>
a2
=
testing
::
SetArgPointee
<
1
>
(
3
);
int
x
=
0
;
a2
.
Perform
(
make_tuple
(
nullptr
,
&
x
));
EXPECT_EQ
(
x
,
3
);
}
#endif // GTEST_LANG_CXX11
}
// Unnamed namespace
}
// Unnamed namespace
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