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
d89b3630
Commit
d89b3630
authored
Nov 06, 2020
by
Abseil Team
Committed by
Andy Getz
Nov 06, 2020
Browse files
Googletest export
Add support for ref qualifiers in MOCK_METHOD. PiperOrigin-RevId: 341047839
parent
710f9c11
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
118 additions
and
28 deletions
+118
-28
googlemock/docs/cook_book.md
googlemock/docs/cook_book.md
+3
-0
googlemock/include/gmock/gmock-function-mocker.h
googlemock/include/gmock/gmock-function-mocker.h
+49
-28
googlemock/test/gmock-function-mocker_test.cc
googlemock/test/gmock-function-mocker_test.cc
+66
-0
No files found.
googlemock/docs/cook_book.md
View file @
d89b3630
...
...
@@ -37,6 +37,9 @@ generated method:
`noexcept`
method.
*
**`Calltype(...)`**
- Sets the call type for the method (e.g. to
`STDMETHODCALLTYPE`
), useful in Windows.
*
**`ref(...)`**
- Marks the method with the reference qualification
specified. Required if overriding a method that has reference
qualifications. Eg
`ref(&)`
or
`ref(&&)`
.
### Dealing with unprotected commas
...
...
googlemock/include/gmock/gmock-function-mocker.h
View file @
d89b3630
...
...
@@ -48,15 +48,21 @@ namespace internal {
template
<
typename
T
>
using
identity_t
=
T
;
template
<
typename
MockType
>
const
MockType
*
AdjustConstness_const
(
const
MockType
*
mock
)
{
return
mock
;
}
template
<
typename
MockType
>
MockType
*
AdjustConstness_
(
const
MockType
*
mock
)
{
return
const_cast
<
MockType
*>
(
mock
);
}
template
<
typename
Pattern
>
struct
ThisRefAdjuster
{
template
<
typename
T
>
using
AdjustT
=
typename
std
::
conditional
<
std
::
is_const
<
typename
std
::
remove_reference
<
Pattern
>::
type
>::
value
,
typename
std
::
conditional
<
std
::
is_lvalue_reference
<
Pattern
>::
value
,
const
T
&
,
const
T
&&>::
type
,
typename
std
::
conditional
<
std
::
is_lvalue_reference
<
Pattern
>::
value
,
T
&
,
T
&&>::
type
>::
type
;
template
<
typename
MockType
>
static
AdjustT
<
MockType
>
Adjust
(
const
MockType
&
mock
)
{
return
static_cast
<
AdjustT
<
MockType
>>
(
const_cast
<
MockType
&>
(
mock
));
}
};
}
// namespace internal
...
...
@@ -90,7 +96,7 @@ using internal::FunctionMocker;
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
GMOCK_INTERNAL_GET_CALLTYPE(_Spec),
\
GMOCK_INTERNAL_GET_CALLTYPE(_Spec),
GMOCK_INTERNAL_GET_REF_SPEC(_Spec),
\
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
...
...
@@ -131,12 +137,12 @@ using internal::FunctionMocker;
#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \
_Override, _Final, _NoexceptSpec, \
_CallType, _Signature)
\
_CallType, _
RefSpec, _
Signature) \
typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \
_Signature)>::Result \
GMOCK_INTERNAL_EXPAND(_CallType) \
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
GMOCK_PP_IF(_Constness, const, ) _NoexceptSpec
\
GMOCK_PP_IF(_Constness, const, )
_RefSpec
_NoexceptSpec \
GMOCK_PP_IF(_Override, override, ) GMOCK_PP_IF(_Final, final, ) { \
GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.SetOwnerAndName(this, #_MethodName); \
...
...
@@ -145,7 +151,7 @@ using internal::FunctionMocker;
} \
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \
GMOCK_PP_IF(_Constness, const, )
{
\
GMOCK_PP_IF(_Constness, const, )
_RefSpec {
\
GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
...
...
@@ -153,10 +159,10 @@ using internal::FunctionMocker;
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
const ::testing::internal::WithoutMatchers&, \
GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \
GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _NoexceptSpec {
\
return
GMOCK_PP_CAT(
::testing::internal::
AdjustConstness_,
\
GMOCK_PP_IF(_Constness, const, ))(this)
\
->
gmock_##_MethodName(GMOCK_PP_REPEAT( \
GMOCK_PP_REMOVE_PARENS(_Signature)>*) const
_RefSpec
_NoexceptSpec { \
return ::testing::internal::
ThisRefAdjuster<GMOCK_PP_IF(
\
_Constness, const, ) int _RefSpec>::Adjust(*this)
\
.
gmock_##_MethodName(GMOCK_PP_REPEAT(
\
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
} \
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
...
...
@@ -183,6 +189,13 @@ using internal::FunctionMocker;
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \
_elem, )
#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)
#define GMOCK_INTERNAL_REF_SPEC_IF_REF(_i, _, _elem) \
GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
...
...
@@ -192,6 +205,7 @@ using internal::FunctionMocker;
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \
GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \
GMOCK_PP_STRINGIZE( \
_elem) " cannot be recognized as a valid specification modifier.");
...
...
@@ -217,6 +231,13 @@ using internal::FunctionMocker;
#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
#define GMOCK_INTERNAL_DETECT_REF(_i, _, _elem) \
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_REF_I_, _elem)
#define GMOCK_INTERNAL_DETECT_REF_I_ref ,
#define GMOCK_INTERNAL_UNPACK_ref(x) x
#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
...
...
@@ -449,7 +470,7 @@ using internal::FunctionMocker;
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
args_num, ::testing::internal::identity_t<__VA_ARGS__>); \
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct,
\
args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct,
,
\
(::testing::internal::identity_t<__VA_ARGS__>))
#define GMOCK_MOCKER_(arity, constness, Method) \
...
...
googlemock/test/gmock-function-mocker_test.cc
View file @
d89b3630
...
...
@@ -108,6 +108,16 @@ class FooInterface {
using
fn_ptr
=
int
(
*
)(
bool
);
virtual
fn_ptr
ReturnsFunctionPointer2
(
int
)
=
0
;
virtual
int
RefQualifiedConstRef
()
const
&
=
0
;
virtual
int
RefQualifiedConstRefRef
()
const
&&
=
0
;
virtual
int
RefQualifiedRef
()
&
=
0
;
virtual
int
RefQualifiedRefRef
()
&&
=
0
;
virtual
int
RefQualifiedOverloaded
()
const
&
=
0
;
virtual
int
RefQualifiedOverloaded
()
const
&&
=
0
;
virtual
int
RefQualifiedOverloaded
()
&
=
0
;
virtual
int
RefQualifiedOverloaded
()
&&
=
0
;
#if GTEST_OS_WINDOWS
STDMETHOD_
(
int
,
CTNullary
)()
=
0
;
STDMETHOD_
(
bool
,
CTUnary
)(
int
x
)
=
0
;
...
...
@@ -181,6 +191,17 @@ class MockFoo : public FooInterface {
(
Calltype
(
STDMETHODCALLTYPE
)));
#endif // GTEST_OS_WINDOWS
// Test reference qualified functions.
MOCK_METHOD
(
int
,
RefQualifiedConstRef
,
(),
(
const
,
ref
(
&
),
override
));
MOCK_METHOD
(
int
,
RefQualifiedConstRefRef
,
(),
(
const
,
ref
(
&&
),
override
));
MOCK_METHOD
(
int
,
RefQualifiedRef
,
(),
(
ref
(
&
),
override
));
MOCK_METHOD
(
int
,
RefQualifiedRefRef
,
(),
(
ref
(
&&
),
override
));
MOCK_METHOD
(
int
,
RefQualifiedOverloaded
,
(),
(
const
,
ref
(
&
),
override
));
MOCK_METHOD
(
int
,
RefQualifiedOverloaded
,
(),
(
const
,
ref
(
&&
),
override
));
MOCK_METHOD
(
int
,
RefQualifiedOverloaded
,
(),
(
ref
(
&
),
override
));
MOCK_METHOD
(
int
,
RefQualifiedOverloaded
,
(),
(
ref
(
&&
),
override
));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
MockFoo
);
};
...
...
@@ -242,6 +263,17 @@ class LegacyMockFoo : public FooInterface {
std
::
map
<
int
,
std
::
string
>
());
#endif // GTEST_OS_WINDOWS
// We can't mock these with the old macros, but we need to define them to make
// it concrete.
int
RefQualifiedConstRef
()
const
&
override
{
return
0
;
}
int
RefQualifiedConstRefRef
()
const
&&
override
{
return
0
;
}
int
RefQualifiedRef
()
&
override
{
return
0
;
}
int
RefQualifiedRefRef
()
&&
override
{
return
0
;
}
int
RefQualifiedOverloaded
()
const
&
override
{
return
0
;
}
int
RefQualifiedOverloaded
()
const
&&
override
{
return
0
;
}
int
RefQualifiedOverloaded
()
&
override
{
return
0
;
}
int
RefQualifiedOverloaded
()
&&
override
{
return
0
;
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
LegacyMockFoo
);
};
...
...
@@ -420,6 +452,40 @@ TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
#endif // GTEST_OS_WINDOWS
TEST
(
FunctionMockerTest
,
RefQualified
)
{
MockFoo
mock_foo
;
EXPECT_CALL
(
mock_foo
,
RefQualifiedConstRef
).
WillOnce
(
Return
(
1
));
EXPECT_CALL
(
std
::
move
(
mock_foo
),
// NOLINT
RefQualifiedConstRefRef
)
.
WillOnce
(
Return
(
2
));
EXPECT_CALL
(
mock_foo
,
RefQualifiedRef
).
WillOnce
(
Return
(
3
));
EXPECT_CALL
(
std
::
move
(
mock_foo
),
// NOLINT
RefQualifiedRefRef
)
.
WillOnce
(
Return
(
4
));
EXPECT_CALL
(
static_cast
<
const
MockFoo
&>
(
mock_foo
),
RefQualifiedOverloaded
())
.
WillOnce
(
Return
(
5
));
EXPECT_CALL
(
static_cast
<
const
MockFoo
&&>
(
mock_foo
),
RefQualifiedOverloaded
())
.
WillOnce
(
Return
(
6
));
EXPECT_CALL
(
static_cast
<
MockFoo
&>
(
mock_foo
),
RefQualifiedOverloaded
())
.
WillOnce
(
Return
(
7
));
EXPECT_CALL
(
static_cast
<
MockFoo
&&>
(
mock_foo
),
RefQualifiedOverloaded
())
.
WillOnce
(
Return
(
8
));
EXPECT_EQ
(
mock_foo
.
RefQualifiedConstRef
(),
1
);
EXPECT_EQ
(
std
::
move
(
mock_foo
).
RefQualifiedConstRefRef
(),
2
);
// NOLINT
EXPECT_EQ
(
mock_foo
.
RefQualifiedRef
(),
3
);
EXPECT_EQ
(
std
::
move
(
mock_foo
).
RefQualifiedRefRef
(),
4
);
// NOLINT
EXPECT_EQ
(
std
::
cref
(
mock_foo
).
get
().
RefQualifiedOverloaded
(),
5
);
EXPECT_EQ
(
std
::
move
(
std
::
cref
(
mock_foo
).
get
())
// NOLINT
.
RefQualifiedOverloaded
(),
6
);
EXPECT_EQ
(
mock_foo
.
RefQualifiedOverloaded
(),
7
);
EXPECT_EQ
(
std
::
move
(
mock_foo
).
RefQualifiedOverloaded
(),
8
);
// NOLINT
}
class
MockB
{
public:
MockB
()
{}
...
...
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