// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_ #define BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_ #include <ostream> #include <tuple> #include <utility> #include "base/check.h" #include "base/functional/callback.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" #include "testing/gmock/include/gmock/gmock.h" namespace base { namespace gmock_callback_support_internal { // Small helper to get the `I`th argument. template <size_t I, typename... Args> decltype(auto) get(Args&&... args) { … } // Wraps `tuple` inside RefCountedData<std::unique_ptr<Tuple>> to allow creating // shallow copies in lambda return of RunOnceCallback<>. // Since RefCountedData<Tuple> stores Tuple directly, the indirection via // std::unique_ptr<Tuple> is necessary to be able to CHECK() on second // invocation instead of running the callback with a default-constructed tuple. template <typename Tuple> auto WrapTupleAsRefCountedData(Tuple&& tuple) { … } // Invokes `cb` with the arguments stored in `tuple`. Both `cb` and `tuple` are // perfectly forwarded, allowing callers to specify whether they should be // passed by move or copy. template <typename Callback, typename Tuple> decltype(auto) RunImpl(Callback&& cb, Tuple&& tuple) { … } } // namespace gmock_callback_support_internal namespace test { // Matchers for base::{Once,Repeating}Callback and // base::{Once,Repeating}Closure. MATCHER(IsNullCallback, "a null callback") { … } MATCHER(IsNotNullCallback, "a non-null callback") { … } // The Run[Once]Closure() action invokes the Run() method on the closure // provided when the action is constructed. Function arguments passed when the // action is run will be ignored. ACTION_P(RunClosure, closure) { … } // This action can be invoked at most once. Any further invocation will trigger // a CHECK failure. inline auto RunOnceClosure(OnceClosure cb) { … } // The Run[Once]Closure<N>() action invokes the Run() method on the N-th // (0-based) argument of the mock function. template <size_t I> auto RunClosure() { … } template <size_t I> auto RunOnceClosure() { … } // The Run[Once]Callback<N>(p1, p2, ..., p_k) action invokes the Run() method on // the N-th (0-based) argument of the mock function, with arguments p1, p2, ..., // p_k. // // Notes: // // 1. The arguments are passed by value by default. If you need to // pass an argument by reference, wrap it inside ByRef(). For example, // // RunCallback<1>(5, string("Hello"), ByRef(foo)) // // passes 5 and string("Hello") by value, and passes foo by reference. // // 2. If the callback takes an argument by reference but ByRef() is // not used, it will receive the reference to a copy of the value, // instead of the original value. For example, when the 0-th // argument of the callback takes a const string&, the action // // RunCallback<0>(string("Hello")) // // makes a copy of the temporary string("Hello") object and passes a // reference of the copy, instead of the original temporary object, // to the callback. This makes it easy for a user to define an // RunCallback action from temporary values and have it performed later. // // 3. There are two separate APIs for interacting with OnceCallback<> -- // RunOnceCallback<> and RunOnceCallbackRepeatedly<>. In the former, arguments // are copies during each run; in the latter, they are passed by move. // Note that RunOnceCallback<> cannot be used with WillRepeatedly() since its // arguments are moved out upon first invocation -- the code doing so will // crash with a CHECK(). // Using move-only arguments with `RunCallback()` is not supported. template <size_t I, typename... RunArgs> auto RunOnceCallback(RunArgs&&... run_args) { … } template <size_t I, typename... RunArgs> auto RunOnceCallbackRepeatedly(RunArgs&&... run_args) { … } template <size_t I, typename... RunArgs> auto RunCallback(RunArgs&&... run_args) { … } } // namespace test } // namespace base #endif // BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_