This commit is contained in:
Gennadiy Civil 2018-04-12 09:13:38 -04:00
commit 07f3bdd4c9
4 changed files with 224 additions and 210 deletions

View File

@ -71,329 +71,345 @@
namespace testing { namespace testing {
namespace internal {
// NiceMockBase serves as a mix-in to establish the "uninteresting call"
// behavior for NiceMock on construction. It accomplishes this via CRTP to get
// access to the derived MockClass.
template <class MockClass> template <class MockClass>
class NiceMockBase { class NiceMock : public MockClass {
protected:
NiceMockBase();
~NiceMockBase();
};
} // namespace internal
template <class MockClass>
class NiceMock : public MockClass, public internal::NiceMockBase<MockClass> {
public: public:
NiceMock() : MockClass() {} NiceMock() : MockClass() {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be // Single argument constructor is special-cased so that it can be
// made explicit. // made explicit.
template <typename A> template <typename A>
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {} explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename... An> template <typename A1, typename A2, typename... An>
NiceMock(A1&& arg1, A2&& arg2, An&&... args) NiceMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {} std::forward<An>(args)...) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#else #else
// C++98 doesn't have variadic templates, so we have to define one // C++98 doesn't have variadic templates, so we have to define one
// for each arity. // for each arity.
template <typename A1> template <typename A1>
explicit NiceMock(const A1& a1) : MockClass(a1) {} explicit NiceMock(const A1& a1) : MockClass(a1) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2> template <typename A1, typename A2>
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {} NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3> template <typename A1, typename A2, typename A3>
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {} NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4> template <typename A1, typename A2, typename A3, typename A4>
NiceMock(const A1& a1, const A2& a2, const A3& a3, NiceMock(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) : MockClass(a1, a2, a3, a4) {} const A4& a4) : MockClass(a1, a2, a3, a4) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5> template <typename A1, typename A2, typename A3, typename A4, typename A5>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {} const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6> typename A6>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {} const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7> typename A6, typename A7>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
a6, a7) {} a6, a7) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8> typename A6, typename A7, typename A8>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
a2, a3, a4, a5, a6, a7, a8) {} a2, a3, a4, a5, a6, a7, a8) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9> typename A6, typename A7, typename A8, typename A9>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A5& a5, const A6& a6, const A7& a7, const A8& a8,
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9, typename A10> typename A6, typename A7, typename A8, typename A9, typename A10>
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#endif // GTEST_LANG_CXX11 #endif // GTEST_LANG_CXX11
~NiceMock() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock); GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
}; };
namespace internal {
template <typename MockClass>
NiceMockBase<MockClass>::NiceMockBase() {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(
static_cast<NiceMock<MockClass> *>(this)));
}
template <typename MockClass>
NiceMockBase<MockClass>::~NiceMockBase() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(
static_cast<NiceMock<MockClass>*>(this)));
}
} // namespace internal
namespace internal {
// NaggyMockBase serves as a mix-in to establish the "uninteresting call"
// behavior for NaggyMock on construction. It accomplishes this via CRTP to get
// access to the derived MockClass.
template <class MockClass> template <class MockClass>
class NaggyMockBase { class NaggyMock : public MockClass {
protected:
NaggyMockBase();
~NaggyMockBase();
};
} // namespace internal
template <class MockClass>
class NaggyMock : public MockClass, public internal::NaggyMockBase<MockClass> {
public: public:
NaggyMock() : MockClass() {} NaggyMock() : MockClass() {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be // Single argument constructor is special-cased so that it can be
// made explicit. // made explicit.
template <typename A> template <typename A>
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {} explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename... An> template <typename A1, typename A2, typename... An>
NaggyMock(A1&& arg1, A2&& arg2, An&&... args) NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {} std::forward<An>(args)...) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#else #else
// C++98 doesn't have variadic templates, so we have to define one // C++98 doesn't have variadic templates, so we have to define one
// for each arity. // for each arity.
template <typename A1> template <typename A1>
explicit NaggyMock(const A1& a1) : MockClass(a1) {} explicit NaggyMock(const A1& a1) : MockClass(a1) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2> template <typename A1, typename A2>
NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {} NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3> template <typename A1, typename A2, typename A3>
NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {} NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4> template <typename A1, typename A2, typename A3, typename A4>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, NaggyMock(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) : MockClass(a1, a2, a3, a4) {} const A4& a4) : MockClass(a1, a2, a3, a4) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5> template <typename A1, typename A2, typename A3, typename A4, typename A5>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {} const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6> typename A6>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {} const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7> typename A6, typename A7>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
a6, a7) {} a6, a7) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8> typename A6, typename A7, typename A8>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
a2, a3, a4, a5, a6, a7, a8) {} a2, a3, a4, a5, a6, a7, a8) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9> typename A6, typename A7, typename A8, typename A9>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A5& a5, const A6& a6, const A7& a7, const A8& a8,
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9, typename A10> typename A6, typename A7, typename A8, typename A9, typename A10>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#endif // GTEST_LANG_CXX11 #endif // GTEST_LANG_CXX11
~NaggyMock() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock); GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
}; };
namespace internal {
template <typename MockClass>
NaggyMockBase<MockClass>::NaggyMockBase() {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(
static_cast<NaggyMock<MockClass> *>(this)));
}
template <typename MockClass>
NaggyMockBase<MockClass>::~NaggyMockBase() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(
static_cast<NaggyMock<MockClass>*>(this)));
}
} // namespace internal
namespace internal {
// StrictMockBase serves as a mix-in to establish the "uninteresting call"
// behavior for StrictMock on construction. It accomplishes this via CRTP to get
// access to the derived MockClass.
template <class MockClass> template <class MockClass>
class StrictMockBase { class StrictMock : public MockClass {
protected:
StrictMockBase();
~StrictMockBase();
};
} // namespace internal
template <class MockClass>
class StrictMock : public MockClass,
public internal::StrictMockBase<MockClass> {
public: public:
StrictMock() : MockClass() {} StrictMock() : MockClass() {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be // Single argument constructor is special-cased so that it can be
// made explicit. // made explicit.
template <typename A> template <typename A>
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {} explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename... An> template <typename A1, typename A2, typename... An>
StrictMock(A1&& arg1, A2&& arg2, An&&... args) StrictMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {} std::forward<An>(args)...) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#else #else
// C++98 doesn't have variadic templates, so we have to define one // C++98 doesn't have variadic templates, so we have to define one
// for each arity. // for each arity.
template <typename A1> template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) {} explicit StrictMock(const A1& a1) : MockClass(a1) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2> template <typename A1, typename A2>
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {} StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3> template <typename A1, typename A2, typename A3>
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
a3) {} ::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4> template <typename A1, typename A2, typename A3, typename A4>
StrictMock(const A1& a1, const A2& a2, const A3& a3, StrictMock(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) : MockClass(a1, a2, a3, a4) {} const A4& a4) : MockClass(a1, a2, a3, a4) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5> template <typename A1, typename A2, typename A3, typename A4, typename A5>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {} const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6> typename A6>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {} const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7> typename A6, typename A7>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
a6, a7) {} a6, a7) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8> typename A6, typename A7, typename A8>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
a2, a3, a4, a5, a6, a7, a8) {} a2, a3, a4, a5, a6, a7, a8) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9> typename A6, typename A7, typename A8, typename A9>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A5& a5, const A6& a6, const A7& a7, const A8& a8,
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5, template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9, typename A10> typename A6, typename A7, typename A8, typename A9, typename A10>
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#endif // GTEST_LANG_CXX11 #endif // GTEST_LANG_CXX11
~StrictMock() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock); GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
}; };
namespace internal {
template <typename MockClass>
StrictMockBase<MockClass>::StrictMockBase() {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(
static_cast<StrictMock<MockClass> *>(this)));
}
template <typename MockClass>
StrictMockBase<MockClass>::~StrictMockBase() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(
static_cast<StrictMock<MockClass>*>(this)));
}
} // namespace internal
// The following specializations catch some (relatively more common) // The following specializations catch some (relatively more common)
// user errors of nesting nice and strict mocks. They do NOT catch // user errors of nesting nice and strict mocks. They do NOT catch
// all possible errors. // all possible errors.

View File

@ -83,79 +83,61 @@ $var method=[[$if kind==0 [[AllowUninterestingCalls]]
$elif kind==1 [[WarnUninterestingCalls]] $elif kind==1 [[WarnUninterestingCalls]]
$else [[FailUninterestingCalls]]]] $else [[FailUninterestingCalls]]]]
namespace internal {
// $clazz[[]]Base serves as a mix-in to establish the "uninteresting call"
// behavior for $clazz on construction. It accomplishes this via CRTP to get
// access to the derived MockClass.
template <class MockClass> template <class MockClass>
class $clazz[[]]Base { class $clazz : public MockClass {
protected:
$clazz[[]]Base();
~$clazz[[]]Base();
};
} // namespace internal
template <class MockClass>
class $clazz : public MockClass, public internal::$clazz[[]]Base<MockClass> {
public: public:
$clazz() : MockClass() {} $clazz() : MockClass() {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be // Single argument constructor is special-cased so that it can be
// made explicit. // made explicit.
template <typename A> template <typename A>
explicit $clazz(A&& arg) : MockClass(std::forward<A>(arg)) {} explicit $clazz(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename... An> template <typename A1, typename A2, typename... An>
$clazz(A1&& arg1, A2&& arg2, An&&... args) $clazz(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {} std::forward<An>(args)...) {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
#else #else
// C++98 doesn't have variadic templates, so we have to define one // C++98 doesn't have variadic templates, so we have to define one
// for each arity. // for each arity.
template <typename A1> template <typename A1>
explicit $clazz(const A1& a1) : MockClass(a1) {} explicit $clazz(const A1& a1) : MockClass(a1) {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
$range i 2..n $range i 2..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
template <$for j, [[typename A$j]]> template <$for j, [[typename A$j]]>
$clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {} $clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
]] ]]
#endif // GTEST_LANG_CXX11 #endif // GTEST_LANG_CXX11
~$clazz() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz); GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz);
}; };
namespace internal {
template <typename MockClass>
$clazz[[]]Base<MockClass>::$clazz[[]]Base() {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(
static_cast<$clazz<MockClass> *>(this)));
}
template <typename MockClass>
$clazz[[]]Base<MockClass>::~$clazz[[]]Base() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(
static_cast<$clazz<MockClass>*>(this)));
}
} // namespace internal
]] ]]
// The following specializations catch some (relatively more common) // The following specializations catch some (relatively more common)

View File

@ -103,11 +103,6 @@ class ExpectationTester;
// Base class for function mockers. // Base class for function mockers.
template <typename F> class FunctionMockerBase; template <typename F> class FunctionMockerBase;
// Uninteresting call behavior mixins.
template <typename M> class NiceMockBase;
template <typename M> class NaggyMockBase;
template <typename M> class StrictMockBase;
// Protects the mock object registry (in class Mock), all function // Protects the mock object registry (in class Mock), all function
// mockers, and all expectations. // mockers, and all expectations.
// //
@ -408,13 +403,13 @@ class GTEST_API_ Mock {
friend class internal::FunctionMockerBase; friend class internal::FunctionMockerBase;
template <typename M> template <typename M>
friend class internal::NiceMockBase; friend class NiceMock;
template <typename M> template <typename M>
friend class internal::NaggyMockBase; friend class NaggyMock;
template <typename M> template <typename M>
friend class internal::StrictMockBase; friend class StrictMock;
// Tells Google Mock to allow uninteresting calls on the given mock // Tells Google Mock to allow uninteresting calls on the given mock
// object. // object.

View File

@ -259,6 +259,13 @@ TEST(NiceMockTest, NonDefaultConstructor10) {
nice_bar.That(5, true); nice_bar.That(5, true);
} }
TEST(NiceMockTest, AllowLeak) {
NiceMock<MockFoo>* leaked = new NiceMock<MockFoo>;
Mock::AllowLeak(leaked);
EXPECT_CALL(*leaked, DoThis());
leaked->DoThis();
}
#if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE #if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE
// Tests that NiceMock<Mock> compiles where Mock is a user-defined // Tests that NiceMock<Mock> compiles where Mock is a user-defined
// class (as opposed to ::testing::Mock). We had to work around an // class (as opposed to ::testing::Mock). We had to work around an
@ -352,6 +359,13 @@ TEST(NaggyMockTest, NonDefaultConstructor10) {
naggy_bar.That(5, true); naggy_bar.That(5, true);
} }
TEST(NaggyMockTest, AllowLeak) {
NaggyMock<MockFoo>* leaked = new NaggyMock<MockFoo>;
Mock::AllowLeak(leaked);
EXPECT_CALL(*leaked, DoThis());
leaked->DoThis();
}
#if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE #if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE
// Tests that NaggyMock<Mock> compiles where Mock is a user-defined // Tests that NaggyMock<Mock> compiles where Mock is a user-defined
// class (as opposed to ::testing::Mock). We had to work around an // class (as opposed to ::testing::Mock). We had to work around an
@ -426,6 +440,13 @@ TEST(StrictMockTest, NonDefaultConstructor10) {
"Uninteresting mock function call"); "Uninteresting mock function call");
} }
TEST(StrictMockTest, AllowLeak) {
StrictMock<MockFoo>* leaked = new StrictMock<MockFoo>;
Mock::AllowLeak(leaked);
EXPECT_CALL(*leaked, DoThis());
leaked->DoThis();
}
#if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE #if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE
// Tests that StrictMock<Mock> compiles where Mock is a user-defined // Tests that StrictMock<Mock> compiles where Mock is a user-defined
// class (as opposed to ::testing::Mock). We had to work around an // class (as opposed to ::testing::Mock). We had to work around an