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 {
// Constructs a null Action. Needed for storing Action objects in
// STL containers.
Action
()
:
impl_
(
NULL
)
{}
Action
()
{}
// Constructs an Action from its implementation. A NULL impl is
// used to represent the "do-default" action.
explicit
Action
(
ActionInterface
<
F
>*
impl
)
:
impl_
(
impl
)
{}
#if GTEST_LANG_CXX11
// Construct an Action from a specified callable.
// 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
.
Action
(
const
Action
&
action
)
:
impl_
(
action
.
impl_
)
{}
// Co
nstructs an Action from its implementation
.
explicit
Action
(
ActionInterface
<
F
>*
impl
)
:
impl_
(
impl
)
{}
// This constructor allows us to turn an Action<Func> object into an
// Action<F>, as long as F's arguments can be implicitly converted
...
...
@@ -377,7 +383,13 @@ class Action {
explicit
Action
(
const
Action
<
Func
>&
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
// the corresponding method in ActionInterface is not. The reason
...
...
@@ -385,14 +397,15 @@ class Action {
// another concrete action, not that the concrete action it binds to
// cannot change state. (Think of the difference between a const
// pointer and a pointer to const.)
Result
Perform
(
const
ArgumentTuple
&
args
)
const
{
internal
::
Assert
(
!
IsDoDefault
(),
__FILE__
,
__LINE__
,
"You are using DoDefault() inside a composite action like "
"DoAll() or WithArgs(). This is not supported for technical "
"reasons. Please instead spell out the default action, or "
"assign the default action to an Action variable and use "
"the variable in various places."
);
Result
Perform
(
ArgumentTuple
args
)
const
{
if
(
IsDoDefault
())
{
internal
::
IllegalDoDefault
(
__FILE__
,
__LINE__
);
}
#if GTEST_LANG_CXX11
if
(
fun_
!=
nullptr
)
{
return
internal
::
Apply
(
fun_
,
::
std
::
move
(
args
));
}
#endif
return
impl_
->
Perform
(
args
);
}
...
...
@@ -400,6 +413,18 @@ class Action {
template
<
typename
F1
,
typename
F2
>
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_
;
};
...
...
@@ -531,6 +556,9 @@ struct ByMoveWrapper {
// statement, and conversion of the result of Return to Action<T(U)> is a
// 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
>
class
ReturnAction
{
public
:
...
...
@@ -750,7 +778,7 @@ class DoDefaultAction {
// This template type conversion operator allows DoDefault() to be
// used in any function.
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
...
...
@@ -886,6 +914,28 @@ class 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.
template
<
typename
A
>
class
IgnoreResultAction
{
...
...
@@ -1053,7 +1103,13 @@ typedef internal::IgnoredValue Unused;
template
<
typename
To
>
template
<
typename
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
// instead of const reference - otherwise Return("string literal")
...
...
googlemock/test/gmock-actions_test.cc
View file @
88fc7d75
...
...
@@ -65,6 +65,7 @@ using testing::ReturnRef;
using
testing
::
ReturnRefOfCopy
;
using
testing
::
SetArgPointee
;
using
testing
::
SetArgumentPointee
;
using
testing
::
Unused
;
using
testing
::
_
;
using
testing
::
get
;
using
testing
::
internal
::
BuiltInDefaultValue
;
...
...
@@ -705,6 +706,8 @@ class MockClass {
MOCK_METHOD0
(
MakeUniqueBase
,
std
::
unique_ptr
<
Base
>
());
MOCK_METHOD0
(
MakeVectorUnique
,
std
::
vector
<
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
private
:
...
...
@@ -756,7 +759,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
}
// 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
)
{
DefaultValue
<
int
>::
Set
(
1
);
MockClass
mock
;
...
...
@@ -1411,6 +1414,145 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
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_
#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
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