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
TEST(CallbackHelpersTest,IsBaseCallback)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, "");
24
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,
29 "");
30 static_assert(base::IsBaseCallback<base::OnceCallback<int(int)>&&>::value,
31 "");
32 static_assert(
33 base::IsBaseCallback<const base::RepeatingCallback<int(int)>&>::value,
34 "");
35
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, "");
40
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, "");
46 }
47
TEST(CallbackHelpersTest,IsOnceCallback)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,
55 "");
56
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,
61 "");
62 static_assert(base::IsOnceCallback<base::OnceCallback<int(int)>&&>::value,
63 "");
64 static_assert(
65 !base::IsOnceCallback<const base::RepeatingCallback<int(int)>&>::value,
66 "");
67
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, "");
72
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, "");
78
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, "");
82 }
83
Increment(int * value)84 void Increment(int* value) {
85 (*value)++;
86 }
87
TEST(CallbackHelpersTest,ScopedClosureRunnerHasClosure)88 TEST(CallbackHelpersTest, ScopedClosureRunnerHasClosure) {
89 base::ScopedClosureRunner runner1;
90 EXPECT_FALSE(runner1);
91
92 base::ScopedClosureRunner runner2{base::DoNothing()};
93 EXPECT_TRUE(runner2);
94 }
95
TEST(CallbackHelpersTest,ScopedClosureRunnerExitScope)96 TEST(CallbackHelpersTest, ScopedClosureRunnerExitScope) {
97 int run_count = 0;
98 {
99 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
100 EXPECT_EQ(0, run_count);
101 }
102 EXPECT_EQ(1, run_count);
103 }
104
TEST(CallbackHelpersTest,ScopedClosureRunnerRelease)105 TEST(CallbackHelpersTest, ScopedClosureRunnerRelease) {
106 int run_count = 0;
107 base::OnceClosure c;
108 {
109 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
110 c = runner.Release();
111 EXPECT_EQ(0, run_count);
112 }
113 EXPECT_EQ(0, run_count);
114 std::move(c).Run();
115 EXPECT_EQ(1, run_count);
116 }
117
TEST(CallbackHelpersTest,ScopedClosureRunnerReplaceClosure)118 TEST(CallbackHelpersTest, ScopedClosureRunnerReplaceClosure) {
119 int run_count_1 = 0;
120 int run_count_2 = 0;
121 {
122 base::ScopedClosureRunner runner;
123 runner.ReplaceClosure(base::BindOnce(&Increment, &run_count_1));
124 runner.ReplaceClosure(base::BindOnce(&Increment, &run_count_2));
125 EXPECT_EQ(0, run_count_1);
126 EXPECT_EQ(0, run_count_2);
127 }
128 EXPECT_EQ(0, run_count_1);
129 EXPECT_EQ(1, run_count_2);
130 }
131
TEST(CallbackHelpersTest,ScopedClosureRunnerRunAndResetNonNull)132 TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNonNull) {
133 int run_count_3 = 0;
134 {
135 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count_3));
136 EXPECT_EQ(0, run_count_3);
137 runner.RunAndReset();
138 EXPECT_EQ(1, run_count_3);
139 }
140 EXPECT_EQ(1, run_count_3);
141 }
142
TEST(CallbackHelpersTest,ScopedClosureRunnerRunAndResetNull)143 TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNull) {
144 base::ScopedClosureRunner runner;
145 runner.RunAndReset(); // Should not crash.
146 }
147
TEST(CallbackHelpersTest,ScopedClosureRunnerMoveConstructor)148 TEST(CallbackHelpersTest, ScopedClosureRunnerMoveConstructor) {
149 int run_count = 0;
150 {
151 std::unique_ptr<base::ScopedClosureRunner> runner(
152 new base::ScopedClosureRunner(base::BindOnce(&Increment, &run_count)));
153 base::ScopedClosureRunner runner2(std::move(*runner));
154 runner.reset();
155 EXPECT_EQ(0, run_count);
156 }
157 EXPECT_EQ(1, run_count);
158 }
159
TEST(CallbackHelpersTest,ScopedClosureRunnerMoveAssignment)160 TEST(CallbackHelpersTest, ScopedClosureRunnerMoveAssignment) {
161 int run_count_1 = 0;
162 int run_count_2 = 0;
163 {
164 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count_1));
165 {
166 base::ScopedClosureRunner runner2(
167 base::BindOnce(&Increment, &run_count_2));
168 runner = std::move(runner2);
169 EXPECT_EQ(1, run_count_1);
170 EXPECT_EQ(0, run_count_2);
171 }
172 EXPECT_EQ(1, run_count_1);
173 EXPECT_EQ(0, run_count_2);
174 }
175 EXPECT_EQ(1, run_count_1);
176 EXPECT_EQ(1, run_count_2);
177 }
178
TEST(CallbackHelpersTest,SplitOnceCallback_EmptyCallback)179 TEST(CallbackHelpersTest, SplitOnceCallback_EmptyCallback) {
180 base::OnceCallback<void(int*)> cb = base::NullCallback();
181 EXPECT_FALSE(cb);
182
183 auto split = base::SplitOnceCallback(std::move(cb));
184
185 static_assert(std::is_same<decltype(split),
186 std::pair<base::OnceCallback<void(int*)>,
187 base::OnceCallback<void(int*)>>>::value,
188 "");
189 EXPECT_FALSE(split.first);
190 EXPECT_FALSE(split.second);
191 }
192
TEST(CallbackHelpersTest,SplitOnceCallback_FirstCallback)193 TEST(CallbackHelpersTest, SplitOnceCallback_FirstCallback) {
194 int count = 0;
195 base::OnceCallback<void(int*)> cb =
196 base::BindOnce([](int* count) { ++*count; });
197
198 auto split = base::SplitOnceCallback(std::move(cb));
199
200 static_assert(std::is_same<decltype(split),
201 std::pair<base::OnceCallback<void(int*)>,
202 base::OnceCallback<void(int*)>>>::value,
203 "");
204
205 EXPECT_EQ(0, count);
206 std::move(split.first).Run(&count);
207 EXPECT_EQ(1, count);
208
209 #if GTEST_HAS_DEATH_TEST
210 EXPECT_CHECK_DEATH(std::move(split.second).Run(&count));
211 #endif // GTEST_HAS_DEATH_TEST
212 }
213
TEST(CallbackHelpersTest,SplitOnceCallback_SecondCallback)214 TEST(CallbackHelpersTest, SplitOnceCallback_SecondCallback) {
215 int count = 0;
216 base::OnceCallback<void(int*)> cb =
217 base::BindOnce([](int* count) { ++*count; });
218
219 auto split = base::SplitOnceCallback(std::move(cb));
220
221 static_assert(std::is_same<decltype(split),
222 std::pair<base::OnceCallback<void(int*)>,
223 base::OnceCallback<void(int*)>>>::value,
224 "");
225
226 EXPECT_EQ(0, count);
227 std::move(split.second).Run(&count);
228 EXPECT_EQ(1, count);
229
230 EXPECT_CHECK_DEATH(std::move(split.first).Run(&count));
231 }
232
TEST(CallbackHelpersTest,SplitSplitOnceCallback_FirstSplit)233 TEST(CallbackHelpersTest, SplitSplitOnceCallback_FirstSplit) {
234 int count = 0;
235 base::OnceCallback<void(int*)> cb =
236 base::BindOnce([](int* count) { ++*count; });
237
238 auto split = base::SplitOnceCallback(std::move(cb));
239 base::OnceCallback<void(int*)> cb1 = std::move(split.first);
240 split = base::SplitOnceCallback(std::move(split.second));
241 base::OnceCallback<void(int*)> cb2 = std::move(split.first);
242 base::OnceCallback<void(int*)> cb3 = std::move(split.second);
243
244 EXPECT_EQ(0, count);
245 std::move(cb1).Run(&count);
246 EXPECT_EQ(1, count);
247
248 EXPECT_CHECK_DEATH(std::move(cb3).Run(&count));
249 }
250
TEST(CallbackHelpersTest,SplitSplitOnceCallback_SecondSplit)251 TEST(CallbackHelpersTest, SplitSplitOnceCallback_SecondSplit) {
252 int count = 0;
253 base::OnceCallback<void(int*)> cb =
254 base::BindOnce([](int* count) { ++*count; });
255
256 auto split = base::SplitOnceCallback(std::move(cb));
257 base::OnceCallback<void(int*)> cb1 = std::move(split.first);
258 split = base::SplitOnceCallback(std::move(split.second));
259 base::OnceCallback<void(int*)> cb2 = std::move(split.first);
260 base::OnceCallback<void(int*)> cb3 = std::move(split.second);
261
262 EXPECT_EQ(0, count);
263 std::move(cb2).Run(&count);
264 EXPECT_EQ(1, count);
265
266 EXPECT_CHECK_DEATH(std::move(cb1).Run(&count));
267 }
268
TEST(CallbackHelpersTest,IgnoreArgs)269 TEST(CallbackHelpersTest, IgnoreArgs) {
270 int count = 0;
271 base::RepeatingClosure repeating_closure =
272 base::BindRepeating(&Increment, &count);
273 base::OnceClosure once_closure = base::BindOnce(&Increment, &count);
274
275 base::RepeatingCallback<void(int)> repeating_int_cb =
276 base::IgnoreArgs<int>(repeating_closure);
277 EXPECT_EQ(0, count);
278 repeating_int_cb.Run(42);
279 EXPECT_EQ(1, count);
280 repeating_int_cb.Run(42);
281 EXPECT_EQ(2, count);
282
283 base::OnceCallback<void(int)> once_int_cb =
284 base::IgnoreArgs<int>(std::move(once_closure));
285 EXPECT_EQ(2, count);
286 std::move(once_int_cb).Run(42);
287 EXPECT_EQ(3, count);
288 }
289
TEST(CallbackHelpersTest,IgnoreArgs_EmptyCallback)290 TEST(CallbackHelpersTest, IgnoreArgs_EmptyCallback) {
291 base::RepeatingCallback<void(int)> repeating_int_cb =
292 base::IgnoreArgs<int>(base::RepeatingClosure());
293 EXPECT_FALSE(repeating_int_cb);
294
295 base::OnceCallback<void(int)> once_int_cb =
296 base::IgnoreArgs<int>(base::OnceClosure());
297 EXPECT_FALSE(once_int_cb);
298 }
299
300 } // namespace
301