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.
5 #include "base/functional/callback_helpers.h"
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"
17 TEST(CallbackHelpersTest, IsBaseCallback) {
18 // Check that base::{Once,Repeating}Closures and references to them are
19 // considered base::{Once,Repeating}Callbacks.
20 static_assert(base::IsBaseCallback<base::OnceClosure>::value, "");
21 static_assert(base::IsBaseCallback<base::RepeatingClosure>::value, "");
22 static_assert(base::IsBaseCallback<base::OnceClosure&&>::value, "");
23 static_assert(base::IsBaseCallback<const base::RepeatingClosure&>::value, "");
25 // Check that base::{Once, Repeating}Callbacks with a given RunType and
26 // references to them are considered base::{Once, Repeating}Callbacks.
27 static_assert(base::IsBaseCallback<base::OnceCallback<int(int)>>::value, "");
28 static_assert(base::IsBaseCallback<base::RepeatingCallback<int(int)>>::value,
30 static_assert(base::IsBaseCallback<base::OnceCallback<int(int)>&&>::value,
33 base::IsBaseCallback<const base::RepeatingCallback<int(int)>&>::value,
36 // Check that POD types are not considered base::{Once, Repeating}Callbacks.
37 static_assert(!base::IsBaseCallback<bool>::value, "");
38 static_assert(!base::IsBaseCallback<int>::value, "");
39 static_assert(!base::IsBaseCallback<double>::value, "");
41 // Check that the closely related std::function is not considered a
42 // base::{Once, Repeating}Callback.
43 static_assert(!base::IsBaseCallback<std::function<void()>>::value, "");
44 static_assert(!base::IsBaseCallback<const std::function<void()>&>::value, "");
45 static_assert(!base::IsBaseCallback<std::function<void()>&&>::value, "");
48 TEST(CallbackHelpersTest, IsOnceCallback) {
49 // Check that base::OnceClosures and references to them are considered
50 // base::OnceCallbacks, but base::RepeatingClosures are not.
51 static_assert(base::IsOnceCallback<base::OnceClosure>::value, "");
52 static_assert(!base::IsOnceCallback<base::RepeatingClosure>::value, "");
53 static_assert(base::IsOnceCallback<base::OnceClosure&&>::value, "");
54 static_assert(!base::IsOnceCallback<const base::RepeatingClosure&>::value,
57 // Check that base::OnceCallbacks with a given RunType and references to them
58 // are considered base::OnceCallbacks, but base::RepeatingCallbacks are not.
59 static_assert(base::IsOnceCallback<base::OnceCallback<int(int)>>::value, "");
60 static_assert(!base::IsOnceCallback<base::RepeatingCallback<int(int)>>::value,
62 static_assert(base::IsOnceCallback<base::OnceCallback<int(int)>&&>::value,
65 !base::IsOnceCallback<const base::RepeatingCallback<int(int)>&>::value,
68 // Check that POD types are not considered base::OnceCallbacks.
69 static_assert(!base::IsOnceCallback<bool>::value, "");
70 static_assert(!base::IsOnceCallback<int>::value, "");
71 static_assert(!base::IsOnceCallback<double>::value, "");
73 // Check that the closely related std::function is not considered a
74 // base::OnceCallback.
75 static_assert(!base::IsOnceCallback<std::function<void()>>::value, "");
76 static_assert(!base::IsOnceCallback<const std::function<void()>&>::value, "");
77 static_assert(!base::IsOnceCallback<std::function<void()>&&>::value, "");
79 // Check that the result of BindOnce is a OnceCallback.
80 auto cb = base::BindOnce([](int* count) { ++*count; });
81 static_assert(base::IsOnceCallback<decltype(cb)>::value, "");
84 void Increment(int* value) {
88 void IncrementWithRef(int& value) {
92 TEST(CallbackHelpersTest, ScopedClosureRunnerHasClosure) {
93 base::ScopedClosureRunner runner1;
94 EXPECT_FALSE(runner1);
96 base::ScopedClosureRunner runner2{base::DoNothing()};
100 TEST(CallbackHelpersTest, ScopedClosureRunnerExitScope) {
103 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
104 EXPECT_EQ(0, run_count);
106 EXPECT_EQ(1, run_count);
109 TEST(CallbackHelpersTest, ScopedClosureRunnerRelease) {
113 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
114 c = runner.Release();
115 EXPECT_EQ(0, run_count);
117 EXPECT_EQ(0, run_count);
119 EXPECT_EQ(1, run_count);
122 TEST(CallbackHelpersTest, ScopedClosureRunnerReplaceClosure) {
126 base::ScopedClosureRunner runner;
127 runner.ReplaceClosure(base::BindOnce(&Increment, &run_count_1));
128 runner.ReplaceClosure(base::BindOnce(&Increment, &run_count_2));
129 EXPECT_EQ(0, run_count_1);
130 EXPECT_EQ(0, run_count_2);
132 EXPECT_EQ(0, run_count_1);
133 EXPECT_EQ(1, run_count_2);
136 TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNonNull) {
139 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count_3));
140 EXPECT_EQ(0, run_count_3);
141 runner.RunAndReset();
142 EXPECT_EQ(1, run_count_3);
144 EXPECT_EQ(1, run_count_3);
147 TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNull) {
148 base::ScopedClosureRunner runner;
149 runner.RunAndReset(); // Should not crash.
152 TEST(CallbackHelpersTest, ScopedClosureRunnerMoveConstructor) {
155 std::unique_ptr<base::ScopedClosureRunner> runner(
156 new base::ScopedClosureRunner(base::BindOnce(&Increment, &run_count)));
157 base::ScopedClosureRunner runner2(std::move(*runner));
159 EXPECT_EQ(0, run_count);
161 EXPECT_EQ(1, run_count);
164 TEST(CallbackHelpersTest, ScopedClosureRunnerMoveAssignment) {
168 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count_1));
170 base::ScopedClosureRunner runner2(
171 base::BindOnce(&Increment, &run_count_2));
172 runner = std::move(runner2);
173 EXPECT_EQ(1, run_count_1);
174 EXPECT_EQ(0, run_count_2);
176 EXPECT_EQ(1, run_count_1);
177 EXPECT_EQ(0, run_count_2);
179 EXPECT_EQ(1, run_count_1);
180 EXPECT_EQ(1, run_count_2);
183 TEST(CallbackHelpersTest, SplitOnceCallback_EmptyCallback) {
184 base::OnceCallback<void(int*)> cb = base::NullCallback();
187 auto split = base::SplitOnceCallback(std::move(cb));
189 static_assert(std::is_same_v<decltype(split),
190 std::pair<base::OnceCallback<void(int*)>,
191 base::OnceCallback<void(int*)>>>,
193 EXPECT_FALSE(split.first);
194 EXPECT_FALSE(split.second);
197 TEST(CallbackHelpersTest, SplitOnceCallback_FirstCallback) {
199 base::OnceCallback<void(int*)> cb =
200 base::BindOnce([](int* count) { ++*count; });
202 auto split = base::SplitOnceCallback(std::move(cb));
204 static_assert(std::is_same_v<decltype(split),
205 std::pair<base::OnceCallback<void(int*)>,
206 base::OnceCallback<void(int*)>>>,
210 std::move(split.first).Run(&count);
213 #if GTEST_HAS_DEATH_TEST
214 EXPECT_CHECK_DEATH(std::move(split.second).Run(&count));
215 #endif // GTEST_HAS_DEATH_TEST
218 TEST(CallbackHelpersTest, SplitOnceCallback_SecondCallback) {
220 base::OnceCallback<void(int*)> cb =
221 base::BindOnce([](int* count) { ++*count; });
223 auto split = base::SplitOnceCallback(std::move(cb));
225 static_assert(std::is_same_v<decltype(split),
226 std::pair<base::OnceCallback<void(int*)>,
227 base::OnceCallback<void(int*)>>>,
231 std::move(split.second).Run(&count);
234 EXPECT_CHECK_DEATH(std::move(split.first).Run(&count));
237 TEST(CallbackHelpersTest, SplitSplitOnceCallback_FirstSplit) {
239 base::OnceCallback<void(int*)> cb =
240 base::BindOnce([](int* count) { ++*count; });
242 auto split = base::SplitOnceCallback(std::move(cb));
243 base::OnceCallback<void(int*)> cb1 = std::move(split.first);
244 split = base::SplitOnceCallback(std::move(split.second));
245 base::OnceCallback<void(int*)> cb2 = std::move(split.first);
246 base::OnceCallback<void(int*)> cb3 = std::move(split.second);
249 std::move(cb1).Run(&count);
252 EXPECT_CHECK_DEATH(std::move(cb3).Run(&count));
255 TEST(CallbackHelpersTest, SplitSplitOnceCallback_SecondSplit) {
257 base::OnceCallback<void(int*)> cb =
258 base::BindOnce([](int* count) { ++*count; });
260 auto split = base::SplitOnceCallback(std::move(cb));
261 base::OnceCallback<void(int*)> cb1 = std::move(split.first);
262 split = base::SplitOnceCallback(std::move(split.second));
263 base::OnceCallback<void(int*)> cb2 = std::move(split.first);
264 base::OnceCallback<void(int*)> cb3 = std::move(split.second);
267 std::move(cb2).Run(&count);
270 EXPECT_CHECK_DEATH(std::move(cb1).Run(&count));
273 TEST(CallbackHelpersTest, IgnoreArgs) {
275 base::RepeatingClosure repeating_closure =
276 base::BindRepeating(&Increment, &count);
277 base::OnceClosure once_closure = base::BindOnce(&Increment, &count);
279 base::RepeatingCallback<void(int)> repeating_int_cb =
280 base::IgnoreArgs<int>(repeating_closure);
282 repeating_int_cb.Run(42);
284 repeating_int_cb.Run(42);
287 base::OnceCallback<void(int)> once_int_cb =
288 base::IgnoreArgs<int>(std::move(once_closure));
290 std::move(once_int_cb).Run(42);
293 // Ignore only some (one) argument and forward the rest.
294 auto repeating_callback = base::BindRepeating(&Increment);
295 auto repeating_cb_with_extra_arg = base::IgnoreArgs<bool>(repeating_callback);
296 repeating_cb_with_extra_arg.Run(false, &count);
299 // Ignore two arguments and forward the rest.
300 auto once_callback = base::BindOnce(&Increment);
301 auto once_cb_with_extra_arg =
302 base::IgnoreArgs<char, bool>(repeating_callback);
303 std::move(once_cb_with_extra_arg).Run('d', false, &count);
307 TEST(CallbackHelpersTest, IgnoreArgs_EmptyCallback) {
308 base::RepeatingCallback<void(int)> repeating_int_cb =
309 base::IgnoreArgs<int>(base::RepeatingClosure());
310 EXPECT_FALSE(repeating_int_cb);
312 base::OnceCallback<void(int)> once_int_cb =
313 base::IgnoreArgs<int>(base::OnceClosure());
314 EXPECT_FALSE(once_int_cb);
317 TEST(CallbackHelpersTest, ForwardRepeatingCallbacks) {
320 base::ForwardRepeatingCallbacks({base::BindRepeating(&IncrementWithRef),
321 base::BindRepeating(&IncrementWithRef)});
330 TEST(CallbackHelpersTest, ReturnValueOnce) {
331 // Check that copyable types are supported.
332 auto string_factory = base::ReturnValueOnce(std::string("test"));
333 static_assert(std::is_same_v<decltype(string_factory),
334 base::OnceCallback<std::string(void)>>);
335 EXPECT_EQ(std::move(string_factory).Run(), "test");
337 // Check that move-only types are supported.
338 auto unique_ptr_factory = base::ReturnValueOnce(std::make_unique<int>(42));
339 static_assert(std::is_same_v<decltype(unique_ptr_factory),
340 base::OnceCallback<std::unique_ptr<int>(void)>>);
341 EXPECT_EQ(*std::move(unique_ptr_factory).Run(), 42);