xref: /aosp_15_r20/external/cronet/base/test/rectify_callback_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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