xref: /aosp_15_r20/external/cronet/base/functional/callback_helpers_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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