• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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