brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.6 KiB · 056d471 Raw
278 lines · c
1// Copyright 2008, Google Inc.2// All rights reserved.3//4// Redistribution and use in source and binary forms, with or without5// modification, are permitted provided that the following conditions are6// met:7//8//     * Redistributions of source code must retain the above copyright9// notice, this list of conditions and the following disclaimer.10//     * Redistributions in binary form must reproduce the above11// copyright notice, this list of conditions and the following disclaimer12// in the documentation and/or other materials provided with the13// distribution.14//     * Neither the name of Google Inc. nor the names of its15// contributors may be used to endorse or promote products derived from16// this software without specific prior written permission.17//18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE28// 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 allows34// uninteresting calls (i.e. calls to mock methods that have no35// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo36// that prints a warning when an uninteresting call occurs, and37// StrictMock<MockFoo> is a subclass of MockFoo that treats all38// uninteresting calls as errors.39//40// Currently a mock is naggy by default, so MockFoo and41// NaggyMock<MockFoo> behave like the same.  However, we will soon42// switch the default behavior of mocks to be nice, as that in general43// leads to more maintainable tests.  When that happens, MockFoo will44// stop behaving like NaggyMock<MockFoo> and start behaving like45// NiceMock<MockFoo>.46//47// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of48// their respective base class.  Therefore you can write49// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo50// 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 using54// 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 NOT58// 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 72namespace testing {73template <class MockClass>74class NiceMock;75template <class MockClass>76class NaggyMock;77template <class MockClass>78class StrictMock;79 80namespace internal {81template <typename T>82std::true_type StrictnessModifierProbe(const NiceMock<T>&);83template <typename T>84std::true_type StrictnessModifierProbe(const NaggyMock<T>&);85template <typename T>86std::true_type StrictnessModifierProbe(const StrictMock<T>&);87std::false_type StrictnessModifierProbe(...);88 89template <typename T>90constexpr 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 the95// default behavior around uninteresting calls. Inheriting from one of these96// classes first and then MockClass ensures the MockClass constructor is run97// after registration, and that the MockClass destructor runs before98// deregistration. This guarantees that MockClass's constructor and destructor99// 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 that104// the empty base class optimization is performed.105#define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases)106#else107#define GTEST_INTERNAL_EMPTY_BASE_CLASS108#endif109 110template <typename Base>111class 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 122template <typename Base>123class 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 134template <typename Base>135class 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 internal147 148template <class MockClass>149class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock150    : 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 using164  // declaration, which would preserve their visibility. However, many existing165  // tests rely on the fact that current implementation reexports protected166  // constructors as public. These tests would need to be cleaned up first.167 168  // Single argument constructor is special-cased so that it can be169  // 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 189template <class MockClass>190class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock191    : 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 using206  // declaration, which would preserve their visibility. However, many existing207  // tests rely on the fact that current implementation reexports protected208  // constructors as public. These tests would need to be cleaned up first.209 210  // Single argument constructor is special-cased so that it can be211  // 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 231template <class MockClass>232class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock233    : 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 using248  // declaration, which would preserve their visibility. However, many existing249  // tests rely on the fact that current implementation reexports protected250  // constructors as public. These tests would need to be cleaned up first.251 252  // Single argument constructor is special-cased so that it can be253  // 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_CLASS274 275}  // namespace testing276 277#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_278