Commit 20d1a235 authored by zhanyong.wan's avatar zhanyong.wan
Browse files

Allows the return type of a mock method to contain unprotected commas.

parent 29be9238
......@@ -104,17 +104,23 @@ $if i >= 1 [[
// cannot handle it if we define FunctionMocker in ::testing.
using internal::FunctionMocker;
// The result type of function type F.
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
// We define this as a variadic macro in case F contains unprotected
// commas (the same reason that we use variadic macros in other places
// in this file).
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_RESULT_(tn, F) tn ::testing::internal::Function<F>::Result
#define GMOCK_RESULT_(tn, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Result
// The type of argument N of function type F.
// The type of argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_ARG_(tn, F, N) tn ::testing::internal::Function<F>::Argument##N
#define GMOCK_ARG_(tn, N, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
// The matcher type for argument N of function type F.
// The matcher type for argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MATCHER_(tn, F, N) const ::testing::Matcher<GMOCK_ARG_(tn, F, N)>&
#define GMOCK_MATCHER_(tn, N, ...) \
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
// The variable for mocking the given method.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
......@@ -125,77 +131,78 @@ using internal::FunctionMocker;
$for i [[
$range j 1..i
$var arg_as = [[$for j, \
[[GMOCK_ARG_(tn, F, $j) gmock_a$j]]]]
[[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
$var as = [[$for j, [[gmock_a$j]]]]
$var matcher_as = [[$for j, \
[[GMOCK_MATCHER_(tn, F, $j) gmock_a$j]]]]
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, F) \
GMOCK_RESULT_(tn, F) ct Method($arg_as) constness { \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == $i, \
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
$arg_as) constness { \
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \
this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
} \
::testing::MockSpec<F>& \
::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method($matcher_as) constness { \
GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_($i, constness, Method).With($as); \
} \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_($i, constness, Method)
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
]]
$for i [[
#define MOCK_METHOD$i(m, F) GMOCK_METHOD$i[[]]_(, , , m, F)
#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i(m, F) GMOCK_METHOD$i[[]]_(, const, , m, F)
#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_METHOD$i[[]]_T(m, F) GMOCK_METHOD$i[[]]_(typename, , , m, F)
#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i[[]]_T(m, F) [[]]
GMOCK_METHOD$i[[]]_(typename, const, , m, F)
#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \
GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) [[]]
GMOCK_METHOD$i[[]]_(, , ct, m, F)
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) \
GMOCK_METHOD$i[[]]_(, const, ct, m, F)
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__)
]]
$for i [[
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \
GMOCK_METHOD$i[[]]_(typename, , ct, m, F)
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \
GMOCK_METHOD$i[[]]_(typename, const, ct, m, F)
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__)
]]
......
......@@ -129,9 +129,16 @@ class MockFoo : public FooInterface {
MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT
MOCK_METHOD1(TakesConstReference, string(const int&));
#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT
#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
#endif
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD0(ReturnTypeWithComma, std::map<int, string>());
MOCK_CONST_METHOD1(ReturnTypeWithComma,
std::map<int, string>(int)); // NOLINT
MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT
MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT
......@@ -143,6 +150,7 @@ class MockFoo : public FooInterface {
MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT
MOCK_METHOD1(TypeWithComma, int(const std::map<int, string>&)); // NOLINT
#if GTEST_OS_WINDOWS
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int));
......@@ -150,6 +158,10 @@ class MockFoo : public FooInterface {
short d, int e, long f, float g, double h, unsigned i, char* j,
const string& k));
MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst, char(int));
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma,
std::map<int, string>());
#endif // GTEST_OS_WINDOWS
private:
......@@ -267,6 +279,17 @@ TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {
EXPECT_EQ('a', Const(*foo_).OverloadedOnConstness());
}
TEST_F(FunctionMockerTest, MocksReturnTypeWithComma) {
const std::map<int, string> a_map;
EXPECT_CALL(mock_foo_, ReturnTypeWithComma())
.WillOnce(Return(a_map));
EXPECT_CALL(mock_foo_, ReturnTypeWithComma(42))
.WillOnce(Return(a_map));
EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma());
EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma(42));
}
#if GTEST_OS_WINDOWS
// Tests mocking a nullary function with calltype.
TEST_F(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
......@@ -306,6 +329,14 @@ TEST_F(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
EXPECT_EQ('a', Const(*foo_).CTConst(0));
}
TEST_F(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
const std::map<int, string> a_map;
EXPECT_CALL(mock_foo_, CTReturnTypeWithComma())
.WillOnce(Return(a_map));
EXPECT_EQ(a_map, mock_foo_.CTReturnTypeWithComma());
}
#endif // GTEST_OS_WINDOWS
class MockB {
......@@ -362,6 +393,10 @@ class MockStack : public StackInterface<T> {
MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT
MOCK_CONST_METHOD0_T(GetTop, const T&());
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>());
MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int)); // NOLINT
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStack);
};
......@@ -389,6 +424,19 @@ TEST(TemplateMockTest, Works) {
EXPECT_EQ(0, mock.GetSize());
}
TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
MockStack<int> mock;
const std::map<int, int> a_map;
EXPECT_CALL(mock, ReturnTypeWithComma())
.WillOnce(Return(a_map));
EXPECT_CALL(mock, ReturnTypeWithComma(1))
.WillOnce(Return(a_map));
EXPECT_EQ(a_map, mock.ReturnTypeWithComma());
EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1));
}
#if GTEST_OS_WINDOWS
// Tests mocking template interfaces with calltype.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment