128f6c2f2SEnji Cooper // Copyright 2008, Google Inc.
228f6c2f2SEnji Cooper // All rights reserved.
328f6c2f2SEnji Cooper //
428f6c2f2SEnji Cooper // Redistribution and use in source and binary forms, with or without
528f6c2f2SEnji Cooper // modification, are permitted provided that the following conditions are
628f6c2f2SEnji Cooper // met:
728f6c2f2SEnji Cooper //
828f6c2f2SEnji Cooper //     * Redistributions of source code must retain the above copyright
928f6c2f2SEnji Cooper // notice, this list of conditions and the following disclaimer.
1028f6c2f2SEnji Cooper //     * Redistributions in binary form must reproduce the above
1128f6c2f2SEnji Cooper // copyright notice, this list of conditions and the following disclaimer
1228f6c2f2SEnji Cooper // in the documentation and/or other materials provided with the
1328f6c2f2SEnji Cooper // distribution.
1428f6c2f2SEnji Cooper //     * Neither the name of Google Inc. nor the names of its
1528f6c2f2SEnji Cooper // contributors may be used to endorse or promote products derived from
1628f6c2f2SEnji Cooper // this software without specific prior written permission.
1728f6c2f2SEnji Cooper //
1828f6c2f2SEnji Cooper // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1928f6c2f2SEnji Cooper // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2028f6c2f2SEnji Cooper // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2128f6c2f2SEnji Cooper // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2228f6c2f2SEnji Cooper // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2328f6c2f2SEnji Cooper // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2428f6c2f2SEnji Cooper // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2528f6c2f2SEnji Cooper // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2628f6c2f2SEnji Cooper // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2728f6c2f2SEnji Cooper // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2828f6c2f2SEnji Cooper // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2928f6c2f2SEnji Cooper 
3028f6c2f2SEnji Cooper // Implements class templates NiceMock, NaggyMock, and StrictMock.
3128f6c2f2SEnji Cooper //
3228f6c2f2SEnji Cooper // Given a mock class MockFoo that is created using Google Mock,
3328f6c2f2SEnji Cooper // NiceMock<MockFoo> is a subclass of MockFoo that allows
3428f6c2f2SEnji Cooper // uninteresting calls (i.e. calls to mock methods that have no
3528f6c2f2SEnji Cooper // EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
3628f6c2f2SEnji Cooper // that prints a warning when an uninteresting call occurs, and
3728f6c2f2SEnji Cooper // StrictMock<MockFoo> is a subclass of MockFoo that treats all
3828f6c2f2SEnji Cooper // uninteresting calls as errors.
3928f6c2f2SEnji Cooper //
4028f6c2f2SEnji Cooper // Currently a mock is naggy by default, so MockFoo and
4128f6c2f2SEnji Cooper // NaggyMock<MockFoo> behave like the same.  However, we will soon
4228f6c2f2SEnji Cooper // switch the default behavior of mocks to be nice, as that in general
4328f6c2f2SEnji Cooper // leads to more maintainable tests.  When that happens, MockFoo will
4428f6c2f2SEnji Cooper // stop behaving like NaggyMock<MockFoo> and start behaving like
4528f6c2f2SEnji Cooper // NiceMock<MockFoo>.
4628f6c2f2SEnji Cooper //
4728f6c2f2SEnji Cooper // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
4828f6c2f2SEnji Cooper // their respective base class.  Therefore you can write
4928f6c2f2SEnji Cooper // NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
5028f6c2f2SEnji Cooper // has a constructor that accepts (int, const char*), for example.
5128f6c2f2SEnji Cooper //
5228f6c2f2SEnji Cooper // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
5328f6c2f2SEnji Cooper // and StrictMock<MockFoo> only works for mock methods defined using
5428f6c2f2SEnji Cooper // the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
5528f6c2f2SEnji Cooper // If a mock method is defined in a base class of MockFoo, the "nice"
5628f6c2f2SEnji Cooper // or "strict" modifier may not affect it, depending on the compiler.
5728f6c2f2SEnji Cooper // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
5828f6c2f2SEnji Cooper // supported.
5928f6c2f2SEnji Cooper 
6028f6c2f2SEnji Cooper // IWYU pragma: private, include "gmock/gmock.h"
6128f6c2f2SEnji Cooper // IWYU pragma: friend gmock/.*
6228f6c2f2SEnji Cooper 
6328f6c2f2SEnji Cooper #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
6428f6c2f2SEnji Cooper #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
6528f6c2f2SEnji Cooper 
6628f6c2f2SEnji Cooper #include <cstdint>
6728f6c2f2SEnji Cooper #include <type_traits>
6828f6c2f2SEnji Cooper 
6928f6c2f2SEnji Cooper #include "gmock/gmock-spec-builders.h"
7028f6c2f2SEnji Cooper #include "gmock/internal/gmock-port.h"
7128f6c2f2SEnji Cooper 
7228f6c2f2SEnji Cooper namespace testing {
7328f6c2f2SEnji Cooper template <class MockClass>
7428f6c2f2SEnji Cooper class NiceMock;
7528f6c2f2SEnji Cooper template <class MockClass>
7628f6c2f2SEnji Cooper class NaggyMock;
7728f6c2f2SEnji Cooper template <class MockClass>
7828f6c2f2SEnji Cooper class StrictMock;
7928f6c2f2SEnji Cooper 
8028f6c2f2SEnji Cooper namespace internal {
8128f6c2f2SEnji Cooper template <typename T>
8228f6c2f2SEnji Cooper std::true_type StrictnessModifierProbe(const NiceMock<T>&);
8328f6c2f2SEnji Cooper template <typename T>
8428f6c2f2SEnji Cooper std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
8528f6c2f2SEnji Cooper template <typename T>
8628f6c2f2SEnji Cooper std::true_type StrictnessModifierProbe(const StrictMock<T>&);
8728f6c2f2SEnji Cooper std::false_type StrictnessModifierProbe(...);
8828f6c2f2SEnji Cooper 
8928f6c2f2SEnji Cooper template <typename T>
HasStrictnessModifier()9028f6c2f2SEnji Cooper constexpr bool HasStrictnessModifier() {
9128f6c2f2SEnji Cooper   return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
9228f6c2f2SEnji Cooper }
9328f6c2f2SEnji Cooper 
9428f6c2f2SEnji Cooper // Base classes that register and deregister with testing::Mock to alter the
9528f6c2f2SEnji Cooper // default behavior around uninteresting calls. Inheriting from one of these
9628f6c2f2SEnji Cooper // classes first and then MockClass ensures the MockClass constructor is run
9728f6c2f2SEnji Cooper // after registration, and that the MockClass destructor runs before
9828f6c2f2SEnji Cooper // deregistration. This guarantees that MockClass's constructor and destructor
9928f6c2f2SEnji Cooper // run with the same level of strictness as its instance methods.
10028f6c2f2SEnji Cooper 
10128f6c2f2SEnji Cooper #if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \
10228f6c2f2SEnji Cooper     (defined(_MSC_VER) || defined(__clang__))
10328f6c2f2SEnji Cooper // We need to mark these classes with this declspec to ensure that
10428f6c2f2SEnji Cooper // the empty base class optimization is performed.
10528f6c2f2SEnji Cooper #define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases)
10628f6c2f2SEnji Cooper #else
10728f6c2f2SEnji Cooper #define GTEST_INTERNAL_EMPTY_BASE_CLASS
10828f6c2f2SEnji Cooper #endif
10928f6c2f2SEnji Cooper 
11028f6c2f2SEnji Cooper template <typename Base>
11128f6c2f2SEnji Cooper class NiceMockImpl {
11228f6c2f2SEnji Cooper  public:
NiceMockImpl()11328f6c2f2SEnji Cooper   NiceMockImpl() {
11428f6c2f2SEnji Cooper     ::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));
11528f6c2f2SEnji Cooper   }
11628f6c2f2SEnji Cooper 
~NiceMockImpl()11728f6c2f2SEnji Cooper   ~NiceMockImpl() {
11828f6c2f2SEnji Cooper     ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));
11928f6c2f2SEnji Cooper   }
12028f6c2f2SEnji Cooper };
12128f6c2f2SEnji Cooper 
12228f6c2f2SEnji Cooper template <typename Base>
12328f6c2f2SEnji Cooper class NaggyMockImpl {
12428f6c2f2SEnji Cooper  public:
NaggyMockImpl()12528f6c2f2SEnji Cooper   NaggyMockImpl() {
12628f6c2f2SEnji Cooper     ::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));
12728f6c2f2SEnji Cooper   }
12828f6c2f2SEnji Cooper 
~NaggyMockImpl()12928f6c2f2SEnji Cooper   ~NaggyMockImpl() {
13028f6c2f2SEnji Cooper     ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));
13128f6c2f2SEnji Cooper   }
13228f6c2f2SEnji Cooper };
13328f6c2f2SEnji Cooper 
13428f6c2f2SEnji Cooper template <typename Base>
13528f6c2f2SEnji Cooper class StrictMockImpl {
13628f6c2f2SEnji Cooper  public:
StrictMockImpl()13728f6c2f2SEnji Cooper   StrictMockImpl() {
13828f6c2f2SEnji Cooper     ::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));
13928f6c2f2SEnji Cooper   }
14028f6c2f2SEnji Cooper 
~StrictMockImpl()14128f6c2f2SEnji Cooper   ~StrictMockImpl() {
14228f6c2f2SEnji Cooper     ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));
14328f6c2f2SEnji Cooper   }
14428f6c2f2SEnji Cooper };
14528f6c2f2SEnji Cooper 
14628f6c2f2SEnji Cooper }  // namespace internal
14728f6c2f2SEnji Cooper 
14828f6c2f2SEnji Cooper template <class MockClass>
14928f6c2f2SEnji Cooper class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
15028f6c2f2SEnji Cooper     : private internal::NiceMockImpl<MockClass>,
15128f6c2f2SEnji Cooper       public MockClass {
15228f6c2f2SEnji Cooper  public:
15328f6c2f2SEnji Cooper   static_assert(!internal::HasStrictnessModifier<MockClass>(),
15428f6c2f2SEnji Cooper                 "Can't apply NiceMock to a class hierarchy that already has a "
15528f6c2f2SEnji Cooper                 "strictness modifier. See "
15628f6c2f2SEnji Cooper                 "https://google.github.io/googletest/"
15728f6c2f2SEnji Cooper                 "gmock_cook_book.html#NiceStrictNaggy");
NiceMock()15828f6c2f2SEnji Cooper   NiceMock() : MockClass() {
15928f6c2f2SEnji Cooper     static_assert(sizeof(*this) == sizeof(MockClass),
16028f6c2f2SEnji Cooper                   "The impl subclass shouldn't introduce any padding");
16128f6c2f2SEnji Cooper   }
16228f6c2f2SEnji Cooper 
16328f6c2f2SEnji Cooper   // Ideally, we would inherit base class's constructors through a using
16428f6c2f2SEnji Cooper   // declaration, which would preserve their visibility. However, many existing
16528f6c2f2SEnji Cooper   // tests rely on the fact that current implementation reexports protected
16628f6c2f2SEnji Cooper   // constructors as public. These tests would need to be cleaned up first.
16728f6c2f2SEnji Cooper 
16828f6c2f2SEnji Cooper   // Single argument constructor is special-cased so that it can be
16928f6c2f2SEnji Cooper   // made explicit.
17028f6c2f2SEnji Cooper   template <typename A>
NiceMock(A && arg)17128f6c2f2SEnji Cooper   explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
17228f6c2f2SEnji Cooper     static_assert(sizeof(*this) == sizeof(MockClass),
17328f6c2f2SEnji Cooper                   "The impl subclass shouldn't introduce any padding");
17428f6c2f2SEnji Cooper   }
17528f6c2f2SEnji Cooper 
17628f6c2f2SEnji Cooper   template <typename TArg1, typename TArg2, typename... An>
NiceMock(TArg1 && arg1,TArg2 && arg2,An &&...args)17728f6c2f2SEnji Cooper   NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
17828f6c2f2SEnji Cooper       : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
17928f6c2f2SEnji Cooper                   std::forward<An>(args)...) {
18028f6c2f2SEnji Cooper     static_assert(sizeof(*this) == sizeof(MockClass),
18128f6c2f2SEnji Cooper                   "The impl subclass shouldn't introduce any padding");
18228f6c2f2SEnji Cooper   }
18328f6c2f2SEnji Cooper 
18428f6c2f2SEnji Cooper  private:
18528f6c2f2SEnji Cooper   NiceMock(const NiceMock&) = delete;
18628f6c2f2SEnji Cooper   NiceMock& operator=(const NiceMock&) = delete;
18728f6c2f2SEnji Cooper };
18828f6c2f2SEnji Cooper 
18928f6c2f2SEnji Cooper template <class MockClass>
19028f6c2f2SEnji Cooper class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
19128f6c2f2SEnji Cooper     : private internal::NaggyMockImpl<MockClass>,
19228f6c2f2SEnji Cooper       public MockClass {
19328f6c2f2SEnji Cooper   static_assert(!internal::HasStrictnessModifier<MockClass>(),
19428f6c2f2SEnji Cooper                 "Can't apply NaggyMock to a class hierarchy that already has a "
19528f6c2f2SEnji Cooper                 "strictness modifier. See "
19628f6c2f2SEnji Cooper                 "https://google.github.io/googletest/"
19728f6c2f2SEnji Cooper                 "gmock_cook_book.html#NiceStrictNaggy");
19828f6c2f2SEnji Cooper 
19928f6c2f2SEnji Cooper  public:
NaggyMock()20028f6c2f2SEnji Cooper   NaggyMock() : MockClass() {
20128f6c2f2SEnji Cooper     static_assert(sizeof(*this) == sizeof(MockClass),
20228f6c2f2SEnji Cooper                   "The impl subclass shouldn't introduce any padding");
20328f6c2f2SEnji Cooper   }
20428f6c2f2SEnji Cooper 
20528f6c2f2SEnji Cooper   // Ideally, we would inherit base class's constructors through a using
20628f6c2f2SEnji Cooper   // declaration, which would preserve their visibility. However, many existing
20728f6c2f2SEnji Cooper   // tests rely on the fact that current implementation reexports protected
20828f6c2f2SEnji Cooper   // constructors as public. These tests would need to be cleaned up first.
20928f6c2f2SEnji Cooper 
21028f6c2f2SEnji Cooper   // Single argument constructor is special-cased so that it can be
21128f6c2f2SEnji Cooper   // made explicit.
21228f6c2f2SEnji Cooper   template <typename A>
NaggyMock(A && arg)21328f6c2f2SEnji Cooper   explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
21428f6c2f2SEnji Cooper     static_assert(sizeof(*this) == sizeof(MockClass),
21528f6c2f2SEnji Cooper                   "The impl subclass shouldn't introduce any padding");
21628f6c2f2SEnji Cooper   }
21728f6c2f2SEnji Cooper 
21828f6c2f2SEnji Cooper   template <typename TArg1, typename TArg2, typename... An>
NaggyMock(TArg1 && arg1,TArg2 && arg2,An &&...args)21928f6c2f2SEnji Cooper   NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
22028f6c2f2SEnji Cooper       : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
22128f6c2f2SEnji Cooper                   std::forward<An>(args)...) {
22228f6c2f2SEnji Cooper     static_assert(sizeof(*this) == sizeof(MockClass),
22328f6c2f2SEnji Cooper                   "The impl subclass shouldn't introduce any padding");
22428f6c2f2SEnji Cooper   }
22528f6c2f2SEnji Cooper 
22628f6c2f2SEnji Cooper  private:
22728f6c2f2SEnji Cooper   NaggyMock(const NaggyMock&) = delete;
22828f6c2f2SEnji Cooper   NaggyMock& operator=(const NaggyMock&) = delete;
22928f6c2f2SEnji Cooper };
23028f6c2f2SEnji Cooper 
23128f6c2f2SEnji Cooper template <class MockClass>
23228f6c2f2SEnji Cooper class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
23328f6c2f2SEnji Cooper     : private internal::StrictMockImpl<MockClass>,
23428f6c2f2SEnji Cooper       public MockClass {
23528f6c2f2SEnji Cooper  public:
23628f6c2f2SEnji Cooper   static_assert(
23728f6c2f2SEnji Cooper       !internal::HasStrictnessModifier<MockClass>(),
23828f6c2f2SEnji Cooper       "Can't apply StrictMock to a class hierarchy that already has a "
23928f6c2f2SEnji Cooper       "strictness modifier. See "
24028f6c2f2SEnji Cooper       "https://google.github.io/googletest/"
24128f6c2f2SEnji Cooper       "gmock_cook_book.html#NiceStrictNaggy");
StrictMock()24228f6c2f2SEnji Cooper   StrictMock() : MockClass() {
24328f6c2f2SEnji Cooper     static_assert(sizeof(*this) == sizeof(MockClass),
24428f6c2f2SEnji Cooper                   "The impl subclass shouldn't introduce any padding");
24528f6c2f2SEnji Cooper   }
24628f6c2f2SEnji Cooper 
24728f6c2f2SEnji Cooper   // Ideally, we would inherit base class's constructors through a using
24828f6c2f2SEnji Cooper   // declaration, which would preserve their visibility. However, many existing
24928f6c2f2SEnji Cooper   // tests rely on the fact that current implementation reexports protected
25028f6c2f2SEnji Cooper   // constructors as public. These tests would need to be cleaned up first.
25128f6c2f2SEnji Cooper 
25228f6c2f2SEnji Cooper   // Single argument constructor is special-cased so that it can be
25328f6c2f2SEnji Cooper   // made explicit.
25428f6c2f2SEnji Cooper   template <typename A>
StrictMock(A && arg)25528f6c2f2SEnji Cooper   explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
25628f6c2f2SEnji Cooper     static_assert(sizeof(*this) == sizeof(MockClass),
25728f6c2f2SEnji Cooper                   "The impl subclass shouldn't introduce any padding");
25828f6c2f2SEnji Cooper   }
25928f6c2f2SEnji Cooper 
26028f6c2f2SEnji Cooper   template <typename TArg1, typename TArg2, typename... An>
StrictMock(TArg1 && arg1,TArg2 && arg2,An &&...args)26128f6c2f2SEnji Cooper   StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
26228f6c2f2SEnji Cooper       : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
26328f6c2f2SEnji Cooper                   std::forward<An>(args)...) {
26428f6c2f2SEnji Cooper     static_assert(sizeof(*this) == sizeof(MockClass),
26528f6c2f2SEnji Cooper                   "The impl subclass shouldn't introduce any padding");
26628f6c2f2SEnji Cooper   }
26728f6c2f2SEnji Cooper 
26828f6c2f2SEnji Cooper  private:
26928f6c2f2SEnji Cooper   StrictMock(const StrictMock&) = delete;
27028f6c2f2SEnji Cooper   StrictMock& operator=(const StrictMock&) = delete;
27128f6c2f2SEnji Cooper };
27228f6c2f2SEnji Cooper 
27328f6c2f2SEnji Cooper #undef GTEST_INTERNAL_EMPTY_BASE_CLASS
27428f6c2f2SEnji Cooper 
27528f6c2f2SEnji Cooper }  // namespace testing
27628f6c2f2SEnji Cooper 
27728f6c2f2SEnji Cooper #endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
278