Googletest export
Move FunctionMocker and MockFunction out of the pump file and implement with variadic templates. PiperOrigin-RevId: 220640265
This commit is contained in:
		
				
					committed by
					
						
						Gennadiy Civil
					
				
			
			
				
	
			
			
			
						parent
						
							105579a6e4
						
					
				
				
					commit
					de5be0eb28
				
			@@ -106,9 +106,6 @@ template <typename F> class TypedExpectation;
 | 
			
		||||
// Helper class for testing the Expectation class template.
 | 
			
		||||
class ExpectationTester;
 | 
			
		||||
 | 
			
		||||
// Base class for function mockers.
 | 
			
		||||
template <typename F> class FunctionMockerBase;
 | 
			
		||||
 | 
			
		||||
// Protects the mock object registry (in class Mock), all function
 | 
			
		||||
// mockers, and all expectations.
 | 
			
		||||
//
 | 
			
		||||
@@ -125,9 +122,9 @@ GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);
 | 
			
		||||
// Untyped base class for ActionResultHolder<R>.
 | 
			
		||||
class UntypedActionResultHolderBase;
 | 
			
		||||
 | 
			
		||||
// Abstract base class of FunctionMockerBase.  This is the
 | 
			
		||||
// Abstract base class of FunctionMocker.  This is the
 | 
			
		||||
// type-agnostic part of the function mocker interface.  Its pure
 | 
			
		||||
// virtual methods are implemented by FunctionMockerBase.
 | 
			
		||||
// virtual methods are implemented by FunctionMocker.
 | 
			
		||||
class GTEST_API_ UntypedFunctionMockerBase {
 | 
			
		||||
 public:
 | 
			
		||||
  UntypedFunctionMockerBase();
 | 
			
		||||
@@ -415,7 +412,7 @@ class GTEST_API_ Mock {
 | 
			
		||||
  // Needed for a function mocker to register itself (so that we know
 | 
			
		||||
  // how to clear a mock object).
 | 
			
		||||
  template <typename F>
 | 
			
		||||
  friend class internal::FunctionMockerBase;
 | 
			
		||||
  friend class internal::FunctionMocker;
 | 
			
		||||
 | 
			
		||||
  template <typename M>
 | 
			
		||||
  friend class NiceMock;
 | 
			
		||||
@@ -478,7 +475,7 @@ class GTEST_API_ Mock {
 | 
			
		||||
  // Unregisters a mock method; removes the owning mock object from
 | 
			
		||||
  // the registry when the last mock method associated with it has
 | 
			
		||||
  // been unregistered.  This is called only in the destructor of
 | 
			
		||||
  // FunctionMockerBase.
 | 
			
		||||
  // FunctionMocker.
 | 
			
		||||
  static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
 | 
			
		||||
      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
 | 
			
		||||
};  // class Mock
 | 
			
		||||
@@ -534,7 +531,7 @@ class GTEST_API_ Expectation {
 | 
			
		||||
  friend class ::testing::internal::UntypedFunctionMockerBase;
 | 
			
		||||
 | 
			
		||||
  template <typename F>
 | 
			
		||||
  friend class ::testing::internal::FunctionMockerBase;
 | 
			
		||||
  friend class ::testing::internal::FunctionMocker;
 | 
			
		||||
 | 
			
		||||
  template <typename F>
 | 
			
		||||
  friend class ::testing::internal::TypedExpectation;
 | 
			
		||||
@@ -893,7 +890,7 @@ class TypedExpectation : public ExpectationBase {
 | 
			
		||||
  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
 | 
			
		||||
  typedef typename Function<F>::Result Result;
 | 
			
		||||
 | 
			
		||||
  TypedExpectation(FunctionMockerBase<F>* owner, const char* a_file, int a_line,
 | 
			
		||||
  TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line,
 | 
			
		||||
                   const std::string& a_source_text,
 | 
			
		||||
                   const ArgumentMatcherTuple& m)
 | 
			
		||||
      : ExpectationBase(a_file, a_line, a_source_text),
 | 
			
		||||
@@ -1082,7 +1079,7 @@ class TypedExpectation : public ExpectationBase {
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  template <typename Function>
 | 
			
		||||
  friend class FunctionMockerBase;
 | 
			
		||||
  friend class FunctionMocker;
 | 
			
		||||
 | 
			
		||||
  // Returns an Expectation object that references and co-owns this
 | 
			
		||||
  // expectation.
 | 
			
		||||
@@ -1161,10 +1158,9 @@ class TypedExpectation : public ExpectationBase {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns the action that should be taken for the current invocation.
 | 
			
		||||
  const Action<F>& GetCurrentAction(
 | 
			
		||||
      const FunctionMockerBase<F>* mocker,
 | 
			
		||||
      const ArgumentTuple& args) const
 | 
			
		||||
          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
 | 
			
		||||
  const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker,
 | 
			
		||||
                                    const ArgumentTuple& args) const
 | 
			
		||||
      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
 | 
			
		||||
    g_gmock_mutex.AssertHeld();
 | 
			
		||||
    const int count = call_count();
 | 
			
		||||
    Assert(count >= 1, __FILE__, __LINE__,
 | 
			
		||||
@@ -1199,12 +1195,11 @@ class TypedExpectation : public ExpectationBase {
 | 
			
		||||
  // Mock does it to 'why'.  This method is not const as it calls
 | 
			
		||||
  // IncrementCallCount().  A return value of NULL means the default
 | 
			
		||||
  // action.
 | 
			
		||||
  const Action<F>* GetActionForArguments(
 | 
			
		||||
      const FunctionMockerBase<F>* mocker,
 | 
			
		||||
      const ArgumentTuple& args,
 | 
			
		||||
      ::std::ostream* what,
 | 
			
		||||
      ::std::ostream* why)
 | 
			
		||||
          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
 | 
			
		||||
  const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker,
 | 
			
		||||
                                         const ArgumentTuple& args,
 | 
			
		||||
                                         ::std::ostream* what,
 | 
			
		||||
                                         ::std::ostream* why)
 | 
			
		||||
      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
 | 
			
		||||
    g_gmock_mutex.AssertHeld();
 | 
			
		||||
    if (IsSaturated()) {
 | 
			
		||||
      // We have an excessive call.
 | 
			
		||||
@@ -1233,7 +1228,7 @@ class TypedExpectation : public ExpectationBase {
 | 
			
		||||
 | 
			
		||||
  // All the fields below won't change once the EXPECT_CALL()
 | 
			
		||||
  // statement finishes.
 | 
			
		||||
  FunctionMockerBase<F>* const owner_;
 | 
			
		||||
  FunctionMocker<F>* const owner_;
 | 
			
		||||
  ArgumentMatcherTuple matchers_;
 | 
			
		||||
  Matcher<const ArgumentTuple&> extra_matcher_;
 | 
			
		||||
  Action<F> repeated_action_;
 | 
			
		||||
@@ -1265,7 +1260,7 @@ class MockSpec {
 | 
			
		||||
 | 
			
		||||
  // Constructs a MockSpec object, given the function mocker object
 | 
			
		||||
  // that the spec is associated with.
 | 
			
		||||
  MockSpec(internal::FunctionMockerBase<F>* function_mocker,
 | 
			
		||||
  MockSpec(internal::FunctionMocker<F>* function_mocker,
 | 
			
		||||
           const ArgumentMatcherTuple& matchers)
 | 
			
		||||
      : function_mocker_(function_mocker), matchers_(matchers) {}
 | 
			
		||||
 | 
			
		||||
@@ -1301,7 +1296,7 @@ class MockSpec {
 | 
			
		||||
  friend class internal::FunctionMocker;
 | 
			
		||||
 | 
			
		||||
  // The function mocker that owns this spec.
 | 
			
		||||
  internal::FunctionMockerBase<F>* const function_mocker_;
 | 
			
		||||
  internal::FunctionMocker<F>* const function_mocker_;
 | 
			
		||||
  // The argument matchers specified in the spec.
 | 
			
		||||
  ArgumentMatcherTuple matchers_;
 | 
			
		||||
 | 
			
		||||
@@ -1402,7 +1397,7 @@ class ActionResultHolder : public UntypedActionResultHolderBase {
 | 
			
		||||
  // result in a new-ed ActionResultHolder.
 | 
			
		||||
  template <typename F>
 | 
			
		||||
  static ActionResultHolder* PerformDefaultAction(
 | 
			
		||||
      const FunctionMockerBase<F>* func_mocker,
 | 
			
		||||
      const FunctionMocker<F>* func_mocker,
 | 
			
		||||
      typename Function<F>::ArgumentTuple&& args,
 | 
			
		||||
      const std::string& call_description) {
 | 
			
		||||
    return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
 | 
			
		||||
@@ -1442,7 +1437,7 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
 | 
			
		||||
  // of an empty ActionResultHolder*.
 | 
			
		||||
  template <typename F>
 | 
			
		||||
  static ActionResultHolder* PerformDefaultAction(
 | 
			
		||||
      const FunctionMockerBase<F>* func_mocker,
 | 
			
		||||
      const FunctionMocker<F>* func_mocker,
 | 
			
		||||
      typename Function<F>::ArgumentTuple&& args,
 | 
			
		||||
      const std::string& call_description) {
 | 
			
		||||
    func_mocker->PerformDefaultAction(std::move(args), call_description);
 | 
			
		||||
@@ -1463,22 +1458,39 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
 | 
			
		||||
  GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// The base of the function mocker class for the given function type.
 | 
			
		||||
// We put the methods in this class instead of its child to avoid code
 | 
			
		||||
// bloat.
 | 
			
		||||
template <typename F>
 | 
			
		||||
class FunctionMockerBase : public UntypedFunctionMockerBase {
 | 
			
		||||
 public:
 | 
			
		||||
  typedef typename Function<F>::Result Result;
 | 
			
		||||
  typedef typename Function<F>::ArgumentTuple ArgumentTuple;
 | 
			
		||||
  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
 | 
			
		||||
class FunctionMocker;
 | 
			
		||||
 | 
			
		||||
  FunctionMockerBase() {}
 | 
			
		||||
template <typename R, typename... Args>
 | 
			
		||||
class FunctionMocker<R(Args...)> : public UntypedFunctionMockerBase {
 | 
			
		||||
  using F = R(Args...);
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  using Result = R;
 | 
			
		||||
  using ArgumentTuple = std::tuple<Args...>;
 | 
			
		||||
  using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
 | 
			
		||||
 | 
			
		||||
  FunctionMocker() {}
 | 
			
		||||
 | 
			
		||||
  // There is no generally useful and implementable semantics of
 | 
			
		||||
  // copying a mock object, so copying a mock is usually a user error.
 | 
			
		||||
  // Thus we disallow copying function mockers.  If the user really
 | 
			
		||||
  // wants to copy a mock object, they should implement their own copy
 | 
			
		||||
  // operation, for example:
 | 
			
		||||
  //
 | 
			
		||||
  //   class MockFoo : public Foo {
 | 
			
		||||
  //    public:
 | 
			
		||||
  //     // Defines a copy constructor explicitly.
 | 
			
		||||
  //     MockFoo(const MockFoo& src) {}
 | 
			
		||||
  //     ...
 | 
			
		||||
  //   };
 | 
			
		||||
  FunctionMocker(const FunctionMocker&) = delete;
 | 
			
		||||
  FunctionMocker& operator=(const FunctionMocker&) = delete;
 | 
			
		||||
 | 
			
		||||
  // The destructor verifies that all expectations on this mock
 | 
			
		||||
  // function have been satisfied.  If not, it will report Google Test
 | 
			
		||||
  // non-fatal failures for the violations.
 | 
			
		||||
  virtual ~FunctionMockerBase()
 | 
			
		||||
  virtual ~FunctionMocker()
 | 
			
		||||
        GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
 | 
			
		||||
    MutexLock l(&g_gmock_mutex);
 | 
			
		||||
    VerifyAndClearExpectationsLocked();
 | 
			
		||||
@@ -1509,7 +1521,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
 | 
			
		||||
  // mutable state of this object, and thus can be called concurrently
 | 
			
		||||
  // without locking.
 | 
			
		||||
  // L = *
 | 
			
		||||
  Result PerformDefaultAction(typename Function<F>::ArgumentTuple&& args,
 | 
			
		||||
  Result PerformDefaultAction(ArgumentTuple&& args,
 | 
			
		||||
                              const std::string& call_description) const {
 | 
			
		||||
    const OnCallSpec<F>* const spec =
 | 
			
		||||
        this->FindOnCallSpec(args);
 | 
			
		||||
@@ -1584,25 +1596,26 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
 | 
			
		||||
    g_gmock_mutex.Lock();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns the result of invoking this mock function with the given
 | 
			
		||||
  // arguments.  This function can be safely called from multiple
 | 
			
		||||
  // threads concurrently.
 | 
			
		||||
  Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
 | 
			
		||||
    ArgumentTuple tuple(std::forward<Args>(args)...);
 | 
			
		||||
    std::unique_ptr<ResultHolder> holder(DownCast_<ResultHolder*>(
 | 
			
		||||
        this->UntypedInvokeWith(static_cast<void*>(&tuple))));
 | 
			
		||||
    return holder->Unwrap();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MockSpec<F> With(Matcher<Args>... m) {
 | 
			
		||||
    return MockSpec<F>(this, ::std::make_tuple(std::move(m)...));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  template <typename Function>
 | 
			
		||||
  friend class MockSpec;
 | 
			
		||||
 | 
			
		||||
  typedef ActionResultHolder<Result> ResultHolder;
 | 
			
		||||
 | 
			
		||||
  // Returns the result of invoking this mock function with the given
 | 
			
		||||
  // arguments.  This function can be safely called from multiple
 | 
			
		||||
  // threads concurrently.
 | 
			
		||||
  Result InvokeWith(typename Function<F>::ArgumentTuple&& 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));
 | 
			
		||||
    std::unique_ptr<ResultHolder> holder(
 | 
			
		||||
        DownCast_<ResultHolder*>(this->UntypedInvokeWith(untyped_args)));
 | 
			
		||||
    return holder->Unwrap();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Adds and returns a default action spec for this mock function.
 | 
			
		||||
  OnCallSpec<F>& AddNewOnCallSpec(
 | 
			
		||||
      const char* file, int line,
 | 
			
		||||
@@ -1779,36 +1792,98 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
 | 
			
		||||
      expectation->DescribeCallCountTo(why);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // There is no generally useful and implementable semantics of
 | 
			
		||||
  // copying a mock object, so copying a mock is usually a user error.
 | 
			
		||||
  // Thus we disallow copying function mockers.  If the user really
 | 
			
		||||
  // wants to copy a mock object, they should implement their own copy
 | 
			
		||||
  // operation, for example:
 | 
			
		||||
  //
 | 
			
		||||
  //   class MockFoo : public Foo {
 | 
			
		||||
  //    public:
 | 
			
		||||
  //     // Defines a copy constructor explicitly.
 | 
			
		||||
  //     MockFoo(const MockFoo& src) {}
 | 
			
		||||
  //     ...
 | 
			
		||||
  //   };
 | 
			
		||||
  GTEST_DISALLOW_COPY_AND_ASSIGN_(FunctionMockerBase);
 | 
			
		||||
};  // class FunctionMockerBase
 | 
			
		||||
};  // class FunctionMocker
 | 
			
		||||
 | 
			
		||||
GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4355
 | 
			
		||||
 | 
			
		||||
// Implements methods of FunctionMockerBase.
 | 
			
		||||
 | 
			
		||||
// Verifies that all expectations on this mock function have been
 | 
			
		||||
// satisfied.  Reports one or more Google Test non-fatal failures and
 | 
			
		||||
// returns false if not.
 | 
			
		||||
 | 
			
		||||
// Reports an uninteresting call (whose description is in msg) in the
 | 
			
		||||
// manner specified by 'reaction'.
 | 
			
		||||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
 | 
			
		||||
 | 
			
		||||
}  // namespace internal
 | 
			
		||||
 | 
			
		||||
// A MockFunction<F> class has one mock method whose type is F.  It is
 | 
			
		||||
// useful when you just want your test code to emit some messages and
 | 
			
		||||
// have Google Mock verify the right messages are sent (and perhaps at
 | 
			
		||||
// the right times).  For example, if you are exercising code:
 | 
			
		||||
//
 | 
			
		||||
//   Foo(1);
 | 
			
		||||
//   Foo(2);
 | 
			
		||||
//   Foo(3);
 | 
			
		||||
//
 | 
			
		||||
// and want to verify that Foo(1) and Foo(3) both invoke
 | 
			
		||||
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
 | 
			
		||||
//
 | 
			
		||||
// TEST(FooTest, InvokesBarCorrectly) {
 | 
			
		||||
//   MyMock mock;
 | 
			
		||||
//   MockFunction<void(string check_point_name)> check;
 | 
			
		||||
//   {
 | 
			
		||||
//     InSequence s;
 | 
			
		||||
//
 | 
			
		||||
//     EXPECT_CALL(mock, Bar("a"));
 | 
			
		||||
//     EXPECT_CALL(check, Call("1"));
 | 
			
		||||
//     EXPECT_CALL(check, Call("2"));
 | 
			
		||||
//     EXPECT_CALL(mock, Bar("a"));
 | 
			
		||||
//   }
 | 
			
		||||
//   Foo(1);
 | 
			
		||||
//   check.Call("1");
 | 
			
		||||
//   Foo(2);
 | 
			
		||||
//   check.Call("2");
 | 
			
		||||
//   Foo(3);
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
// The expectation spec says that the first Bar("a") must happen
 | 
			
		||||
// before check point "1", the second Bar("a") must happen after check
 | 
			
		||||
// point "2", and nothing should happen between the two check
 | 
			
		||||
// points. The explicit check points make it easy to tell which
 | 
			
		||||
// Bar("a") is called by which call to Foo().
 | 
			
		||||
//
 | 
			
		||||
// MockFunction<F> can also be used to exercise code that accepts
 | 
			
		||||
// std::function<F> callbacks. To do so, use AsStdFunction() method
 | 
			
		||||
// to create std::function proxy forwarding to original object's Call.
 | 
			
		||||
// Example:
 | 
			
		||||
//
 | 
			
		||||
// TEST(FooTest, RunsCallbackWithBarArgument) {
 | 
			
		||||
//   MockFunction<int(string)> callback;
 | 
			
		||||
//   EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
 | 
			
		||||
//   Foo(callback.AsStdFunction());
 | 
			
		||||
// }
 | 
			
		||||
template <typename F>
 | 
			
		||||
class MockFunction;
 | 
			
		||||
 | 
			
		||||
template <typename R, typename... Args>
 | 
			
		||||
class MockFunction<R(Args...)> {
 | 
			
		||||
 public:
 | 
			
		||||
  MockFunction() {}
 | 
			
		||||
  MockFunction(const MockFunction&) = delete;
 | 
			
		||||
  MockFunction& operator=(const MockFunction&) = delete;
 | 
			
		||||
 | 
			
		||||
  std::function<R(Args...)> AsStdFunction() {
 | 
			
		||||
    return [this](Args... args) -> R {
 | 
			
		||||
      return this->Call(std::forward<Args>(args)...);
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Implementation detail: the expansion of the MOCK_METHOD macro.
 | 
			
		||||
  R Call(Args... args) {
 | 
			
		||||
    mock_.SetOwnerAndName(this, "Call");
 | 
			
		||||
    return mock_.Invoke(std::forward<Args>(args)...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
 | 
			
		||||
    mock_.RegisterOwner(this);
 | 
			
		||||
    return mock_.With(std::move(m)...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&,
 | 
			
		||||
                                            R (*)(Args...)) {
 | 
			
		||||
    return this->gmock_Call(::testing::A<Args>()...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  mutable internal::FunctionMocker<R(Args...)> mock_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// The style guide prohibits "using" statements in a namespace scope
 | 
			
		||||
// inside a header file.  However, the MockSpec class template is
 | 
			
		||||
// meant to be defined in the ::testing namespace.  The following line
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user