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