1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <functional>
8*6777b538SAndroid Build Coastguard Worker #include <type_traits>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
13*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker namespace {
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker struct BadArg {};
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Worker template <typename TagType, typename CallbackType>
20*6777b538SAndroid Build Coastguard Worker struct TestConversionAndAssignmentImpl {
21*6777b538SAndroid Build Coastguard Worker static constexpr bool kSupportsConversion =
22*6777b538SAndroid Build Coastguard Worker std::is_convertible_v<TagType, CallbackType>;
23*6777b538SAndroid Build Coastguard Worker static constexpr bool kSupportsAssignment =
24*6777b538SAndroid Build Coastguard Worker std::is_assignable_v<CallbackType, TagType>;
25*6777b538SAndroid Build Coastguard Worker static_assert(kSupportsConversion == kSupportsAssignment);
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker static constexpr bool kValue = kSupportsConversion;
28*6777b538SAndroid Build Coastguard Worker };
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker template <typename T, typename U>
31*6777b538SAndroid Build Coastguard Worker constexpr bool TestConversionAndAssignment =
32*6777b538SAndroid Build Coastguard Worker TestConversionAndAssignmentImpl<T, U>::kValue;
33*6777b538SAndroid Build Coastguard Worker
34*6777b538SAndroid Build Coastguard Worker #define VOID_RETURN_CALLBACK_TAG_TEST(CallbackType, Sig, BadSig, BoundArg) \
35*6777b538SAndroid Build Coastguard Worker static_assert(TestConversionAndAssignment<decltype(base::NullCallback()), \
36*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
37*6777b538SAndroid Build Coastguard Worker static_assert( \
38*6777b538SAndroid Build Coastguard Worker TestConversionAndAssignment<decltype(base::NullCallbackAs<Sig>()), \
39*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
40*6777b538SAndroid Build Coastguard Worker static_assert(TestConversionAndAssignment<decltype(base::DoNothing()), \
41*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
42*6777b538SAndroid Build Coastguard Worker static_assert( \
43*6777b538SAndroid Build Coastguard Worker TestConversionAndAssignment<decltype(base::DoNothingAs<Sig>()), \
44*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
45*6777b538SAndroid Build Coastguard Worker static_assert(TestConversionAndAssignment< \
46*6777b538SAndroid Build Coastguard Worker decltype(base::DoNothingWithBoundArgs(BoundArg)), \
47*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
48*6777b538SAndroid Build Coastguard Worker \
49*6777b538SAndroid Build Coastguard Worker static_assert( \
50*6777b538SAndroid Build Coastguard Worker !TestConversionAndAssignment<decltype(base::NullCallbackAs<BadSig>()), \
51*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
52*6777b538SAndroid Build Coastguard Worker static_assert( \
53*6777b538SAndroid Build Coastguard Worker !TestConversionAndAssignment<decltype(base::DoNothingAs<BadSig>()), \
54*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
55*6777b538SAndroid Build Coastguard Worker static_assert(TestConversionAndAssignment< \
56*6777b538SAndroid Build Coastguard Worker decltype(base::DoNothingWithBoundArgs(BadArg())), \
57*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>)
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker #define NON_VOID_RETURN_CALLBACK_TAG_TEST(CallbackType, Sig, BadSig, BoundArg) \
60*6777b538SAndroid Build Coastguard Worker static_assert(TestConversionAndAssignment<decltype(base::NullCallback()), \
61*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
62*6777b538SAndroid Build Coastguard Worker static_assert( \
63*6777b538SAndroid Build Coastguard Worker TestConversionAndAssignment<decltype(base::NullCallbackAs<Sig>()), \
64*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
65*6777b538SAndroid Build Coastguard Worker \
66*6777b538SAndroid Build Coastguard Worker /* Unlike callbacks that return void, callbacks that return non-void */ \
67*6777b538SAndroid Build Coastguard Worker /* should not be implicitly convertible from DoNothingCallbackTag since */ \
68*6777b538SAndroid Build Coastguard Worker /* this would require guessing what the callback should return. */ \
69*6777b538SAndroid Build Coastguard Worker static_assert(!TestConversionAndAssignment<decltype(base::DoNothing()), \
70*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
71*6777b538SAndroid Build Coastguard Worker static_assert( \
72*6777b538SAndroid Build Coastguard Worker !TestConversionAndAssignment<decltype(base::DoNothingAs<Sig>()), \
73*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
74*6777b538SAndroid Build Coastguard Worker static_assert(!TestConversionAndAssignment< \
75*6777b538SAndroid Build Coastguard Worker decltype(base::DoNothingWithBoundArgs(BoundArg)), \
76*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
77*6777b538SAndroid Build Coastguard Worker \
78*6777b538SAndroid Build Coastguard Worker static_assert( \
79*6777b538SAndroid Build Coastguard Worker !TestConversionAndAssignment<decltype(base::NullCallbackAs<BadSig>()), \
80*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
81*6777b538SAndroid Build Coastguard Worker static_assert( \
82*6777b538SAndroid Build Coastguard Worker !TestConversionAndAssignment<decltype(base::DoNothingAs<BadSig>()), \
83*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>); \
84*6777b538SAndroid Build Coastguard Worker static_assert(!TestConversionAndAssignment< \
85*6777b538SAndroid Build Coastguard Worker decltype(base::DoNothingWithBoundArgs(BadArg())), \
86*6777b538SAndroid Build Coastguard Worker CallbackType<Sig>>)
87*6777b538SAndroid Build Coastguard Worker
88*6777b538SAndroid Build Coastguard Worker VOID_RETURN_CALLBACK_TAG_TEST(base::OnceCallback, void(), void(char), );
89*6777b538SAndroid Build Coastguard Worker VOID_RETURN_CALLBACK_TAG_TEST(base::OnceCallback, void(int), void(char), 8);
90*6777b538SAndroid Build Coastguard Worker NON_VOID_RETURN_CALLBACK_TAG_TEST(base::OnceCallback, int(int), char(int), 8);
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker VOID_RETURN_CALLBACK_TAG_TEST(base::RepeatingCallback, void(), void(char), );
93*6777b538SAndroid Build Coastguard Worker VOID_RETURN_CALLBACK_TAG_TEST(base::RepeatingCallback,
94*6777b538SAndroid Build Coastguard Worker void(int),
95*6777b538SAndroid Build Coastguard Worker void(char),
96*6777b538SAndroid Build Coastguard Worker 8);
97*6777b538SAndroid Build Coastguard Worker NON_VOID_RETURN_CALLBACK_TAG_TEST(base::RepeatingCallback,
98*6777b538SAndroid Build Coastguard Worker int(int),
99*6777b538SAndroid Build Coastguard Worker char(int),
100*6777b538SAndroid Build Coastguard Worker 8);
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Worker #undef VOID_RETURN_CALLBACK_TAG_TEST
103*6777b538SAndroid Build Coastguard Worker #undef NON_VOID_RETURN_CALLBACK_TAG_TEST
104*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,IsBaseCallback)105*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, IsBaseCallback) {
106*6777b538SAndroid Build Coastguard Worker // Check that base::{Once,Repeating}Closures and references to them are
107*6777b538SAndroid Build Coastguard Worker // considered base::{Once,Repeating}Callbacks.
108*6777b538SAndroid Build Coastguard Worker static_assert(base::IsBaseCallback<base::OnceClosure>);
109*6777b538SAndroid Build Coastguard Worker static_assert(base::IsBaseCallback<base::RepeatingClosure>);
110*6777b538SAndroid Build Coastguard Worker static_assert(base::IsBaseCallback<base::OnceClosure&&>);
111*6777b538SAndroid Build Coastguard Worker static_assert(base::IsBaseCallback<const base::RepeatingClosure&>);
112*6777b538SAndroid Build Coastguard Worker
113*6777b538SAndroid Build Coastguard Worker // Check that base::{Once, Repeating}Callbacks with a given RunType and
114*6777b538SAndroid Build Coastguard Worker // references to them are considered base::{Once, Repeating}Callbacks.
115*6777b538SAndroid Build Coastguard Worker static_assert(base::IsBaseCallback<base::OnceCallback<int(int)>>);
116*6777b538SAndroid Build Coastguard Worker static_assert(base::IsBaseCallback<base::RepeatingCallback<int(int)>>);
117*6777b538SAndroid Build Coastguard Worker static_assert(base::IsBaseCallback<base::OnceCallback<int(int)>&&>);
118*6777b538SAndroid Build Coastguard Worker static_assert(base::IsBaseCallback<const base::RepeatingCallback<int(int)>&>);
119*6777b538SAndroid Build Coastguard Worker
120*6777b538SAndroid Build Coastguard Worker // Check that POD types are not considered base::{Once, Repeating}Callbacks.
121*6777b538SAndroid Build Coastguard Worker static_assert(!base::IsBaseCallback<bool>);
122*6777b538SAndroid Build Coastguard Worker static_assert(!base::IsBaseCallback<int>);
123*6777b538SAndroid Build Coastguard Worker static_assert(!base::IsBaseCallback<double>);
124*6777b538SAndroid Build Coastguard Worker
125*6777b538SAndroid Build Coastguard Worker // Check that the closely related std::function is not considered a
126*6777b538SAndroid Build Coastguard Worker // base::{Once, Repeating}Callback.
127*6777b538SAndroid Build Coastguard Worker static_assert(!base::IsBaseCallback<std::function<void()>>);
128*6777b538SAndroid Build Coastguard Worker static_assert(!base::IsBaseCallback<const std::function<void()>&>);
129*6777b538SAndroid Build Coastguard Worker static_assert(!base::IsBaseCallback<std::function<void()>&&>);
130*6777b538SAndroid Build Coastguard Worker }
131*6777b538SAndroid Build Coastguard Worker
Increment(int * value)132*6777b538SAndroid Build Coastguard Worker void Increment(int* value) {
133*6777b538SAndroid Build Coastguard Worker (*value)++;
134*6777b538SAndroid Build Coastguard Worker }
135*6777b538SAndroid Build Coastguard Worker
IncrementWithRef(int & value)136*6777b538SAndroid Build Coastguard Worker void IncrementWithRef(int& value) {
137*6777b538SAndroid Build Coastguard Worker value++;
138*6777b538SAndroid Build Coastguard Worker }
139*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ScopedClosureRunnerHasClosure)140*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ScopedClosureRunnerHasClosure) {
141*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner1;
142*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(runner1);
143*6777b538SAndroid Build Coastguard Worker
144*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner2{base::DoNothing()};
145*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(runner2);
146*6777b538SAndroid Build Coastguard Worker }
147*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ScopedClosureRunnerExitScope)148*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ScopedClosureRunnerExitScope) {
149*6777b538SAndroid Build Coastguard Worker int run_count = 0;
150*6777b538SAndroid Build Coastguard Worker {
151*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
152*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count);
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count);
155*6777b538SAndroid Build Coastguard Worker }
156*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ScopedClosureRunnerRelease)157*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ScopedClosureRunnerRelease) {
158*6777b538SAndroid Build Coastguard Worker int run_count = 0;
159*6777b538SAndroid Build Coastguard Worker base::OnceClosure c;
160*6777b538SAndroid Build Coastguard Worker {
161*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
162*6777b538SAndroid Build Coastguard Worker c = runner.Release();
163*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count);
164*6777b538SAndroid Build Coastguard Worker }
165*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count);
166*6777b538SAndroid Build Coastguard Worker std::move(c).Run();
167*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count);
168*6777b538SAndroid Build Coastguard Worker }
169*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ScopedClosureRunnerReplaceClosure)170*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ScopedClosureRunnerReplaceClosure) {
171*6777b538SAndroid Build Coastguard Worker int run_count_1 = 0;
172*6777b538SAndroid Build Coastguard Worker int run_count_2 = 0;
173*6777b538SAndroid Build Coastguard Worker {
174*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner;
175*6777b538SAndroid Build Coastguard Worker runner.ReplaceClosure(base::BindOnce(&Increment, &run_count_1));
176*6777b538SAndroid Build Coastguard Worker runner.ReplaceClosure(base::BindOnce(&Increment, &run_count_2));
177*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count_1);
178*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count_2);
179*6777b538SAndroid Build Coastguard Worker }
180*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count_1);
181*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count_2);
182*6777b538SAndroid Build Coastguard Worker }
183*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ScopedClosureRunnerRunAndResetNonNull)184*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNonNull) {
185*6777b538SAndroid Build Coastguard Worker int run_count_3 = 0;
186*6777b538SAndroid Build Coastguard Worker {
187*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count_3));
188*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count_3);
189*6777b538SAndroid Build Coastguard Worker runner.RunAndReset();
190*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count_3);
191*6777b538SAndroid Build Coastguard Worker }
192*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count_3);
193*6777b538SAndroid Build Coastguard Worker }
194*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ScopedClosureRunnerRunAndResetNull)195*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNull) {
196*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner;
197*6777b538SAndroid Build Coastguard Worker runner.RunAndReset(); // Should not crash.
198*6777b538SAndroid Build Coastguard Worker }
199*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ScopedClosureRunnerMoveConstructor)200*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ScopedClosureRunnerMoveConstructor) {
201*6777b538SAndroid Build Coastguard Worker int run_count = 0;
202*6777b538SAndroid Build Coastguard Worker {
203*6777b538SAndroid Build Coastguard Worker std::unique_ptr<base::ScopedClosureRunner> runner(
204*6777b538SAndroid Build Coastguard Worker new base::ScopedClosureRunner(base::BindOnce(&Increment, &run_count)));
205*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner2(std::move(*runner));
206*6777b538SAndroid Build Coastguard Worker runner.reset();
207*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count);
208*6777b538SAndroid Build Coastguard Worker }
209*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count);
210*6777b538SAndroid Build Coastguard Worker }
211*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ScopedClosureRunnerMoveAssignment)212*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ScopedClosureRunnerMoveAssignment) {
213*6777b538SAndroid Build Coastguard Worker int run_count_1 = 0;
214*6777b538SAndroid Build Coastguard Worker int run_count_2 = 0;
215*6777b538SAndroid Build Coastguard Worker {
216*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count_1));
217*6777b538SAndroid Build Coastguard Worker {
218*6777b538SAndroid Build Coastguard Worker base::ScopedClosureRunner runner2(
219*6777b538SAndroid Build Coastguard Worker base::BindOnce(&Increment, &run_count_2));
220*6777b538SAndroid Build Coastguard Worker runner = std::move(runner2);
221*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count_1);
222*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count_2);
223*6777b538SAndroid Build Coastguard Worker }
224*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count_1);
225*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, run_count_2);
226*6777b538SAndroid Build Coastguard Worker }
227*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count_1);
228*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, run_count_2);
229*6777b538SAndroid Build Coastguard Worker }
230*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,SplitOnceCallback_EmptyCallback)231*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, SplitOnceCallback_EmptyCallback) {
232*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb = base::NullCallback();
233*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cb);
234*6777b538SAndroid Build Coastguard Worker
235*6777b538SAndroid Build Coastguard Worker auto split = base::SplitOnceCallback(std::move(cb));
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker static_assert(std::is_same_v<decltype(split),
238*6777b538SAndroid Build Coastguard Worker std::pair<base::OnceCallback<void(int*)>,
239*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)>>>,
240*6777b538SAndroid Build Coastguard Worker "");
241*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(split.first);
242*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(split.second);
243*6777b538SAndroid Build Coastguard Worker }
244*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,SplitOnceCallback_FirstCallback)245*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, SplitOnceCallback_FirstCallback) {
246*6777b538SAndroid Build Coastguard Worker int count = 0;
247*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb =
248*6777b538SAndroid Build Coastguard Worker base::BindOnce([](int* count) { ++*count; });
249*6777b538SAndroid Build Coastguard Worker
250*6777b538SAndroid Build Coastguard Worker auto split = base::SplitOnceCallback(std::move(cb));
251*6777b538SAndroid Build Coastguard Worker
252*6777b538SAndroid Build Coastguard Worker static_assert(std::is_same_v<decltype(split),
253*6777b538SAndroid Build Coastguard Worker std::pair<base::OnceCallback<void(int*)>,
254*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)>>>,
255*6777b538SAndroid Build Coastguard Worker "");
256*6777b538SAndroid Build Coastguard Worker
257*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, count);
258*6777b538SAndroid Build Coastguard Worker std::move(split.first).Run(&count);
259*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, count);
260*6777b538SAndroid Build Coastguard Worker
261*6777b538SAndroid Build Coastguard Worker #if GTEST_HAS_DEATH_TEST
262*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(std::move(split.second).Run(&count));
263*6777b538SAndroid Build Coastguard Worker #endif // GTEST_HAS_DEATH_TEST
264*6777b538SAndroid Build Coastguard Worker }
265*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,SplitOnceCallback_SecondCallback)266*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, SplitOnceCallback_SecondCallback) {
267*6777b538SAndroid Build Coastguard Worker int count = 0;
268*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb =
269*6777b538SAndroid Build Coastguard Worker base::BindOnce([](int* count) { ++*count; });
270*6777b538SAndroid Build Coastguard Worker
271*6777b538SAndroid Build Coastguard Worker auto split = base::SplitOnceCallback(std::move(cb));
272*6777b538SAndroid Build Coastguard Worker
273*6777b538SAndroid Build Coastguard Worker static_assert(std::is_same_v<decltype(split),
274*6777b538SAndroid Build Coastguard Worker std::pair<base::OnceCallback<void(int*)>,
275*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)>>>,
276*6777b538SAndroid Build Coastguard Worker "");
277*6777b538SAndroid Build Coastguard Worker
278*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, count);
279*6777b538SAndroid Build Coastguard Worker std::move(split.second).Run(&count);
280*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, count);
281*6777b538SAndroid Build Coastguard Worker
282*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(std::move(split.first).Run(&count));
283*6777b538SAndroid Build Coastguard Worker }
284*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,SplitSplitOnceCallback_FirstSplit)285*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, SplitSplitOnceCallback_FirstSplit) {
286*6777b538SAndroid Build Coastguard Worker int count = 0;
287*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb =
288*6777b538SAndroid Build Coastguard Worker base::BindOnce([](int* count) { ++*count; });
289*6777b538SAndroid Build Coastguard Worker
290*6777b538SAndroid Build Coastguard Worker auto split = base::SplitOnceCallback(std::move(cb));
291*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb1 = std::move(split.first);
292*6777b538SAndroid Build Coastguard Worker split = base::SplitOnceCallback(std::move(split.second));
293*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb2 = std::move(split.first);
294*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb3 = std::move(split.second);
295*6777b538SAndroid Build Coastguard Worker
296*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, count);
297*6777b538SAndroid Build Coastguard Worker std::move(cb1).Run(&count);
298*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, count);
299*6777b538SAndroid Build Coastguard Worker
300*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(std::move(cb3).Run(&count));
301*6777b538SAndroid Build Coastguard Worker }
302*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,SplitSplitOnceCallback_SecondSplit)303*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, SplitSplitOnceCallback_SecondSplit) {
304*6777b538SAndroid Build Coastguard Worker int count = 0;
305*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb =
306*6777b538SAndroid Build Coastguard Worker base::BindOnce([](int* count) { ++*count; });
307*6777b538SAndroid Build Coastguard Worker
308*6777b538SAndroid Build Coastguard Worker auto split = base::SplitOnceCallback(std::move(cb));
309*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb1 = std::move(split.first);
310*6777b538SAndroid Build Coastguard Worker split = base::SplitOnceCallback(std::move(split.second));
311*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb2 = std::move(split.first);
312*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int*)> cb3 = std::move(split.second);
313*6777b538SAndroid Build Coastguard Worker
314*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, count);
315*6777b538SAndroid Build Coastguard Worker std::move(cb2).Run(&count);
316*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, count);
317*6777b538SAndroid Build Coastguard Worker
318*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(std::move(cb1).Run(&count));
319*6777b538SAndroid Build Coastguard Worker }
320*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,IgnoreArgs)321*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, IgnoreArgs) {
322*6777b538SAndroid Build Coastguard Worker int count = 0;
323*6777b538SAndroid Build Coastguard Worker base::RepeatingClosure repeating_closure =
324*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&Increment, &count);
325*6777b538SAndroid Build Coastguard Worker base::OnceClosure once_closure = base::BindOnce(&Increment, &count);
326*6777b538SAndroid Build Coastguard Worker
327*6777b538SAndroid Build Coastguard Worker base::RepeatingCallback<void(int)> repeating_int_cb =
328*6777b538SAndroid Build Coastguard Worker base::IgnoreArgs<int>(repeating_closure);
329*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, count);
330*6777b538SAndroid Build Coastguard Worker repeating_int_cb.Run(42);
331*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, count);
332*6777b538SAndroid Build Coastguard Worker repeating_int_cb.Run(42);
333*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, count);
334*6777b538SAndroid Build Coastguard Worker
335*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int)> once_int_cb =
336*6777b538SAndroid Build Coastguard Worker base::IgnoreArgs<int>(std::move(once_closure));
337*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, count);
338*6777b538SAndroid Build Coastguard Worker std::move(once_int_cb).Run(42);
339*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, count);
340*6777b538SAndroid Build Coastguard Worker
341*6777b538SAndroid Build Coastguard Worker // Ignore only some (one) argument and forward the rest.
342*6777b538SAndroid Build Coastguard Worker auto repeating_callback = base::BindRepeating(&Increment);
343*6777b538SAndroid Build Coastguard Worker auto repeating_cb_with_extra_arg = base::IgnoreArgs<bool>(repeating_callback);
344*6777b538SAndroid Build Coastguard Worker repeating_cb_with_extra_arg.Run(false, &count);
345*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(4, count);
346*6777b538SAndroid Build Coastguard Worker
347*6777b538SAndroid Build Coastguard Worker // Ignore two arguments and forward the rest.
348*6777b538SAndroid Build Coastguard Worker auto once_callback = base::BindOnce(&Increment);
349*6777b538SAndroid Build Coastguard Worker auto once_cb_with_extra_arg =
350*6777b538SAndroid Build Coastguard Worker base::IgnoreArgs<char, bool>(repeating_callback);
351*6777b538SAndroid Build Coastguard Worker std::move(once_cb_with_extra_arg).Run('d', false, &count);
352*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5, count);
353*6777b538SAndroid Build Coastguard Worker }
354*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,IgnoreArgs_EmptyCallback)355*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, IgnoreArgs_EmptyCallback) {
356*6777b538SAndroid Build Coastguard Worker base::RepeatingCallback<void(int)> repeating_int_cb =
357*6777b538SAndroid Build Coastguard Worker base::IgnoreArgs<int>(base::RepeatingClosure());
358*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(repeating_int_cb);
359*6777b538SAndroid Build Coastguard Worker
360*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(int)> once_int_cb =
361*6777b538SAndroid Build Coastguard Worker base::IgnoreArgs<int>(base::OnceClosure());
362*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(once_int_cb);
363*6777b538SAndroid Build Coastguard Worker }
364*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ForwardRepeatingCallbacks)365*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ForwardRepeatingCallbacks) {
366*6777b538SAndroid Build Coastguard Worker int count = 0;
367*6777b538SAndroid Build Coastguard Worker auto tie_cb =
368*6777b538SAndroid Build Coastguard Worker base::ForwardRepeatingCallbacks({base::BindRepeating(&IncrementWithRef),
369*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&IncrementWithRef)});
370*6777b538SAndroid Build Coastguard Worker
371*6777b538SAndroid Build Coastguard Worker tie_cb.Run(count);
372*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(count, 2);
373*6777b538SAndroid Build Coastguard Worker
374*6777b538SAndroid Build Coastguard Worker tie_cb.Run(count);
375*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(count, 4);
376*6777b538SAndroid Build Coastguard Worker }
377*6777b538SAndroid Build Coastguard Worker
TEST(CallbackHelpersTest,ReturnValueOnce)378*6777b538SAndroid Build Coastguard Worker TEST(CallbackHelpersTest, ReturnValueOnce) {
379*6777b538SAndroid Build Coastguard Worker // Check that copyable types are supported.
380*6777b538SAndroid Build Coastguard Worker auto string_factory = base::ReturnValueOnce(std::string("test"));
381*6777b538SAndroid Build Coastguard Worker static_assert(std::is_same_v<decltype(string_factory),
382*6777b538SAndroid Build Coastguard Worker base::OnceCallback<std::string(void)>>);
383*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::move(string_factory).Run(), "test");
384*6777b538SAndroid Build Coastguard Worker
385*6777b538SAndroid Build Coastguard Worker // Check that move-only types are supported.
386*6777b538SAndroid Build Coastguard Worker auto unique_ptr_factory = base::ReturnValueOnce(std::make_unique<int>(42));
387*6777b538SAndroid Build Coastguard Worker static_assert(std::is_same_v<decltype(unique_ptr_factory),
388*6777b538SAndroid Build Coastguard Worker base::OnceCallback<std::unique_ptr<int>(void)>>);
389*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(*std::move(unique_ptr_factory).Run(), 42);
390*6777b538SAndroid Build Coastguard Worker }
391*6777b538SAndroid Build Coastguard Worker
392*6777b538SAndroid Build Coastguard Worker } // namespace
393