Clone of unsubmitted cr/176529515. Introduce parameterless expectations.
This commit is contained in:
@@ -332,6 +332,58 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
|
||||
}
|
||||
};
|
||||
|
||||
// Removes the given pointer; this is a helper for the expectation setter method
|
||||
// for parameterless matchers.
|
||||
//
|
||||
// We want to make sure that the user cannot set a parameterless expectation on
|
||||
// overloaded methods, including methods which are overloaded on const. Example:
|
||||
//
|
||||
// class MockClass {
|
||||
// MOCK_METHOD0(GetName, string&());
|
||||
// MOCK_CONST_METHOD0(GetName, const string&());
|
||||
// };
|
||||
//
|
||||
// TEST() {
|
||||
// // This should be an error, as it's not clear which overload is expected.
|
||||
// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value));
|
||||
// }
|
||||
//
|
||||
// Here are the generated expectation-setter methods:
|
||||
//
|
||||
// class MockClass {
|
||||
// // Overload 1
|
||||
// MockSpec<string&()> gmock_GetName() { … }
|
||||
// // Overload 2. Declared const so that the compiler will generate an
|
||||
// // error when trying to resolve between this and overload 4 in
|
||||
// // 'gmock_GetName(WithoutMatchers(), nullptr)'.
|
||||
// MockSpec<string&()> gmock_GetName(
|
||||
// const WithoutMatchers&, const Function<string&()>*) const {
|
||||
// // Removes const from this, calls overload 1
|
||||
// return AdjustConstness_(this)->gmock_GetName();
|
||||
// }
|
||||
//
|
||||
// // Overload 3
|
||||
// const string& gmock_GetName() const { … }
|
||||
// // Overload 4
|
||||
// MockSpec<const string&()> gmock_GetName(
|
||||
// const WithoutMatchers&, const Function<const string&()>*) const {
|
||||
// // Does not remove const, calls overload 3
|
||||
// return AdjustConstness_const(this)->gmock_GetName();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
template <typename MockType>
|
||||
const MockType* AdjustConstness_const(const MockType* mock) {
|
||||
return mock;
|
||||
}
|
||||
|
||||
// Removes const from and returns the given pointer; this is a helper for the
|
||||
// expectation setter method for parameterless matchers.
|
||||
template <typename MockType>
|
||||
MockType* AdjustConstness_(const MockType* mock) {
|
||||
return const_cast<MockType*>(mock);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
@@ -380,6 +432,12 @@ using internal::FunctionMocker;
|
||||
GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(0, constness, Method).With(); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \
|
||||
Method)
|
||||
|
||||
@@ -401,6 +459,12 @@ using internal::FunctionMocker;
|
||||
GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \
|
||||
Method)
|
||||
|
||||
@@ -425,6 +489,13 @@ using internal::FunctionMocker;
|
||||
GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \
|
||||
Method)
|
||||
|
||||
@@ -453,6 +524,14 @@ using internal::FunctionMocker;
|
||||
return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \
|
||||
Method)
|
||||
|
||||
@@ -483,6 +562,15 @@ using internal::FunctionMocker;
|
||||
return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \
|
||||
Method)
|
||||
|
||||
@@ -516,6 +604,16 @@ using internal::FunctionMocker;
|
||||
return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \
|
||||
Method)
|
||||
|
||||
@@ -552,6 +650,17 @@ using internal::FunctionMocker;
|
||||
return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \
|
||||
Method)
|
||||
|
||||
@@ -590,6 +699,18 @@ using internal::FunctionMocker;
|
||||
return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \
|
||||
Method)
|
||||
|
||||
@@ -631,6 +752,19 @@ using internal::FunctionMocker;
|
||||
return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \
|
||||
Method)
|
||||
|
||||
@@ -676,6 +810,20 @@ using internal::FunctionMocker;
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
|
||||
gmock_a9); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \
|
||||
Method)
|
||||
|
||||
@@ -724,6 +872,21 @@ using internal::FunctionMocker;
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
|
||||
gmock_a10); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(), \
|
||||
::testing::A<GMOCK_ARG_(tn, 10, __VA_ARGS__)>()); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \
|
||||
Method)
|
||||
|
||||
|
||||
@@ -94,6 +94,58 @@ class FunctionMocker<R($As)> : public
|
||||
|
||||
|
||||
]]
|
||||
// Removes the given pointer; this is a helper for the expectation setter method
|
||||
// for parameterless matchers.
|
||||
//
|
||||
// We want to make sure that the user cannot set a parameterless expectation on
|
||||
// overloaded methods, including methods which are overloaded on const. Example:
|
||||
//
|
||||
// class MockClass {
|
||||
// MOCK_METHOD0(GetName, string&());
|
||||
// MOCK_CONST_METHOD0(GetName, const string&());
|
||||
// };
|
||||
//
|
||||
// TEST() {
|
||||
// // This should be an error, as it's not clear which overload is expected.
|
||||
// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value));
|
||||
// }
|
||||
//
|
||||
// Here are the generated expectation-setter methods:
|
||||
//
|
||||
// class MockClass {
|
||||
// // Overload 1
|
||||
// MockSpec<string&()> gmock_GetName() { … }
|
||||
// // Overload 2. Declared const so that the compiler will generate an
|
||||
// // error when trying to resolve between this and overload 4 in
|
||||
// // 'gmock_GetName(WithoutMatchers(), nullptr)'.
|
||||
// MockSpec<string&()> gmock_GetName(
|
||||
// const WithoutMatchers&, const Function<string&()>*) const {
|
||||
// // Removes const from this, calls overload 1
|
||||
// return AdjustConstness_(this)->gmock_GetName();
|
||||
// }
|
||||
//
|
||||
// // Overload 3
|
||||
// const string& gmock_GetName() const { … }
|
||||
// // Overload 4
|
||||
// MockSpec<const string&()> gmock_GetName(
|
||||
// const WithoutMatchers&, const Function<const string&()>*) const {
|
||||
// // Does not remove const, calls overload 3
|
||||
// return AdjustConstness_const(this)->gmock_GetName();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
template <typename MockType>
|
||||
const MockType* AdjustConstness_const(const MockType* mock) {
|
||||
return mock;
|
||||
}
|
||||
|
||||
// Removes const from and returns the given pointer; this is a helper for the
|
||||
// expectation setter method for parameterless matchers.
|
||||
template <typename MockType>
|
||||
MockType* AdjustConstness_(const MockType* mock) {
|
||||
return const_cast<MockType*>(mock);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
@@ -135,6 +187,8 @@ $var as = [[$for j, \
|
||||
$var matcher_arg_as = [[$for j, \
|
||||
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
||||
$var matcher_as = [[$for j, [[gmock_a$j]]]]
|
||||
$var anything_matchers = [[$for j, \
|
||||
[[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]]
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
@@ -150,6 +204,12 @@ $var matcher_as = [[$for j, [[gmock_a$j]]]]
|
||||
GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
|
||||
return ::testing::internal::AdjustConstness_##constness(this)-> \
|
||||
gmock_##Method($anything_matchers); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
|
||||
|
||||
|
||||
|
||||
@@ -1282,6 +1282,13 @@ class MockSpec {
|
||||
file, line, source_text, matchers_);
|
||||
}
|
||||
|
||||
// This operator overload is used to swallow the superfluous parameter list
|
||||
// introduced by the ON/EXPECT_CALL macros. See the macro comments for more
|
||||
// explanation.
|
||||
MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Function>
|
||||
friend class internal::FunctionMocker;
|
||||
@@ -1836,17 +1843,76 @@ inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT
|
||||
|
||||
} // namespace testing
|
||||
|
||||
// A separate macro is required to avoid compile errors when the name
|
||||
// of the method used in call is a result of macro expansion.
|
||||
// See CompilesWithMethodNameExpandedFromMacro tests in
|
||||
// internal/gmock-spec-builders_test.cc for more details.
|
||||
#define GMOCK_ON_CALL_IMPL_(obj, call) \
|
||||
((obj).gmock_##call).InternalDefaultActionSetAt(__FILE__, __LINE__, \
|
||||
#obj, #call)
|
||||
#define ON_CALL(obj, call) GMOCK_ON_CALL_IMPL_(obj, call)
|
||||
// Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is
|
||||
// required to avoid compile errors when the name of the method used in call is
|
||||
// a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro
|
||||
// tests in internal/gmock-spec-builders_test.cc for more details.
|
||||
//
|
||||
// This macro supports statements both with and without parameter matchers. If
|
||||
// the parameter list is omitted, gMock will accept any parameters, which allows
|
||||
// tests to be written that don't need to encode the number of method
|
||||
// parameter. This technique may only be used for non-overloaded methods.
|
||||
//
|
||||
// // These are the same:
|
||||
// ON_CALL(mock, NoArgsMethod()).WillByDefault(…);
|
||||
// ON_CALL(mock, NoArgsMethod).WillByDefault(…);
|
||||
//
|
||||
// // As are these:
|
||||
// ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(…);
|
||||
// ON_CALL(mock, TwoArgsMethod).WillByDefault(…);
|
||||
//
|
||||
// // Can also specify args if you want, of course:
|
||||
// ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(…);
|
||||
//
|
||||
// // Overloads work as long as you specify parameters:
|
||||
// ON_CALL(mock, OverloadedMethod(_)).WillByDefault(…);
|
||||
// ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(…);
|
||||
//
|
||||
// // Oops! Which overload did you want?
|
||||
// ON_CALL(mock, OverloadedMethod).WillByDefault(…);
|
||||
// => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous
|
||||
//
|
||||
// How this works: The mock class uses two overloads of the gmock_Method
|
||||
// expectation setter method plus an operator() overload on the MockSpec object.
|
||||
// In the matcher list form, the macro expands to:
|
||||
//
|
||||
// // This statement:
|
||||
// ON_CALL(mock, TwoArgsMethod(_, 45))…
|
||||
//
|
||||
// // …expands to:
|
||||
// mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)…
|
||||
// |-------------v---------------||------------v-------------|
|
||||
// invokes first overload swallowed by operator()
|
||||
//
|
||||
// // …which is essentially:
|
||||
// mock.gmock_TwoArgsMethod(_, 45)…
|
||||
//
|
||||
// Whereas the form without a matcher list:
|
||||
//
|
||||
// // This statement:
|
||||
// ON_CALL(mock, TwoArgsMethod)…
|
||||
//
|
||||
// // …expands to:
|
||||
// mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)…
|
||||
// |-----------------------v--------------------------|
|
||||
// invokes second overload
|
||||
//
|
||||
// // …which is essentially:
|
||||
// mock.gmock_TwoArgsMethod(_, _)…
|
||||
//
|
||||
// The WithoutMatchers() argument is used to disambiguate overloads and to
|
||||
// block the caller from accidentally invoking the second overload directly. The
|
||||
// second argument is an internal type derived from the method signature. The
|
||||
// failure to disambiguate two overloads of this method in the ON_CALL statement
|
||||
// is how we block callers from setting expectations on overloaded methods.
|
||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), NULL) \
|
||||
.Setter(__FILE__, __LINE__, #mock_expr, #call)
|
||||
|
||||
#define GMOCK_EXPECT_CALL_IMPL_(obj, call) \
|
||||
((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call)
|
||||
#define EXPECT_CALL(obj, call) GMOCK_EXPECT_CALL_IMPL_(obj, call)
|
||||
#define ON_CALL(obj, call) \
|
||||
GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call)
|
||||
|
||||
#define EXPECT_CALL(obj, call) \
|
||||
GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
||||
|
||||
@@ -344,6 +344,21 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity);
|
||||
GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
||||
int stack_frames_to_skip);
|
||||
|
||||
// A marker class that is used to resolve parameterless expectations to the
|
||||
// correct overload. This must not be instantiable, to prevent client code from
|
||||
// accidentally resolving to the overload; for example:
|
||||
//
|
||||
// ON_CALL(mock, Method({}, nullptr))…
|
||||
//
|
||||
class WithoutMatchers {
|
||||
private:
|
||||
WithoutMatchers() {}
|
||||
friend WithoutMatchers GetWithoutMatchers();
|
||||
};
|
||||
|
||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
||||
WithoutMatchers GetWithoutMatchers();
|
||||
|
||||
// TODO(wan@google.com): group all type utilities together.
|
||||
|
||||
// Type traits.
|
||||
|
||||
Reference in New Issue
Block a user