Commit ed972a52 authored by Anand K. Mistry's avatar Anand K. Mistry Committed by Commit Bot

Fix base::test::RunOnceCallback to support OnceCallback by move.

Also, remove the various ACTION_TEMPLATEs and replace them with aliases
to RunOnceCallback.

Bug: 1018338
Change-Id: Ib6c4b04d3d75b5b4efcadeb8a01bd6e3a142d622
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1918785
Commit-Queue: Anand Mistry <amistry@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#716051}
parent 90659d61
...@@ -5,8 +5,11 @@ ...@@ -5,8 +5,11 @@
#ifndef BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_ #ifndef BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_
#define BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_ #define BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_
#include <functional>
#include <tuple> #include <tuple>
#include <utility>
#include "base/callback.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
namespace base { namespace base {
...@@ -36,7 +39,17 @@ ACTION_P(RunClosure, closure) { ...@@ -36,7 +39,17 @@ ACTION_P(RunClosure, closure) {
closure.Run(); closure.Run();
} }
// Various overloads for RunCallback<N>(). ACTION_TEMPLATE(RunOnceClosure,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
std::move(::testing::get<k>(args)).Run();
}
ACTION_P(RunOnceClosure, closure) {
std::move(closure).Run();
}
// Implementation of the Run(Once)Callback gmock action.
// //
// The RunCallback<N>(p1, p2, ..., p_k) action invokes Run() method on the N-th // The RunCallback<N>(p1, p2, ..., p_k) action invokes Run() method on the N-th
// (0-based) argument of the mock function, with arguments p1, p2, ..., p_k. // (0-based) argument of the mock function, with arguments p1, p2, ..., p_k.
...@@ -62,114 +75,36 @@ ACTION_P(RunClosure, closure) { ...@@ -62,114 +75,36 @@ ACTION_P(RunClosure, closure) {
// to the callback. This makes it easy for a user to define an // to the callback. This makes it easy for a user to define an
// RunCallback action from temporary values and have it performed later. // RunCallback action from temporary values and have it performed later.
ACTION_TEMPLATE(RunCallback, // TODO(crbug.com/752720): Simplify using std::apply once C++17 is available.
HAS_1_TEMPLATE_PARAMS(int, k), template <typename CallbackFunc, typename ArgTuple, size_t... I>
AND_0_VALUE_PARAMS()) { decltype(auto) RunCallbackUnwrapped(CallbackFunc&& f,
return ::testing::get<k>(args).Run(); ArgTuple&& t,
} std::index_sequence<I...>) {
return std::move(f).Run(std::get<I>(t)...);
ACTION_TEMPLATE(RunCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(p0)) {
return ::testing::get<k>(args).Run(p0);
}
ACTION_TEMPLATE(RunCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_2_VALUE_PARAMS(p0, p1)) {
return ::testing::get<k>(args).Run(p0, p1);
}
ACTION_TEMPLATE(RunCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_3_VALUE_PARAMS(p0, p1, p2)) {
return ::testing::get<k>(args).Run(p0, p1, p2);
}
ACTION_TEMPLATE(RunCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_4_VALUE_PARAMS(p0, p1, p2, p3)) {
return ::testing::get<k>(args).Run(p0, p1, p2, p3);
} }
ACTION_TEMPLATE(RunCallback, template <size_t I, typename... Vals>
HAS_1_TEMPLATE_PARAMS(int, k), struct RunOnceCallbackAction {
AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { std::tuple<Vals...> vals;
return ::testing::get<k>(args).Run(p0, p1, p2, p3, p4);
}
ACTION_TEMPLATE(RunCallback, template <typename... Args>
HAS_1_TEMPLATE_PARAMS(int, k), decltype(auto) operator()(Args&&... args) {
AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { constexpr size_t size = std::tuple_size<decltype(vals)>::value;
return ::testing::get<k>(args).Run(p0, p1, p2, p3, p4, p5); return RunCallbackUnwrapped(
} std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...)),
std::move(vals), std::make_index_sequence<size>{});
}
};
ACTION_TEMPLATE(RunCallback, template <size_t I, typename... Vals>
HAS_1_TEMPLATE_PARAMS(int, k), RunOnceCallbackAction<I, std::decay_t<Vals>...> RunOnceCallback(
AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { Vals&&... vals) {
return ::testing::get<k>(args).Run(p0, p1, p2, p3, p4, p5, p6); return {std::forward_as_tuple(std::forward<Vals>(vals)...)};
} }
// Various overloads for RunOnceClosure and RunOnceCallback<N>(). These are template <size_t I, typename... Vals>
// mostly the same as RunClosure and RunCallback<N>() above except that they RunOnceCallbackAction<I, std::decay_t<Vals>...> RunCallback(Vals&&... vals) {
// support the move-only base::OnceCallback types. return {std::forward_as_tuple(std::forward<Vals>(vals)...)};
ACTION_TEMPLATE(RunOnceClosure,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
std::move(::testing::get<k>(args)).Run();
}
ACTION_P(RunOnceClosure, closure) {
std::move(closure).Run();
}
ACTION_TEMPLATE(RunOnceCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
return std::move(::testing::get<k>(args)).Run();
}
ACTION_TEMPLATE(RunOnceCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(p0)) {
return std::move(::testing::get<k>(args)).Run(p0);
}
ACTION_TEMPLATE(RunOnceCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_2_VALUE_PARAMS(p0, p1)) {
return std::move(::testing::get<k>(args)).Run(p0, p1);
}
ACTION_TEMPLATE(RunOnceCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_3_VALUE_PARAMS(p0, p1, p2)) {
return std::move(::testing::get<k>(args)).Run(p0, p1, p2);
}
ACTION_TEMPLATE(RunOnceCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_4_VALUE_PARAMS(p0, p1, p2, p3)) {
return std::move(::testing::get<k>(args)).Run(p0, p1, p2, p3);
}
ACTION_TEMPLATE(RunOnceCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) {
return std::move(::testing::get<k>(args)).Run(p0, p1, p2, p3, p4);
}
ACTION_TEMPLATE(RunOnceCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) {
return std::move(::testing::get<k>(args)).Run(p0, p1, p2, p3, p4, p5);
}
ACTION_TEMPLATE(RunOnceCallback,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) {
return std::move(::testing::get<k>(args)).Run(p0, p1, p2, p3, p4, p5, p6);
} }
} // namespace test } // namespace test
......
...@@ -16,6 +16,7 @@ namespace base { ...@@ -16,6 +16,7 @@ namespace base {
namespace test { namespace test {
using TestCallback = base::RepeatingCallback<void(const bool& src, bool* dst)>; using TestCallback = base::RepeatingCallback<void(const bool& src, bool* dst)>;
using TestOnceCallback = base::OnceCallback<void(const bool& src, bool* dst)>;
void SetBool(const bool& src, bool* dst) { void SetBool(const bool& src, bool* dst) {
*dst = src; *dst = src;
...@@ -81,5 +82,24 @@ TEST(GmockCallbackSupportTest, RunCallbackPassByValue) { ...@@ -81,5 +82,24 @@ TEST(GmockCallbackSupportTest, RunCallbackPassByValue) {
EXPECT_TRUE(dst); EXPECT_TRUE(dst);
} }
TEST(GmockCallbackSupportTest, RunOnceClosure) {
MockFunction<void(base::OnceClosure)> check;
bool dst = false;
EXPECT_CALL(check, Call(IsNotNullCallback())).WillOnce(RunOnceCallback<0>());
check.Call(base::BindOnce(&SetBool, true, &dst));
EXPECT_TRUE(dst);
}
TEST(GmockCallbackSupportTest, RunOnceCallback) {
MockFunction<void(TestOnceCallback)> check;
bool dst = false;
bool src = true;
EXPECT_CALL(check, Call(IsNotNullCallback()))
.WillOnce(RunOnceCallback<0>(src, &dst));
src = false;
check.Call(base::BindOnce(&SetBool));
EXPECT_TRUE(dst);
}
} // namespace test } // namespace test
} // namespace base } // namespace base
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment