Commit fe402c27 authored by Gennadiy Civil's avatar Gennadiy Civil
Browse files

Merging gMock, 2

parent 7e5f90d3
$$ -*- mode: c++; -*- $$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to $$ This is a Pump source file. Please use Pump to convert
$$ gmock-generated-function-mockers.h. $$ it to gmock-generated-function-mockers.h.
$$ $$
$var n = 10 $$ The maximum arity we support. $var n = 10 $$ The maximum arity we support.
// Copyright 2007, Google Inc. // Copyright 2007, Google Inc.
......
...@@ -51,10 +51,9 @@ ...@@ -51,10 +51,9 @@
// NiceMock<MockFoo>. // NiceMock<MockFoo>.
// //
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
// their respective base class, with up-to 10 arguments. Therefore // their respective base class. Therefore you can write
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock // NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
// where MockFoo has a constructor that accepts (int, const char*), // has a constructor that accepts (int, const char*), for example.
// for example.
// //
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
// and StrictMock<MockFoo> only works for mock methods defined using // and StrictMock<MockFoo> only works for mock methods defined using
...@@ -63,10 +62,6 @@ ...@@ -63,10 +62,6 @@
// or "strict" modifier may not affect it, depending on the compiler. // or "strict" modifier may not affect it, depending on the compiler.
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported. // supported.
//
// Another known limitation is that the constructors of the base mock
// cannot have arguments passed by non-const reference, which are
// banned by the Google C++ style guide anyway.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
...@@ -76,294 +71,329 @@ ...@@ -76,294 +71,329 @@
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>
class NiceMockBase {
protected:
NiceMockBase();
~NiceMockBase();
};
} // namespace internal
template <class MockClass> template <class MockClass>
class NiceMock : public MockClass { class NiceMock : public MockClass, public internal::NiceMockBase<MockClass> {
public: public:
// We don't factor out the constructor body to a common method, as NiceMock() : MockClass() {}
// we have to avoid a possible clash with members of MockClass.
NiceMock() { #if GTEST_LANG_CXX11
::testing::Mock::AllowUninterestingCalls( // Ideally, we would inherit base class's constructors through a using
internal::ImplicitCast_<MockClass*>(this)); // 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.
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity. // Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {}
template <typename A1, typename A2, typename... An>
NiceMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {}
#else
// C++98 doesn't have variadic templates, so we have to define one
// 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));
}
virtual ~NiceMock() { #endif // GTEST_LANG_CXX11
::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>
class NaggyMockBase {
protected:
NaggyMockBase();
~NaggyMockBase();
};
} // namespace internal
template <class MockClass> template <class MockClass>
class NaggyMock : public MockClass { class NaggyMock : public MockClass, public internal::NaggyMockBase<MockClass> {
public: public:
// We don't factor out the constructor body to a common method, as NaggyMock() : MockClass() {}
// we have to avoid a possible clash with members of MockClass.
NaggyMock() { #if GTEST_LANG_CXX11
::testing::Mock::WarnUninterestingCalls( // Ideally, we would inherit base class's constructors through a using
internal::ImplicitCast_<MockClass*>(this)); // 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.
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity. // Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {}
template <typename A1, typename A2, typename... An>
NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {}
#else
// C++98 doesn't have variadic templates, so we have to define one
// 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));
}
virtual ~NaggyMock() { #endif // GTEST_LANG_CXX11
::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>
class StrictMockBase {
protected:
StrictMockBase();
~StrictMockBase();
};
} // namespace internal
template <class MockClass> template <class MockClass>
class StrictMock : public MockClass { class StrictMock : public MockClass,
public internal::StrictMockBase<MockClass> {
public: public:
// We don't factor out the constructor body to a common method, as StrictMock() : MockClass() {}
// we have to avoid a possible clash with members of MockClass.
StrictMock() { #if GTEST_LANG_CXX11
::testing::Mock::FailUninterestingCalls( // Ideally, we would inherit base class's constructors through a using
internal::ImplicitCast_<MockClass*>(this)); // 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.
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity. // Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {}
template <typename A1, typename A2, typename... An>
StrictMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {}
#else
// C++98 doesn't have variadic templates, so we have to define one
// 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, a3) { StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2,
::testing::Mock::FailUninterestingCalls( a3) {}
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));
}
virtual ~StrictMock() { #endif // GTEST_LANG_CXX11
::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.
......
...@@ -103,6 +103,11 @@ class ExpectationTester; ...@@ -103,6 +103,11 @@ 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.
// //
...@@ -147,14 +152,13 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -147,14 +152,13 @@ class GTEST_API_ UntypedFunctionMockerBase {
// action fails. // action fails.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
const void* untyped_args, const std::string& call_description) const = 0; void* untyped_args, const std::string& call_description) const = 0;
// Performs the given action with the given arguments and returns // Performs the given action with the given arguments and returns
// the action's result. // the action's result.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformAction( virtual UntypedActionResultHolderBase* UntypedPerformAction(
const void* untyped_action, const void* untyped_action, void* untyped_args) const = 0;
const void* untyped_args) const = 0;
// Writes a message that the call is uninteresting (i.e. neither // Writes a message that the call is uninteresting (i.e. neither
// explicitly expected nor explicitly unexpected) to the given // explicitly expected nor explicitly unexpected) to the given
...@@ -209,9 +213,8 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -209,9 +213,8 @@ class GTEST_API_ UntypedFunctionMockerBase {
// arguments. This function can be safely called from multiple // arguments. This function can be safely called from multiple
// threads concurrently. The caller is responsible for deleting the // threads concurrently. The caller is responsible for deleting the
// result. // result.
UntypedActionResultHolderBase* UntypedInvokeWith( UntypedActionResultHolderBase* UntypedInvokeWith(void* untyped_args)
const void* untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
protected: protected:
typedef std::vector<const void*> UntypedOnCallSpecs; typedef std::vector<const void*> UntypedOnCallSpecs;
...@@ -236,6 +239,14 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -236,6 +239,14 @@ class GTEST_API_ UntypedFunctionMockerBase {
UntypedOnCallSpecs untyped_on_call_specs_; UntypedOnCallSpecs untyped_on_call_specs_;
// All expectations for this function mocker. // All expectations for this function mocker.
//
// It's undefined behavior to interleave expectations (EXPECT_CALLs
// or ON_CALLs) and mock function calls. Also, the order of
// expectations is important. Therefore it's a logic race condition
// to read/write untyped_expectations_ concurrently. In order for
// tools like tsan to catch concurrent read/write accesses to
// untyped_expectations, we deliberately leave accesses to it
// unprotected.
UntypedExpectations untyped_expectations_; UntypedExpectations untyped_expectations_;
}; // class UntypedFunctionMockerBase }; // class UntypedFunctionMockerBase
...@@ -397,13 +408,13 @@ class GTEST_API_ Mock { ...@@ -397,13 +408,13 @@ class GTEST_API_ Mock {
friend class internal::FunctionMockerBase; friend class internal::FunctionMockerBase;
template <typename M> template <typename M>
friend class NiceMock; friend class internal::NiceMockBase;
template <typename M> template <typename M>
friend class NaggyMock; friend class internal::NaggyMockBase;
template <typename M> template <typename M>
friend class StrictMock; friend class internal::StrictMockBase;
// Tells Google Mock to allow uninteresting calls on the given mock // Tells Google Mock to allow uninteresting calls on the given mock
// object. // object.
...@@ -1252,8 +1263,9 @@ class MockSpec { ...@@ -1252,8 +1263,9 @@ class MockSpec {
// Constructs a MockSpec object, given the function mocker object // Constructs a MockSpec object, given the function mocker object
// that the spec is associated with. // that the spec is associated with.
explicit MockSpec(internal::FunctionMockerBase<F>* function_mocker) MockSpec(internal::FunctionMockerBase<F>* function_mocker,
: function_mocker_(function_mocker) {} const ArgumentMatcherTuple& matchers)
: function_mocker_(function_mocker), matchers_(matchers) {}
// Adds a new default action spec to the function mocker and returns // Adds a new default action spec to the function mocker and returns
// the newly created spec. // the newly created spec.
...@@ -1279,10 +1291,6 @@ class MockSpec { ...@@ -1279,10 +1291,6 @@ class MockSpec {
template <typename Function> template <typename Function>
friend class internal::FunctionMocker; friend class internal::FunctionMocker;
void SetMatchers(const ArgumentMatcherTuple& matchers) {
matchers_ = matchers;
}
// The function mocker that owns this spec. // The function mocker that owns this spec.
internal::FunctionMockerBase<F>* const function_mocker_; internal::FunctionMockerBase<F>* const function_mocker_;
// The argument matchers specified in the spec. // The argument matchers specified in the spec.
...@@ -1390,19 +1398,20 @@ class ActionResultHolder : public UntypedActionResultHolderBase { ...@@ -1390,19 +1398,20 @@ class ActionResultHolder : public UntypedActionResultHolderBase {
template <typename F> template <typename F>
static ActionResultHolder* PerformDefaultAction( static ActionResultHolder* PerformDefaultAction(
const FunctionMockerBase<F>* func_mocker, const FunctionMockerBase<F>* func_mocker,
const typename Function<F>::ArgumentTuple& args, typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
const std::string& call_description) { const std::string& call_description) {
return new ActionResultHolder(Wrapper( return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
func_mocker->PerformDefaultAction(args, call_description))); internal::move(args), call_description)));
} }
// Performs the given action and returns the result in a new-ed // Performs the given action and returns the result in a new-ed
// ActionResultHolder. // ActionResultHolder.
template <typename F> template <typename F>
static ActionResultHolder* static ActionResultHolder* PerformAction(
PerformAction(const Action<F>& action, const Action<F>& action,
const typename Function<F>::ArgumentTuple& args) { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) {
return new ActionResultHolder(Wrapper(action.Perform(args))); return new ActionResultHolder(
Wrapper(action.Perform(internal::move(args))));
} }
private: private:
...@@ -1430,9 +1439,9 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase { ...@@ -1430,9 +1439,9 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
template <typename F> template <typename F>
static ActionResultHolder* PerformDefaultAction( static ActionResultHolder* PerformDefaultAction(
const FunctionMockerBase<F>* func_mocker, const FunctionMockerBase<F>* func_mocker,
const typename Function<F>::ArgumentTuple& args, typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
const std::string& call_description) { const std::string& call_description) {
func_mocker->PerformDefaultAction(args, call_description); func_mocker->PerformDefaultAction(internal::move(args), call_description);
return new ActionResultHolder; return new ActionResultHolder;
} }
...@@ -1441,8 +1450,8 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase { ...@@ -1441,8 +1450,8 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
template <typename F> template <typename F>
static ActionResultHolder* PerformAction( static ActionResultHolder* PerformAction(
const Action<F>& action, const Action<F>& action,
const typename Function<F>::ArgumentTuple& args) { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) {
action.Perform(args); action.Perform(internal::move(args));
return new ActionResultHolder; return new ActionResultHolder;
} }
...@@ -1461,7 +1470,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1461,7 +1470,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
typedef typename Function<F>::ArgumentTuple ArgumentTuple; typedef typename Function<F>::ArgumentTuple ArgumentTuple;
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
FunctionMockerBase() : current_spec_(this) {} FunctionMockerBase() {}
// The destructor verifies that all expectations on this mock // The destructor verifies that all expectations on this mock
// function have been satisfied. If not, it will report Google Test // function have been satisfied. If not, it will report Google Test
...@@ -1497,12 +1506,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1497,12 +1506,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// mutable state of this object, and thus can be called concurrently // mutable state of this object, and thus can be called concurrently
// without locking. // without locking.
// L = * // L = *
Result PerformDefaultAction(const ArgumentTuple& args, Result PerformDefaultAction(
const std::string& call_description) const { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
const std::string& call_description) const {
const OnCallSpec<F>* const spec = const OnCallSpec<F>* const spec =
this->FindOnCallSpec(args); this->FindOnCallSpec(args);
if (spec != NULL) { if (spec != NULL) {
return spec->GetAction().Perform(args); return spec->GetAction().Perform(internal::move(args));
} }
const std::string message = const std::string message =
call_description + call_description +
...@@ -1524,11 +1534,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1524,11 +1534,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// action fails. The caller is responsible for deleting the result. // action fails. The caller is responsible for deleting the result.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
const void* untyped_args, // must point to an ArgumentTuple void* untyped_args, // must point to an ArgumentTuple
const std::string& call_description) const { const std::string& call_description) const {
const ArgumentTuple& args = ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
*static_cast<const ArgumentTuple*>(untyped_args); return ResultHolder::PerformDefaultAction(this, internal::move(*args),
return ResultHolder::PerformDefaultAction(this, args, call_description); call_description);
} }
// Performs the given action with the given arguments and returns // Performs the given action with the given arguments and returns
...@@ -1536,13 +1546,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1536,13 +1546,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// result. // result.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformAction( virtual UntypedActionResultHolderBase* UntypedPerformAction(
const void* untyped_action, const void* untyped_args) const { const void* untyped_action, void* untyped_args) const {
// Make a copy of the action before performing it, in case the // Make a copy of the action before performing it, in case the
// action deletes the mock object (and thus deletes itself). // action deletes the mock object (and thus deletes itself).
const Action<F> action = *static_cast<const Action<F>*>(untyped_action); const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
const ArgumentTuple& args = ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
*static_cast<const ArgumentTuple*>(untyped_args); return ResultHolder::PerformAction(action, internal::move(*args));
return ResultHolder::PerformAction(action, args);
} }
// Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked(): // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
...@@ -1582,10 +1591,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1582,10 +1591,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Returns the result of invoking this mock function with the given // Returns the result of invoking this mock function with the given
// arguments. This function can be safely called from multiple // arguments. This function can be safely called from multiple
// threads concurrently. // threads concurrently.
Result InvokeWith(const ArgumentTuple& args) Result InvokeWith(
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
// const_cast is required since in C++98 we still pass ArgumentTuple around
// by const& instead of rvalue reference.
void* untyped_args = const_cast<void*>(static_cast<const void*>(&args));
scoped_ptr<ResultHolder> holder( scoped_ptr<ResultHolder> holder(
DownCast_<ResultHolder*>(this->UntypedInvokeWith(&args))); DownCast_<ResultHolder*>(this->UntypedInvokeWith(untyped_args)));
return holder->Unwrap(); return holder->Unwrap();
} }
...@@ -1609,6 +1622,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1609,6 +1622,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
TypedExpectation<F>* const expectation = TypedExpectation<F>* const expectation =
new TypedExpectation<F>(this, file, line, source_text, m); new TypedExpectation<F>(this, file, line, source_text, m);
const linked_ptr<ExpectationBase> untyped_expectation(expectation); const linked_ptr<ExpectationBase> untyped_expectation(expectation);
// See the definition of untyped_expectations_ for why access to
// it is unprotected here.
untyped_expectations_.push_back(untyped_expectation); untyped_expectations_.push_back(untyped_expectation);
// Adds this expectation into the implicit sequence if there is one. // Adds this expectation into the implicit sequence if there is one.
...@@ -1620,10 +1635,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1620,10 +1635,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
return *expectation; return *expectation;
} }
// The current spec (either default action spec or expectation spec)
// being described on this function mocker.
MockSpec<F>& current_spec() { return current_spec_; }
private: private:
template <typename Func> friend class TypedExpectation; template <typename Func> friend class TypedExpectation;
...@@ -1716,6 +1727,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1716,6 +1727,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
const ArgumentTuple& args) const const ArgumentTuple& args) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
// See the definition of untyped_expectations_ for why access to
// it is unprotected here.
for (typename UntypedExpectations::const_reverse_iterator it = for (typename UntypedExpectations::const_reverse_iterator it =
untyped_expectations_.rbegin(); untyped_expectations_.rbegin();
it != untyped_expectations_.rend(); ++it) { it != untyped_expectations_.rend(); ++it) {
...@@ -1766,10 +1779,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1766,10 +1779,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
} }
} }
// The current spec (either default action spec or expectation spec)
// being described on this function mocker.
MockSpec<F> current_spec_;
// There is no generally useful and implementable semantics of // There is no generally useful and implementable semantics of
// copying a mock object, so copying a mock is usually a user error. // copying a mock object, so copying a mock is usually a user error.
// Thus we disallow copying function mockers. If the user really // Thus we disallow copying function mockers. If the user really
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <map> #include <map>
#include <set> #include <set>
#include <string> #include <string>
#include <vector>
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
...@@ -99,12 +100,19 @@ void ExpectationBase::RetireAllPreRequisites() ...@@ -99,12 +100,19 @@ void ExpectationBase::RetireAllPreRequisites()
return; return;
} }
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); ::std::vector<ExpectationBase*> expectations(1, this);
it != immediate_prerequisites_.end(); ++it) { while (!expectations.empty()) {
ExpectationBase* const prerequisite = it->expectation_base().get(); ExpectationBase* exp = expectations.back();
if (!prerequisite->is_retired()) { expectations.pop_back();
prerequisite->RetireAllPreRequisites();
prerequisite->Retire(); for (ExpectationSet::const_iterator it =
exp->immediate_prerequisites_.begin();
it != exp->immediate_prerequisites_.end(); ++it) {
ExpectationBase* next = it->expectation_base().get();
if (!next->is_retired()) {
next->Retire();
expectations.push_back(next);
}
} }
} }
} }
...@@ -114,11 +122,18 @@ void ExpectationBase::RetireAllPreRequisites() ...@@ -114,11 +122,18 @@ void ExpectationBase::RetireAllPreRequisites()
bool ExpectationBase::AllPrerequisitesAreSatisfied() const bool ExpectationBase::AllPrerequisitesAreSatisfied() const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); ::std::vector<const ExpectationBase*> expectations(1, this);
it != immediate_prerequisites_.end(); ++it) { while (!expectations.empty()) {
if (!(it->expectation_base()->IsSatisfied()) || const ExpectationBase* exp = expectations.back();
!(it->expectation_base()->AllPrerequisitesAreSatisfied())) expectations.pop_back();
return false;
for (ExpectationSet::const_iterator it =
exp->immediate_prerequisites_.begin();
it != exp->immediate_prerequisites_.end(); ++it) {
const ExpectationBase* next = it->expectation_base().get();
if (!next->IsSatisfied()) return false;
expectations.push_back(next);
}
} }
return true; return true;
} }
...@@ -127,19 +142,28 @@ bool ExpectationBase::AllPrerequisitesAreSatisfied() const ...@@ -127,19 +142,28 @@ bool ExpectationBase::AllPrerequisitesAreSatisfied() const
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); ::std::vector<const ExpectationBase*> expectations(1, this);
it != immediate_prerequisites_.end(); ++it) { while (!expectations.empty()) {
if (it->expectation_base()->IsSatisfied()) { const ExpectationBase* exp = expectations.back();
// If *it is satisfied and has a call count of 0, some of its expectations.pop_back();
// pre-requisites may not be satisfied yet.
if (it->expectation_base()->call_count_ == 0) { for (ExpectationSet::const_iterator it =
it->expectation_base()->FindUnsatisfiedPrerequisites(result); exp->immediate_prerequisites_.begin();
it != exp->immediate_prerequisites_.end(); ++it) {
const ExpectationBase* next = it->expectation_base().get();
if (next->IsSatisfied()) {
// If *it is satisfied and has a call count of 0, some of its
// pre-requisites may not be satisfied yet.
if (next->call_count_ == 0) {
expectations.push_back(next);
}
} else {
// Now that we know next is unsatisfied, we are not so interested
// in whether its pre-requisites are satisfied. Therefore we
// don't iterate into it here.
*result += *it;
} }
} else {
// Now that we know *it is unsatisfied, we are not so interested
// in whether its pre-requisites are satisfied. Therefore we
// don't recursively call FindUnsatisfiedPrerequisites() here.
*result += *it;
} }
} }
} }
...@@ -254,11 +278,13 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) { ...@@ -254,11 +278,13 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
case kWarn: case kWarn:
Log(kWarning, Log(kWarning,
msg + msg +
"\nNOTE: You can safely ignore the above warning unless this " "\nNOTE: You can safely ignore the above warning unless this "
"call should not happen. Do not suppress it by blindly adding " "call should not happen. Do not suppress it by blindly adding "
"an EXPECT_CALL() if you don't mean to enforce the call. " "an EXPECT_CALL() if you don't mean to enforce the call. "
"See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#" "See "
"knowing-when-to-expect for details.\n", "https://github.com/google/googletest/blob/master/googlemock/"
"docs/CookBook.md#"
"knowing-when-to-expect for details.\n",
stack_frames_to_skip); stack_frames_to_skip);
break; break;
default: // FAIL default: // FAIL
...@@ -334,9 +360,10 @@ const char* UntypedFunctionMockerBase::Name() const ...@@ -334,9 +360,10 @@ const char* UntypedFunctionMockerBase::Name() const
// Calculates the result of invoking this mock function with the given // Calculates the result of invoking this mock function with the given
// arguments, prints it, and returns it. The caller is responsible // arguments, prints it, and returns it. The caller is responsible
// for deleting the result. // for deleting the result.
UntypedActionResultHolderBase* UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith(
UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) void* const untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { // See the definition of untyped_expectations_ for why access to it
// is unprotected here.
if (untyped_expectations_.size() == 0) { if (untyped_expectations_.size() == 0) {
// No expectation is set on this mock method - we have an // No expectation is set on this mock method - we have an
// uninteresting call. // uninteresting call.
...@@ -355,16 +382,19 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) ...@@ -355,16 +382,19 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
// If the user allows this uninteresting call, we print it // If the user allows this uninteresting call, we print it
// only when they want informational messages. // only when they want informational messages.
reaction == kAllow ? LogIsVisible(kInfo) : reaction == kAllow ? LogIsVisible(kInfo) :
// If the user wants this to be a warning, we print it only // If the user wants this to be a warning, we print
// when they want to see warnings. // it only when they want to see warnings.
reaction == kWarn ? LogIsVisible(kWarning) : reaction == kWarn
// Otherwise, the user wants this to be an error, and we ? LogIsVisible(kWarning)
// should always print detailed information in the error. :
true; // Otherwise, the user wants this to be an error, and we
// should always print detailed information in the error.
true;
if (!need_to_report_uninteresting_call) { if (!need_to_report_uninteresting_call) {
// Perform the action without printing the call information. // Perform the action without printing the call information.
return this->UntypedPerformDefaultAction(untyped_args, "Function call: " + std::string(Name())); return this->UntypedPerformDefaultAction(
untyped_args, "Function call: " + std::string(Name()));
} }
// Warns about the uninteresting call. // Warns about the uninteresting call.
...@@ -446,6 +476,8 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) ...@@ -446,6 +476,8 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
// Returns an Expectation object that references and co-owns exp, // Returns an Expectation object that references and co-owns exp,
// which must be an expectation on this mock function. // which must be an expectation on this mock function.
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) { Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
// See the definition of untyped_expectations_ for why access to it
// is unprotected here.
for (UntypedExpectations::const_iterator it = for (UntypedExpectations::const_iterator it =
untyped_expectations_.begin(); untyped_expectations_.begin();
it != untyped_expectations_.end(); ++it) { it != untyped_expectations_.end(); ++it) {
...@@ -508,7 +540,7 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() ...@@ -508,7 +540,7 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
return expectations_met; return expectations_met;
} }
static CallReaction intToCallReaction(int mock_behavior) { CallReaction intToCallReaction(int mock_behavior) {
if (mock_behavior >= kAllow && mock_behavior <= kFail) { if (mock_behavior >= kAllow && mock_behavior <= kFail) {
return static_cast<internal::CallReaction>(mock_behavior); return static_cast<internal::CallReaction>(mock_behavior);
} }
...@@ -582,9 +614,15 @@ class MockObjectRegistry { ...@@ -582,9 +614,15 @@ class MockObjectRegistry {
leaked_count++; leaked_count++;
} }
if (leaked_count > 0) { if (leaked_count > 0) {
std::cout << "\nERROR: " << leaked_count std::cout << "\nERROR: " << leaked_count << " leaked mock "
<< " leaked mock " << (leaked_count == 1 ? "object" : "objects") << (leaked_count == 1 ? "object" : "objects")
<< " found at program exit.\n"; << " found at program exit. Expectations on a mock object is "
"verified when the object is destructed. Leaking a mock "
"means that its expectations aren't verified, which is "
"usually a test bug. If you really intend to leak a mock, "
"you can suppress this error using "
"testing::Mock::AllowLeak(mock_object), or you may use a "
"fake or stub instead of a mock.\n";
std::cout.flush(); std::cout.flush();
::std::cerr.flush(); ::std::cerr.flush();
// RUN_ALL_TESTS() has already returned when this destructor is // RUN_ALL_TESTS() has already returned when this destructor is
......
...@@ -704,6 +704,7 @@ class MockClass { ...@@ -704,6 +704,7 @@ class MockClass {
MOCK_METHOD0(MakeUnique, std::unique_ptr<int>()); MOCK_METHOD0(MakeUnique, std::unique_ptr<int>());
MOCK_METHOD0(MakeUniqueBase, std::unique_ptr<Base>()); MOCK_METHOD0(MakeUniqueBase, std::unique_ptr<Base>());
MOCK_METHOD0(MakeVectorUnique, std::vector<std::unique_ptr<int>>()); MOCK_METHOD0(MakeVectorUnique, std::vector<std::unique_ptr<int>>());
MOCK_METHOD1(TakeUnique, int(std::unique_ptr<int>));
#endif #endif
private: private:
......
...@@ -748,7 +748,6 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) { ...@@ -748,7 +748,6 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
testing::GMOCK_FLAG(default_mock_behavior) = original_behavior; testing::GMOCK_FLAG(default_mock_behavior) = original_behavior;
} }
#endif // GTEST_HAS_STREAM_REDIRECTION #endif // GTEST_HAS_STREAM_REDIRECTION
// Tests the semantics of ON_CALL(). // Tests the semantics of ON_CALL().
...@@ -2691,7 +2690,6 @@ int gmock_main(int argc, char **argv) { ...@@ -2691,7 +2690,6 @@ int gmock_main(int argc, char **argv) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
#endif // GMOCK_RENAME_MAIN #endif // GMOCK_RENAME_MAIN
testing::InitGoogleMock(&argc, argv); testing::InitGoogleMock(&argc, argv);
// Ensures that the tests pass no matter what value of // Ensures that the tests pass no matter what value of
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies. // --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
testing::GMOCK_FLAG(catch_leaked_mocks) = true; testing::GMOCK_FLAG(catch_leaked_mocks) = true;
......
...@@ -273,6 +273,11 @@ MATCHER_P2(IsPair, first, second, "") { ...@@ -273,6 +273,11 @@ MATCHER_P2(IsPair, first, second, "") {
return Value(arg.first, first) && Value(arg.second, second); return Value(arg.first, first) && Value(arg.second, second);
} }
TEST_F(GMockOutputTest, PrintsMatcher) {
const testing::Matcher<int> m1 = Ge(48);
EXPECT_THAT((std::pair<int, bool>(42, true)), IsPair(m1, true));
}
void TestCatchesLeakedMocksInAdHocTests() { void TestCatchesLeakedMocksInAdHocTests() {
MockFoo* foo = new MockFoo; MockFoo* foo = new MockFoo;
......
...@@ -288,6 +288,12 @@ Stack trace: ...@@ -288,6 +288,12 @@ Stack trace:
[ OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction [ OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
[ RUN ] GMockOutputTest.CatchesLeakedMocks [ RUN ] GMockOutputTest.CatchesLeakedMocks
[ OK ] GMockOutputTest.CatchesLeakedMocks [ OK ] GMockOutputTest.CatchesLeakedMocks
[ RUN ] GMockOutputTest.PrintsMatcher
FILE:#: Failure
Value of: (std::pair<int, bool>(42, true))
Expected: is pair (is >= 48, true)
Actual: (42, true) (of type std::pair<int, bool>)
[ FAILED ] GMockOutputTest.PrintsMatcher
[ FAILED ] GMockOutputTest.UnexpectedCall [ FAILED ] GMockOutputTest.UnexpectedCall
[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction [ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
[ FAILED ] GMockOutputTest.ExcessiveCall [ FAILED ] GMockOutputTest.ExcessiveCall
...@@ -302,9 +308,10 @@ Stack trace: ...@@ -302,9 +308,10 @@ Stack trace:
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWith [ FAILED ] GMockOutputTest.MismatchArgumentsAndWith
[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction [ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction [ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
[ FAILED ] GMockOutputTest.PrintsMatcher
FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#.
FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#.
FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#.
ERROR: 3 leaked mock objects found at program exit. ERROR: 3 leaked mock objects found at program exit. Expectations on a mock object is verified when the object is destructed. Leaking a mock means that its expectations aren't verified, which is usually a test bug. If you really intend to leak a mock, you can suppress this error using testing::Mock::AllowLeak(mock_object), or you may use a fake or stub instead of a mock.
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