tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gmock-nice-strict.h (10858B)


      1 // Copyright 2008, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 
     30 // Implements class templates NiceMock, NaggyMock, and StrictMock.
     31 //
     32 // Given a mock class MockFoo that is created using Google Mock,
     33 // NiceMock<MockFoo> is a subclass of MockFoo that allows
     34 // uninteresting calls (i.e. calls to mock methods that have no
     35 // EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
     36 // that prints a warning when an uninteresting call occurs, and
     37 // StrictMock<MockFoo> is a subclass of MockFoo that treats all
     38 // uninteresting calls as errors.
     39 //
     40 // Currently a mock is naggy by default, so MockFoo and
     41 // NaggyMock<MockFoo> behave like the same.  However, we will soon
     42 // switch the default behavior of mocks to be nice, as that in general
     43 // leads to more maintainable tests.  When that happens, MockFoo will
     44 // stop behaving like NaggyMock<MockFoo> and start behaving like
     45 // NiceMock<MockFoo>.
     46 //
     47 // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
     48 // their respective base class.  Therefore you can write
     49 // NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
     50 // has a constructor that accepts (int, const char*), for example.
     51 //
     52 // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
     53 // and StrictMock<MockFoo> only works for mock methods defined using
     54 // the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
     55 // If a mock method is defined in a base class of MockFoo, the "nice"
     56 // or "strict" modifier may not affect it, depending on the compiler.
     57 // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
     58 // supported.
     59 
     60 // IWYU pragma: private, include "gmock/gmock.h"
     61 // IWYU pragma: friend gmock/.*
     62 
     63 #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
     64 #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
     65 
     66 #include <cstdint>
     67 #include <type_traits>
     68 
     69 #include "gmock/gmock-spec-builders.h"
     70 #include "gmock/internal/gmock-port.h"
     71 
     72 namespace testing {
     73 template <class MockClass>
     74 class NiceMock;
     75 template <class MockClass>
     76 class NaggyMock;
     77 template <class MockClass>
     78 class StrictMock;
     79 
     80 namespace internal {
     81 template <typename T>
     82 std::true_type StrictnessModifierProbe(const NiceMock<T>&);
     83 template <typename T>
     84 std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
     85 template <typename T>
     86 std::true_type StrictnessModifierProbe(const StrictMock<T>&);
     87 std::false_type StrictnessModifierProbe(...);
     88 
     89 template <typename T>
     90 constexpr bool HasStrictnessModifier() {
     91  return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
     92 }
     93 
     94 // Base classes that register and deregister with testing::Mock to alter the
     95 // default behavior around uninteresting calls. Inheriting from one of these
     96 // classes first and then MockClass ensures the MockClass constructor is run
     97 // after registration, and that the MockClass destructor runs before
     98 // deregistration. This guarantees that MockClass's constructor and destructor
     99 // run with the same level of strictness as its instance methods.
    100 
    101 #if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \
    102    (defined(_MSC_VER) || defined(__clang__))
    103 // We need to mark these classes with this declspec to ensure that
    104 // the empty base class optimization is performed.
    105 #define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases)
    106 #else
    107 #define GTEST_INTERNAL_EMPTY_BASE_CLASS
    108 #endif
    109 
    110 template <typename Base>
    111 class NiceMockImpl {
    112 public:
    113  NiceMockImpl() {
    114    ::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));
    115  }
    116 
    117  ~NiceMockImpl() {
    118    ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));
    119  }
    120 };
    121 
    122 template <typename Base>
    123 class NaggyMockImpl {
    124 public:
    125  NaggyMockImpl() {
    126    ::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));
    127  }
    128 
    129  ~NaggyMockImpl() {
    130    ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));
    131  }
    132 };
    133 
    134 template <typename Base>
    135 class StrictMockImpl {
    136 public:
    137  StrictMockImpl() {
    138    ::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));
    139  }
    140 
    141  ~StrictMockImpl() {
    142    ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));
    143  }
    144 };
    145 
    146 }  // namespace internal
    147 
    148 template <class MockClass>
    149 class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
    150    : private internal::NiceMockImpl<MockClass>,
    151      public MockClass {
    152 public:
    153  static_assert(!internal::HasStrictnessModifier<MockClass>(),
    154                "Can't apply NiceMock to a class hierarchy that already has a "
    155                "strictness modifier. See "
    156                "https://google.github.io/googletest/"
    157                "gmock_cook_book.html#NiceStrictNaggy");
    158  NiceMock() : MockClass() {
    159    static_assert(sizeof(*this) == sizeof(MockClass),
    160                  "The impl subclass shouldn't introduce any padding");
    161  }
    162 
    163  // Ideally, we would inherit base class's constructors through a using
    164  // declaration, which would preserve their visibility. However, many existing
    165  // tests rely on the fact that current implementation reexports protected
    166  // constructors as public. These tests would need to be cleaned up first.
    167 
    168  // Single argument constructor is special-cased so that it can be
    169  // made explicit.
    170  template <typename A>
    171  explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
    172    static_assert(sizeof(*this) == sizeof(MockClass),
    173                  "The impl subclass shouldn't introduce any padding");
    174  }
    175 
    176  template <typename TArg1, typename TArg2, typename... An>
    177  NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
    178      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
    179                  std::forward<An>(args)...) {
    180    static_assert(sizeof(*this) == sizeof(MockClass),
    181                  "The impl subclass shouldn't introduce any padding");
    182  }
    183 
    184 private:
    185  NiceMock(const NiceMock&) = delete;
    186  NiceMock& operator=(const NiceMock&) = delete;
    187 };
    188 
    189 template <class MockClass>
    190 class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
    191    : private internal::NaggyMockImpl<MockClass>,
    192      public MockClass {
    193  static_assert(!internal::HasStrictnessModifier<MockClass>(),
    194                "Can't apply NaggyMock to a class hierarchy that already has a "
    195                "strictness modifier. See "
    196                "https://google.github.io/googletest/"
    197                "gmock_cook_book.html#NiceStrictNaggy");
    198 
    199 public:
    200  NaggyMock() : MockClass() {
    201    static_assert(sizeof(*this) == sizeof(MockClass),
    202                  "The impl subclass shouldn't introduce any padding");
    203  }
    204 
    205  // Ideally, we would inherit base class's constructors through a using
    206  // declaration, which would preserve their visibility. However, many existing
    207  // tests rely on the fact that current implementation reexports protected
    208  // constructors as public. These tests would need to be cleaned up first.
    209 
    210  // Single argument constructor is special-cased so that it can be
    211  // made explicit.
    212  template <typename A>
    213  explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
    214    static_assert(sizeof(*this) == sizeof(MockClass),
    215                  "The impl subclass shouldn't introduce any padding");
    216  }
    217 
    218  template <typename TArg1, typename TArg2, typename... An>
    219  NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
    220      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
    221                  std::forward<An>(args)...) {
    222    static_assert(sizeof(*this) == sizeof(MockClass),
    223                  "The impl subclass shouldn't introduce any padding");
    224  }
    225 
    226 private:
    227  NaggyMock(const NaggyMock&) = delete;
    228  NaggyMock& operator=(const NaggyMock&) = delete;
    229 };
    230 
    231 template <class MockClass>
    232 class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
    233    : private internal::StrictMockImpl<MockClass>,
    234      public MockClass {
    235 public:
    236  static_assert(
    237      !internal::HasStrictnessModifier<MockClass>(),
    238      "Can't apply StrictMock to a class hierarchy that already has a "
    239      "strictness modifier. See "
    240      "https://google.github.io/googletest/"
    241      "gmock_cook_book.html#NiceStrictNaggy");
    242  StrictMock() : MockClass() {
    243    static_assert(sizeof(*this) == sizeof(MockClass),
    244                  "The impl subclass shouldn't introduce any padding");
    245  }
    246 
    247  // Ideally, we would inherit base class's constructors through a using
    248  // declaration, which would preserve their visibility. However, many existing
    249  // tests rely on the fact that current implementation reexports protected
    250  // constructors as public. These tests would need to be cleaned up first.
    251 
    252  // Single argument constructor is special-cased so that it can be
    253  // made explicit.
    254  template <typename A>
    255  explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
    256    static_assert(sizeof(*this) == sizeof(MockClass),
    257                  "The impl subclass shouldn't introduce any padding");
    258  }
    259 
    260  template <typename TArg1, typename TArg2, typename... An>
    261  StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
    262      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
    263                  std::forward<An>(args)...) {
    264    static_assert(sizeof(*this) == sizeof(MockClass),
    265                  "The impl subclass shouldn't introduce any padding");
    266  }
    267 
    268 private:
    269  StrictMock(const StrictMock&) = delete;
    270  StrictMock& operator=(const StrictMock&) = delete;
    271 };
    272 
    273 #undef GTEST_INTERNAL_EMPTY_BASE_CLASS
    274 
    275 }  // namespace testing
    276 
    277 #endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_