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