// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_TEST_BIND_TEST_UTIL_H_ #define BASE_TEST_BIND_TEST_UTIL_H_ #include #include #include "base/bind.h" #include "base/strings/string_piece.h" namespace base { class Location; namespace internal { template struct HasConstCallOperatorImpl : std::false_type {}; template struct HasConstCallOperatorImpl : std::true_type {}; template constexpr bool HasConstCallOperator = HasConstCallOperatorImpl>::value; template struct BindLambdaHelper; template struct BindLambdaHelper { static R Run(const std::decay_t& f, Args... args) { return f(std::forward(args)...); } static R RunOnce(std::decay_t&& f, Args... args) { return f(std::forward(args)...); } }; } // namespace internal // A variant of BindRepeating() that can bind capturing lambdas for testing. // This doesn't support extra arguments binding as the lambda itself can do. template >* = nullptr> decltype(auto) BindLambdaForTesting(Lambda&& lambda) { using Signature = internal::ExtractCallableRunType>; return BindRepeating(&internal::BindLambdaHelper::Run, std::forward(lambda)); } // A variant of BindRepeating() that can bind mutable capturing lambdas for // testing. This doesn't support extra arguments binding as the lambda itself // can do. Since a mutable lambda potentially can invalidate its state after // being run once, this method returns a OnceCallback instead of a // RepeatingCallback. template >* = nullptr> decltype(auto) BindLambdaForTesting(Lambda&& lambda) { static_assert( std::is_rvalue_reference() && !std::is_const>(), "BindLambdaForTesting requires non-const rvalue for mutable lambda " "binding. I.e.: base::BindLambdaForTesting(std::move(lambda))."); using Signature = internal::ExtractCallableRunType>; return BindOnce(&internal::BindLambdaHelper::RunOnce, std::move(lambda)); } // Returns a closure that fails on destruction if it hasn't been run. OnceClosure MakeExpectedRunClosure(const Location& location, StringPiece message = StringPiece()); RepeatingClosure MakeExpectedRunAtLeastOnceClosure( const Location& location, StringPiece message = StringPiece()); // Returns a closure that fails the test if run. RepeatingClosure MakeExpectedNotRunClosure(const Location& location, StringPiece message = StringPiece()); } // namespace base #endif // BASE_TEST_BIND_TEST_UTIL_H_