Add support for move-only and &&-qualified actions in WillOnce.
This provides a type-safe way for an action to express that it wants to be called only once, or to capture move-only objects. It is a generalization of the type system-evading hack in ByMove, with the improvement that it works for _any_ action (including user-defined ones), and correctly expresses that the action can only be used with WillOnce. I'll make existing actions benefit in a future commit. PiperOrigin-RevId: 440496139 Change-Id: I4145d191cca5655995ef41360bb126c123cb41d3
This commit is contained in:
		
				
					committed by
					
						
						Copybara-Service
					
				
			
			
				
	
			
			
			
						parent
						
							5f467ec04d
						
					
				
				
					commit
					a1cc8c5519
				
			@@ -248,7 +248,9 @@ EXPECT_CALL(my_mock, GetNumber())
 | 
				
			|||||||
    .WillOnce(Return(3));
 | 
					    .WillOnce(Return(3));
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The `WillOnce` clause can be used any number of times on an expectation.
 | 
					The `WillOnce` clause can be used any number of times on an expectation. Unlike
 | 
				
			||||||
 | 
					`WillRepeatedly`, the action fed to each `WillOnce` call will be called at most
 | 
				
			||||||
 | 
					once, so may be a move-only type and/or have an `&&`-qualified call operator.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### WillRepeatedly {#EXPECT_CALL.WillRepeatedly}
 | 
					#### WillRepeatedly {#EXPECT_CALL.WillRepeatedly}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -262,9 +262,65 @@ GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_
 | 
					#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Simple two-arg form of std::disjunction.
 | 
					// Partial implementations of metaprogramming types from the standard library
 | 
				
			||||||
template <typename P, typename Q>
 | 
					// not available in C++11.
 | 
				
			||||||
using disjunction = typename ::std::conditional<P::value, P, Q>::type;
 | 
					
 | 
				
			||||||
 | 
					template <typename P>
 | 
				
			||||||
 | 
					struct negation
 | 
				
			||||||
 | 
					    // NOLINTNEXTLINE
 | 
				
			||||||
 | 
					    : std::integral_constant<bool, bool(!P::value)> {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Base case: with zero predicates the answer is always true.
 | 
				
			||||||
 | 
					template <typename...>
 | 
				
			||||||
 | 
					struct conjunction : std::true_type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// With a single predicate, the answer is that predicate.
 | 
				
			||||||
 | 
					template <typename P1>
 | 
				
			||||||
 | 
					struct conjunction<P1> : P1 {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// With multiple predicates the answer is the first predicate if that is false,
 | 
				
			||||||
 | 
					// and we recurse otherwise.
 | 
				
			||||||
 | 
					template <typename P1, typename... Ps>
 | 
				
			||||||
 | 
					struct conjunction<P1, Ps...>
 | 
				
			||||||
 | 
					    : std::conditional<bool(P1::value), conjunction<Ps...>, P1>::type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename...>
 | 
				
			||||||
 | 
					struct disjunction : std::false_type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename P1>
 | 
				
			||||||
 | 
					struct disjunction<P1> : P1 {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename P1, typename... Ps>
 | 
				
			||||||
 | 
					struct disjunction<P1, Ps...>
 | 
				
			||||||
 | 
					    // NOLINTNEXTLINE
 | 
				
			||||||
 | 
					    : std::conditional<!bool(P1::value), disjunction<Ps...>, P1>::type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename...>
 | 
				
			||||||
 | 
					using void_t = void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Like std::invoke_result_t from C++17, but works only for objects with call
 | 
				
			||||||
 | 
					// operators (not e.g. member function pointers, which we don't need specific
 | 
				
			||||||
 | 
					// support for in OnceAction because std::function deals with them).
 | 
				
			||||||
 | 
					template <typename F, typename... Args>
 | 
				
			||||||
 | 
					using call_result_t = decltype(std::declval<F>()(std::declval<Args>()...));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename Void, typename R, typename F, typename... Args>
 | 
				
			||||||
 | 
					struct is_callable_r_impl : std::false_type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Specialize the struct for those template arguments where call_result_t is
 | 
				
			||||||
 | 
					// well-formed. When it's not, the generic template above is chosen, resulting
 | 
				
			||||||
 | 
					// in std::false_type.
 | 
				
			||||||
 | 
					template <typename R, typename F, typename... Args>
 | 
				
			||||||
 | 
					struct is_callable_r_impl<void_t<call_result_t<F, Args...>>, R, F, Args...>
 | 
				
			||||||
 | 
					    : std::conditional<
 | 
				
			||||||
 | 
					          std::is_same<R, void>::value,  //
 | 
				
			||||||
 | 
					          std::true_type,                //
 | 
				
			||||||
 | 
					          std::is_convertible<call_result_t<F, Args...>, R>>::type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Like std::is_invocable_r from C++17, but works only for objects with call
 | 
				
			||||||
 | 
					// operators. See the note on call_result_t.
 | 
				
			||||||
 | 
					template <typename R, typename F, typename... Args>
 | 
				
			||||||
 | 
					using is_callable_r = is_callable_r_impl<void, R, F, Args...>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace internal
 | 
					}  // namespace internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -596,6 +652,213 @@ inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace internal {
 | 
					namespace internal {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename F>
 | 
				
			||||||
 | 
					class TypedExpectation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Specialized for function types below.
 | 
				
			||||||
 | 
					template <typename F>
 | 
				
			||||||
 | 
					class OnceAction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// An action that can only be used once.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This is what is accepted by WillOnce, which doesn't require the underlying
 | 
				
			||||||
 | 
					// action to be copy-constructible (only move-constructible), and promises to
 | 
				
			||||||
 | 
					// invoke it as an rvalue reference. This allows the action to work with
 | 
				
			||||||
 | 
					// move-only types like std::move_only_function in a type-safe manner.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// For example:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     // Assume we have some API that needs to accept a unique pointer to some
 | 
				
			||||||
 | 
					//     // non-copyable object Foo.
 | 
				
			||||||
 | 
					//     void AcceptUniquePointer(std::unique_ptr<Foo> foo);
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     // We can define an action that provides a Foo to that API. Because It
 | 
				
			||||||
 | 
					//     // has to give away its unique pointer, it must not be called more than
 | 
				
			||||||
 | 
					//     // once, so its call operator is &&-qualified.
 | 
				
			||||||
 | 
					//     struct ProvideFoo {
 | 
				
			||||||
 | 
					//       std::unique_ptr<Foo> foo;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//       void operator()() && {
 | 
				
			||||||
 | 
					//         AcceptUniquePointer(std::move(Foo));
 | 
				
			||||||
 | 
					//       }
 | 
				
			||||||
 | 
					//     };
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     // This action can be used with WillOnce.
 | 
				
			||||||
 | 
					//     EXPECT_CALL(mock, Call)
 | 
				
			||||||
 | 
					//         .WillOnce(ProvideFoo{std::make_unique<Foo>(...)});
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     // But a call to WillRepeatedly will fail to compile. This is correct,
 | 
				
			||||||
 | 
					//     // since the action cannot correctly be used repeatedly.
 | 
				
			||||||
 | 
					//     EXPECT_CALL(mock, Call)
 | 
				
			||||||
 | 
					//         .WillRepeatedly(ProvideFoo{std::make_unique<Foo>(...)});
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// A less-contrived example would be an action that returns an arbitrary type,
 | 
				
			||||||
 | 
					// whose &&-qualified call operator is capable of dealing with move-only types.
 | 
				
			||||||
 | 
					template <typename Result, typename... Args>
 | 
				
			||||||
 | 
					class OnceAction<Result(Args...)> final {
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  // True iff we can use the given callable type (or lvalue reference) directly
 | 
				
			||||||
 | 
					  // via ActionAdaptor.
 | 
				
			||||||
 | 
					  template <typename Callable>
 | 
				
			||||||
 | 
					  using IsDirectlyCompatible = internal::conjunction<
 | 
				
			||||||
 | 
					      // It must be possible to capture the callable in ActionAdaptor.
 | 
				
			||||||
 | 
					      std::is_constructible<typename std::decay<Callable>::type, Callable>,
 | 
				
			||||||
 | 
					      // The callable must be compatible with our signature.
 | 
				
			||||||
 | 
					      internal::is_callable_r<Result, typename std::decay<Callable>::type,
 | 
				
			||||||
 | 
					                              Args...>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // True iff we can use the given callable type via ActionAdaptor once we
 | 
				
			||||||
 | 
					  // ignore incoming arguments.
 | 
				
			||||||
 | 
					  template <typename Callable>
 | 
				
			||||||
 | 
					  using IsCompatibleAfterIgnoringArguments = internal::conjunction<
 | 
				
			||||||
 | 
					      // It must be possible to capture the callable in a lambda.
 | 
				
			||||||
 | 
					      std::is_constructible<typename std::decay<Callable>::type, Callable>,
 | 
				
			||||||
 | 
					      // The callable must be invocable with zero arguments, returning something
 | 
				
			||||||
 | 
					      // convertible to Result.
 | 
				
			||||||
 | 
					      internal::is_callable_r<Result, typename std::decay<Callable>::type>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  // Construct from a callable that is directly compatible with our mocked
 | 
				
			||||||
 | 
					  // signature: it accepts our function type's arguments and returns something
 | 
				
			||||||
 | 
					  // convertible to our result type.
 | 
				
			||||||
 | 
					  template <typename Callable,
 | 
				
			||||||
 | 
					            typename std::enable_if<
 | 
				
			||||||
 | 
					                internal::conjunction<
 | 
				
			||||||
 | 
					                    // Teach clang on macOS that we're not talking about a
 | 
				
			||||||
 | 
					                    // copy/move constructor here. Otherwise it gets confused
 | 
				
			||||||
 | 
					                    // when checking the is_constructible requirement of our
 | 
				
			||||||
 | 
					                    // traits above.
 | 
				
			||||||
 | 
					                    internal::negation<std::is_same<
 | 
				
			||||||
 | 
					                        OnceAction, typename std::decay<Callable>::type>>,
 | 
				
			||||||
 | 
					                    IsDirectlyCompatible<Callable>>  //
 | 
				
			||||||
 | 
					                ::value,
 | 
				
			||||||
 | 
					                int>::type = 0>
 | 
				
			||||||
 | 
					  OnceAction(Callable&& callable)  // NOLINT
 | 
				
			||||||
 | 
					      : action_(ActionAdaptor<typename std::decay<Callable>::type>(
 | 
				
			||||||
 | 
					            {}, std::forward<Callable>(callable))) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // As above, but for a callable that ignores the mocked function's arguments.
 | 
				
			||||||
 | 
					  template <typename Callable,
 | 
				
			||||||
 | 
					            typename std::enable_if<
 | 
				
			||||||
 | 
					                internal::conjunction<
 | 
				
			||||||
 | 
					                    // Teach clang on macOS that we're not talking about a
 | 
				
			||||||
 | 
					                    // copy/move constructor here. Otherwise it gets confused
 | 
				
			||||||
 | 
					                    // when checking the is_constructible requirement of our
 | 
				
			||||||
 | 
					                    // traits above.
 | 
				
			||||||
 | 
					                    internal::negation<std::is_same<
 | 
				
			||||||
 | 
					                        OnceAction, typename std::decay<Callable>::type>>,
 | 
				
			||||||
 | 
					                    // Exclude callables for which the overload above works.
 | 
				
			||||||
 | 
					                    // We'd rather provide the arguments if possible.
 | 
				
			||||||
 | 
					                    internal::negation<IsDirectlyCompatible<Callable>>,
 | 
				
			||||||
 | 
					                    IsCompatibleAfterIgnoringArguments<Callable>>::value,
 | 
				
			||||||
 | 
					                int>::type = 0>
 | 
				
			||||||
 | 
					  OnceAction(Callable&& callable)  // NOLINT
 | 
				
			||||||
 | 
					                                   // Call the constructor above with a callable
 | 
				
			||||||
 | 
					                                   // that ignores the input arguments.
 | 
				
			||||||
 | 
					      : OnceAction(IgnoreIncomingArguments<typename std::decay<Callable>::type>{
 | 
				
			||||||
 | 
					            std::forward<Callable>(callable)}) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // A fallback constructor for anything that is convertible to Action, for use
 | 
				
			||||||
 | 
					  // with legacy actions that uses older styles like implementing
 | 
				
			||||||
 | 
					  // ActionInterface or a conversion operator to Action. Modern code should
 | 
				
			||||||
 | 
					  // implement a call operator with appropriate restrictions.
 | 
				
			||||||
 | 
					  template <typename T,
 | 
				
			||||||
 | 
					            typename std::enable_if<
 | 
				
			||||||
 | 
					                internal::conjunction<
 | 
				
			||||||
 | 
					                    // Teach clang on macOS that we're not talking about a
 | 
				
			||||||
 | 
					                    // copy/move constructor here. Otherwise it gets confused
 | 
				
			||||||
 | 
					                    // when checking the is_constructible requirement of our
 | 
				
			||||||
 | 
					                    // traits above.
 | 
				
			||||||
 | 
					                    internal::negation<
 | 
				
			||||||
 | 
					                        std::is_same<OnceAction, typename std::decay<T>::type>>,
 | 
				
			||||||
 | 
					                    // Exclude the overloads above, which we want to take
 | 
				
			||||||
 | 
					                    // precedence.
 | 
				
			||||||
 | 
					                    internal::negation<IsDirectlyCompatible<T>>,
 | 
				
			||||||
 | 
					                    internal::negation<IsCompatibleAfterIgnoringArguments<T>>,
 | 
				
			||||||
 | 
					                    // It must be possible to turn the object into an action of
 | 
				
			||||||
 | 
					                    // the appropriate type.
 | 
				
			||||||
 | 
					                    std::is_convertible<T, Action<Result(Args...)>>  //
 | 
				
			||||||
 | 
					                    >::value,
 | 
				
			||||||
 | 
					                int>::type = 0>
 | 
				
			||||||
 | 
					  OnceAction(T&& action) : action_(std::forward<T>(action)) {}  // NOLINT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // We are naturally copyable because we store only an Action, but semantically
 | 
				
			||||||
 | 
					  // we should not be copyable.
 | 
				
			||||||
 | 
					  OnceAction(const OnceAction&) = delete;
 | 
				
			||||||
 | 
					  OnceAction& operator=(const OnceAction&) = delete;
 | 
				
			||||||
 | 
					  OnceAction(OnceAction&&) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  // Allow TypedExpectation::WillOnce to use our type-unsafe API below.
 | 
				
			||||||
 | 
					  friend class TypedExpectation<Result(Args...)>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // An adaptor that wraps a callable that is compatible with our signature and
 | 
				
			||||||
 | 
					  // being invoked as an rvalue reference so that it can be used as an
 | 
				
			||||||
 | 
					  // Action. This throws away type safety, but that's fine because this is only
 | 
				
			||||||
 | 
					  // used by WillOnce, which we know calls at most once.
 | 
				
			||||||
 | 
					  template <typename Callable>
 | 
				
			||||||
 | 
					  class ActionAdaptor final {
 | 
				
			||||||
 | 
					   public:
 | 
				
			||||||
 | 
					    // A tag indicating that the (otherwise universal) constructor is accepting
 | 
				
			||||||
 | 
					    // the callable itself, instead of e.g. stealing calls for the move
 | 
				
			||||||
 | 
					    // constructor.
 | 
				
			||||||
 | 
					    struct CallableTag final {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template <typename F>
 | 
				
			||||||
 | 
					    explicit ActionAdaptor(CallableTag, F&& callable)
 | 
				
			||||||
 | 
					        : callable_(std::make_shared<Callable>(std::forward<F>(callable))) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Rather than explicitly returning Result, we return whatever the wrapped
 | 
				
			||||||
 | 
					    // callable returns. This allows for compatibility with existing uses like
 | 
				
			||||||
 | 
					    // the following, when the mocked function returns void:
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    //     EXPECT_CALL(mock_fn_, Call)
 | 
				
			||||||
 | 
					    //         .WillOnce([&] {
 | 
				
			||||||
 | 
					    //            [...]
 | 
				
			||||||
 | 
					    //            return 0;
 | 
				
			||||||
 | 
					    //         });
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // This works with Action since such a callable can be turned into
 | 
				
			||||||
 | 
					    // std::function<void()>. If we use an explicit return type of Result here
 | 
				
			||||||
 | 
					    // then it *doesn't* work with OnceAction, because we'll get a "void
 | 
				
			||||||
 | 
					    // function should not return a value" error.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // We need not worry about incompatible result types because the SFINAE on
 | 
				
			||||||
 | 
					    // OnceAction already checks this for us. std::is_invocable_r_v itself makes
 | 
				
			||||||
 | 
					    // the same allowance for void result types.
 | 
				
			||||||
 | 
					    template <typename... ArgRefs>
 | 
				
			||||||
 | 
					    internal::call_result_t<Callable, ArgRefs...> operator()(
 | 
				
			||||||
 | 
					        ArgRefs&&... args) const {
 | 
				
			||||||
 | 
					      return std::move(*callable_)(std::forward<ArgRefs>(args)...);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   private:
 | 
				
			||||||
 | 
					    // We must put the callable on the heap so that we are copyable, which
 | 
				
			||||||
 | 
					    // Action needs.
 | 
				
			||||||
 | 
					    std::shared_ptr<Callable> callable_;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // An adaptor that makes a callable that accepts zero arguments callable with
 | 
				
			||||||
 | 
					  // our mocked arguments.
 | 
				
			||||||
 | 
					  template <typename Callable>
 | 
				
			||||||
 | 
					  struct IgnoreIncomingArguments {
 | 
				
			||||||
 | 
					    internal::call_result_t<Callable> operator()(Args&&...) {
 | 
				
			||||||
 | 
					      return std::move(callable)();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Callable callable;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Return an Action that calls the underlying callable in a type-safe manner.
 | 
				
			||||||
 | 
					  // The action's Perform method must be called at most once.
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // This is the transition from a type-safe API to a type-unsafe one, since
 | 
				
			||||||
 | 
					  // "must be called at most once" is no longer reflecting in the type system.
 | 
				
			||||||
 | 
					  Action<Result(Args...)> ReleaseAction() && { return std::move(action_); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Action<Result(Args...)> action_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper struct to specialize ReturnAction to execute a move instead of a copy
 | 
					// Helper struct to specialize ReturnAction to execute a move instead of a copy
 | 
				
			||||||
// on return. Useful for move-only types, but could be used on any type.
 | 
					// on return. Useful for move-only types, but could be used on any type.
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -992,14 +992,16 @@ class TypedExpectation : public ExpectationBase {
 | 
				
			|||||||
    return After(s1, s2, s3, s4).After(s5);
 | 
					    return After(s1, s2, s3, s4).After(s5);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Implements the .WillOnce() clause.
 | 
					  // Implements the .WillOnce() clause for copyable actions.
 | 
				
			||||||
  TypedExpectation& WillOnce(const Action<F>& action) {
 | 
					  TypedExpectation& WillOnce(OnceAction<F> once_action) {
 | 
				
			||||||
    ExpectSpecProperty(last_clause_ <= kWillOnce,
 | 
					    ExpectSpecProperty(last_clause_ <= kWillOnce,
 | 
				
			||||||
                       ".WillOnce() cannot appear after "
 | 
					                       ".WillOnce() cannot appear after "
 | 
				
			||||||
                       ".WillRepeatedly() or .RetiresOnSaturation().");
 | 
					                       ".WillRepeatedly() or .RetiresOnSaturation().");
 | 
				
			||||||
    last_clause_ = kWillOnce;
 | 
					    last_clause_ = kWillOnce;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    untyped_actions_.push_back(new Action<F>(action));
 | 
					    untyped_actions_.push_back(
 | 
				
			||||||
 | 
					        new Action<F>(std::move(once_action).ReleaseAction()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!cardinality_specified()) {
 | 
					    if (!cardinality_specified()) {
 | 
				
			||||||
      set_cardinality(Exactly(static_cast<int>(untyped_actions_.size())));
 | 
					      set_cardinality(Exactly(static_cast<int>(untyped_actions_.size())));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,37 +55,170 @@
 | 
				
			|||||||
#include "gtest/gtest-spi.h"
 | 
					#include "gtest/gtest-spi.h"
 | 
				
			||||||
#include "gtest/gtest.h"
 | 
					#include "gtest/gtest.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace testing {
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using ::testing::_;
 | 
					 | 
				
			||||||
using ::testing::Action;
 | 
					 | 
				
			||||||
using ::testing::ActionInterface;
 | 
					 | 
				
			||||||
using ::testing::Assign;
 | 
					 | 
				
			||||||
using ::testing::ByMove;
 | 
					 | 
				
			||||||
using ::testing::ByRef;
 | 
					 | 
				
			||||||
using ::testing::DefaultValue;
 | 
					 | 
				
			||||||
using ::testing::DoAll;
 | 
					 | 
				
			||||||
using ::testing::DoDefault;
 | 
					 | 
				
			||||||
using ::testing::IgnoreResult;
 | 
					 | 
				
			||||||
using ::testing::Invoke;
 | 
					 | 
				
			||||||
using ::testing::InvokeWithoutArgs;
 | 
					 | 
				
			||||||
using ::testing::MakePolymorphicAction;
 | 
					 | 
				
			||||||
using ::testing::PolymorphicAction;
 | 
					 | 
				
			||||||
using ::testing::Return;
 | 
					 | 
				
			||||||
using ::testing::ReturnNew;
 | 
					 | 
				
			||||||
using ::testing::ReturnNull;
 | 
					 | 
				
			||||||
using ::testing::ReturnRef;
 | 
					 | 
				
			||||||
using ::testing::ReturnRefOfCopy;
 | 
					 | 
				
			||||||
using ::testing::ReturnRoundRobin;
 | 
					 | 
				
			||||||
using ::testing::SetArgPointee;
 | 
					 | 
				
			||||||
using ::testing::SetArgumentPointee;
 | 
					 | 
				
			||||||
using ::testing::Unused;
 | 
					 | 
				
			||||||
using ::testing::WithArgs;
 | 
					 | 
				
			||||||
using ::testing::internal::BuiltInDefaultValue;
 | 
					using ::testing::internal::BuiltInDefaultValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !GTEST_OS_WINDOWS_MOBILE
 | 
					TEST(TypeTraits, Negation) {
 | 
				
			||||||
using ::testing::SetErrnoAndReturn;
 | 
					  // Direct use with std types.
 | 
				
			||||||
#endif
 | 
					  static_assert(std::is_base_of<std::false_type,
 | 
				
			||||||
 | 
					                                internal::negation<std::true_type>>::value,
 | 
				
			||||||
 | 
					                "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static_assert(std::is_base_of<std::true_type,
 | 
				
			||||||
 | 
					                                internal::negation<std::false_type>>::value,
 | 
				
			||||||
 | 
					                "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // With other types that fit the requirement of a value member that is
 | 
				
			||||||
 | 
					  // convertible to bool.
 | 
				
			||||||
 | 
					  static_assert(std::is_base_of<
 | 
				
			||||||
 | 
					                    std::true_type,
 | 
				
			||||||
 | 
					                    internal::negation<std::integral_constant<int, 0>>>::value,
 | 
				
			||||||
 | 
					                "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static_assert(std::is_base_of<
 | 
				
			||||||
 | 
					                    std::false_type,
 | 
				
			||||||
 | 
					                    internal::negation<std::integral_constant<int, 1>>>::value,
 | 
				
			||||||
 | 
					                "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static_assert(std::is_base_of<
 | 
				
			||||||
 | 
					                    std::false_type,
 | 
				
			||||||
 | 
					                    internal::negation<std::integral_constant<int, -1>>>::value,
 | 
				
			||||||
 | 
					                "");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Weird false/true types that aren't actually bool constants (but should still
 | 
				
			||||||
 | 
					// be legal according to [meta.logical] because `bool(T::value)` is valid), are
 | 
				
			||||||
 | 
					// distinct from std::false_type and std::true_type, and are distinct from other
 | 
				
			||||||
 | 
					// instantiations of the same template.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// These let us check finicky details mandated by the standard like
 | 
				
			||||||
 | 
					// "std::conjunction should evaluate to a type that inherits from the first
 | 
				
			||||||
 | 
					// false-y input".
 | 
				
			||||||
 | 
					template <int>
 | 
				
			||||||
 | 
					struct MyFalse : std::integral_constant<int, 0> {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <int>
 | 
				
			||||||
 | 
					struct MyTrue : std::integral_constant<int, -1> {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(TypeTraits, Conjunction) {
 | 
				
			||||||
 | 
					  // Base case: always true.
 | 
				
			||||||
 | 
					  static_assert(std::is_base_of<std::true_type, internal::conjunction<>>::value,
 | 
				
			||||||
 | 
					                "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // One predicate: inherits from that predicate, regardless of value.
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyFalse<0>, internal::conjunction<MyFalse<0>>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyTrue<0>, internal::conjunction<MyTrue<0>>>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Multiple predicates, with at least one false: inherits from that one.
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
 | 
				
			||||||
 | 
					                                                        MyTrue<2>>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
 | 
				
			||||||
 | 
					                                                        MyFalse<2>>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Short circuiting: in the case above, additional predicates need not even
 | 
				
			||||||
 | 
					  // define a value member.
 | 
				
			||||||
 | 
					  struct Empty {};
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
 | 
				
			||||||
 | 
					                                                        Empty>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // All predicates true: inherits from the last.
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyTrue<2>, internal::conjunction<MyTrue<0>, MyTrue<1>,
 | 
				
			||||||
 | 
					                                                       MyTrue<2>>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(TypeTraits, Disjunction) {
 | 
				
			||||||
 | 
					  // Base case: always false.
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<std::false_type, internal::disjunction<>>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // One predicate: inherits from that predicate, regardless of value.
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyFalse<0>, internal::disjunction<MyFalse<0>>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyTrue<0>, internal::disjunction<MyTrue<0>>>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Multiple predicates, with at least one true: inherits from that one.
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
 | 
				
			||||||
 | 
					                                                       MyFalse<2>>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
 | 
				
			||||||
 | 
					                                                       MyTrue<2>>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Short circuiting: in the case above, additional predicates need not even
 | 
				
			||||||
 | 
					  // define a value member.
 | 
				
			||||||
 | 
					  struct Empty {};
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
 | 
				
			||||||
 | 
					                                                       Empty>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // All predicates false: inherits from the last.
 | 
				
			||||||
 | 
					  static_assert(
 | 
				
			||||||
 | 
					      std::is_base_of<MyFalse<2>, internal::disjunction<MyFalse<0>, MyFalse<1>,
 | 
				
			||||||
 | 
					                                                        MyFalse<2>>>::value,
 | 
				
			||||||
 | 
					      "");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(TypeTraits, IsInvocableRV) {
 | 
				
			||||||
 | 
					  struct C {
 | 
				
			||||||
 | 
					    int operator()() const { return 0; }
 | 
				
			||||||
 | 
					    void operator()(int) & {}
 | 
				
			||||||
 | 
					    std::string operator()(int) && { return ""; };
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // The first overload is callable for const and non-const rvalues and lvalues.
 | 
				
			||||||
 | 
					  // It can be used to obtain an int, void, or anything int is convertible too.
 | 
				
			||||||
 | 
					  static_assert(internal::is_callable_r<int, C>::value, "");
 | 
				
			||||||
 | 
					  static_assert(internal::is_callable_r<int, C&>::value, "");
 | 
				
			||||||
 | 
					  static_assert(internal::is_callable_r<int, const C>::value, "");
 | 
				
			||||||
 | 
					  static_assert(internal::is_callable_r<int, const C&>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static_assert(internal::is_callable_r<void, C>::value, "");
 | 
				
			||||||
 | 
					  static_assert(internal::is_callable_r<char, C>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // It's possible to provide an int. If it's given to an lvalue, the result is
 | 
				
			||||||
 | 
					  // void. Otherwise it is std::string (which is also treated as allowed for a
 | 
				
			||||||
 | 
					  // void result type).
 | 
				
			||||||
 | 
					  static_assert(internal::is_callable_r<void, C&, int>::value, "");
 | 
				
			||||||
 | 
					  static_assert(!internal::is_callable_r<int, C&, int>::value, "");
 | 
				
			||||||
 | 
					  static_assert(!internal::is_callable_r<std::string, C&, int>::value, "");
 | 
				
			||||||
 | 
					  static_assert(!internal::is_callable_r<void, const C&, int>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static_assert(internal::is_callable_r<std::string, C, int>::value, "");
 | 
				
			||||||
 | 
					  static_assert(internal::is_callable_r<void, C, int>::value, "");
 | 
				
			||||||
 | 
					  static_assert(!internal::is_callable_r<int, C, int>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // It's not possible to provide other arguments.
 | 
				
			||||||
 | 
					  static_assert(!internal::is_callable_r<void, C, std::string>::value, "");
 | 
				
			||||||
 | 
					  static_assert(!internal::is_callable_r<void, C, int, int>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Nothing should choke when we try to call other arguments besides directly
 | 
				
			||||||
 | 
					  // callable objects, but they should not show up as callable.
 | 
				
			||||||
 | 
					  static_assert(!internal::is_callable_r<void, int>::value, "");
 | 
				
			||||||
 | 
					  static_assert(!internal::is_callable_r<void, void (C::*)()>::value, "");
 | 
				
			||||||
 | 
					  static_assert(!internal::is_callable_r<void, void (C::*)(), C*>::value, "");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that BuiltInDefaultValue<T*>::Get() returns NULL.
 | 
					// Tests that BuiltInDefaultValue<T*>::Get() returns NULL.
 | 
				
			||||||
TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) {
 | 
					TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) {
 | 
				
			||||||
@@ -1428,6 +1561,154 @@ TEST(MockMethodTest, CanTakeMoveOnlyValue) {
 | 
				
			|||||||
  EXPECT_EQ(42, *saved);
 | 
					  EXPECT_EQ(42, *saved);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// It should be possible to use callables with an &&-qualified call operator
 | 
				
			||||||
 | 
					// with WillOnce, since they will be called only once. This allows actions to
 | 
				
			||||||
 | 
					// contain and manipulate move-only types.
 | 
				
			||||||
 | 
					TEST(MockMethodTest, ActionHasRvalueRefQualifiedCallOperator) {
 | 
				
			||||||
 | 
					  struct Return17 {
 | 
				
			||||||
 | 
					    int operator()() && { return 17; }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Action is directly compatible with mocked function type.
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    MockFunction<int()> mock;
 | 
				
			||||||
 | 
					    EXPECT_CALL(mock, Call).WillOnce(Return17());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EXPECT_EQ(17, mock.AsStdFunction()());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Action doesn't want mocked function arguments.
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    MockFunction<int(int)> mock;
 | 
				
			||||||
 | 
					    EXPECT_CALL(mock, Call).WillOnce(Return17());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EXPECT_EQ(17, mock.AsStdFunction()(0));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Edge case: if an action has both a const-qualified and an &&-qualified call
 | 
				
			||||||
 | 
					// operator, there should be no "ambiguous call" errors. The &&-qualified
 | 
				
			||||||
 | 
					// operator should be used by WillOnce (since it doesn't need to retain the
 | 
				
			||||||
 | 
					// action beyond one call), and the const-qualified one by WillRepeatedly.
 | 
				
			||||||
 | 
					TEST(MockMethodTest, ActionHasMultipleCallOperators) {
 | 
				
			||||||
 | 
					  struct ReturnInt {
 | 
				
			||||||
 | 
					    int operator()() && { return 17; }
 | 
				
			||||||
 | 
					    int operator()() const& { return 19; }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Directly compatible with mocked function type.
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    MockFunction<int()> mock;
 | 
				
			||||||
 | 
					    EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EXPECT_EQ(17, mock.AsStdFunction()());
 | 
				
			||||||
 | 
					    EXPECT_EQ(19, mock.AsStdFunction()());
 | 
				
			||||||
 | 
					    EXPECT_EQ(19, mock.AsStdFunction()());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Ignores function arguments.
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    MockFunction<int(int)> mock;
 | 
				
			||||||
 | 
					    EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EXPECT_EQ(17, mock.AsStdFunction()(0));
 | 
				
			||||||
 | 
					    EXPECT_EQ(19, mock.AsStdFunction()(0));
 | 
				
			||||||
 | 
					    EXPECT_EQ(19, mock.AsStdFunction()(0));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WillOnce should have no problem coping with a move-only action, whether it is
 | 
				
			||||||
 | 
					// &&-qualified or not.
 | 
				
			||||||
 | 
					TEST(MockMethodTest, MoveOnlyAction) {
 | 
				
			||||||
 | 
					  // &&-qualified
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    struct Return17 {
 | 
				
			||||||
 | 
					      Return17() = default;
 | 
				
			||||||
 | 
					      Return17(Return17&&) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Return17(const Return17&) = delete;
 | 
				
			||||||
 | 
					      Return17 operator=(const Return17&) = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      int operator()() && { return 17; }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MockFunction<int()> mock;
 | 
				
			||||||
 | 
					    EXPECT_CALL(mock, Call).WillOnce(Return17());
 | 
				
			||||||
 | 
					    EXPECT_EQ(17, mock.AsStdFunction()());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Not &&-qualified
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    struct Return17 {
 | 
				
			||||||
 | 
					      Return17() = default;
 | 
				
			||||||
 | 
					      Return17(Return17&&) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Return17(const Return17&) = delete;
 | 
				
			||||||
 | 
					      Return17 operator=(const Return17&) = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      int operator()() const { return 17; }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MockFunction<int()> mock;
 | 
				
			||||||
 | 
					    EXPECT_CALL(mock, Call).WillOnce(Return17());
 | 
				
			||||||
 | 
					    EXPECT_EQ(17, mock.AsStdFunction()());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// It should be possible to use an action that returns a value with a mock
 | 
				
			||||||
 | 
					// function that doesn't, both through WillOnce and WillRepeatedly.
 | 
				
			||||||
 | 
					TEST(MockMethodTest, ActionReturnsIgnoredValue) {
 | 
				
			||||||
 | 
					  struct ReturnInt {
 | 
				
			||||||
 | 
					    int operator()() const { return 0; }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MockFunction<void()> mock;
 | 
				
			||||||
 | 
					  EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mock.AsStdFunction()();
 | 
				
			||||||
 | 
					  mock.AsStdFunction()();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Despite the fanciness around move-only actions and so on, it should still be
 | 
				
			||||||
 | 
					// possible to hand an lvalue reference to a copyable action to WillOnce.
 | 
				
			||||||
 | 
					TEST(MockMethodTest, WillOnceCanAcceptLvalueReference) {
 | 
				
			||||||
 | 
					  MockFunction<int()> mock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const auto action = [] { return 17; };
 | 
				
			||||||
 | 
					  EXPECT_CALL(mock, Call).WillOnce(action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_EQ(17, mock.AsStdFunction()());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A callable that doesn't use SFINAE to restrict its call operator's overload
 | 
				
			||||||
 | 
					// set, but is still picky about which arguments it will accept.
 | 
				
			||||||
 | 
					struct StaticAssertSingleArgument {
 | 
				
			||||||
 | 
					  template <typename... Args>
 | 
				
			||||||
 | 
					  static constexpr bool CheckArgs() {
 | 
				
			||||||
 | 
					    static_assert(sizeof...(Args) == 1, "");
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <typename... Args, bool = CheckArgs<Args...>()>
 | 
				
			||||||
 | 
					  int operator()(Args...) const {
 | 
				
			||||||
 | 
					    return 17;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WillOnce and WillRepeatedly should both work fine with naïve implementations
 | 
				
			||||||
 | 
					// of actions that don't use SFINAE to limit the overload set for their call
 | 
				
			||||||
 | 
					// operator. If they are compatible with the actual mocked signature, we
 | 
				
			||||||
 | 
					// shouldn't probe them with no arguments and trip a static_assert.
 | 
				
			||||||
 | 
					TEST(MockMethodTest, ActionSwallowsAllArguments) {
 | 
				
			||||||
 | 
					  MockFunction<int(int)> mock;
 | 
				
			||||||
 | 
					  EXPECT_CALL(mock, Call)
 | 
				
			||||||
 | 
					      .WillOnce(StaticAssertSingleArgument{})
 | 
				
			||||||
 | 
					      .WillRepeatedly(StaticAssertSingleArgument{});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_EQ(17, mock.AsStdFunction()(0));
 | 
				
			||||||
 | 
					  EXPECT_EQ(17, mock.AsStdFunction()(0));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests for std::function based action.
 | 
					// Tests for std::function based action.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int Add(int val, int& ref, int* ptr) {  // NOLINT
 | 
					int Add(int val, int& ref, int* ptr) {  // NOLINT
 | 
				
			||||||
@@ -1552,7 +1833,8 @@ TEST(ActionMacro, LargeArity) {
 | 
				
			|||||||
                                   14, 15, 16, 17, 18, 19)));
 | 
					                                   14, 15, 16, 17, 18, 19)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // Unnamed namespace
 | 
					}  // namespace
 | 
				
			||||||
 | 
					}  // namespace testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _MSC_VER
 | 
					#ifdef _MSC_VER
 | 
				
			||||||
#if _MSC_VER == 1900
 | 
					#if _MSC_VER == 1900
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user