1 // Copyright 2013 The Chromium Authors. All rights reserved.
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/callback_helpers.h"
10 #include "base/bind.h"
11 #include "base/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 TEST(CallbackHelpersTest, ScopedClosureRunnerHasClosure) {
89 base::ScopedClosureRunner runner1;
90 EXPECT_FALSE(runner1);
92 base::ScopedClosureRunner runner2{base::DoNothing()};
96 TEST(CallbackHelpersTest, ScopedClosureRunnerExitScope) {
99 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
100 EXPECT_EQ(0, run_count);
102 EXPECT_EQ(1, run_count);
105 TEST(CallbackHelpersTest, ScopedClosureRunnerRelease) {
109 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count));
110 c = runner.Release();
111 EXPECT_EQ(0, run_count);
113 EXPECT_EQ(0, run_count);
115 EXPECT_EQ(1, run_count);
118 TEST(CallbackHelpersTest, ScopedClosureRunnerReplaceClosure) {
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);
128 EXPECT_EQ(0, run_count_1);
129 EXPECT_EQ(1, run_count_2);
132 TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNonNull) {
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);
140 EXPECT_EQ(1, run_count_3);
143 TEST(CallbackHelpersTest, ScopedClosureRunnerRunAndResetNull) {
144 base::ScopedClosureRunner runner;
145 runner.RunAndReset(); // Should not crash.
148 TEST(CallbackHelpersTest, ScopedClosureRunnerMoveConstructor) {
151 std::unique_ptr<base::ScopedClosureRunner> runner(
152 new base::ScopedClosureRunner(base::BindOnce(&Increment, &run_count)));
153 base::ScopedClosureRunner runner2(std::move(*runner));
155 EXPECT_EQ(0, run_count);
157 EXPECT_EQ(1, run_count);
160 TEST(CallbackHelpersTest, ScopedClosureRunnerMoveAssignment) {
164 base::ScopedClosureRunner runner(base::BindOnce(&Increment, &run_count_1));
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);
172 EXPECT_EQ(1, run_count_1);
173 EXPECT_EQ(0, run_count_2);
175 EXPECT_EQ(1, run_count_1);
176 EXPECT_EQ(1, run_count_2);
179 TEST(CallbackHelpersTest, SplitOnceCallback_EmptyCallback) {
180 base::OnceCallback<void(int*)> cb = base::NullCallback();
183 auto split = base::SplitOnceCallback(std::move(cb));
185 static_assert(std::is_same<decltype(split),
186 std::pair<base::OnceCallback<void(int*)>,
187 base::OnceCallback<void(int*)>>>::value,
189 EXPECT_FALSE(split.first);
190 EXPECT_FALSE(split.second);
193 TEST(CallbackHelpersTest, SplitOnceCallback_FirstCallback) {
195 base::OnceCallback<void(int*)> cb =
196 base::BindOnce([](int* count) { ++*count; });
198 auto split = base::SplitOnceCallback(std::move(cb));
200 static_assert(std::is_same<decltype(split),
201 std::pair<base::OnceCallback<void(int*)>,
202 base::OnceCallback<void(int*)>>>::value,
206 std::move(split.first).Run(&count);
209 #if GTEST_HAS_DEATH_TEST
210 EXPECT_CHECK_DEATH(std::move(split.second).Run(&count));
211 #endif // GTEST_HAS_DEATH_TEST
214 TEST(CallbackHelpersTest, SplitOnceCallback_SecondCallback) {
216 base::OnceCallback<void(int*)> cb =
217 base::BindOnce([](int* count) { ++*count; });
219 auto split = base::SplitOnceCallback(std::move(cb));
221 static_assert(std::is_same<decltype(split),
222 std::pair<base::OnceCallback<void(int*)>,
223 base::OnceCallback<void(int*)>>>::value,
227 std::move(split.second).Run(&count);
230 EXPECT_CHECK_DEATH(std::move(split.first).Run(&count));
233 TEST(CallbackHelpersTest, SplitSplitOnceCallback_FirstSplit) {
235 base::OnceCallback<void(int*)> cb =
236 base::BindOnce([](int* count) { ++*count; });
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);
245 std::move(cb1).Run(&count);
248 EXPECT_CHECK_DEATH(std::move(cb3).Run(&count));
251 TEST(CallbackHelpersTest, SplitSplitOnceCallback_SecondSplit) {
253 base::OnceCallback<void(int*)> cb =
254 base::BindOnce([](int* count) { ++*count; });
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);
263 std::move(cb2).Run(&count);
266 EXPECT_CHECK_DEATH(std::move(cb1).Run(&count));