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
a070cbd9
Commit
a070cbd9
authored
Nov 18, 2009
by
vladlosev
Browse files
Enables gmock's implicit_cast to work with source types that
parent
2871bb4d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
81 additions
and
3 deletions
+81
-3
include/gmock/gmock-actions.h
include/gmock/gmock-actions.h
+34
-3
test/gmock-actions_test.cc
test/gmock-actions_test.cc
+47
-0
No files found.
include/gmock/gmock-actions.h
View file @
a070cbd9
...
...
@@ -310,7 +310,7 @@ class Action {
// This constructor allows us to turn an Action<Func> object into an
// Action<F>, as long as F's arguments can be implicitly converted
// to Func's and Func's return type can
n
be implicitly converted to
// to Func's and Func's return type can be implicitly converted to
// F's.
template
<
typename
Func
>
explicit
Action
(
const
Action
<
Func
>&
action
);
...
...
@@ -425,6 +425,27 @@ class ActionAdaptor : public ActionInterface<F1> {
// Implements the polymorphic Return(x) action, which can be used in
// any function that returns the type of x, regardless of the argument
// types.
//
// Note: The value passed into Return must be converted into
// Function<F>::Result when this action is cast to Action<F> rather than
// when that action is performed. This is important in scenarios like
//
// MOCK_METHOD1(Method, T(U));
// ...
// {
// Foo foo;
// X x(&foo);
// EXPECT_CALL(mock, Method(_)).WillOnce(Return(x));
// }
//
// In the example above the variable x holds reference to foo which leaves
// scope and gets destroyed. If copying X just copies a reference to foo,
// that copy will be left with a hanging reference. If conversion to T
// makes a copy of foo, the above code is safe. To support that scenario, we
// need to make sure that the type conversion happens inside the EXPECT_CALL
// statement, and conversion of the result of Return to Action<T(U)> is a
// good place for that.
//
template
<
typename
R
>
class
ReturnAction
{
public:
...
...
@@ -459,12 +480,22 @@ class ReturnAction {
typedef
typename
Function
<
F
>::
Result
Result
;
typedef
typename
Function
<
F
>::
ArgumentTuple
ArgumentTuple
;
explicit
Impl
(
R
value
)
:
value_
(
value
)
{}
// The implicit cast is necessary when Result has more than one
// single-argument constructor (e.g. Result is std::vector<int>) and R
// has a type conversion operator template. In that case, value_(value)
// won't compile as the compiler doesn't known which constructor of
// Result to call. implicit_cast forces the compiler to convert R to
// Result without considering explicit constructors, thus resolving the
// ambiguity. value_ is then initialized using its copy constructor.
explicit
Impl
(
R
value
)
:
value_
(
::
testing
::
internal
::
implicit_cast
<
Result
>
(
value
))
{}
virtual
Result
Perform
(
const
ArgumentTuple
&
)
{
return
value_
;
}
private:
R
value_
;
GMOCK_COMPILE_ASSERT_
(
!
internal
::
is_reference
<
Result
>::
value
,
Result_cannot_be_a_reference_type
);
Result
value_
;
};
R
value_
;
...
...
test/gmock-actions_test.cc
View file @
a070cbd9
...
...
@@ -515,6 +515,53 @@ TEST(ReturnTest, IsCovariant) {
EXPECT_EQ
(
&
derived
,
ret
.
Perform
(
make_tuple
()));
}
// Tests that the type of the value passed into Return is converted into T
// when the action is cast to Action<T(...)> rather than when the action is
// performed. See comments on testing::internal::ReturnAction in
// gmock-actions.h for more information.
class
FromType
{
public:
FromType
(
bool
*
converted
)
:
converted_
(
converted
)
{}
bool
*
converted
()
const
{
return
converted_
;
}
private:
bool
*
const
converted_
;
};
class
ToType
{
public:
ToType
(
const
FromType
&
x
)
{
*
x
.
converted
()
=
true
;
}
};
TEST
(
ReturnTest
,
ConvertsArgumentWhenConverted
)
{
bool
converted
=
false
;
FromType
x
(
&
converted
);
Action
<
ToType
()
>
action
(
Return
(
x
));
EXPECT_TRUE
(
converted
)
<<
"Return must convert its argument in its own "
<<
"conversion operator."
;
converted
=
false
;
action
.
Perform
(
tuple
<>
());
EXPECT_FALSE
(
converted
)
<<
"Action must NOT convert its argument "
<<
"when performed."
;
}
// We do not support non-const type conversions on Symbian. See
// definition of implicit_cast in gmock-port.h for more information.
#if !GTEST_OS_SYMBIAN
class
DestinationType
{};
class
SourceType
{
public:
// Note: a non-const typecast operator.
operator
DestinationType
()
{
return
DestinationType
();
}
};
TEST
(
ReturnTest
,
CanConvertArgumentUsingNonConstTypeCastOperator
)
{
SourceType
s
;
Action
<
DestinationType
()
>
action
(
Return
(
s
));
}
#endif // !GTEST_OS_SYMBIAN
// Tests that ReturnNull() returns NULL in a pointer-returning function.
TEST
(
ReturnNullTest
,
WorksInPointerReturningFunction
)
{
const
Action
<
int
*
()
>
a1
=
ReturnNull
();
...
...
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