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
TEST(CallbackHelpersTest,IsOnceCallback)132 TEST(CallbackHelpersTest, IsOnceCallback) {
133 // Check that base::OnceClosures and references to them are considered
134 // base::OnceCallbacks, but base::RepeatingClosures are not.
135 static_assert(base::IsOnceCallback<base::OnceClosure>);
136 static_assert(!base::IsOnceCallback<base::RepeatingClosure>);
137 static_assert(base::IsOnceCallback<base::OnceClosure&&>);
138 static_assert(!base::IsOnceCallback<const base::RepeatingClosure&>);
139
140 // Check that base::OnceCallbacks with a given RunType and references to them
141 // are considered base::OnceCallbacks, but base::RepeatingCallbacks are not.
142 static_assert(base::IsOnceCallback<base::OnceCallback<int(int)>>);
143 static_assert(!base::IsOnceCallback<base::RepeatingCallback<int(int)>>);
144 static_assert(base::IsOnceCallback<base::OnceCallback<int(int)>&&>);
145 static_assert(
146 !base::IsOnceCallback<const base::RepeatingCallback<int(int)>&>);
147
148 // Check that POD types are not considered base::OnceCallbacks.
149 static_assert(!base::IsOnceCallback<bool>);
150 static_assert(!base::IsOnceCallback<int>);
151 static_assert(!base::IsOnceCallback<double>);
152
153 // Check that the closely related std::function is not considered a
154 // base::OnceCallback.
155 static_assert(!base::IsOnceCallback<std::function<void()>>);
156 static_assert(!base::IsOnceCallback<const std::function<void()>&>);
157 static_assert(!base::IsOnceCallback<std::function<void()>&&>);
158
159 // Check that the result of BindOnce is a OnceCallback.
160 auto cb = base::BindOnce([](int* count) { ++*count; });
161 static_assert(base::IsOnceCallback<decltype(cb)>);
162 }
163
Increment(int * value)164 void Increment(int* value) {
165 (*value)++;
166 }
167
IncrementWithRef(int & value)168 void IncrementWithRef(int& value) {
169 value++;
170 }
171
TEST(CallbackHelpersTest,ScopedClosureRunnerHasClosure)172 TEST(CallbackHelpersTest, ScopedClosureRunnerHasClosure) {
173 base::ScopedClosureRunner runner1;
174 EXPECT_FALSE(runner1);
175
176 base::ScopedClosureRunner runner2{base::DoNothing()};
177 EXPECT_TRUE(runner2);
178 }
179
TEST(CallbackHelpersTest,ScopedClosureRunnerExitScope)180 TEST(CallbackHelpersTest, ScopedClosureRunnerExitScope) {
181 int run_count = 0;
182 {
183 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
184 EXPECT_EQ(0, run_count);
185 }
186 EXPECT_EQ(1, run_count);
187 }
188
TEST(CallbackHelpersTest,ScopedClosureRunnerRelease)189 TEST(CallbackHelpersTest, ScopedClosureRunnerRelease) {
190 int run_count = 0;
191 base::OnceClosure c;
192 {
193 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
194 c = runner.Release();
195 EXPECT_EQ(0, run_count);
196 }
197 EXPECT_EQ(0, run_count);
198 std::move(c).Run();
199 EXPECT_EQ(1, run_count);
200 }
201
TEST(CallbackHelpersTest,ScopedClosureRunnerReplaceClosure)202 TEST(CallbackHelpersTest, ScopedClosureRunnerReplaceClosure) {
203 int run_count_1 = 0;
204 int run_count_2 = 0;
205 {
206 base::ScopedClosureRunner runner;
207 runner.ReplaceClosure(base::BindOnce(&Increment, &run_count_1));
208 runner.ReplaceClosure(base::BindOnce(&Increment, &run_count_2));
209 EXPECT_EQ(0, run_count_1);
210 EXPECT_EQ(0, run_count_2);
211 }
212 EXPECT_EQ(0, run_count_1);
213 EXPECT_EQ(1, run_count_2);
214 }
215
TEST(CallbackHelpersTest,ScopedClosureRunnerRunAndResetNonNull)216 TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNonNull) {
217 int run_count_3 = 0;
218 {
219 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count_3));
220 EXPECT_EQ(0, run_count_3);
221 runner.RunAndReset();
222 EXPECT_EQ(1, run_count_3);
223 }
224 EXPECT_EQ(1, run_count_3);
225 }
226
TEST(CallbackHelpersTest,ScopedClosureRunnerRunAndResetNull)227 TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNull) {
228 base::ScopedClosureRunner runner;
229 runner.RunAndReset(); // Should not crash.
230 }
231
TEST(CallbackHelpersTest,ScopedClosureRunnerMoveConstructor)232 TEST(CallbackHelpersTest, ScopedClosureRunnerMoveConstructor) {
233 int run_count = 0;
234 {
235 std::unique_ptr<base::ScopedClosureRunner> runner(
236 new base::ScopedClosureRunner(base::BindOnce(&Increment, &run_count)));
237 base::ScopedClosureRunner runner2(std::move(*runner));
238 runner.reset();
239 EXPECT_EQ(0, run_count);
240 }
241 EXPECT_EQ(1, run_count);
242 }
243
TEST(CallbackHelpersTest,ScopedClosureRunnerMoveAssignment)244 TEST(CallbackHelpersTest, ScopedClosureRunnerMoveAssignment) {
245 int run_count_1 = 0;
246 int run_count_2 = 0;
247 {
248 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count_1));
249 {
250 base::ScopedClosureRunner runner2(
251 base::BindOnce(&Increment, &run_count_2));
252 runner = std::move(runner2);
253 EXPECT_EQ(1, run_count_1);
254 EXPECT_EQ(0, run_count_2);
255 }
256 EXPECT_EQ(1, run_count_1);
257 EXPECT_EQ(0, run_count_2);
258 }
259 EXPECT_EQ(1, run_count_1);
260 EXPECT_EQ(1, run_count_2);
261 }
262
TEST(CallbackHelpersTest,SplitOnceCallback_EmptyCallback)263 TEST(CallbackHelpersTest, SplitOnceCallback_EmptyCallback) {
264 base::OnceCallback<void(int*)> cb = base::NullCallback();
265 EXPECT_FALSE(cb);
266
267 auto split = base::SplitOnceCallback(std::move(cb));
268
269 static_assert(std::is_same_v<decltype(split),
270 std::pair<base::OnceCallback<void(int*)>,
271 base::OnceCallback<void(int*)>>>,
272 "");
273 EXPECT_FALSE(split.first);
274 EXPECT_FALSE(split.second);
275 }
276
TEST(CallbackHelpersTest,SplitOnceCallback_FirstCallback)277 TEST(CallbackHelpersTest, SplitOnceCallback_FirstCallback) {
278 int count = 0;
279 base::OnceCallback<void(int*)> cb =
280 base::BindOnce([](int* count) { ++*count; });
281
282 auto split = base::SplitOnceCallback(std::move(cb));
283
284 static_assert(std::is_same_v<decltype(split),
285 std::pair<base::OnceCallback<void(int*)>,
286 base::OnceCallback<void(int*)>>>,
287 "");
288
289 EXPECT_EQ(0, count);
290 std::move(split.first).Run(&count);
291 EXPECT_EQ(1, count);
292
293 #if GTEST_HAS_DEATH_TEST
294 EXPECT_CHECK_DEATH(std::move(split.second).Run(&count));
295 #endif // GTEST_HAS_DEATH_TEST
296 }
297
TEST(CallbackHelpersTest,SplitOnceCallback_SecondCallback)298 TEST(CallbackHelpersTest, SplitOnceCallback_SecondCallback) {
299 int count = 0;
300 base::OnceCallback<void(int*)> cb =
301 base::BindOnce([](int* count) { ++*count; });
302
303 auto split = base::SplitOnceCallback(std::move(cb));
304
305 static_assert(std::is_same_v<decltype(split),
306 std::pair<base::OnceCallback<void(int*)>,
307 base::OnceCallback<void(int*)>>>,
308 "");
309
310 EXPECT_EQ(0, count);
311 std::move(split.second).Run(&count);
312 EXPECT_EQ(1, count);
313
314 EXPECT_CHECK_DEATH(std::move(split.first).Run(&count));
315 }
316
TEST(CallbackHelpersTest,SplitSplitOnceCallback_FirstSplit)317 TEST(CallbackHelpersTest, SplitSplitOnceCallback_FirstSplit) {
318 int count = 0;
319 base::OnceCallback<void(int*)> cb =
320 base::BindOnce([](int* count) { ++*count; });
321
322 auto split = base::SplitOnceCallback(std::move(cb));
323 base::OnceCallback<void(int*)> cb1 = std::move(split.first);
324 split = base::SplitOnceCallback(std::move(split.second));
325 base::OnceCallback<void(int*)> cb2 = std::move(split.first);
326 base::OnceCallback<void(int*)> cb3 = std::move(split.second);
327
328 EXPECT_EQ(0, count);
329 std::move(cb1).Run(&count);
330 EXPECT_EQ(1, count);
331
332 EXPECT_CHECK_DEATH(std::move(cb3).Run(&count));
333 }
334
TEST(CallbackHelpersTest,SplitSplitOnceCallback_SecondSplit)335 TEST(CallbackHelpersTest, SplitSplitOnceCallback_SecondSplit) {
336 int count = 0;
337 base::OnceCallback<void(int*)> cb =
338 base::BindOnce([](int* count) { ++*count; });
339
340 auto split = base::SplitOnceCallback(std::move(cb));
341 base::OnceCallback<void(int*)> cb1 = std::move(split.first);
342 split = base::SplitOnceCallback(std::move(split.second));
343 base::OnceCallback<void(int*)> cb2 = std::move(split.first);
344 base::OnceCallback<void(int*)> cb3 = std::move(split.second);
345
346 EXPECT_EQ(0, count);
347 std::move(cb2).Run(&count);
348 EXPECT_EQ(1, count);
349
350 EXPECT_CHECK_DEATH(std::move(cb1).Run(&count));
351 }
352
TEST(CallbackHelpersTest,IgnoreArgs)353 TEST(CallbackHelpersTest, IgnoreArgs) {
354 int count = 0;
355 base::RepeatingClosure repeating_closure =
356 base::BindRepeating(&Increment, &count);
357 base::OnceClosure once_closure = base::BindOnce(&Increment, &count);
358
359 base::RepeatingCallback<void(int)> repeating_int_cb =
360 base::IgnoreArgs<int>(repeating_closure);
361 EXPECT_EQ(0, count);
362 repeating_int_cb.Run(42);
363 EXPECT_EQ(1, count);
364 repeating_int_cb.Run(42);
365 EXPECT_EQ(2, count);
366
367 base::OnceCallback<void(int)> once_int_cb =
368 base::IgnoreArgs<int>(std::move(once_closure));
369 EXPECT_EQ(2, count);
370 std::move(once_int_cb).Run(42);
371 EXPECT_EQ(3, count);
372
373 // Ignore only some (one) argument and forward the rest.
374 auto repeating_callback = base::BindRepeating(&Increment);
375 auto repeating_cb_with_extra_arg = base::IgnoreArgs<bool>(repeating_callback);
376 repeating_cb_with_extra_arg.Run(false, &count);
377 EXPECT_EQ(4, count);
378
379 // Ignore two arguments and forward the rest.
380 auto once_callback = base::BindOnce(&Increment);
381 auto once_cb_with_extra_arg =
382 base::IgnoreArgs<char, bool>(repeating_callback);
383 std::move(once_cb_with_extra_arg).Run('d', false, &count);
384 EXPECT_EQ(5, count);
385 }
386
TEST(CallbackHelpersTest,IgnoreArgs_EmptyCallback)387 TEST(CallbackHelpersTest, IgnoreArgs_EmptyCallback) {
388 base::RepeatingCallback<void(int)> repeating_int_cb =
389 base::IgnoreArgs<int>(base::RepeatingClosure());
390 EXPECT_FALSE(repeating_int_cb);
391
392 base::OnceCallback<void(int)> once_int_cb =
393 base::IgnoreArgs<int>(base::OnceClosure());
394 EXPECT_FALSE(once_int_cb);
395 }
396
TEST(CallbackHelpersTest,ForwardRepeatingCallbacks)397 TEST(CallbackHelpersTest, ForwardRepeatingCallbacks) {
398 int count = 0;
399 auto tie_cb =
400 base::ForwardRepeatingCallbacks({base::BindRepeating(&IncrementWithRef),
401 base::BindRepeating(&IncrementWithRef)});
402
403 tie_cb.Run(count);
404 EXPECT_EQ(count, 2);
405
406 tie_cb.Run(count);
407 EXPECT_EQ(count, 4);
408 }
409
TEST(CallbackHelpersTest,ReturnValueOnce)410 TEST(CallbackHelpersTest, ReturnValueOnce) {
411 // Check that copyable types are supported.
412 auto string_factory = base::ReturnValueOnce(std::string("test"));
413 static_assert(std::is_same_v<decltype(string_factory),
414 base::OnceCallback<std::string(void)>>);
415 EXPECT_EQ(std::move(string_factory).Run(), "test");
416
417 // Check that move-only types are supported.
418 auto unique_ptr_factory = base::ReturnValueOnce(std::make_unique<int>(42));
419 static_assert(std::is_same_v<decltype(unique_ptr_factory),
420 base::OnceCallback<std::unique_ptr<int>(void)>>);
421 EXPECT_EQ(*std::move(unique_ptr_factory).Run(), 42);
422 }
423
424 } // namespace
425