1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/test/rectify_callback.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <sstream>
8*6777b538SAndroid Build Coastguard Worker #include <utility>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_forward.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
15*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker namespace base {
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Worker // Test rectifying functions with no return value.
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker #define CALLBACK_TESTS_VOID(TestNameSuffix, Signature, LambdaToRectify, ...) \
22*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, RepeatingCallbackSignatureVoid##TestNameSuffix) { \
23*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<Signature>(BindRepeating(LambdaToRectify)); \
24*6777b538SAndroid Build Coastguard Worker cb.Run(__VA_ARGS__); \
25*6777b538SAndroid Build Coastguard Worker } \
26*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, RepeatingCallbackTypeVoid##TestNameSuffix) { \
27*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<RepeatingCallback<Signature>>( \
28*6777b538SAndroid Build Coastguard Worker BindRepeating(LambdaToRectify)); \
29*6777b538SAndroid Build Coastguard Worker cb.Run(__VA_ARGS__); \
30*6777b538SAndroid Build Coastguard Worker } \
31*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, RepeatingToOnceVoid##TestNameSuffix) { \
32*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<OnceCallback<Signature>>( \
33*6777b538SAndroid Build Coastguard Worker BindRepeating(LambdaToRectify)); \
34*6777b538SAndroid Build Coastguard Worker std::move(cb).Run(__VA_ARGS__); \
35*6777b538SAndroid Build Coastguard Worker } \
36*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, OnceCallbackSignatureVoid##TestNameSuffix) { \
37*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<Signature>(BindOnce(LambdaToRectify)); \
38*6777b538SAndroid Build Coastguard Worker std::move(cb).Run(__VA_ARGS__); \
39*6777b538SAndroid Build Coastguard Worker } \
40*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, OnceCallbackTypeVoid##TestNameSuffix) { \
41*6777b538SAndroid Build Coastguard Worker auto cb = \
42*6777b538SAndroid Build Coastguard Worker RectifyCallback<OnceCallback<Signature>>(BindOnce(LambdaToRectify)); \
43*6777b538SAndroid Build Coastguard Worker std::move(cb).Run(__VA_ARGS__); \
44*6777b538SAndroid Build Coastguard Worker }
45*6777b538SAndroid Build Coastguard Worker
__anon8df38ecf0102() 46*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_VOID(NoArgsSameSignature, void(), []() {})
47*6777b538SAndroid Build Coastguard Worker
48*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_VOID(
49*6777b538SAndroid Build Coastguard Worker OneArgRemoveOneArg,
50*6777b538SAndroid Build Coastguard Worker void(int),
__anon8df38ecf0202() 51*6777b538SAndroid Build Coastguard Worker []() {},
52*6777b538SAndroid Build Coastguard Worker 1)
53*6777b538SAndroid Build Coastguard Worker
54*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_VOID(
55*6777b538SAndroid Build Coastguard Worker TwoArgsRemoveTwoArgs,
56*6777b538SAndroid Build Coastguard Worker void(float, int),
__anon8df38ecf0302() 57*6777b538SAndroid Build Coastguard Worker []() {},
58*6777b538SAndroid Build Coastguard Worker 0.25f,
59*6777b538SAndroid Build Coastguard Worker 1)
60*6777b538SAndroid Build Coastguard Worker
61*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_VOID(
62*6777b538SAndroid Build Coastguard Worker OneArgSameSignature,
63*6777b538SAndroid Build Coastguard Worker void(int),
__anon8df38ecf0402(int x) 64*6777b538SAndroid Build Coastguard Worker [](int x) { EXPECT_EQ(1, x); },
65*6777b538SAndroid Build Coastguard Worker 1)
66*6777b538SAndroid Build Coastguard Worker
67*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_VOID(
68*6777b538SAndroid Build Coastguard Worker TwoArgsRemoveOneArg,
69*6777b538SAndroid Build Coastguard Worker void(float, int),
__anon8df38ecf0502(int x) 70*6777b538SAndroid Build Coastguard Worker [](int x) { EXPECT_EQ(1, x); },
71*6777b538SAndroid Build Coastguard Worker 0.25f,
72*6777b538SAndroid Build Coastguard Worker 1)
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_VOID(
75*6777b538SAndroid Build Coastguard Worker ThreeArgsRemoveTwoArgs,
76*6777b538SAndroid Build Coastguard Worker void(bool, float, int),
__anon8df38ecf0602(int x) 77*6777b538SAndroid Build Coastguard Worker [](int x) { EXPECT_EQ(1, x); },
78*6777b538SAndroid Build Coastguard Worker true,
79*6777b538SAndroid Build Coastguard Worker 0.25f,
80*6777b538SAndroid Build Coastguard Worker 1)
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker // Test rectifying functions that do return a value.
83*6777b538SAndroid Build Coastguard Worker
84*6777b538SAndroid Build Coastguard Worker #define CALLBACK_TESTS_RETURN(TestNameSuffix, Signature, LambdaToRectify, \
85*6777b538SAndroid Build Coastguard Worker ExpectedReturn, ...) \
86*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, \
87*6777b538SAndroid Build Coastguard Worker RepeatingCallbackSignatureReturn##TestNameSuffix) { \
88*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<Signature>(BindRepeating(LambdaToRectify)); \
89*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ExpectedReturn, cb.Run(__VA_ARGS__)); \
90*6777b538SAndroid Build Coastguard Worker } \
91*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, RepeatingCallbackTypeReturn##TestNameSuffix) { \
92*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<RepeatingCallback<Signature>>( \
93*6777b538SAndroid Build Coastguard Worker BindRepeating(LambdaToRectify)); \
94*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ExpectedReturn, cb.Run(__VA_ARGS__)); \
95*6777b538SAndroid Build Coastguard Worker } \
96*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, RepeatingToOnceReturn##TestNameSuffix) { \
97*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<OnceCallback<Signature>>( \
98*6777b538SAndroid Build Coastguard Worker BindRepeating(LambdaToRectify)); \
99*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ExpectedReturn, std::move(cb).Run(__VA_ARGS__)); \
100*6777b538SAndroid Build Coastguard Worker } \
101*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, OnceCallbackSignatureReturn##TestNameSuffix) { \
102*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<Signature>(BindOnce(LambdaToRectify)); \
103*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ExpectedReturn, std::move(cb).Run(__VA_ARGS__)); \
104*6777b538SAndroid Build Coastguard Worker } \
105*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, OnceCallbackTypeReturn##TestNameSuffix) { \
106*6777b538SAndroid Build Coastguard Worker auto cb = \
107*6777b538SAndroid Build Coastguard Worker RectifyCallback<OnceCallback<Signature>>(BindOnce(LambdaToRectify)); \
108*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ExpectedReturn, std::move(cb).Run(__VA_ARGS__)); \
109*6777b538SAndroid Build Coastguard Worker }
110*6777b538SAndroid Build Coastguard Worker
111*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_RETURN(
112*6777b538SAndroid Build Coastguard Worker NoArgsSameSignature,
113*6777b538SAndroid Build Coastguard Worker int(),
__anon8df38ecf0702() 114*6777b538SAndroid Build Coastguard Worker []() { return 2; },
115*6777b538SAndroid Build Coastguard Worker 2)
116*6777b538SAndroid Build Coastguard Worker
117*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_RETURN(
118*6777b538SAndroid Build Coastguard Worker OneArgRemoveOneArg,
119*6777b538SAndroid Build Coastguard Worker int(int),
__anon8df38ecf0802() 120*6777b538SAndroid Build Coastguard Worker []() { return 2; },
121*6777b538SAndroid Build Coastguard Worker 2,
122*6777b538SAndroid Build Coastguard Worker 1)
123*6777b538SAndroid Build Coastguard Worker
124*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_RETURN(
125*6777b538SAndroid Build Coastguard Worker TwoArgsRemoveTwoArgs,
126*6777b538SAndroid Build Coastguard Worker int(float, int),
__anon8df38ecf0902() 127*6777b538SAndroid Build Coastguard Worker []() { return 2; },
128*6777b538SAndroid Build Coastguard Worker 2,
129*6777b538SAndroid Build Coastguard Worker 0.25f,
130*6777b538SAndroid Build Coastguard Worker 1)
131*6777b538SAndroid Build Coastguard Worker
132*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_RETURN(
133*6777b538SAndroid Build Coastguard Worker OneArgSameSignature,
134*6777b538SAndroid Build Coastguard Worker int(int),
__anon8df38ecf0a02(int x) 135*6777b538SAndroid Build Coastguard Worker [](int x) { return x; },
136*6777b538SAndroid Build Coastguard Worker 2,
137*6777b538SAndroid Build Coastguard Worker 2)
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_RETURN(
140*6777b538SAndroid Build Coastguard Worker TwoArgsRemoveOneArg,
141*6777b538SAndroid Build Coastguard Worker int(float, int),
__anon8df38ecf0b02(int x) 142*6777b538SAndroid Build Coastguard Worker [](int x) { return x; },
143*6777b538SAndroid Build Coastguard Worker 2,
144*6777b538SAndroid Build Coastguard Worker 0.25f,
145*6777b538SAndroid Build Coastguard Worker 2)
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_RETURN(
148*6777b538SAndroid Build Coastguard Worker ThreeArgsRemoveTwoArgs,
149*6777b538SAndroid Build Coastguard Worker int(bool, float, int),
__anon8df38ecf0c02(int x) 150*6777b538SAndroid Build Coastguard Worker [](int x) { return x; },
151*6777b538SAndroid Build Coastguard Worker 2,
152*6777b538SAndroid Build Coastguard Worker true,
153*6777b538SAndroid Build Coastguard Worker 0.25f,
154*6777b538SAndroid Build Coastguard Worker 2)
155*6777b538SAndroid Build Coastguard Worker
156*6777b538SAndroid Build Coastguard Worker // Test proper forwarding of move-only arguments.
157*6777b538SAndroid Build Coastguard Worker
158*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_RETURN(
159*6777b538SAndroid Build Coastguard Worker DiscardsMoveOnlyArgs,
160*6777b538SAndroid Build Coastguard Worker bool(int, std::unique_ptr<int>),
__anon8df38ecf0d02() 161*6777b538SAndroid Build Coastguard Worker []() { return true; },
162*6777b538SAndroid Build Coastguard Worker true,
163*6777b538SAndroid Build Coastguard Worker 2,
164*6777b538SAndroid Build Coastguard Worker std::make_unique<int>(3))
165*6777b538SAndroid Build Coastguard Worker
166*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_RETURN(
167*6777b538SAndroid Build Coastguard Worker UsesMoveOnlyArg,
168*6777b538SAndroid Build Coastguard Worker int(float, int, std::unique_ptr<int>),
__anon8df38ecf0e02(std::unique_ptr<int> p) 169*6777b538SAndroid Build Coastguard Worker [](std::unique_ptr<int> p) { return *p; },
170*6777b538SAndroid Build Coastguard Worker 3,
171*6777b538SAndroid Build Coastguard Worker 0.25f,
172*6777b538SAndroid Build Coastguard Worker 2,
173*6777b538SAndroid Build Coastguard Worker std::make_unique<int>(3))
174*6777b538SAndroid Build Coastguard Worker
175*6777b538SAndroid Build Coastguard Worker // Test rectifying DoNothing().
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker #define CALLBACK_TESTS_DO_NOTHING(TestNameSuffix, Signature, ...) \
178*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, SignatureDoNothing##TestNameSuffix) { \
179*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<Signature>(DoNothing()); \
180*6777b538SAndroid Build Coastguard Worker cb.Run(__VA_ARGS__); \
181*6777b538SAndroid Build Coastguard Worker } \
182*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, RepeatingCallbackDoNothing##TestNameSuffix) { \
183*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<RepeatingCallback<Signature>>(DoNothing()); \
184*6777b538SAndroid Build Coastguard Worker cb.Run(__VA_ARGS__); \
185*6777b538SAndroid Build Coastguard Worker } \
186*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, OnceCallbackDoNothing##TestNameSuffix) { \
187*6777b538SAndroid Build Coastguard Worker auto cb = RectifyCallback<OnceCallback<Signature>>(DoNothing()); \
188*6777b538SAndroid Build Coastguard Worker std::move(cb).Run(__VA_ARGS__); \
189*6777b538SAndroid Build Coastguard Worker }
190*6777b538SAndroid Build Coastguard Worker
CALLBACK_TESTS_DO_NOTHING(NoArgs,void ())191*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_DO_NOTHING(NoArgs, void())
192*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_DO_NOTHING(OneArg, void(int), 2)
193*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_DO_NOTHING(TwoArgs, void(float, int), 0.25, 2)
194*6777b538SAndroid Build Coastguard Worker CALLBACK_TESTS_DO_NOTHING(ThreeArgs, void(bool, float, int), false, 0.25, 2)
195*6777b538SAndroid Build Coastguard Worker
196*6777b538SAndroid Build Coastguard Worker // Test passing callbacks to RectifyCallback() in different ways.
197*6777b538SAndroid Build Coastguard Worker
198*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, RepeatingMove) {
199*6777b538SAndroid Build Coastguard Worker auto cb = BindRepeating([](int x) { return x != 0; });
200*6777b538SAndroid Build Coastguard Worker auto cb2 = RectifyCallback<bool(float, int)>(std::move(cb));
201*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(true, cb2.Run(1.0, 1));
202*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(false, cb2.Run(1.0, 0));
203*6777b538SAndroid Build Coastguard Worker }
204*6777b538SAndroid Build Coastguard Worker
TEST(RectifyCallbackTest,RepeatingCopy)205*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, RepeatingCopy) {
206*6777b538SAndroid Build Coastguard Worker const auto cb = BindRepeating([](int x) { return x != 0; });
207*6777b538SAndroid Build Coastguard Worker auto cb2 = RectifyCallback<bool(float, int)>(cb);
208*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(true, cb2.Run(1.0, 1));
209*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(false, cb2.Run(1.0, 0));
210*6777b538SAndroid Build Coastguard Worker }
211*6777b538SAndroid Build Coastguard Worker
TEST(RectifyCallbackTest,RepeatingConstReference)212*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, RepeatingConstReference) {
213*6777b538SAndroid Build Coastguard Worker const auto cb = BindRepeating([](int x) { return x != 0; });
214*6777b538SAndroid Build Coastguard Worker const auto& cb_ref = cb;
215*6777b538SAndroid Build Coastguard Worker auto cb2 = RectifyCallback<bool(float, int)>(cb_ref);
216*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(true, cb2.Run(1.0, 1));
217*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(false, cb2.Run(1.0, 0));
218*6777b538SAndroid Build Coastguard Worker }
219*6777b538SAndroid Build Coastguard Worker
TEST(RectifyCallbackTest,OnceMove)220*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, OnceMove) {
221*6777b538SAndroid Build Coastguard Worker auto cb = BindOnce([](int x) { return x != 0; });
222*6777b538SAndroid Build Coastguard Worker auto cb2 = RectifyCallback<bool(float, int)>(std::move(cb));
223*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(true, std::move(cb2).Run(1.0, 1));
224*6777b538SAndroid Build Coastguard Worker }
225*6777b538SAndroid Build Coastguard Worker
TEST(RectifyCallbackTest,OnceFromRepeating)226*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, OnceFromRepeating) {
227*6777b538SAndroid Build Coastguard Worker auto cb = BindRepeating([](int x) { return x != 0; });
228*6777b538SAndroid Build Coastguard Worker auto cb2 = RectifyCallback<OnceCallback<bool(float, int)>>(std::move(cb));
229*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(true, std::move(cb2).Run(1.0, 1));
230*6777b538SAndroid Build Coastguard Worker }
231*6777b538SAndroid Build Coastguard Worker
232*6777b538SAndroid Build Coastguard Worker // Test that we can write a function that can rectify its callback argument into
233*6777b538SAndroid Build Coastguard Worker // the signature it wants.
234*6777b538SAndroid Build Coastguard Worker //
235*6777b538SAndroid Build Coastguard Worker // If this is implemented incorrectly, it can result in strange/bad behavior,
236*6777b538SAndroid Build Coastguard Worker // even if it manages to compile.
237*6777b538SAndroid Build Coastguard Worker
238*6777b538SAndroid Build Coastguard Worker namespace {
239*6777b538SAndroid Build Coastguard Worker
240*6777b538SAndroid Build Coastguard Worker using ExampleRepeatingTargetType = RepeatingCallback<bool(double, int)>;
241*6777b538SAndroid Build Coastguard Worker using ExampleOnceTargetType = OnceCallback<bool(double, int)>;
242*6777b538SAndroid Build Coastguard Worker
243*6777b538SAndroid Build Coastguard Worker // This is the call we'll be rectifying into the expected signature.
ExampleTargetFunction(int x)244*6777b538SAndroid Build Coastguard Worker bool ExampleTargetFunction(int x) {
245*6777b538SAndroid Build Coastguard Worker return x != 0;
246*6777b538SAndroid Build Coastguard Worker }
247*6777b538SAndroid Build Coastguard Worker
248*6777b538SAndroid Build Coastguard Worker // Base version of the function that takes a repeating callback.
249*6777b538SAndroid Build Coastguard Worker // This is the actual implementation.
ExampleFunctionRepeatingCallback(ExampleRepeatingTargetType callback)250*6777b538SAndroid Build Coastguard Worker void ExampleFunctionRepeatingCallback(ExampleRepeatingTargetType callback) {
251*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(true, std::move(callback).Run(1.0, 1));
252*6777b538SAndroid Build Coastguard Worker }
253*6777b538SAndroid Build Coastguard Worker
254*6777b538SAndroid Build Coastguard Worker // Template version of the function that wants a repeating callback; it will
255*6777b538SAndroid Build Coastguard Worker // rectify its input and call the base version.
256*6777b538SAndroid Build Coastguard Worker //
257*6777b538SAndroid Build Coastguard Worker // If the rectify goes awry (e.g. the wrong kind of callback is generated),
258*6777b538SAndroid Build Coastguard Worker // this can result in an infinite loop.
259*6777b538SAndroid Build Coastguard Worker template <typename T>
ExampleFunctionRepeatingCallback(T && callback)260*6777b538SAndroid Build Coastguard Worker void ExampleFunctionRepeatingCallback(T&& callback) {
261*6777b538SAndroid Build Coastguard Worker ExampleFunctionRepeatingCallback(
262*6777b538SAndroid Build Coastguard Worker RectifyCallback<ExampleRepeatingTargetType>(std::forward<T>(callback)));
263*6777b538SAndroid Build Coastguard Worker }
264*6777b538SAndroid Build Coastguard Worker
265*6777b538SAndroid Build Coastguard Worker // Base version of the function that takes a once callback.
266*6777b538SAndroid Build Coastguard Worker // This is the actual implementation.
ExampleFunctionOnceCallback(ExampleOnceTargetType callback)267*6777b538SAndroid Build Coastguard Worker void ExampleFunctionOnceCallback(ExampleOnceTargetType callback) {
268*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(true, std::move(callback).Run(1.0, 1));
269*6777b538SAndroid Build Coastguard Worker }
270*6777b538SAndroid Build Coastguard Worker
271*6777b538SAndroid Build Coastguard Worker // Template version of the function that wants a once callback; it will
272*6777b538SAndroid Build Coastguard Worker // rectify its input and call the base version.
273*6777b538SAndroid Build Coastguard Worker //
274*6777b538SAndroid Build Coastguard Worker // If the rectify goes awry (e.g. the wrong kind of callback is generated),
275*6777b538SAndroid Build Coastguard Worker // this can result in an infinite loop.
276*6777b538SAndroid Build Coastguard Worker template <typename T>
ExampleFunctionOnceCallback(T && callback)277*6777b538SAndroid Build Coastguard Worker void ExampleFunctionOnceCallback(T&& callback) {
278*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(
279*6777b538SAndroid Build Coastguard Worker RectifyCallback<ExampleOnceTargetType>(std::forward<T>(callback)));
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker
282*6777b538SAndroid Build Coastguard Worker } // namespace
283*6777b538SAndroid Build Coastguard Worker
TEST(RectifyCallbackTest,TemplateOverloadRectifiesOnceCallback)284*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, TemplateOverloadRectifiesOnceCallback) {
285*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(BindOnce(&ExampleTargetFunction));
286*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(BindOnce([]() { return true; }));
287*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(BindOnce([](double d, int i) { return d && i; }));
288*6777b538SAndroid Build Coastguard Worker auto cb = BindOnce(&ExampleTargetFunction);
289*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(std::move(cb));
290*6777b538SAndroid Build Coastguard Worker }
291*6777b538SAndroid Build Coastguard Worker
TEST(RectifyCallbackTest,TemplateOverloadRectifiesRepeatingCallback)292*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, TemplateOverloadRectifiesRepeatingCallback) {
293*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(BindRepeating(&ExampleTargetFunction));
294*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(BindRepeating([]() { return true; }));
295*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(
296*6777b538SAndroid Build Coastguard Worker BindRepeating([](double d, int i) { return d && i; }));
297*6777b538SAndroid Build Coastguard Worker auto cb = BindRepeating(&ExampleTargetFunction);
298*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(cb);
299*6777b538SAndroid Build Coastguard Worker bool result = true;
300*6777b538SAndroid Build Coastguard Worker ExampleFunctionOnceCallback(BindLambdaForTesting([&]() { return result; }));
301*6777b538SAndroid Build Coastguard Worker }
302*6777b538SAndroid Build Coastguard Worker
TEST(RectifyCallbackTest,TemplateOverloadCoerceRepeatingTarget)303*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, TemplateOverloadCoerceRepeatingTarget) {
304*6777b538SAndroid Build Coastguard Worker ExampleFunctionRepeatingCallback(BindRepeating(&ExampleTargetFunction));
305*6777b538SAndroid Build Coastguard Worker ExampleFunctionRepeatingCallback(BindRepeating([]() { return true; }));
306*6777b538SAndroid Build Coastguard Worker ExampleFunctionRepeatingCallback(
307*6777b538SAndroid Build Coastguard Worker BindRepeating([](double d, int i) { return d && i; }));
308*6777b538SAndroid Build Coastguard Worker auto cb = BindRepeating(&ExampleTargetFunction);
309*6777b538SAndroid Build Coastguard Worker ExampleFunctionRepeatingCallback(cb);
310*6777b538SAndroid Build Coastguard Worker bool result = true;
311*6777b538SAndroid Build Coastguard Worker ExampleFunctionRepeatingCallback(
312*6777b538SAndroid Build Coastguard Worker BindLambdaForTesting([&]() { return result; }));
313*6777b538SAndroid Build Coastguard Worker }
314*6777b538SAndroid Build Coastguard Worker
TEST(RectifyCallbackTest,NullCallbackPassthrough)315*6777b538SAndroid Build Coastguard Worker TEST(RectifyCallbackTest, NullCallbackPassthrough) {
316*6777b538SAndroid Build Coastguard Worker {
317*6777b538SAndroid Build Coastguard Worker OnceCallback<void()> once;
318*6777b538SAndroid Build Coastguard Worker RepeatingCallback<void()> repeating;
319*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(RectifyCallback<void()>(std::move(once)).is_null());
320*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(RectifyCallback<void()>(repeating).is_null());
321*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(RectifyCallback<void()>(NullCallback()).is_null());
322*6777b538SAndroid Build Coastguard Worker }
323*6777b538SAndroid Build Coastguard Worker
324*6777b538SAndroid Build Coastguard Worker {
325*6777b538SAndroid Build Coastguard Worker OnceCallback<void()> once;
326*6777b538SAndroid Build Coastguard Worker RepeatingCallback<void()> repeating;
327*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(RectifyCallback<void(int)>(std::move(once)).is_null());
328*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(RectifyCallback<void(int)>(repeating).is_null());
329*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(RectifyCallback<void(int)>(NullCallback()).is_null());
330*6777b538SAndroid Build Coastguard Worker }
331*6777b538SAndroid Build Coastguard Worker }
332*6777b538SAndroid Build Coastguard Worker
333*6777b538SAndroid Build Coastguard Worker } // namespace base
334