xref: /aosp_15_r20/external/google-fruit/tests/test_register_factory.py (revision a65addddcf69f38db5b288d787b6b7571a57bb8f)
1*a65addddSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*a65addddSAndroid Build Coastguard Worker#  Copyright 2016 Google Inc. All Rights Reserved.
3*a65addddSAndroid Build Coastguard Worker#
4*a65addddSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
5*a65addddSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
6*a65addddSAndroid Build Coastguard Worker# You may obtain a copy of the License at
7*a65addddSAndroid Build Coastguard Worker#
8*a65addddSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
9*a65addddSAndroid Build Coastguard Worker#
10*a65addddSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*a65addddSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS-IS" BASIS,
12*a65addddSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*a65addddSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
14*a65addddSAndroid Build Coastguard Worker# limitations under the License.
15*a65addddSAndroid Build Coastguard Workerimport pytest
16*a65addddSAndroid Build Coastguard Workerfrom absl.testing import parameterized
17*a65addddSAndroid Build Coastguard Workerfrom fruit_test_common import *
18*a65addddSAndroid Build Coastguard Workerfrom fruit_test_config import CXX_COMPILER_NAME
19*a65addddSAndroid Build Coastguard Worker
20*a65addddSAndroid Build Coastguard WorkerCOMMON_DEFINITIONS = '''
21*a65addddSAndroid Build Coastguard Worker    #include "test_common.h"
22*a65addddSAndroid Build Coastguard Worker
23*a65addddSAndroid Build Coastguard Worker    struct Scaler;
24*a65addddSAndroid Build Coastguard Worker    struct ScalerImpl;
25*a65addddSAndroid Build Coastguard Worker
26*a65addddSAndroid Build Coastguard Worker    struct Annotation1 {};
27*a65addddSAndroid Build Coastguard Worker    using ScalerAnnot1 = fruit::Annotated<Annotation1, Scaler>;
28*a65addddSAndroid Build Coastguard Worker    using ScalerImplAnnot1 = fruit::Annotated<Annotation1, ScalerImpl>;
29*a65addddSAndroid Build Coastguard Worker
30*a65addddSAndroid Build Coastguard Worker    struct Annotation2 {};
31*a65addddSAndroid Build Coastguard Worker    using ScalerAnnot2 = fruit::Annotated<Annotation2, Scaler>;
32*a65addddSAndroid Build Coastguard Worker    using ScalerImplAnnot2 = fruit::Annotated<Annotation2, ScalerImpl>;
33*a65addddSAndroid Build Coastguard Worker
34*a65addddSAndroid Build Coastguard Worker    template <typename T>
35*a65addddSAndroid Build Coastguard Worker    using WithNoAnnotation = T;
36*a65addddSAndroid Build Coastguard Worker
37*a65addddSAndroid Build Coastguard Worker    template <typename T>
38*a65addddSAndroid Build Coastguard Worker    using WithAnnotation1 = fruit::Annotated<Annotation1, T>;
39*a65addddSAndroid Build Coastguard Worker    '''
40*a65addddSAndroid Build Coastguard Worker
41*a65addddSAndroid Build Coastguard Workerclass TestRegisterFactory(parameterized.TestCase):
42*a65addddSAndroid Build Coastguard Worker
43*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
44*a65addddSAndroid Build Coastguard Worker        'std::function<X()>',
45*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, std::function<X()>>',
46*a65addddSAndroid Build Coastguard Worker    ])
47*a65addddSAndroid Build Coastguard Worker    def test_register_factory_success_no_params_autoinject(self, XFactoryAnnot):
48*a65addddSAndroid Build Coastguard Worker        source = '''
49*a65addddSAndroid Build Coastguard Worker            struct X {
50*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
51*a65addddSAndroid Build Coastguard Worker            };
52*a65addddSAndroid Build Coastguard Worker
53*a65addddSAndroid Build Coastguard Worker            fruit::Component<XFactoryAnnot> getComponent() {
54*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
55*a65addddSAndroid Build Coastguard Worker            }
56*a65addddSAndroid Build Coastguard Worker
57*a65addddSAndroid Build Coastguard Worker            int main() {
58*a65addddSAndroid Build Coastguard Worker              fruit::Injector<XFactoryAnnot> injector(getComponent);
59*a65addddSAndroid Build Coastguard Worker              injector.get<XFactoryAnnot>()();
60*a65addddSAndroid Build Coastguard Worker            }
61*a65addddSAndroid Build Coastguard Worker            '''
62*a65addddSAndroid Build Coastguard Worker        expect_success(
63*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
64*a65addddSAndroid Build Coastguard Worker            source,
65*a65addddSAndroid Build Coastguard Worker            locals())
66*a65addddSAndroid Build Coastguard Worker
67*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
68*a65addddSAndroid Build Coastguard Worker        ('X()', 'X', 'std::function<X()>'),
69*a65addddSAndroid Build Coastguard Worker        ('X()', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, std::function<X()>>'),
70*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>()', 'std::unique_ptr<X>', 'std::function<std::unique_ptr<X>()>'),
71*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>()', 'fruit::Annotated<Annotation1, std::unique_ptr<X>>', 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>'),
72*a65addddSAndroid Build Coastguard Worker    ])
73*a65addddSAndroid Build Coastguard Worker    def test_register_factory_success_no_params(self, ConstructX, XPtrAnnot, XPtrFactoryAnnot):
74*a65addddSAndroid Build Coastguard Worker        source = '''
75*a65addddSAndroid Build Coastguard Worker            struct X {};
76*a65addddSAndroid Build Coastguard Worker
77*a65addddSAndroid Build Coastguard Worker            fruit::Component<XPtrFactoryAnnot> getComponent() {
78*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
79*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtrAnnot()>([](){return ConstructX;});
80*a65addddSAndroid Build Coastguard Worker            }
81*a65addddSAndroid Build Coastguard Worker
82*a65addddSAndroid Build Coastguard Worker            int main() {
83*a65addddSAndroid Build Coastguard Worker              fruit::Injector<XPtrFactoryAnnot> injector(getComponent);
84*a65addddSAndroid Build Coastguard Worker              injector.get<XPtrFactoryAnnot>()();
85*a65addddSAndroid Build Coastguard Worker            }
86*a65addddSAndroid Build Coastguard Worker            '''
87*a65addddSAndroid Build Coastguard Worker        expect_success(
88*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
89*a65addddSAndroid Build Coastguard Worker            source,
90*a65addddSAndroid Build Coastguard Worker            locals())
91*a65addddSAndroid Build Coastguard Worker
92*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
93*a65addddSAndroid Build Coastguard Worker        '',
94*a65addddSAndroid Build Coastguard Worker        'const',
95*a65addddSAndroid Build Coastguard Worker    ])
96*a65addddSAndroid Build Coastguard Worker    def test_register_factory_autoinject_success(self, MaybeConst):
97*a65addddSAndroid Build Coastguard Worker        source = '''
98*a65addddSAndroid Build Coastguard Worker            struct Scaler {
99*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
100*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
101*a65addddSAndroid Build Coastguard Worker            };
102*a65addddSAndroid Build Coastguard Worker
103*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
104*a65addddSAndroid Build Coastguard Worker            private:
105*a65addddSAndroid Build Coastguard Worker              double factor;
106*a65addddSAndroid Build Coastguard Worker
107*a65addddSAndroid Build Coastguard Worker            public:
108*a65addddSAndroid Build Coastguard Worker              INJECT(ScalerImpl(ASSISTED(double) factor))
109*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
110*a65addddSAndroid Build Coastguard Worker              }
111*a65addddSAndroid Build Coastguard Worker
112*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
113*a65addddSAndroid Build Coastguard Worker                return x * factor;
114*a65addddSAndroid Build Coastguard Worker              }
115*a65addddSAndroid Build Coastguard Worker            };
116*a65addddSAndroid Build Coastguard Worker
117*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
118*a65addddSAndroid Build Coastguard Worker
119*a65addddSAndroid Build Coastguard Worker            fruit::Component<MaybeConst ScalerFactory> getScalerComponent() {
120*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
121*a65addddSAndroid Build Coastguard Worker                .bind<Scaler, ScalerImpl>();
122*a65addddSAndroid Build Coastguard Worker            }
123*a65addddSAndroid Build Coastguard Worker
124*a65addddSAndroid Build Coastguard Worker            int main() {
125*a65addddSAndroid Build Coastguard Worker              fruit::Injector<MaybeConst ScalerFactory> injector(getScalerComponent);
126*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
127*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
128*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
129*a65addddSAndroid Build Coastguard Worker            }
130*a65addddSAndroid Build Coastguard Worker            '''
131*a65addddSAndroid Build Coastguard Worker        expect_success(
132*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
133*a65addddSAndroid Build Coastguard Worker            source,
134*a65addddSAndroid Build Coastguard Worker            locals())
135*a65addddSAndroid Build Coastguard Worker
136*a65addddSAndroid Build Coastguard Worker    def test_register_factory_autoinject_abstract_class_with_no_virtual_destructor_error(self):
137*a65addddSAndroid Build Coastguard Worker        source = '''
138*a65addddSAndroid Build Coastguard Worker            struct Scaler {
139*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
140*a65addddSAndroid Build Coastguard Worker            };
141*a65addddSAndroid Build Coastguard Worker
142*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
143*a65addddSAndroid Build Coastguard Worker            public:
144*a65addddSAndroid Build Coastguard Worker              INJECT(ScalerImpl(ASSISTED(double))) {
145*a65addddSAndroid Build Coastguard Worker              }
146*a65addddSAndroid Build Coastguard Worker
147*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
148*a65addddSAndroid Build Coastguard Worker                return x;
149*a65addddSAndroid Build Coastguard Worker              }
150*a65addddSAndroid Build Coastguard Worker            };
151*a65addddSAndroid Build Coastguard Worker
152*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
153*a65addddSAndroid Build Coastguard Worker
154*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
155*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
156*a65addddSAndroid Build Coastguard Worker                .bind<Scaler, ScalerImpl>();
157*a65addddSAndroid Build Coastguard Worker            }
158*a65addddSAndroid Build Coastguard Worker            '''
159*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
160*a65addddSAndroid Build Coastguard Worker            r'FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError<std::function<std::unique_ptr<Scaler(,std::default_delete<Scaler>)?>\(double\)>,std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>>',
161*a65addddSAndroid Build Coastguard Worker            r'Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr of a class with no virtual destructor',
162*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
163*a65addddSAndroid Build Coastguard Worker            source,
164*a65addddSAndroid Build Coastguard Worker            locals())
165*a65addddSAndroid Build Coastguard Worker
166*a65addddSAndroid Build Coastguard Worker    def test_register_factory_autoinject_non_abstract_class_with_no_virtual_destructor_error(self):
167*a65addddSAndroid Build Coastguard Worker        source = '''
168*a65addddSAndroid Build Coastguard Worker            struct Scaler {
169*a65addddSAndroid Build Coastguard Worker            };
170*a65addddSAndroid Build Coastguard Worker
171*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
172*a65addddSAndroid Build Coastguard Worker            public:
173*a65addddSAndroid Build Coastguard Worker              INJECT(ScalerImpl(ASSISTED(double))) {
174*a65addddSAndroid Build Coastguard Worker              }
175*a65addddSAndroid Build Coastguard Worker            };
176*a65addddSAndroid Build Coastguard Worker
177*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
178*a65addddSAndroid Build Coastguard Worker
179*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
180*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
181*a65addddSAndroid Build Coastguard Worker                .bind<Scaler, ScalerImpl>();
182*a65addddSAndroid Build Coastguard Worker            }
183*a65addddSAndroid Build Coastguard Worker            '''
184*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
185*a65addddSAndroid Build Coastguard Worker            r'FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError<std::function<std::unique_ptr<Scaler(,std::default_delete<Scaler>)?>\(double\)>,std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>>',
186*a65addddSAndroid Build Coastguard Worker            r'Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr of a class with no virtual destructor',
187*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
188*a65addddSAndroid Build Coastguard Worker            source,
189*a65addddSAndroid Build Coastguard Worker            locals())
190*a65addddSAndroid Build Coastguard Worker
191*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
192*a65addddSAndroid Build Coastguard Worker        ('Scaler',
193*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>',
194*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>'),
195*a65addddSAndroid Build Coastguard Worker        ('Scaler',
196*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>',
197*a65addddSAndroid Build Coastguard Worker         'const std::function<std::unique_ptr<Scaler>(double)>'),
198*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
199*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>',
200*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>'),
201*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
202*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>',
203*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, const std::function<std::unique_ptr<Scaler>(double)>>'),
204*a65addddSAndroid Build Coastguard Worker    ])
205*a65addddSAndroid Build Coastguard Worker    def test_autoinject(self, ScalerAnnot, ScalerFactoryAnnot, MaybeConstScalerFactoryAnnot):
206*a65addddSAndroid Build Coastguard Worker        source = '''
207*a65addddSAndroid Build Coastguard Worker            struct Scaler {
208*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
209*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
210*a65addddSAndroid Build Coastguard Worker            };
211*a65addddSAndroid Build Coastguard Worker
212*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
213*a65addddSAndroid Build Coastguard Worker            private:
214*a65addddSAndroid Build Coastguard Worker              double factor;
215*a65addddSAndroid Build Coastguard Worker
216*a65addddSAndroid Build Coastguard Worker            public:
217*a65addddSAndroid Build Coastguard Worker              INJECT(ScalerImpl(ASSISTED(double) factor))
218*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
219*a65addddSAndroid Build Coastguard Worker              }
220*a65addddSAndroid Build Coastguard Worker
221*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
222*a65addddSAndroid Build Coastguard Worker                return x * factor;
223*a65addddSAndroid Build Coastguard Worker              }
224*a65addddSAndroid Build Coastguard Worker            };
225*a65addddSAndroid Build Coastguard Worker
226*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
227*a65addddSAndroid Build Coastguard Worker
228*a65addddSAndroid Build Coastguard Worker            fruit::Component<MaybeConstScalerFactoryAnnot> getScalerComponent() {
229*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
230*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot, ScalerImpl>();
231*a65addddSAndroid Build Coastguard Worker            }
232*a65addddSAndroid Build Coastguard Worker
233*a65addddSAndroid Build Coastguard Worker            int main() {
234*a65addddSAndroid Build Coastguard Worker              fruit::Injector<MaybeConstScalerFactoryAnnot> injector(getScalerComponent);
235*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
236*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
237*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
238*a65addddSAndroid Build Coastguard Worker            }
239*a65addddSAndroid Build Coastguard Worker            '''
240*a65addddSAndroid Build Coastguard Worker        expect_success(
241*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
242*a65addddSAndroid Build Coastguard Worker            source,
243*a65addddSAndroid Build Coastguard Worker            locals())
244*a65addddSAndroid Build Coastguard Worker
245*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
246*a65addddSAndroid Build Coastguard Worker        '',
247*a65addddSAndroid Build Coastguard Worker        'const',
248*a65addddSAndroid Build Coastguard Worker    ])
249*a65addddSAndroid Build Coastguard Worker    def test_autoinject_returning_value(self, MaybeConst):
250*a65addddSAndroid Build Coastguard Worker        source = '''
251*a65addddSAndroid Build Coastguard Worker            struct X {
252*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
253*a65addddSAndroid Build Coastguard Worker            };
254*a65addddSAndroid Build Coastguard Worker
255*a65addddSAndroid Build Coastguard Worker            struct Scaler {
256*a65addddSAndroid Build Coastguard Worker            private:
257*a65addddSAndroid Build Coastguard Worker              double factor;
258*a65addddSAndroid Build Coastguard Worker
259*a65addddSAndroid Build Coastguard Worker            public:
260*a65addddSAndroid Build Coastguard Worker              INJECT(Scaler(ASSISTED(double) factor, X))
261*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
262*a65addddSAndroid Build Coastguard Worker              }
263*a65addddSAndroid Build Coastguard Worker
264*a65addddSAndroid Build Coastguard Worker              double scale(double x) {
265*a65addddSAndroid Build Coastguard Worker                return x * factor;
266*a65addddSAndroid Build Coastguard Worker              }
267*a65addddSAndroid Build Coastguard Worker            };
268*a65addddSAndroid Build Coastguard Worker
269*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<Scaler(double)>;
270*a65addddSAndroid Build Coastguard Worker
271*a65addddSAndroid Build Coastguard Worker            fruit::Component<MaybeConst ScalerFactory> getScalerComponent() {
272*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
273*a65addddSAndroid Build Coastguard Worker            }
274*a65addddSAndroid Build Coastguard Worker
275*a65addddSAndroid Build Coastguard Worker            int main() {
276*a65addddSAndroid Build Coastguard Worker              fruit::Injector<MaybeConst ScalerFactory> injector(getScalerComponent);
277*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
278*a65addddSAndroid Build Coastguard Worker              Scaler scaler = scalerFactory(12.1);
279*a65addddSAndroid Build Coastguard Worker              std::cout << scaler.scale(3) << std::endl;
280*a65addddSAndroid Build Coastguard Worker            }
281*a65addddSAndroid Build Coastguard Worker            '''
282*a65addddSAndroid Build Coastguard Worker        expect_success(
283*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
284*a65addddSAndroid Build Coastguard Worker            source,
285*a65addddSAndroid Build Coastguard Worker            locals())
286*a65addddSAndroid Build Coastguard Worker
287*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
288*a65addddSAndroid Build Coastguard Worker        ('Scaler',
289*a65addddSAndroid Build Coastguard Worker         'ScalerImpl',
290*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>',
291*a65addddSAndroid Build Coastguard Worker         r'std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>',
292*a65addddSAndroid Build Coastguard Worker         ),
293*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
294*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, ScalerImpl>',
295*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>',
296*a65addddSAndroid Build Coastguard Worker         r'fruit::Annotated<Annotation2,std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>>',
297*a65addddSAndroid Build Coastguard Worker         ),
298*a65addddSAndroid Build Coastguard Worker    ])
299*a65addddSAndroid Build Coastguard Worker    def test_autoinject_error_abstract_class(self, ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot, ScalerImplFactoryAnnotRegex):
300*a65addddSAndroid Build Coastguard Worker        source = '''
301*a65addddSAndroid Build Coastguard Worker            struct Scaler {
302*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
303*a65addddSAndroid Build Coastguard Worker            };
304*a65addddSAndroid Build Coastguard Worker
305*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
306*a65addddSAndroid Build Coastguard Worker            private:
307*a65addddSAndroid Build Coastguard Worker              double factor;
308*a65addddSAndroid Build Coastguard Worker
309*a65addddSAndroid Build Coastguard Worker            public:
310*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
311*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
312*a65addddSAndroid Build Coastguard Worker              }
313*a65addddSAndroid Build Coastguard Worker
314*a65addddSAndroid Build Coastguard Worker              // Note: here we "forgot" to implement scale() (on purpose, for this test) so ScalerImpl is an abstract class.
315*a65addddSAndroid Build Coastguard Worker            };
316*a65addddSAndroid Build Coastguard Worker
317*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
318*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
319*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot, ScalerImplAnnot>();
320*a65addddSAndroid Build Coastguard Worker            }
321*a65addddSAndroid Build Coastguard Worker            '''
322*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
323*a65addddSAndroid Build Coastguard Worker            'NoBindingFoundForAbstractClassError<ScalerImplFactoryAnnotRegex,ScalerImpl>',
324*a65addddSAndroid Build Coastguard Worker            'No explicit binding was found for T, and note that C is an abstract class',
325*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
326*a65addddSAndroid Build Coastguard Worker            source,
327*a65addddSAndroid Build Coastguard Worker            locals())
328*a65addddSAndroid Build Coastguard Worker
329*a65addddSAndroid Build Coastguard Worker    def test_autoinject_nonmovable_ok(self):
330*a65addddSAndroid Build Coastguard Worker        source = '''
331*a65addddSAndroid Build Coastguard Worker            struct I {
332*a65addddSAndroid Build Coastguard Worker              virtual ~I() = default;
333*a65addddSAndroid Build Coastguard Worker            };
334*a65addddSAndroid Build Coastguard Worker
335*a65addddSAndroid Build Coastguard Worker            struct C : public I {
336*a65addddSAndroid Build Coastguard Worker              INJECT(C()) = default;
337*a65addddSAndroid Build Coastguard Worker
338*a65addddSAndroid Build Coastguard Worker              C(const C&) = delete;
339*a65addddSAndroid Build Coastguard Worker              C(C&&) = delete;
340*a65addddSAndroid Build Coastguard Worker              C& operator=(const C&) = delete;
341*a65addddSAndroid Build Coastguard Worker              C& operator=(C&&) = delete;
342*a65addddSAndroid Build Coastguard Worker            };
343*a65addddSAndroid Build Coastguard Worker
344*a65addddSAndroid Build Coastguard Worker            using IFactory = std::function<std::unique_ptr<I>()>;
345*a65addddSAndroid Build Coastguard Worker
346*a65addddSAndroid Build Coastguard Worker            fruit::Component<IFactory> getIFactory() {
347*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
348*a65addddSAndroid Build Coastguard Worker                  .bind<I, C>();
349*a65addddSAndroid Build Coastguard Worker            }
350*a65addddSAndroid Build Coastguard Worker
351*a65addddSAndroid Build Coastguard Worker            int main() {
352*a65addddSAndroid Build Coastguard Worker              fruit::Injector<IFactory> injector(getIFactory);
353*a65addddSAndroid Build Coastguard Worker              IFactory iFactory(injector);
354*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<I> i = iFactory();
355*a65addddSAndroid Build Coastguard Worker              (void)i;
356*a65addddSAndroid Build Coastguard Worker            }
357*a65addddSAndroid Build Coastguard Worker            '''
358*a65addddSAndroid Build Coastguard Worker        expect_success(
359*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
360*a65addddSAndroid Build Coastguard Worker            source)
361*a65addddSAndroid Build Coastguard Worker
362*a65addddSAndroid Build Coastguard Worker    def test_autoinject_moveonly_ref(self):
363*a65addddSAndroid Build Coastguard Worker        source = '''
364*a65addddSAndroid Build Coastguard Worker            struct Bar {
365*a65addddSAndroid Build Coastguard Worker              Bar() = default;
366*a65addddSAndroid Build Coastguard Worker
367*a65addddSAndroid Build Coastguard Worker              Bar(const Bar&) = delete;
368*a65addddSAndroid Build Coastguard Worker              Bar(Bar&&) = default;
369*a65addddSAndroid Build Coastguard Worker              Bar& operator=(const Bar&) = delete;
370*a65addddSAndroid Build Coastguard Worker              Bar& operator=(Bar&&) = default;
371*a65addddSAndroid Build Coastguard Worker            };
372*a65addddSAndroid Build Coastguard Worker
373*a65addddSAndroid Build Coastguard Worker            struct Foo {
374*a65addddSAndroid Build Coastguard Worker              Foo(Bar&& bar) {
375*a65addddSAndroid Build Coastguard Worker                Bar b(std::move(bar));
376*a65addddSAndroid Build Coastguard Worker                (void)b;
377*a65addddSAndroid Build Coastguard Worker              }
378*a65addddSAndroid Build Coastguard Worker            };
379*a65addddSAndroid Build Coastguard Worker
380*a65addddSAndroid Build Coastguard Worker            using FooFactory = std::function<Foo(Bar&&)>;
381*a65addddSAndroid Build Coastguard Worker
382*a65addddSAndroid Build Coastguard Worker            fruit::Component<FooFactory> getComponent() {
383*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
384*a65addddSAndroid Build Coastguard Worker                  .registerFactory<Foo(fruit::Assisted<Bar&&>)>(
385*a65addddSAndroid Build Coastguard Worker                      [](Bar&& bar) {
386*a65addddSAndroid Build Coastguard Worker                        return Foo(std::move(bar));
387*a65addddSAndroid Build Coastguard Worker                      });
388*a65addddSAndroid Build Coastguard Worker            }
389*a65addddSAndroid Build Coastguard Worker
390*a65addddSAndroid Build Coastguard Worker            int main() {
391*a65addddSAndroid Build Coastguard Worker              fruit::Injector<FooFactory> injector(getComponent);
392*a65addddSAndroid Build Coastguard Worker              FooFactory fooFactory(injector);
393*a65addddSAndroid Build Coastguard Worker              Foo foo = fooFactory(Bar());
394*a65addddSAndroid Build Coastguard Worker              (void)foo;
395*a65addddSAndroid Build Coastguard Worker            }
396*a65addddSAndroid Build Coastguard Worker            '''
397*a65addddSAndroid Build Coastguard Worker        expect_success(
398*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
399*a65addddSAndroid Build Coastguard Worker            source)
400*a65addddSAndroid Build Coastguard Worker
401*a65addddSAndroid Build Coastguard Worker    def test_autoinject_nonmovable_ref(self):
402*a65addddSAndroid Build Coastguard Worker        source = '''
403*a65addddSAndroid Build Coastguard Worker            struct Bar {
404*a65addddSAndroid Build Coastguard Worker              Bar() = default;
405*a65addddSAndroid Build Coastguard Worker
406*a65addddSAndroid Build Coastguard Worker              Bar(const Bar&) = delete;
407*a65addddSAndroid Build Coastguard Worker              Bar(Bar&&) = delete;
408*a65addddSAndroid Build Coastguard Worker              Bar& operator=(const Bar&) = delete;
409*a65addddSAndroid Build Coastguard Worker              Bar& operator=(Bar&&) = delete;
410*a65addddSAndroid Build Coastguard Worker            };
411*a65addddSAndroid Build Coastguard Worker
412*a65addddSAndroid Build Coastguard Worker            struct Foo {
413*a65addddSAndroid Build Coastguard Worker              Foo(Bar& bar) {
414*a65addddSAndroid Build Coastguard Worker                (void)bar;
415*a65addddSAndroid Build Coastguard Worker              }
416*a65addddSAndroid Build Coastguard Worker            };
417*a65addddSAndroid Build Coastguard Worker
418*a65addddSAndroid Build Coastguard Worker            using FooFactory = std::function<Foo(Bar&)>;
419*a65addddSAndroid Build Coastguard Worker
420*a65addddSAndroid Build Coastguard Worker            fruit::Component<FooFactory> getComponent() {
421*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
422*a65addddSAndroid Build Coastguard Worker                  .registerFactory<Foo(fruit::Assisted<Bar&>)>(
423*a65addddSAndroid Build Coastguard Worker                      [](Bar& bar) {
424*a65addddSAndroid Build Coastguard Worker                        return Foo(bar);
425*a65addddSAndroid Build Coastguard Worker                      });
426*a65addddSAndroid Build Coastguard Worker            }
427*a65addddSAndroid Build Coastguard Worker
428*a65addddSAndroid Build Coastguard Worker            int main() {
429*a65addddSAndroid Build Coastguard Worker              fruit::Injector<FooFactory> injector(getComponent);
430*a65addddSAndroid Build Coastguard Worker              FooFactory fooFactory(injector);
431*a65addddSAndroid Build Coastguard Worker              Bar bar;
432*a65addddSAndroid Build Coastguard Worker              Foo foo = fooFactory(bar);
433*a65addddSAndroid Build Coastguard Worker              (void)foo;
434*a65addddSAndroid Build Coastguard Worker            }
435*a65addddSAndroid Build Coastguard Worker            '''
436*a65addddSAndroid Build Coastguard Worker        expect_success(
437*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
438*a65addddSAndroid Build Coastguard Worker            source)
439*a65addddSAndroid Build Coastguard Worker
440*a65addddSAndroid Build Coastguard Worker    def test_autoinject_2_assisted_params(self):
441*a65addddSAndroid Build Coastguard Worker        source = '''
442*a65addddSAndroid Build Coastguard Worker            struct Foo {
443*a65addddSAndroid Build Coastguard Worker              Foo(int x, float y) {
444*a65addddSAndroid Build Coastguard Worker                (void)x;
445*a65addddSAndroid Build Coastguard Worker                (void)y;
446*a65addddSAndroid Build Coastguard Worker              }
447*a65addddSAndroid Build Coastguard Worker            };
448*a65addddSAndroid Build Coastguard Worker
449*a65addddSAndroid Build Coastguard Worker            using FooFactory = std::function<Foo(int, float)>;
450*a65addddSAndroid Build Coastguard Worker
451*a65addddSAndroid Build Coastguard Worker            fruit::Component<FooFactory> getComponent() {
452*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
453*a65addddSAndroid Build Coastguard Worker                  .registerFactory<Foo(fruit::Assisted<int>, fruit::Assisted<float>)>(
454*a65addddSAndroid Build Coastguard Worker                      [](int x, float y) {
455*a65addddSAndroid Build Coastguard Worker                        return Foo(x, y);
456*a65addddSAndroid Build Coastguard Worker                      });
457*a65addddSAndroid Build Coastguard Worker            }
458*a65addddSAndroid Build Coastguard Worker
459*a65addddSAndroid Build Coastguard Worker            int main() {
460*a65addddSAndroid Build Coastguard Worker              fruit::Injector<FooFactory> injector(getComponent);
461*a65addddSAndroid Build Coastguard Worker              FooFactory fooFactory(injector);
462*a65addddSAndroid Build Coastguard Worker              Foo foo = fooFactory(1, 2.3f);
463*a65addddSAndroid Build Coastguard Worker              (void)foo;
464*a65addddSAndroid Build Coastguard Worker            }
465*a65addddSAndroid Build Coastguard Worker            '''
466*a65addddSAndroid Build Coastguard Worker        expect_success(
467*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
468*a65addddSAndroid Build Coastguard Worker            source)
469*a65addddSAndroid Build Coastguard Worker
470*a65addddSAndroid Build Coastguard Worker    def test_autoinject_assisted_params_ref(self):
471*a65addddSAndroid Build Coastguard Worker        source = '''
472*a65addddSAndroid Build Coastguard Worker            struct Foo {
473*a65addddSAndroid Build Coastguard Worker              Foo(int x, float y, char z) {
474*a65addddSAndroid Build Coastguard Worker                (void)x;
475*a65addddSAndroid Build Coastguard Worker                (void)y;
476*a65addddSAndroid Build Coastguard Worker                (void)z;
477*a65addddSAndroid Build Coastguard Worker              }
478*a65addddSAndroid Build Coastguard Worker            };
479*a65addddSAndroid Build Coastguard Worker
480*a65addddSAndroid Build Coastguard Worker            using FooFactory = std::function<Foo(int&, float&&, char)>;
481*a65addddSAndroid Build Coastguard Worker
482*a65addddSAndroid Build Coastguard Worker            fruit::Component<FooFactory> getComponent() {
483*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
484*a65addddSAndroid Build Coastguard Worker                  .registerFactory<Foo(fruit::Assisted<int&>, fruit::Assisted<float&&>, fruit::Assisted<char>)>(
485*a65addddSAndroid Build Coastguard Worker                      [](int& x, float&& y, char z) {
486*a65addddSAndroid Build Coastguard Worker                        return Foo(x, std::move(y), z);
487*a65addddSAndroid Build Coastguard Worker                      });
488*a65addddSAndroid Build Coastguard Worker            }
489*a65addddSAndroid Build Coastguard Worker
490*a65addddSAndroid Build Coastguard Worker            int main() {
491*a65addddSAndroid Build Coastguard Worker              fruit::Injector<FooFactory> injector(getComponent);
492*a65addddSAndroid Build Coastguard Worker              FooFactory fooFactory(injector);
493*a65addddSAndroid Build Coastguard Worker              int x = 1;
494*a65addddSAndroid Build Coastguard Worker              Foo foo = fooFactory(x, 2.3f, 'z');
495*a65addddSAndroid Build Coastguard Worker              (void)foo;
496*a65addddSAndroid Build Coastguard Worker            }
497*a65addddSAndroid Build Coastguard Worker            '''
498*a65addddSAndroid Build Coastguard Worker        expect_success(
499*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
500*a65addddSAndroid Build Coastguard Worker            source)
501*a65addddSAndroid Build Coastguard Worker
502*a65addddSAndroid Build Coastguard Worker    def test_autoinject_2_assisted_params_returning_value(self):
503*a65addddSAndroid Build Coastguard Worker        source = '''
504*a65addddSAndroid Build Coastguard Worker            struct Foo {
505*a65addddSAndroid Build Coastguard Worker              Foo(int x, float y) {
506*a65addddSAndroid Build Coastguard Worker                (void)x;
507*a65addddSAndroid Build Coastguard Worker                (void)y;
508*a65addddSAndroid Build Coastguard Worker              }
509*a65addddSAndroid Build Coastguard Worker            };
510*a65addddSAndroid Build Coastguard Worker
511*a65addddSAndroid Build Coastguard Worker            using FooFactory = std::function<Foo(int, float)>;
512*a65addddSAndroid Build Coastguard Worker
513*a65addddSAndroid Build Coastguard Worker            fruit::Component<FooFactory> getComponent() {
514*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
515*a65addddSAndroid Build Coastguard Worker                  .registerFactory<Foo(fruit::Assisted<int>, fruit::Assisted<float>)>(
516*a65addddSAndroid Build Coastguard Worker                      [](int x, float y) {
517*a65addddSAndroid Build Coastguard Worker                        return Foo(x, y);
518*a65addddSAndroid Build Coastguard Worker                      });
519*a65addddSAndroid Build Coastguard Worker            }
520*a65addddSAndroid Build Coastguard Worker
521*a65addddSAndroid Build Coastguard Worker            int main() {
522*a65addddSAndroid Build Coastguard Worker              fruit::Injector<FooFactory> injector(getComponent);
523*a65addddSAndroid Build Coastguard Worker              FooFactory fooFactory(injector);
524*a65addddSAndroid Build Coastguard Worker              Foo foo = fooFactory(1, 2.3f);
525*a65addddSAndroid Build Coastguard Worker              (void)foo;
526*a65addddSAndroid Build Coastguard Worker            }
527*a65addddSAndroid Build Coastguard Worker            '''
528*a65addddSAndroid Build Coastguard Worker        expect_success(
529*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
530*a65addddSAndroid Build Coastguard Worker            source)
531*a65addddSAndroid Build Coastguard Worker
532*a65addddSAndroid Build Coastguard Worker    def test_autoinject_instances_bound_to_assisted_params(self):
533*a65addddSAndroid Build Coastguard Worker        source = '''
534*a65addddSAndroid Build Coastguard Worker            struct X {};
535*a65addddSAndroid Build Coastguard Worker            struct Y {};
536*a65addddSAndroid Build Coastguard Worker
537*a65addddSAndroid Build Coastguard Worker            struct Foo {
538*a65addddSAndroid Build Coastguard Worker              Foo(X x, Y y) {
539*a65addddSAndroid Build Coastguard Worker                (void)x;
540*a65addddSAndroid Build Coastguard Worker                (void)y;
541*a65addddSAndroid Build Coastguard Worker              }
542*a65addddSAndroid Build Coastguard Worker            };
543*a65addddSAndroid Build Coastguard Worker
544*a65addddSAndroid Build Coastguard Worker            using FooFactory = std::function<Foo()>;
545*a65addddSAndroid Build Coastguard Worker
546*a65addddSAndroid Build Coastguard Worker            fruit::Component<FooFactory> getComponent() {
547*a65addddSAndroid Build Coastguard Worker              static X x = X();
548*a65addddSAndroid Build Coastguard Worker              static Y y = Y();
549*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
550*a65addddSAndroid Build Coastguard Worker                  .bindInstance(x)
551*a65addddSAndroid Build Coastguard Worker                  .bindInstance(y)
552*a65addddSAndroid Build Coastguard Worker                  .registerFactory<Foo(X, Y)>(
553*a65addddSAndroid Build Coastguard Worker                      [](X x, Y y) {
554*a65addddSAndroid Build Coastguard Worker                        return Foo(x, y);
555*a65addddSAndroid Build Coastguard Worker                      });
556*a65addddSAndroid Build Coastguard Worker            }
557*a65addddSAndroid Build Coastguard Worker
558*a65addddSAndroid Build Coastguard Worker
559*a65addddSAndroid Build Coastguard Worker            int main() {
560*a65addddSAndroid Build Coastguard Worker              fruit::Injector<FooFactory> injector(getComponent);
561*a65addddSAndroid Build Coastguard Worker              FooFactory fooFactory(injector);
562*a65addddSAndroid Build Coastguard Worker              Foo foo = fooFactory();
563*a65addddSAndroid Build Coastguard Worker              (void)foo;
564*a65addddSAndroid Build Coastguard Worker            }
565*a65addddSAndroid Build Coastguard Worker            '''
566*a65addddSAndroid Build Coastguard Worker        expect_success(
567*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
568*a65addddSAndroid Build Coastguard Worker            source)
569*a65addddSAndroid Build Coastguard Worker
570*a65addddSAndroid Build Coastguard Worker    def test_autoinject_2_assisted_params_plus_nonassisted_params(self):
571*a65addddSAndroid Build Coastguard Worker        source = '''
572*a65addddSAndroid Build Coastguard Worker            struct X {};
573*a65addddSAndroid Build Coastguard Worker            struct Y {};
574*a65addddSAndroid Build Coastguard Worker            struct Z {};
575*a65addddSAndroid Build Coastguard Worker
576*a65addddSAndroid Build Coastguard Worker            struct Foo {
577*a65addddSAndroid Build Coastguard Worker              Foo(X, Y, int, float, Z) {
578*a65addddSAndroid Build Coastguard Worker              }
579*a65addddSAndroid Build Coastguard Worker            };
580*a65addddSAndroid Build Coastguard Worker
581*a65addddSAndroid Build Coastguard Worker            using FooPtrFactory = std::function<std::unique_ptr<Foo>(int, float)>;
582*a65addddSAndroid Build Coastguard Worker
583*a65addddSAndroid Build Coastguard Worker            fruit::Component<FooPtrFactory> getComponent() {
584*a65addddSAndroid Build Coastguard Worker              static X x = X();
585*a65addddSAndroid Build Coastguard Worker              static Y y = Y();
586*a65addddSAndroid Build Coastguard Worker              static Z z = Z();
587*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
588*a65addddSAndroid Build Coastguard Worker                  .bindInstance(x)
589*a65addddSAndroid Build Coastguard Worker                  .bindInstance(y)
590*a65addddSAndroid Build Coastguard Worker                  .bindInstance(z)
591*a65addddSAndroid Build Coastguard Worker                  .registerFactory<std::unique_ptr<Foo>(X, Y, fruit::Assisted<int>, fruit::Assisted<float>, Z)>(
592*a65addddSAndroid Build Coastguard Worker                      [](X x, Y y, int n, float a, Z z) {
593*a65addddSAndroid Build Coastguard Worker                        return std::unique_ptr<Foo>(new Foo(x, y, n, a, z));
594*a65addddSAndroid Build Coastguard Worker                      });
595*a65addddSAndroid Build Coastguard Worker            }
596*a65addddSAndroid Build Coastguard Worker
597*a65addddSAndroid Build Coastguard Worker            int main() {
598*a65addddSAndroid Build Coastguard Worker              fruit::Injector<FooPtrFactory> injector(getComponent);
599*a65addddSAndroid Build Coastguard Worker              FooPtrFactory fooPtrFactory(injector);
600*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Foo> foo = fooPtrFactory(1, 3.4f);
601*a65addddSAndroid Build Coastguard Worker              (void)foo;
602*a65addddSAndroid Build Coastguard Worker            }
603*a65addddSAndroid Build Coastguard Worker            '''
604*a65addddSAndroid Build Coastguard Worker        expect_success(
605*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
606*a65addddSAndroid Build Coastguard Worker            source)
607*a65addddSAndroid Build Coastguard Worker
608*a65addddSAndroid Build Coastguard Worker    def test_autoinject_2_assisted_params_plus_nonassisted_params_returning_value(self):
609*a65addddSAndroid Build Coastguard Worker        source = '''
610*a65addddSAndroid Build Coastguard Worker            struct X {};
611*a65addddSAndroid Build Coastguard Worker            struct Y {};
612*a65addddSAndroid Build Coastguard Worker            struct Z {};
613*a65addddSAndroid Build Coastguard Worker
614*a65addddSAndroid Build Coastguard Worker            struct Foo {
615*a65addddSAndroid Build Coastguard Worker              Foo(X, Y, int, float, Z) {
616*a65addddSAndroid Build Coastguard Worker              }
617*a65addddSAndroid Build Coastguard Worker            };
618*a65addddSAndroid Build Coastguard Worker
619*a65addddSAndroid Build Coastguard Worker            using FooFactory = std::function<Foo(int, float)>;
620*a65addddSAndroid Build Coastguard Worker
621*a65addddSAndroid Build Coastguard Worker            fruit::Component<FooFactory> getComponent() {
622*a65addddSAndroid Build Coastguard Worker              static X x = X();
623*a65addddSAndroid Build Coastguard Worker              static Y y = Y();
624*a65addddSAndroid Build Coastguard Worker              static Z z = Z();
625*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
626*a65addddSAndroid Build Coastguard Worker                  .bindInstance(x)
627*a65addddSAndroid Build Coastguard Worker                  .bindInstance(y)
628*a65addddSAndroid Build Coastguard Worker                  .bindInstance(z)
629*a65addddSAndroid Build Coastguard Worker                  .registerFactory<Foo(X, Y, fruit::Assisted<int>, fruit::Assisted<float>, Z)>(
630*a65addddSAndroid Build Coastguard Worker                      [](X x, Y y, int n, float a, Z z) {
631*a65addddSAndroid Build Coastguard Worker                        return Foo(x, y, n, a, z);
632*a65addddSAndroid Build Coastguard Worker                      });
633*a65addddSAndroid Build Coastguard Worker            }
634*a65addddSAndroid Build Coastguard Worker
635*a65addddSAndroid Build Coastguard Worker            int main() {
636*a65addddSAndroid Build Coastguard Worker              fruit::Injector<FooFactory> injector(getComponent);
637*a65addddSAndroid Build Coastguard Worker              FooFactory fooFactory(injector);
638*a65addddSAndroid Build Coastguard Worker              Foo foo = fooFactory(1, 3.4f);
639*a65addddSAndroid Build Coastguard Worker              (void)foo;
640*a65addddSAndroid Build Coastguard Worker            }
641*a65addddSAndroid Build Coastguard Worker            '''
642*a65addddSAndroid Build Coastguard Worker        expect_success(
643*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
644*a65addddSAndroid Build Coastguard Worker            source)
645*a65addddSAndroid Build Coastguard Worker
646*a65addddSAndroid Build Coastguard Worker    def test_autoinject_mixed_assisted_and_injected_params(self):
647*a65addddSAndroid Build Coastguard Worker        source = '''
648*a65addddSAndroid Build Coastguard Worker            struct X {};
649*a65addddSAndroid Build Coastguard Worker            struct Y {};
650*a65addddSAndroid Build Coastguard Worker
651*a65addddSAndroid Build Coastguard Worker            struct Foo {
652*a65addddSAndroid Build Coastguard Worker              Foo(int, float, X, Y, double) {
653*a65addddSAndroid Build Coastguard Worker              }
654*a65addddSAndroid Build Coastguard Worker            };
655*a65addddSAndroid Build Coastguard Worker
656*a65addddSAndroid Build Coastguard Worker            using FooFactory = std::function<Foo(int, float, double)>;
657*a65addddSAndroid Build Coastguard Worker
658*a65addddSAndroid Build Coastguard Worker            fruit::Component<FooFactory> getComponent() {
659*a65addddSAndroid Build Coastguard Worker              static X x = X();
660*a65addddSAndroid Build Coastguard Worker              static Y y = Y();
661*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
662*a65addddSAndroid Build Coastguard Worker                  .bindInstance(x)
663*a65addddSAndroid Build Coastguard Worker                  .bindInstance(y)
664*a65addddSAndroid Build Coastguard Worker                  .registerFactory<Foo(fruit::Assisted<int>, fruit::Assisted<float>, X, Y, fruit::Assisted<double>)>(
665*a65addddSAndroid Build Coastguard Worker                      [](int n, float a, X x, Y y, double d) {
666*a65addddSAndroid Build Coastguard Worker                        return Foo(n, a, x, y, d);
667*a65addddSAndroid Build Coastguard Worker                      });
668*a65addddSAndroid Build Coastguard Worker            }
669*a65addddSAndroid Build Coastguard Worker
670*a65addddSAndroid Build Coastguard Worker            int main() {
671*a65addddSAndroid Build Coastguard Worker              fruit::Injector<FooFactory> injector(getComponent);
672*a65addddSAndroid Build Coastguard Worker              FooFactory fooFactory(injector);
673*a65addddSAndroid Build Coastguard Worker              Foo foo = fooFactory(1, 3.4f, 3.456);
674*a65addddSAndroid Build Coastguard Worker              (void)foo;
675*a65addddSAndroid Build Coastguard Worker            }
676*a65addddSAndroid Build Coastguard Worker            '''
677*a65addddSAndroid Build Coastguard Worker        expect_success(
678*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
679*a65addddSAndroid Build Coastguard Worker            source)
680*a65addddSAndroid Build Coastguard Worker
681*a65addddSAndroid Build Coastguard Worker    def test_autoinject_annotation_in_signature_return_type(self):
682*a65addddSAndroid Build Coastguard Worker        source = '''
683*a65addddSAndroid Build Coastguard Worker            struct X {
684*a65addddSAndroid Build Coastguard Worker              using Inject = fruit::Annotated<Annotation1, X>();
685*a65addddSAndroid Build Coastguard Worker            };
686*a65addddSAndroid Build Coastguard Worker
687*a65addddSAndroid Build Coastguard Worker            fruit::Component<fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>> getComponent() {
688*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
689*a65addddSAndroid Build Coastguard Worker            }
690*a65addddSAndroid Build Coastguard Worker            '''
691*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
692*a65addddSAndroid Build Coastguard Worker            'InjectTypedefWithAnnotationError<X>',
693*a65addddSAndroid Build Coastguard Worker            'C::Inject is a signature that returns an annotated type',
694*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
695*a65addddSAndroid Build Coastguard Worker            source)
696*a65addddSAndroid Build Coastguard Worker
697*a65addddSAndroid Build Coastguard Worker    def test_autoinject_annotation_in_signature_return_type_returning_value(self):
698*a65addddSAndroid Build Coastguard Worker        source = '''
699*a65addddSAndroid Build Coastguard Worker            struct X {
700*a65addddSAndroid Build Coastguard Worker              using Inject = fruit::Annotated<Annotation1, X>();
701*a65addddSAndroid Build Coastguard Worker            };
702*a65addddSAndroid Build Coastguard Worker
703*a65addddSAndroid Build Coastguard Worker            fruit::Component<fruit::Annotated<Annotation1, std::function<X()>>> getComponent() {
704*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
705*a65addddSAndroid Build Coastguard Worker            }
706*a65addddSAndroid Build Coastguard Worker            '''
707*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
708*a65addddSAndroid Build Coastguard Worker            'InjectTypedefWithAnnotationError<X>',
709*a65addddSAndroid Build Coastguard Worker            'C::Inject is a signature that returns an annotated type',
710*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
711*a65addddSAndroid Build Coastguard Worker            source)
712*a65addddSAndroid Build Coastguard Worker
713*a65addddSAndroid Build Coastguard Worker    def test_autoinject_from_provider_simple(self):
714*a65addddSAndroid Build Coastguard Worker        source = '''
715*a65addddSAndroid Build Coastguard Worker            struct X {
716*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
717*a65addddSAndroid Build Coastguard Worker            };
718*a65addddSAndroid Build Coastguard Worker
719*a65addddSAndroid Build Coastguard Worker            struct Scaler {
720*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
721*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
722*a65addddSAndroid Build Coastguard Worker            };
723*a65addddSAndroid Build Coastguard Worker
724*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
725*a65addddSAndroid Build Coastguard Worker            private:
726*a65addddSAndroid Build Coastguard Worker              double factor;
727*a65addddSAndroid Build Coastguard Worker
728*a65addddSAndroid Build Coastguard Worker            public:
729*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor, X)
730*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
731*a65addddSAndroid Build Coastguard Worker              }
732*a65addddSAndroid Build Coastguard Worker
733*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
734*a65addddSAndroid Build Coastguard Worker                return x * factor;
735*a65addddSAndroid Build Coastguard Worker              }
736*a65addddSAndroid Build Coastguard Worker            };
737*a65addddSAndroid Build Coastguard Worker
738*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
739*a65addddSAndroid Build Coastguard Worker
740*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
741*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
742*a65addddSAndroid Build Coastguard Worker                .registerProvider([](X x) {
743*a65addddSAndroid Build Coastguard Worker                  return std::function<std::unique_ptr<ScalerImpl>(double)>([x](double n){
744*a65addddSAndroid Build Coastguard Worker                    return std::unique_ptr<ScalerImpl>(new ScalerImpl(n, x));
745*a65addddSAndroid Build Coastguard Worker                  });
746*a65addddSAndroid Build Coastguard Worker                })
747*a65addddSAndroid Build Coastguard Worker                .bind<Scaler, ScalerImpl>();
748*a65addddSAndroid Build Coastguard Worker            }
749*a65addddSAndroid Build Coastguard Worker
750*a65addddSAndroid Build Coastguard Worker            int main() {
751*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactory> injector(getScalerComponent);
752*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
753*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
754*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
755*a65addddSAndroid Build Coastguard Worker            }
756*a65addddSAndroid Build Coastguard Worker            '''
757*a65addddSAndroid Build Coastguard Worker        expect_success(
758*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
759*a65addddSAndroid Build Coastguard Worker            source)
760*a65addddSAndroid Build Coastguard Worker
761*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
762*a65addddSAndroid Build Coastguard Worker        ('Scaler',
763*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>',
764*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>',
765*a65addddSAndroid Build Coastguard Worker         'ScalerImpl',
766*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<ScalerImpl>(double)>'),
767*a65addddSAndroid Build Coastguard Worker        ('Scaler',
768*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>',
769*a65addddSAndroid Build Coastguard Worker         'const std::function<std::unique_ptr<Scaler>(double)>',
770*a65addddSAndroid Build Coastguard Worker         'ScalerImpl',
771*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<ScalerImpl>(double)>'),
772*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
773*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>',
774*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>',
775*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, ScalerImpl>',
776*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, std::function<std::unique_ptr<ScalerImpl>(double)>>'),
777*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
778*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>',
779*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, const std::function<std::unique_ptr<Scaler>(double)>>',
780*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, ScalerImpl>',
781*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, std::function<std::unique_ptr<ScalerImpl>(double)>>'),
782*a65addddSAndroid Build Coastguard Worker    ])
783*a65addddSAndroid Build Coastguard Worker    def test_autoinject_from_provider(self, ScalerAnnot, ScalerFactoryAnnot, MaybeConstScalerFactoryAnnot, ScalerImplAnnot, ScalerImplFactoryAnnot):
784*a65addddSAndroid Build Coastguard Worker        source = '''
785*a65addddSAndroid Build Coastguard Worker            struct X {
786*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
787*a65addddSAndroid Build Coastguard Worker            };
788*a65addddSAndroid Build Coastguard Worker
789*a65addddSAndroid Build Coastguard Worker            struct Scaler {
790*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
791*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
792*a65addddSAndroid Build Coastguard Worker            };
793*a65addddSAndroid Build Coastguard Worker
794*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
795*a65addddSAndroid Build Coastguard Worker            private:
796*a65addddSAndroid Build Coastguard Worker              double factor;
797*a65addddSAndroid Build Coastguard Worker
798*a65addddSAndroid Build Coastguard Worker            public:
799*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor, X)
800*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
801*a65addddSAndroid Build Coastguard Worker              }
802*a65addddSAndroid Build Coastguard Worker
803*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
804*a65addddSAndroid Build Coastguard Worker                return x * factor;
805*a65addddSAndroid Build Coastguard Worker              }
806*a65addddSAndroid Build Coastguard Worker            };
807*a65addddSAndroid Build Coastguard Worker
808*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
809*a65addddSAndroid Build Coastguard Worker            using ScalerImplFactory = std::function<std::unique_ptr<ScalerImpl>(double)>;
810*a65addddSAndroid Build Coastguard Worker
811*a65addddSAndroid Build Coastguard Worker            fruit::Component<MaybeConstScalerFactoryAnnot> getScalerComponent() {
812*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
813*a65addddSAndroid Build Coastguard Worker                .registerProvider<ScalerImplFactoryAnnot(X)>([](X x) {
814*a65addddSAndroid Build Coastguard Worker                  return std::function<std::unique_ptr<ScalerImpl>(double)>([x](double n){
815*a65addddSAndroid Build Coastguard Worker                    return std::unique_ptr<ScalerImpl>(new ScalerImpl(n, x));
816*a65addddSAndroid Build Coastguard Worker                  });
817*a65addddSAndroid Build Coastguard Worker                })
818*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot, ScalerImplAnnot>();
819*a65addddSAndroid Build Coastguard Worker            }
820*a65addddSAndroid Build Coastguard Worker
821*a65addddSAndroid Build Coastguard Worker            int main() {
822*a65addddSAndroid Build Coastguard Worker              fruit::Injector<MaybeConstScalerFactoryAnnot> injector(getScalerComponent);
823*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
824*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
825*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
826*a65addddSAndroid Build Coastguard Worker            }
827*a65addddSAndroid Build Coastguard Worker            '''
828*a65addddSAndroid Build Coastguard Worker        expect_success(
829*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
830*a65addddSAndroid Build Coastguard Worker            source,
831*a65addddSAndroid Build Coastguard Worker            locals())
832*a65addddSAndroid Build Coastguard Worker
833*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
834*a65addddSAndroid Build Coastguard Worker        'ScalerFactory',
835*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, ScalerFactory>',
836*a65addddSAndroid Build Coastguard Worker    ])
837*a65addddSAndroid Build Coastguard Worker    def test_autoinject_from_provider_returning_value(self, ScalerFactoryAnnot):
838*a65addddSAndroid Build Coastguard Worker        source = '''
839*a65addddSAndroid Build Coastguard Worker            struct X {
840*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
841*a65addddSAndroid Build Coastguard Worker            };
842*a65addddSAndroid Build Coastguard Worker
843*a65addddSAndroid Build Coastguard Worker            struct Scaler {
844*a65addddSAndroid Build Coastguard Worker            private:
845*a65addddSAndroid Build Coastguard Worker              double factor;
846*a65addddSAndroid Build Coastguard Worker
847*a65addddSAndroid Build Coastguard Worker            public:
848*a65addddSAndroid Build Coastguard Worker              Scaler(double factor, X)
849*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
850*a65addddSAndroid Build Coastguard Worker              }
851*a65addddSAndroid Build Coastguard Worker
852*a65addddSAndroid Build Coastguard Worker              double scale(double x) {
853*a65addddSAndroid Build Coastguard Worker                return x * factor;
854*a65addddSAndroid Build Coastguard Worker              }
855*a65addddSAndroid Build Coastguard Worker            };
856*a65addddSAndroid Build Coastguard Worker
857*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<Scaler(double)>;
858*a65addddSAndroid Build Coastguard Worker
859*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
860*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
861*a65addddSAndroid Build Coastguard Worker                .registerProvider<ScalerFactoryAnnot(X)>([](X x) {
862*a65addddSAndroid Build Coastguard Worker                  return std::function<Scaler(double)>([x](double n){
863*a65addddSAndroid Build Coastguard Worker                    return Scaler(n, x);
864*a65addddSAndroid Build Coastguard Worker                  });
865*a65addddSAndroid Build Coastguard Worker                });
866*a65addddSAndroid Build Coastguard Worker            }
867*a65addddSAndroid Build Coastguard Worker
868*a65addddSAndroid Build Coastguard Worker            int main() {
869*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent);
870*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
871*a65addddSAndroid Build Coastguard Worker              Scaler scaler = scalerFactory(12.1);
872*a65addddSAndroid Build Coastguard Worker              std::cout << scaler.scale(3) << std::endl;
873*a65addddSAndroid Build Coastguard Worker            }
874*a65addddSAndroid Build Coastguard Worker            '''
875*a65addddSAndroid Build Coastguard Worker        expect_success(
876*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
877*a65addddSAndroid Build Coastguard Worker            source,
878*a65addddSAndroid Build Coastguard Worker            locals())
879*a65addddSAndroid Build Coastguard Worker
880*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
881*a65addddSAndroid Build Coastguard Worker        '',
882*a65addddSAndroid Build Coastguard Worker        'const',
883*a65addddSAndroid Build Coastguard Worker    ], [
884*a65addddSAndroid Build Coastguard Worker        'X',
885*a65addddSAndroid Build Coastguard Worker        'ANNOTATED(Annotation1, X)',
886*a65addddSAndroid Build Coastguard Worker    ])
887*a65addddSAndroid Build Coastguard Worker    def test_autoinject_with_binding(self, MaybeConst, X_ANNOT):
888*a65addddSAndroid Build Coastguard Worker        source = '''
889*a65addddSAndroid Build Coastguard Worker            struct X {
890*a65addddSAndroid Build Coastguard Worker              using Inject = X();
891*a65addddSAndroid Build Coastguard Worker            };
892*a65addddSAndroid Build Coastguard Worker
893*a65addddSAndroid Build Coastguard Worker            struct Scaler {
894*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
895*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
896*a65addddSAndroid Build Coastguard Worker            };
897*a65addddSAndroid Build Coastguard Worker
898*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
899*a65addddSAndroid Build Coastguard Worker            private:
900*a65addddSAndroid Build Coastguard Worker              double factor;
901*a65addddSAndroid Build Coastguard Worker
902*a65addddSAndroid Build Coastguard Worker            public:
903*a65addddSAndroid Build Coastguard Worker              INJECT(ScalerImpl(ASSISTED(double) factor, X_ANNOT x))
904*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
905*a65addddSAndroid Build Coastguard Worker                  (void)x;
906*a65addddSAndroid Build Coastguard Worker              }
907*a65addddSAndroid Build Coastguard Worker
908*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
909*a65addddSAndroid Build Coastguard Worker                return x * factor;
910*a65addddSAndroid Build Coastguard Worker              }
911*a65addddSAndroid Build Coastguard Worker            };
912*a65addddSAndroid Build Coastguard Worker
913*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
914*a65addddSAndroid Build Coastguard Worker
915*a65addddSAndroid Build Coastguard Worker            fruit::Component<MaybeConst ScalerFactory> getScalerComponent() {
916*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
917*a65addddSAndroid Build Coastguard Worker                .bind<Scaler, ScalerImpl>();
918*a65addddSAndroid Build Coastguard Worker            }
919*a65addddSAndroid Build Coastguard Worker
920*a65addddSAndroid Build Coastguard Worker            int main() {
921*a65addddSAndroid Build Coastguard Worker              fruit::Injector<MaybeConst ScalerFactory> injector(getScalerComponent);
922*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
923*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
924*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
925*a65addddSAndroid Build Coastguard Worker            }
926*a65addddSAndroid Build Coastguard Worker            '''
927*a65addddSAndroid Build Coastguard Worker        expect_success(
928*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
929*a65addddSAndroid Build Coastguard Worker            source,
930*a65addddSAndroid Build Coastguard Worker            locals())
931*a65addddSAndroid Build Coastguard Worker
932*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
933*a65addddSAndroid Build Coastguard Worker        '',
934*a65addddSAndroid Build Coastguard Worker        'const',
935*a65addddSAndroid Build Coastguard Worker    ], [
936*a65addddSAndroid Build Coastguard Worker        'X',
937*a65addddSAndroid Build Coastguard Worker        'ANNOTATED(Annotation1, X)',
938*a65addddSAndroid Build Coastguard Worker    ])
939*a65addddSAndroid Build Coastguard Worker    def test_autoinject_with_binding_returning_value(self, MaybeConst, X_ANNOT):
940*a65addddSAndroid Build Coastguard Worker        source = '''
941*a65addddSAndroid Build Coastguard Worker            struct X {
942*a65addddSAndroid Build Coastguard Worker              using Inject = X();
943*a65addddSAndroid Build Coastguard Worker            };
944*a65addddSAndroid Build Coastguard Worker
945*a65addddSAndroid Build Coastguard Worker            struct Scaler {
946*a65addddSAndroid Build Coastguard Worker            private:
947*a65addddSAndroid Build Coastguard Worker              double factor;
948*a65addddSAndroid Build Coastguard Worker
949*a65addddSAndroid Build Coastguard Worker            public:
950*a65addddSAndroid Build Coastguard Worker              INJECT(Scaler(ASSISTED(double) factor, X_ANNOT x))
951*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
952*a65addddSAndroid Build Coastguard Worker                  (void)x;
953*a65addddSAndroid Build Coastguard Worker              }
954*a65addddSAndroid Build Coastguard Worker
955*a65addddSAndroid Build Coastguard Worker              double scale(double x) {
956*a65addddSAndroid Build Coastguard Worker                return x * factor;
957*a65addddSAndroid Build Coastguard Worker              }
958*a65addddSAndroid Build Coastguard Worker            };
959*a65addddSAndroid Build Coastguard Worker
960*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<Scaler(double)>;
961*a65addddSAndroid Build Coastguard Worker
962*a65addddSAndroid Build Coastguard Worker            fruit::Component<MaybeConst ScalerFactory> getScalerComponent() {
963*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
964*a65addddSAndroid Build Coastguard Worker            }
965*a65addddSAndroid Build Coastguard Worker
966*a65addddSAndroid Build Coastguard Worker            int main() {
967*a65addddSAndroid Build Coastguard Worker              fruit::Injector<MaybeConst ScalerFactory> injector(getScalerComponent);
968*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
969*a65addddSAndroid Build Coastguard Worker              Scaler scaler = scalerFactory(12.1);
970*a65addddSAndroid Build Coastguard Worker              std::cout << scaler.scale(3) << std::endl;
971*a65addddSAndroid Build Coastguard Worker            }
972*a65addddSAndroid Build Coastguard Worker            '''
973*a65addddSAndroid Build Coastguard Worker        expect_success(
974*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
975*a65addddSAndroid Build Coastguard Worker            source,
976*a65addddSAndroid Build Coastguard Worker            locals())
977*a65addddSAndroid Build Coastguard Worker
978*a65addddSAndroid Build Coastguard Worker    def test_autoinject_with_binding_variant(self):
979*a65addddSAndroid Build Coastguard Worker        source = '''
980*a65addddSAndroid Build Coastguard Worker            struct X {
981*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
982*a65addddSAndroid Build Coastguard Worker            };
983*a65addddSAndroid Build Coastguard Worker
984*a65addddSAndroid Build Coastguard Worker            struct Scaler {
985*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
986*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
987*a65addddSAndroid Build Coastguard Worker            };
988*a65addddSAndroid Build Coastguard Worker
989*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
990*a65addddSAndroid Build Coastguard Worker            private:
991*a65addddSAndroid Build Coastguard Worker              double factor;
992*a65addddSAndroid Build Coastguard Worker
993*a65addddSAndroid Build Coastguard Worker            public:
994*a65addddSAndroid Build Coastguard Worker              INJECT(ScalerImpl(X, ASSISTED(double) factor))
995*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
996*a65addddSAndroid Build Coastguard Worker              }
997*a65addddSAndroid Build Coastguard Worker
998*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
999*a65addddSAndroid Build Coastguard Worker                return x * factor;
1000*a65addddSAndroid Build Coastguard Worker              }
1001*a65addddSAndroid Build Coastguard Worker            };
1002*a65addddSAndroid Build Coastguard Worker
1003*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1004*a65addddSAndroid Build Coastguard Worker
1005*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
1006*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1007*a65addddSAndroid Build Coastguard Worker                .bind<Scaler, ScalerImpl>();
1008*a65addddSAndroid Build Coastguard Worker            }
1009*a65addddSAndroid Build Coastguard Worker
1010*a65addddSAndroid Build Coastguard Worker            int main() {
1011*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactory> injector(getScalerComponent);
1012*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
1013*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
1014*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
1015*a65addddSAndroid Build Coastguard Worker            }
1016*a65addddSAndroid Build Coastguard Worker            '''
1017*a65addddSAndroid Build Coastguard Worker        expect_success(
1018*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1019*a65addddSAndroid Build Coastguard Worker            source)
1020*a65addddSAndroid Build Coastguard Worker
1021*a65addddSAndroid Build Coastguard Worker    def test_autoinject_with_binding_variant_returning_value(self):
1022*a65addddSAndroid Build Coastguard Worker        source = '''
1023*a65addddSAndroid Build Coastguard Worker            struct X {
1024*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
1025*a65addddSAndroid Build Coastguard Worker            };
1026*a65addddSAndroid Build Coastguard Worker
1027*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1028*a65addddSAndroid Build Coastguard Worker            private:
1029*a65addddSAndroid Build Coastguard Worker              double factor;
1030*a65addddSAndroid Build Coastguard Worker
1031*a65addddSAndroid Build Coastguard Worker            public:
1032*a65addddSAndroid Build Coastguard Worker              INJECT(Scaler(X, ASSISTED(double) factor))
1033*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1034*a65addddSAndroid Build Coastguard Worker              }
1035*a65addddSAndroid Build Coastguard Worker
1036*a65addddSAndroid Build Coastguard Worker              double scale(double x) {
1037*a65addddSAndroid Build Coastguard Worker                return x * factor;
1038*a65addddSAndroid Build Coastguard Worker              }
1039*a65addddSAndroid Build Coastguard Worker            };
1040*a65addddSAndroid Build Coastguard Worker
1041*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<Scaler(double)>;
1042*a65addddSAndroid Build Coastguard Worker
1043*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
1044*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
1045*a65addddSAndroid Build Coastguard Worker            }
1046*a65addddSAndroid Build Coastguard Worker
1047*a65addddSAndroid Build Coastguard Worker            int main() {
1048*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactory> injector(getScalerComponent);
1049*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
1050*a65addddSAndroid Build Coastguard Worker              Scaler scaler = scalerFactory(12.1);
1051*a65addddSAndroid Build Coastguard Worker              std::cout << scaler.scale(3) << std::endl;
1052*a65addddSAndroid Build Coastguard Worker            }
1053*a65addddSAndroid Build Coastguard Worker            '''
1054*a65addddSAndroid Build Coastguard Worker        expect_success(
1055*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1056*a65addddSAndroid Build Coastguard Worker            source)
1057*a65addddSAndroid Build Coastguard Worker
1058*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1059*a65addddSAndroid Build Coastguard Worker        ('Scaler',
1060*a65addddSAndroid Build Coastguard Worker         'ScalerImpl',
1061*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>'),
1062*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
1063*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, ScalerImpl>',
1064*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>'),
1065*a65addddSAndroid Build Coastguard Worker    ])
1066*a65addddSAndroid Build Coastguard Worker    def test_register_factory_success(self, ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot):
1067*a65addddSAndroid Build Coastguard Worker        source = '''
1068*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1069*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1070*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
1071*a65addddSAndroid Build Coastguard Worker            };
1072*a65addddSAndroid Build Coastguard Worker
1073*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1074*a65addddSAndroid Build Coastguard Worker            private:
1075*a65addddSAndroid Build Coastguard Worker              double factor;
1076*a65addddSAndroid Build Coastguard Worker
1077*a65addddSAndroid Build Coastguard Worker            public:
1078*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1079*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1080*a65addddSAndroid Build Coastguard Worker              }
1081*a65addddSAndroid Build Coastguard Worker
1082*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
1083*a65addddSAndroid Build Coastguard Worker                return x * factor;
1084*a65addddSAndroid Build Coastguard Worker              }
1085*a65addddSAndroid Build Coastguard Worker            };
1086*a65addddSAndroid Build Coastguard Worker
1087*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1088*a65addddSAndroid Build Coastguard Worker
1089*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
1090*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1091*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot, ScalerImplAnnot>()
1092*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerImplAnnot(fruit::Assisted<double>)>([](double factor) { return ScalerImpl(factor); });
1093*a65addddSAndroid Build Coastguard Worker            }
1094*a65addddSAndroid Build Coastguard Worker
1095*a65addddSAndroid Build Coastguard Worker            int main() {
1096*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent);
1097*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
1098*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
1099*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
1100*a65addddSAndroid Build Coastguard Worker            }
1101*a65addddSAndroid Build Coastguard Worker            '''
1102*a65addddSAndroid Build Coastguard Worker        expect_success(
1103*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1104*a65addddSAndroid Build Coastguard Worker            source,
1105*a65addddSAndroid Build Coastguard Worker            locals())
1106*a65addddSAndroid Build Coastguard Worker
1107*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_annotation_returning_value(self):
1108*a65addddSAndroid Build Coastguard Worker        source = '''
1109*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1110*a65addddSAndroid Build Coastguard Worker            private:
1111*a65addddSAndroid Build Coastguard Worker              double factor;
1112*a65addddSAndroid Build Coastguard Worker
1113*a65addddSAndroid Build Coastguard Worker            public:
1114*a65addddSAndroid Build Coastguard Worker              Scaler(double factor)
1115*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1116*a65addddSAndroid Build Coastguard Worker              }
1117*a65addddSAndroid Build Coastguard Worker
1118*a65addddSAndroid Build Coastguard Worker              double scale(double x) {
1119*a65addddSAndroid Build Coastguard Worker                return x * factor;
1120*a65addddSAndroid Build Coastguard Worker              }
1121*a65addddSAndroid Build Coastguard Worker            };
1122*a65addddSAndroid Build Coastguard Worker
1123*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<Scaler(double)>;
1124*a65addddSAndroid Build Coastguard Worker            using ScalerFactoryAnnot1 = fruit::Annotated<Annotation1, ScalerFactory>;
1125*a65addddSAndroid Build Coastguard Worker
1126*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot1> getScalerComponent() {
1127*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1128*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerAnnot1(fruit::Assisted<double>)>(
1129*a65addddSAndroid Build Coastguard Worker                  [](double factor) {
1130*a65addddSAndroid Build Coastguard Worker                      return Scaler(factor);
1131*a65addddSAndroid Build Coastguard Worker                  });
1132*a65addddSAndroid Build Coastguard Worker            }
1133*a65addddSAndroid Build Coastguard Worker
1134*a65addddSAndroid Build Coastguard Worker            int main() {
1135*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot1> injector(getScalerComponent);
1136*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot1>();
1137*a65addddSAndroid Build Coastguard Worker              Scaler scaler = scalerFactory(12.1);
1138*a65addddSAndroid Build Coastguard Worker              std::cout << scaler.scale(3) << std::endl;
1139*a65addddSAndroid Build Coastguard Worker            }
1140*a65addddSAndroid Build Coastguard Worker            '''
1141*a65addddSAndroid Build Coastguard Worker        expect_success(
1142*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1143*a65addddSAndroid Build Coastguard Worker            source)
1144*a65addddSAndroid Build Coastguard Worker
1145*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_different_annotation(self):
1146*a65addddSAndroid Build Coastguard Worker        source = '''
1147*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1148*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1149*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
1150*a65addddSAndroid Build Coastguard Worker            };
1151*a65addddSAndroid Build Coastguard Worker
1152*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1153*a65addddSAndroid Build Coastguard Worker            private:
1154*a65addddSAndroid Build Coastguard Worker              double factor;
1155*a65addddSAndroid Build Coastguard Worker
1156*a65addddSAndroid Build Coastguard Worker            public:
1157*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1158*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1159*a65addddSAndroid Build Coastguard Worker              }
1160*a65addddSAndroid Build Coastguard Worker
1161*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
1162*a65addddSAndroid Build Coastguard Worker                return x * factor;
1163*a65addddSAndroid Build Coastguard Worker              }
1164*a65addddSAndroid Build Coastguard Worker            };
1165*a65addddSAndroid Build Coastguard Worker
1166*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1167*a65addddSAndroid Build Coastguard Worker            using ScalerFactoryAnnot1 = fruit::Annotated<Annotation1, ScalerFactory>;
1168*a65addddSAndroid Build Coastguard Worker
1169*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot1> getScalerComponent() {
1170*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1171*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot1, ScalerImplAnnot2>()
1172*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerImplAnnot2(fruit::Assisted<double>)>(
1173*a65addddSAndroid Build Coastguard Worker                    [](double factor) {
1174*a65addddSAndroid Build Coastguard Worker                        return ScalerImpl(factor);
1175*a65addddSAndroid Build Coastguard Worker                    });
1176*a65addddSAndroid Build Coastguard Worker            }
1177*a65addddSAndroid Build Coastguard Worker
1178*a65addddSAndroid Build Coastguard Worker            int main() {
1179*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot1> injector(getScalerComponent);
1180*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot1>();
1181*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
1182*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
1183*a65addddSAndroid Build Coastguard Worker            }
1184*a65addddSAndroid Build Coastguard Worker            '''
1185*a65addddSAndroid Build Coastguard Worker        expect_success(
1186*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1187*a65addddSAndroid Build Coastguard Worker            source)
1188*a65addddSAndroid Build Coastguard Worker
1189*a65addddSAndroid Build Coastguard Worker
1190*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1191*a65addddSAndroid Build Coastguard Worker        ('Scaler',
1192*a65addddSAndroid Build Coastguard Worker         'ScalerImpl',
1193*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double, double)>'),
1194*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
1195*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, ScalerImpl>',
1196*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double, double)>>'),
1197*a65addddSAndroid Build Coastguard Worker    ])
1198*a65addddSAndroid Build Coastguard Worker    def test_register_factory_2arg_success(self, ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot):
1199*a65addddSAndroid Build Coastguard Worker        source = '''
1200*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1201*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1202*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
1203*a65addddSAndroid Build Coastguard Worker            };
1204*a65addddSAndroid Build Coastguard Worker
1205*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1206*a65addddSAndroid Build Coastguard Worker            private:
1207*a65addddSAndroid Build Coastguard Worker              double factor;
1208*a65addddSAndroid Build Coastguard Worker
1209*a65addddSAndroid Build Coastguard Worker            public:
1210*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1211*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1212*a65addddSAndroid Build Coastguard Worker              }
1213*a65addddSAndroid Build Coastguard Worker
1214*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
1215*a65addddSAndroid Build Coastguard Worker                return x * factor;
1216*a65addddSAndroid Build Coastguard Worker              }
1217*a65addddSAndroid Build Coastguard Worker            };
1218*a65addddSAndroid Build Coastguard Worker
1219*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double, double)>;
1220*a65addddSAndroid Build Coastguard Worker
1221*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
1222*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1223*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot, ScalerImplAnnot>()
1224*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerImplAnnot(fruit::Assisted<double>, fruit::Assisted<double>)>(
1225*a65addddSAndroid Build Coastguard Worker                    [](double factor, double) {
1226*a65addddSAndroid Build Coastguard Worker                        return ScalerImpl(factor);
1227*a65addddSAndroid Build Coastguard Worker                    });
1228*a65addddSAndroid Build Coastguard Worker            }
1229*a65addddSAndroid Build Coastguard Worker
1230*a65addddSAndroid Build Coastguard Worker            int main() {
1231*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent);
1232*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
1233*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1, 34.2);
1234*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
1235*a65addddSAndroid Build Coastguard Worker            }
1236*a65addddSAndroid Build Coastguard Worker            '''
1237*a65addddSAndroid Build Coastguard Worker        expect_success(
1238*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1239*a65addddSAndroid Build Coastguard Worker            source,
1240*a65addddSAndroid Build Coastguard Worker            locals())
1241*a65addddSAndroid Build Coastguard Worker
1242*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_different_annotation_error(self):
1243*a65addddSAndroid Build Coastguard Worker        source = '''
1244*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1245*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1246*a65addddSAndroid Build Coastguard Worker            };
1247*a65addddSAndroid Build Coastguard Worker
1248*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1249*a65addddSAndroid Build Coastguard Worker            private:
1250*a65addddSAndroid Build Coastguard Worker              double factor;
1251*a65addddSAndroid Build Coastguard Worker
1252*a65addddSAndroid Build Coastguard Worker            public:
1253*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1254*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1255*a65addddSAndroid Build Coastguard Worker              }
1256*a65addddSAndroid Build Coastguard Worker
1257*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
1258*a65addddSAndroid Build Coastguard Worker                return x * factor;
1259*a65addddSAndroid Build Coastguard Worker              }
1260*a65addddSAndroid Build Coastguard Worker            };
1261*a65addddSAndroid Build Coastguard Worker
1262*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1263*a65addddSAndroid Build Coastguard Worker            using ScalerFactoryAnnot1 = fruit::Annotated<Annotation1, ScalerFactory>;
1264*a65addddSAndroid Build Coastguard Worker
1265*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot1> getScalerComponent() {
1266*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1267*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot1, ScalerImplAnnot1>()
1268*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerImplAnnot2(fruit::Assisted<double>)>([](double factor) { return ScalerImpl(factor); });
1269*a65addddSAndroid Build Coastguard Worker            }
1270*a65addddSAndroid Build Coastguard Worker
1271*a65addddSAndroid Build Coastguard Worker            int main() {
1272*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot1> injector(getScalerComponent);
1273*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot1>();
1274*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
1275*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
1276*a65addddSAndroid Build Coastguard Worker            }
1277*a65addddSAndroid Build Coastguard Worker            '''
1278*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1279*a65addddSAndroid Build Coastguard Worker            r'NoBindingFoundError<fruit::Annotated<Annotation1,std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>>>',
1280*a65addddSAndroid Build Coastguard Worker            r'',
1281*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1282*a65addddSAndroid Build Coastguard Worker            source)
1283*a65addddSAndroid Build Coastguard Worker
1284*a65addddSAndroid Build Coastguard Worker
1285*a65addddSAndroid Build Coastguard Worker    def test_register_factory_dep_on_provider(self):
1286*a65addddSAndroid Build Coastguard Worker        source = '''
1287*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1288*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1289*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
1290*a65addddSAndroid Build Coastguard Worker            };
1291*a65addddSAndroid Build Coastguard Worker
1292*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1293*a65addddSAndroid Build Coastguard Worker            private:
1294*a65addddSAndroid Build Coastguard Worker              double factor;
1295*a65addddSAndroid Build Coastguard Worker
1296*a65addddSAndroid Build Coastguard Worker            public:
1297*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1298*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1299*a65addddSAndroid Build Coastguard Worker              }
1300*a65addddSAndroid Build Coastguard Worker
1301*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
1302*a65addddSAndroid Build Coastguard Worker                return x * factor;
1303*a65addddSAndroid Build Coastguard Worker              }
1304*a65addddSAndroid Build Coastguard Worker            };
1305*a65addddSAndroid Build Coastguard Worker
1306*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1307*a65addddSAndroid Build Coastguard Worker
1308*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
1309*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1310*a65addddSAndroid Build Coastguard Worker                .bind<Scaler, ScalerImpl>()
1311*a65addddSAndroid Build Coastguard Worker                .registerProvider([](){return 23;})
1312*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerImpl(fruit::Assisted<double>, fruit::Provider<int>)>(
1313*a65addddSAndroid Build Coastguard Worker                    [](double factor, fruit::Provider<int> provider) {
1314*a65addddSAndroid Build Coastguard Worker                        return ScalerImpl(factor * provider.get<int>());
1315*a65addddSAndroid Build Coastguard Worker                    });
1316*a65addddSAndroid Build Coastguard Worker            }
1317*a65addddSAndroid Build Coastguard Worker
1318*a65addddSAndroid Build Coastguard Worker            int main() {
1319*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactory> injector(getScalerComponent);
1320*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
1321*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
1322*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
1323*a65addddSAndroid Build Coastguard Worker            }
1324*a65addddSAndroid Build Coastguard Worker            '''
1325*a65addddSAndroid Build Coastguard Worker        expect_success(
1326*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1327*a65addddSAndroid Build Coastguard Worker            source)
1328*a65addddSAndroid Build Coastguard Worker
1329*a65addddSAndroid Build Coastguard Worker    def test_register_factory_dep_on_provider_returning_value(self):
1330*a65addddSAndroid Build Coastguard Worker        source = '''
1331*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1332*a65addddSAndroid Build Coastguard Worker            private:
1333*a65addddSAndroid Build Coastguard Worker              double factor;
1334*a65addddSAndroid Build Coastguard Worker
1335*a65addddSAndroid Build Coastguard Worker            public:
1336*a65addddSAndroid Build Coastguard Worker              Scaler(double factor)
1337*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1338*a65addddSAndroid Build Coastguard Worker              }
1339*a65addddSAndroid Build Coastguard Worker
1340*a65addddSAndroid Build Coastguard Worker              double scale(double x) {
1341*a65addddSAndroid Build Coastguard Worker                return x * factor;
1342*a65addddSAndroid Build Coastguard Worker              }
1343*a65addddSAndroid Build Coastguard Worker            };
1344*a65addddSAndroid Build Coastguard Worker
1345*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<Scaler(double)>;
1346*a65addddSAndroid Build Coastguard Worker
1347*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
1348*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1349*a65addddSAndroid Build Coastguard Worker                .registerProvider([](){return 23;})
1350*a65addddSAndroid Build Coastguard Worker                .registerFactory<Scaler(fruit::Assisted<double>, fruit::Provider<int>)>(
1351*a65addddSAndroid Build Coastguard Worker                    [](double factor, fruit::Provider<int> provider) {
1352*a65addddSAndroid Build Coastguard Worker                        return Scaler(factor * provider.get<int>());
1353*a65addddSAndroid Build Coastguard Worker                    });
1354*a65addddSAndroid Build Coastguard Worker            }
1355*a65addddSAndroid Build Coastguard Worker
1356*a65addddSAndroid Build Coastguard Worker            int main() {
1357*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactory> injector(getScalerComponent);
1358*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
1359*a65addddSAndroid Build Coastguard Worker              Scaler scaler = scalerFactory(12.1);
1360*a65addddSAndroid Build Coastguard Worker              std::cout << scaler.scale(3) << std::endl;
1361*a65addddSAndroid Build Coastguard Worker            }
1362*a65addddSAndroid Build Coastguard Worker            '''
1363*a65addddSAndroid Build Coastguard Worker        expect_success(
1364*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1365*a65addddSAndroid Build Coastguard Worker            source)
1366*a65addddSAndroid Build Coastguard Worker
1367*a65addddSAndroid Build Coastguard Worker    def test_register_factory_error_abstract_class(self):
1368*a65addddSAndroid Build Coastguard Worker        source = '''
1369*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1370*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1371*a65addddSAndroid Build Coastguard Worker            };
1372*a65addddSAndroid Build Coastguard Worker
1373*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1374*a65addddSAndroid Build Coastguard Worker            private:
1375*a65addddSAndroid Build Coastguard Worker              double factor;
1376*a65addddSAndroid Build Coastguard Worker
1377*a65addddSAndroid Build Coastguard Worker            public:
1378*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1379*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1380*a65addddSAndroid Build Coastguard Worker              }
1381*a65addddSAndroid Build Coastguard Worker
1382*a65addddSAndroid Build Coastguard Worker              // Note: here we "forgot" to implement scale() (on purpose, for this test) so ScalerImpl is an abstract class.
1383*a65addddSAndroid Build Coastguard Worker            };
1384*a65addddSAndroid Build Coastguard Worker
1385*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1386*a65addddSAndroid Build Coastguard Worker
1387*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
1388*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1389*a65addddSAndroid Build Coastguard Worker                .bind<Scaler, ScalerImpl>()
1390*a65addddSAndroid Build Coastguard Worker                .registerFactory<fruit::Annotated<Annotation1, ScalerImpl>(fruit::Assisted<double>)>([](double) { return (ScalerImpl*)nullptr; });
1391*a65addddSAndroid Build Coastguard Worker            }
1392*a65addddSAndroid Build Coastguard Worker            '''
1393*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1394*a65addddSAndroid Build Coastguard Worker            'CannotConstructAbstractClassError<ScalerImpl>',
1395*a65addddSAndroid Build Coastguard Worker            'The specified class can.t be constructed because it.s an abstract class.',
1396*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1397*a65addddSAndroid Build Coastguard Worker            source)
1398*a65addddSAndroid Build Coastguard Worker
1399*a65addddSAndroid Build Coastguard Worker    def test_register_factory_error_not_function(self):
1400*a65addddSAndroid Build Coastguard Worker        source = '''
1401*a65addddSAndroid Build Coastguard Worker            struct X {
1402*a65addddSAndroid Build Coastguard Worker              X(int) {}
1403*a65addddSAndroid Build Coastguard Worker            };
1404*a65addddSAndroid Build Coastguard Worker
1405*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<X()>> getComponent() {
1406*a65addddSAndroid Build Coastguard Worker              int n = 3;
1407*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1408*a65addddSAndroid Build Coastguard Worker                .registerFactory<X()>([=]{return X(n);});
1409*a65addddSAndroid Build Coastguard Worker            }
1410*a65addddSAndroid Build Coastguard Worker            '''
1411*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1412*a65addddSAndroid Build Coastguard Worker            'LambdaWithCapturesError<.*>',
1413*a65addddSAndroid Build Coastguard Worker            'Only lambdas with no captures are supported',
1414*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1415*a65addddSAndroid Build Coastguard Worker            source)
1416*a65addddSAndroid Build Coastguard Worker
1417*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1418*a65addddSAndroid Build Coastguard Worker        ('Scaler',
1419*a65addddSAndroid Build Coastguard Worker         'ScalerImpl',
1420*a65addddSAndroid Build Coastguard Worker         'ScalerImpl*',
1421*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>',
1422*a65addddSAndroid Build Coastguard Worker         r'ScalerImpl\*\(fruit::Assisted<double>\)'),
1423*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
1424*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, ScalerImpl>',
1425*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, ScalerImpl*>',
1426*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, std::function<std::unique_ptr<Scaler>(double)>>',
1427*a65addddSAndroid Build Coastguard Worker         r'fruit::Annotated<Annotation2,ScalerImpl\*>\(fruit::Assisted<double>\)')
1428*a65addddSAndroid Build Coastguard Worker    ])
1429*a65addddSAndroid Build Coastguard Worker    def test_register_factory_for_pointer(self, ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, ScalerFactoryAnnot, ScalerImplFactorySignatureAnnotRegex):
1430*a65addddSAndroid Build Coastguard Worker        source = '''
1431*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1432*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1433*a65addddSAndroid Build Coastguard Worker            };
1434*a65addddSAndroid Build Coastguard Worker
1435*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1436*a65addddSAndroid Build Coastguard Worker            private:
1437*a65addddSAndroid Build Coastguard Worker              double factor;
1438*a65addddSAndroid Build Coastguard Worker
1439*a65addddSAndroid Build Coastguard Worker            public:
1440*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1441*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1442*a65addddSAndroid Build Coastguard Worker              }
1443*a65addddSAndroid Build Coastguard Worker
1444*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
1445*a65addddSAndroid Build Coastguard Worker                return x * factor;
1446*a65addddSAndroid Build Coastguard Worker              }
1447*a65addddSAndroid Build Coastguard Worker            };
1448*a65addddSAndroid Build Coastguard Worker
1449*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1450*a65addddSAndroid Build Coastguard Worker
1451*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
1452*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1453*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot, ScalerImplAnnot>()
1454*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerImplPtrAnnot(fruit::Assisted<double>)>([](double factor) { return new ScalerImpl(factor); });
1455*a65addddSAndroid Build Coastguard Worker            }
1456*a65addddSAndroid Build Coastguard Worker
1457*a65addddSAndroid Build Coastguard Worker            int main() {
1458*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent);
1459*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
1460*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
1461*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
1462*a65addddSAndroid Build Coastguard Worker            }
1463*a65addddSAndroid Build Coastguard Worker            '''
1464*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1465*a65addddSAndroid Build Coastguard Worker            'FactoryReturningPointerError<ScalerImplFactorySignatureAnnotRegex>',
1466*a65addddSAndroid Build Coastguard Worker            'The specified factory returns a pointer. This is not supported',
1467*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1468*a65addddSAndroid Build Coastguard Worker            source,
1469*a65addddSAndroid Build Coastguard Worker            locals())
1470*a65addddSAndroid Build Coastguard Worker
1471*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1472*a65addddSAndroid Build Coastguard Worker        ('Scaler*',
1473*a65addddSAndroid Build Coastguard Worker         'std::function<Scaler(double)>',
1474*a65addddSAndroid Build Coastguard Worker         r'Scaler\*\(fruit::Assisted<double>\)'),
1475*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler*>',
1476*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<Scaler(double)>>',
1477*a65addddSAndroid Build Coastguard Worker         r'fruit::Annotated<Annotation1,Scaler\*>\(fruit::Assisted<double>\)'),
1478*a65addddSAndroid Build Coastguard Worker    ])
1479*a65addddSAndroid Build Coastguard Worker    def test_register_factory_for_pointer_returning_value(self, ScalerPtrAnnot, ScalerFactoryAnnot, ScalerFactorySignatureAnnotRegex):
1480*a65addddSAndroid Build Coastguard Worker        source = '''
1481*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1482*a65addddSAndroid Build Coastguard Worker            private:
1483*a65addddSAndroid Build Coastguard Worker              double factor;
1484*a65addddSAndroid Build Coastguard Worker
1485*a65addddSAndroid Build Coastguard Worker            public:
1486*a65addddSAndroid Build Coastguard Worker              Scaler(double factor)
1487*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1488*a65addddSAndroid Build Coastguard Worker              }
1489*a65addddSAndroid Build Coastguard Worker
1490*a65addddSAndroid Build Coastguard Worker              double scale(double x) {
1491*a65addddSAndroid Build Coastguard Worker                return x * factor;
1492*a65addddSAndroid Build Coastguard Worker              }
1493*a65addddSAndroid Build Coastguard Worker            };
1494*a65addddSAndroid Build Coastguard Worker
1495*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<Scaler(double)>;
1496*a65addddSAndroid Build Coastguard Worker
1497*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
1498*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1499*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerPtrAnnot(fruit::Assisted<double>)>([](double factor) { return new Scaler(factor); });
1500*a65addddSAndroid Build Coastguard Worker            }
1501*a65addddSAndroid Build Coastguard Worker
1502*a65addddSAndroid Build Coastguard Worker            int main() {
1503*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent);
1504*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
1505*a65addddSAndroid Build Coastguard Worker              Scaler scaler = scalerFactory(12.1);
1506*a65addddSAndroid Build Coastguard Worker              std::cout << scaler.scale(3) << std::endl;
1507*a65addddSAndroid Build Coastguard Worker            }
1508*a65addddSAndroid Build Coastguard Worker            '''
1509*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1510*a65addddSAndroid Build Coastguard Worker            'FactoryReturningPointerError<ScalerFactorySignatureAnnotRegex>',
1511*a65addddSAndroid Build Coastguard Worker            'The specified factory returns a pointer. This is not supported',
1512*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1513*a65addddSAndroid Build Coastguard Worker            source,
1514*a65addddSAndroid Build Coastguard Worker            locals())
1515*a65addddSAndroid Build Coastguard Worker
1516*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1517*a65addddSAndroid Build Coastguard Worker        ('Scaler',
1518*a65addddSAndroid Build Coastguard Worker         'ScalerImpl',
1519*a65addddSAndroid Build Coastguard Worker         'std::unique_ptr<ScalerImpl>',
1520*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>'),
1521*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
1522*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, ScalerImpl>',
1523*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, std::unique_ptr<ScalerImpl>>',
1524*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>'),
1525*a65addddSAndroid Build Coastguard Worker    ])
1526*a65addddSAndroid Build Coastguard Worker    def test_register_factory_for_unique_pointer(self, ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, ScalerFactoryAnnot):
1527*a65addddSAndroid Build Coastguard Worker        source = '''
1528*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1529*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1530*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
1531*a65addddSAndroid Build Coastguard Worker            };
1532*a65addddSAndroid Build Coastguard Worker
1533*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1534*a65addddSAndroid Build Coastguard Worker            private:
1535*a65addddSAndroid Build Coastguard Worker              double factor;
1536*a65addddSAndroid Build Coastguard Worker
1537*a65addddSAndroid Build Coastguard Worker            public:
1538*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1539*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1540*a65addddSAndroid Build Coastguard Worker              }
1541*a65addddSAndroid Build Coastguard Worker
1542*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
1543*a65addddSAndroid Build Coastguard Worker                return x * factor;
1544*a65addddSAndroid Build Coastguard Worker              }
1545*a65addddSAndroid Build Coastguard Worker            };
1546*a65addddSAndroid Build Coastguard Worker
1547*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1548*a65addddSAndroid Build Coastguard Worker
1549*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
1550*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1551*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot, ScalerImplAnnot>()
1552*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerImplPtrAnnot(fruit::Assisted<double>)>(
1553*a65addddSAndroid Build Coastguard Worker                    [](double factor) {
1554*a65addddSAndroid Build Coastguard Worker                        return std::unique_ptr<ScalerImpl>(new ScalerImpl(factor));
1555*a65addddSAndroid Build Coastguard Worker                    });
1556*a65addddSAndroid Build Coastguard Worker            }
1557*a65addddSAndroid Build Coastguard Worker
1558*a65addddSAndroid Build Coastguard Worker            int main() {
1559*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent);
1560*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
1561*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
1562*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
1563*a65addddSAndroid Build Coastguard Worker            }
1564*a65addddSAndroid Build Coastguard Worker            '''
1565*a65addddSAndroid Build Coastguard Worker        expect_success(
1566*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1567*a65addddSAndroid Build Coastguard Worker            source,
1568*a65addddSAndroid Build Coastguard Worker            locals())
1569*a65addddSAndroid Build Coastguard Worker
1570*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1571*a65addddSAndroid Build Coastguard Worker        ('Scaler',
1572*a65addddSAndroid Build Coastguard Worker         'ScalerImpl',
1573*a65addddSAndroid Build Coastguard Worker         'std::unique_ptr<ScalerImpl>',
1574*a65addddSAndroid Build Coastguard Worker         'std::function<std::unique_ptr<Scaler>(double)>'),
1575*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
1576*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, ScalerImpl>',
1577*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation2, std::unique_ptr<ScalerImpl>>',
1578*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>'),
1579*a65addddSAndroid Build Coastguard Worker    ])
1580*a65addddSAndroid Build Coastguard Worker    def test_register_factory_for_unique_pointer_returning_invalid_unique_ptr_ok(self, ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, ScalerFactoryAnnot):
1581*a65addddSAndroid Build Coastguard Worker        source = '''
1582*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1583*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1584*a65addddSAndroid Build Coastguard Worker              virtual ~Scaler() = default;
1585*a65addddSAndroid Build Coastguard Worker            };
1586*a65addddSAndroid Build Coastguard Worker
1587*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1588*a65addddSAndroid Build Coastguard Worker            private:
1589*a65addddSAndroid Build Coastguard Worker              double factor;
1590*a65addddSAndroid Build Coastguard Worker
1591*a65addddSAndroid Build Coastguard Worker            public:
1592*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1593*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1594*a65addddSAndroid Build Coastguard Worker              }
1595*a65addddSAndroid Build Coastguard Worker
1596*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
1597*a65addddSAndroid Build Coastguard Worker                return x * factor;
1598*a65addddSAndroid Build Coastguard Worker              }
1599*a65addddSAndroid Build Coastguard Worker            };
1600*a65addddSAndroid Build Coastguard Worker
1601*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1602*a65addddSAndroid Build Coastguard Worker
1603*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
1604*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1605*a65addddSAndroid Build Coastguard Worker                .bind<ScalerAnnot, ScalerImplAnnot>()
1606*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerImplPtrAnnot(fruit::Assisted<double>)>(
1607*a65addddSAndroid Build Coastguard Worker                    [](double) {
1608*a65addddSAndroid Build Coastguard Worker                        return std::unique_ptr<ScalerImpl>(nullptr);
1609*a65addddSAndroid Build Coastguard Worker                    });
1610*a65addddSAndroid Build Coastguard Worker            }
1611*a65addddSAndroid Build Coastguard Worker
1612*a65addddSAndroid Build Coastguard Worker            int main() {
1613*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent);
1614*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
1615*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
1616*a65addddSAndroid Build Coastguard Worker              Assert(scaler.get() == nullptr);
1617*a65addddSAndroid Build Coastguard Worker            }
1618*a65addddSAndroid Build Coastguard Worker            '''
1619*a65addddSAndroid Build Coastguard Worker        expect_success(
1620*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1621*a65addddSAndroid Build Coastguard Worker            source,
1622*a65addddSAndroid Build Coastguard Worker            locals())
1623*a65addddSAndroid Build Coastguard Worker
1624*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1625*a65addddSAndroid Build Coastguard Worker        ('Scaler',
1626*a65addddSAndroid Build Coastguard Worker         'std::function<Scaler(double)>'),
1627*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Scaler>',
1628*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<Scaler(double)>>'),
1629*a65addddSAndroid Build Coastguard Worker    ])
1630*a65addddSAndroid Build Coastguard Worker    def test_register_factory_for_unique_pointer_returning_value(self, ScalerAnnot, ScalerFactoryAnnot):
1631*a65addddSAndroid Build Coastguard Worker        source = '''
1632*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1633*a65addddSAndroid Build Coastguard Worker            private:
1634*a65addddSAndroid Build Coastguard Worker              double factor;
1635*a65addddSAndroid Build Coastguard Worker
1636*a65addddSAndroid Build Coastguard Worker            public:
1637*a65addddSAndroid Build Coastguard Worker              Scaler(double factor)
1638*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1639*a65addddSAndroid Build Coastguard Worker              }
1640*a65addddSAndroid Build Coastguard Worker
1641*a65addddSAndroid Build Coastguard Worker              double scale(double x) {
1642*a65addddSAndroid Build Coastguard Worker                return x * factor;
1643*a65addddSAndroid Build Coastguard Worker              }
1644*a65addddSAndroid Build Coastguard Worker            };
1645*a65addddSAndroid Build Coastguard Worker
1646*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<Scaler(double)>;
1647*a65addddSAndroid Build Coastguard Worker
1648*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
1649*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1650*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerAnnot(fruit::Assisted<double>)>(
1651*a65addddSAndroid Build Coastguard Worker                    [](double factor) {
1652*a65addddSAndroid Build Coastguard Worker                        return Scaler(factor);
1653*a65addddSAndroid Build Coastguard Worker                    });
1654*a65addddSAndroid Build Coastguard Worker            }
1655*a65addddSAndroid Build Coastguard Worker
1656*a65addddSAndroid Build Coastguard Worker            int main() {
1657*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent);
1658*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
1659*a65addddSAndroid Build Coastguard Worker              Scaler scaler = scalerFactory(12.1);
1660*a65addddSAndroid Build Coastguard Worker              std::cout << scaler.scale(3) << std::endl;
1661*a65addddSAndroid Build Coastguard Worker            }
1662*a65addddSAndroid Build Coastguard Worker            '''
1663*a65addddSAndroid Build Coastguard Worker        expect_success(
1664*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1665*a65addddSAndroid Build Coastguard Worker            source,
1666*a65addddSAndroid Build Coastguard Worker            locals())
1667*a65addddSAndroid Build Coastguard Worker
1668*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1669*a65addddSAndroid Build Coastguard Worker        'ScalerImpl',
1670*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, ScalerImpl>',
1671*a65addddSAndroid Build Coastguard Worker    ])
1672*a65addddSAndroid Build Coastguard Worker    def test_register_factory_inconsistent_signature(self, ScalerImplAnnot):
1673*a65addddSAndroid Build Coastguard Worker        source = '''
1674*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1675*a65addddSAndroid Build Coastguard Worker              virtual double scale(double x) = 0;
1676*a65addddSAndroid Build Coastguard Worker            };
1677*a65addddSAndroid Build Coastguard Worker
1678*a65addddSAndroid Build Coastguard Worker            struct ScalerImpl : public Scaler {
1679*a65addddSAndroid Build Coastguard Worker            private:
1680*a65addddSAndroid Build Coastguard Worker              double factor;
1681*a65addddSAndroid Build Coastguard Worker
1682*a65addddSAndroid Build Coastguard Worker            public:
1683*a65addddSAndroid Build Coastguard Worker              ScalerImpl(double factor)
1684*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1685*a65addddSAndroid Build Coastguard Worker              }
1686*a65addddSAndroid Build Coastguard Worker
1687*a65addddSAndroid Build Coastguard Worker              double scale(double x) override {
1688*a65addddSAndroid Build Coastguard Worker                return x * factor;
1689*a65addddSAndroid Build Coastguard Worker              }
1690*a65addddSAndroid Build Coastguard Worker            };
1691*a65addddSAndroid Build Coastguard Worker
1692*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
1693*a65addddSAndroid Build Coastguard Worker
1694*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
1695*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1696*a65addddSAndroid Build Coastguard Worker                .bind<Scaler, ScalerImplAnnot>()
1697*a65addddSAndroid Build Coastguard Worker                .registerFactory<ScalerImplAnnot(fruit::Assisted<double>)>([](float factor) { return ScalerImpl(factor); });
1698*a65addddSAndroid Build Coastguard Worker            }
1699*a65addddSAndroid Build Coastguard Worker
1700*a65addddSAndroid Build Coastguard Worker            int main() {
1701*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactory> injector(getScalerComponent);
1702*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
1703*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
1704*a65addddSAndroid Build Coastguard Worker              std::cout << scaler->scale(3) << std::endl;
1705*a65addddSAndroid Build Coastguard Worker            }
1706*a65addddSAndroid Build Coastguard Worker            '''
1707*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1708*a65addddSAndroid Build Coastguard Worker            r'FunctorSignatureDoesNotMatchError<ScalerImpl\(double\),ScalerImpl\(float\)>',
1709*a65addddSAndroid Build Coastguard Worker            r'Unexpected functor signature',
1710*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1711*a65addddSAndroid Build Coastguard Worker            source,
1712*a65addddSAndroid Build Coastguard Worker            locals())
1713*a65addddSAndroid Build Coastguard Worker
1714*a65addddSAndroid Build Coastguard Worker    def test_register_factory_inconsistent_signature_returning_value(self):
1715*a65addddSAndroid Build Coastguard Worker        source = '''
1716*a65addddSAndroid Build Coastguard Worker            struct Scaler {
1717*a65addddSAndroid Build Coastguard Worker            private:
1718*a65addddSAndroid Build Coastguard Worker              double factor;
1719*a65addddSAndroid Build Coastguard Worker
1720*a65addddSAndroid Build Coastguard Worker            public:
1721*a65addddSAndroid Build Coastguard Worker              Scaler(double factor)
1722*a65addddSAndroid Build Coastguard Worker                : factor(factor) {
1723*a65addddSAndroid Build Coastguard Worker              }
1724*a65addddSAndroid Build Coastguard Worker
1725*a65addddSAndroid Build Coastguard Worker              double scale(double x) {
1726*a65addddSAndroid Build Coastguard Worker                return x * factor;
1727*a65addddSAndroid Build Coastguard Worker              }
1728*a65addddSAndroid Build Coastguard Worker            };
1729*a65addddSAndroid Build Coastguard Worker
1730*a65addddSAndroid Build Coastguard Worker            using ScalerFactory = std::function<Scaler(double)>;
1731*a65addddSAndroid Build Coastguard Worker
1732*a65addddSAndroid Build Coastguard Worker            fruit::Component<ScalerFactory> getScalerComponent() {
1733*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1734*a65addddSAndroid Build Coastguard Worker                .registerFactory<Scaler(fruit::Assisted<double>)>([](float factor) { return Scaler(factor); });
1735*a65addddSAndroid Build Coastguard Worker            }
1736*a65addddSAndroid Build Coastguard Worker
1737*a65addddSAndroid Build Coastguard Worker            int main() {
1738*a65addddSAndroid Build Coastguard Worker              fruit::Injector<ScalerFactory> injector(getScalerComponent);
1739*a65addddSAndroid Build Coastguard Worker              ScalerFactory scalerFactory(injector);
1740*a65addddSAndroid Build Coastguard Worker              Scaler scaler = scalerFactory(12.1);
1741*a65addddSAndroid Build Coastguard Worker              std::cout << scaler.scale(3) << std::endl;
1742*a65addddSAndroid Build Coastguard Worker            }
1743*a65addddSAndroid Build Coastguard Worker            '''
1744*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1745*a65addddSAndroid Build Coastguard Worker            r'FunctorSignatureDoesNotMatchError<Scaler\(double\),Scaler\(float\)>',
1746*a65addddSAndroid Build Coastguard Worker            r'Unexpected functor signature',
1747*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1748*a65addddSAndroid Build Coastguard Worker            source)
1749*a65addddSAndroid Build Coastguard Worker
1750*a65addddSAndroid Build Coastguard Worker    def test_register_factory_nonmovable_ok(self):
1751*a65addddSAndroid Build Coastguard Worker        source = '''
1752*a65addddSAndroid Build Coastguard Worker            struct C {
1753*a65addddSAndroid Build Coastguard Worker              INJECT(C()) = default;
1754*a65addddSAndroid Build Coastguard Worker
1755*a65addddSAndroid Build Coastguard Worker              C(const C&) = delete;
1756*a65addddSAndroid Build Coastguard Worker              C(C&&) = delete;
1757*a65addddSAndroid Build Coastguard Worker              C& operator=(const C&) = delete;
1758*a65addddSAndroid Build Coastguard Worker              C& operator=(C&&) = delete;
1759*a65addddSAndroid Build Coastguard Worker            };
1760*a65addddSAndroid Build Coastguard Worker
1761*a65addddSAndroid Build Coastguard Worker            using CFactory = std::function<std::unique_ptr<C>()>;
1762*a65addddSAndroid Build Coastguard Worker
1763*a65addddSAndroid Build Coastguard Worker            fruit::Component<CFactory> getCFactory() {
1764*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
1765*a65addddSAndroid Build Coastguard Worker            }
1766*a65addddSAndroid Build Coastguard Worker
1767*a65addddSAndroid Build Coastguard Worker            int main() {
1768*a65addddSAndroid Build Coastguard Worker              fruit::Injector<CFactory> injector(getCFactory);
1769*a65addddSAndroid Build Coastguard Worker              CFactory cFactory(injector);
1770*a65addddSAndroid Build Coastguard Worker              std::unique_ptr<C> c = cFactory();
1771*a65addddSAndroid Build Coastguard Worker              (void)c;
1772*a65addddSAndroid Build Coastguard Worker            }
1773*a65addddSAndroid Build Coastguard Worker            '''
1774*a65addddSAndroid Build Coastguard Worker        expect_success(
1775*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1776*a65addddSAndroid Build Coastguard Worker            source)
1777*a65addddSAndroid Build Coastguard Worker
1778*a65addddSAndroid Build Coastguard Worker    # TODO: this might not be the best error message, maybe we should ignore the constructor entirely in the message,
1779*a65addddSAndroid Build Coastguard Worker    # or mention that there are other ways to satisfy that dependency.
1780*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1781*a65addddSAndroid Build Coastguard Worker        ('X',
1782*a65addddSAndroid Build Coastguard Worker         'std::function<X(int)>'),
1783*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>',
1784*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<X(int)>>'),
1785*a65addddSAndroid Build Coastguard Worker    ])
1786*a65addddSAndroid Build Coastguard Worker    def test_register_factory_not_existing_constructor1(self, XAnnot, XFactoryAnnot):
1787*a65addddSAndroid Build Coastguard Worker        source = '''
1788*a65addddSAndroid Build Coastguard Worker            struct X {
1789*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
1790*a65addddSAndroid Build Coastguard Worker            };
1791*a65addddSAndroid Build Coastguard Worker
1792*a65addddSAndroid Build Coastguard Worker            fruit::Component<XFactoryAnnot> getComponent() {
1793*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
1794*a65addddSAndroid Build Coastguard Worker            }
1795*a65addddSAndroid Build Coastguard Worker            '''
1796*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1797*a65addddSAndroid Build Coastguard Worker            r'FunctorSignatureDoesNotMatchError<XAnnot\(int\),XAnnot\((void)?\)>',
1798*a65addddSAndroid Build Coastguard Worker            r'Unexpected functor signature',
1799*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1800*a65addddSAndroid Build Coastguard Worker            source,
1801*a65addddSAndroid Build Coastguard Worker            locals())
1802*a65addddSAndroid Build Coastguard Worker
1803*a65addddSAndroid Build Coastguard Worker    # TODO: this might not be the best error message, maybe we should ignore the constructor entirely in the message,
1804*a65addddSAndroid Build Coastguard Worker    # or mention that there are other ways to satisfy that dependency.
1805*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1806*a65addddSAndroid Build Coastguard Worker        ('std::function<std::unique_ptr<X>(int)>',
1807*a65addddSAndroid Build Coastguard Worker         r'std::unique_ptr<X(,std::default_delete<X>)?>\(int\)',
1808*a65addddSAndroid Build Coastguard Worker         r'std::unique_ptr<X(,std::default_delete<X>)?>\((void)?\)'),
1809*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>(int)>>',
1810*a65addddSAndroid Build Coastguard Worker         r'fruit::Annotated<Annotation1,std::unique_ptr<X(,std::default_delete<X>)?>>\(int\)',
1811*a65addddSAndroid Build Coastguard Worker         r'fruit::Annotated<Annotation1,std::unique_ptr<X(,std::default_delete<X>)?>>\((void)?\)')
1812*a65addddSAndroid Build Coastguard Worker    ])
1813*a65addddSAndroid Build Coastguard Worker    def test_register_factory_not_existing_constructor2(self, XIntFactoryAnnot, XIntFactoryAnnotRegex, XVoidFactoryAnnotRegex):
1814*a65addddSAndroid Build Coastguard Worker        source = '''
1815*a65addddSAndroid Build Coastguard Worker            struct X {
1816*a65addddSAndroid Build Coastguard Worker              using Inject = X();
1817*a65addddSAndroid Build Coastguard Worker            };
1818*a65addddSAndroid Build Coastguard Worker
1819*a65addddSAndroid Build Coastguard Worker            fruit::Component<XIntFactoryAnnot> getComponent() {
1820*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
1821*a65addddSAndroid Build Coastguard Worker            }
1822*a65addddSAndroid Build Coastguard Worker            '''
1823*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1824*a65addddSAndroid Build Coastguard Worker            'FunctorSignatureDoesNotMatchError<XIntFactoryAnnotRegex,XVoidFactoryAnnotRegex>',
1825*a65addddSAndroid Build Coastguard Worker            'Unexpected functor signature',
1826*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1827*a65addddSAndroid Build Coastguard Worker            source,
1828*a65addddSAndroid Build Coastguard Worker            locals())
1829*a65addddSAndroid Build Coastguard Worker
1830*a65addddSAndroid Build Coastguard Worker    # TODO: this might not be the best error message, maybe we should ignore the constructor entirely in the message,
1831*a65addddSAndroid Build Coastguard Worker    # or mention that there are other ways to satisfy that dependency.
1832*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1833*a65addddSAndroid Build Coastguard Worker        ('X',
1834*a65addddSAndroid Build Coastguard Worker         'std::function<X(int)>'),
1835*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>',
1836*a65addddSAndroid Build Coastguard Worker         'fruit::Annotated<Annotation1, std::function<X(int)>>'),
1837*a65addddSAndroid Build Coastguard Worker    ])
1838*a65addddSAndroid Build Coastguard Worker    def test_register_factory_not_existing_constructor2_returning_value(self, XAnnot, XFactoryAnnot):
1839*a65addddSAndroid Build Coastguard Worker        source = '''
1840*a65addddSAndroid Build Coastguard Worker            struct X {
1841*a65addddSAndroid Build Coastguard Worker              using Inject = X();
1842*a65addddSAndroid Build Coastguard Worker            };
1843*a65addddSAndroid Build Coastguard Worker
1844*a65addddSAndroid Build Coastguard Worker            fruit::Component<XFactoryAnnot> getComponent() {
1845*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
1846*a65addddSAndroid Build Coastguard Worker            }
1847*a65addddSAndroid Build Coastguard Worker            '''
1848*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
1849*a65addddSAndroid Build Coastguard Worker            r'FunctorSignatureDoesNotMatchError<XAnnot\(int\), XAnnot\((void)?\)>',
1850*a65addddSAndroid Build Coastguard Worker            r'Unexpected functor signature',
1851*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1852*a65addddSAndroid Build Coastguard Worker            source,
1853*a65addddSAndroid Build Coastguard Worker            locals())
1854*a65addddSAndroid Build Coastguard Worker
1855*a65addddSAndroid Build Coastguard Worker
1856*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1857*a65addddSAndroid Build Coastguard Worker        'std::function<X()>',
1858*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, std::function<X()>>',
1859*a65addddSAndroid Build Coastguard Worker    ])
1860*a65addddSAndroid Build Coastguard Worker    def test_register_factory_success_factory_movable_only_implicit(self, XFactoryAnnot):
1861*a65addddSAndroid Build Coastguard Worker        source = '''
1862*a65addddSAndroid Build Coastguard Worker            struct X {
1863*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
1864*a65addddSAndroid Build Coastguard Worker              X(X&&) = default;
1865*a65addddSAndroid Build Coastguard Worker              X(const X&) = delete;
1866*a65addddSAndroid Build Coastguard Worker            };
1867*a65addddSAndroid Build Coastguard Worker
1868*a65addddSAndroid Build Coastguard Worker            fruit::Component<XFactoryAnnot> getComponent() {
1869*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
1870*a65addddSAndroid Build Coastguard Worker            }
1871*a65addddSAndroid Build Coastguard Worker
1872*a65addddSAndroid Build Coastguard Worker            int main() {
1873*a65addddSAndroid Build Coastguard Worker              fruit::Injector<XFactoryAnnot> injector(getComponent);
1874*a65addddSAndroid Build Coastguard Worker              injector.get<XFactoryAnnot>()();
1875*a65addddSAndroid Build Coastguard Worker            }
1876*a65addddSAndroid Build Coastguard Worker            '''
1877*a65addddSAndroid Build Coastguard Worker        expect_success(
1878*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1879*a65addddSAndroid Build Coastguard Worker            source,
1880*a65addddSAndroid Build Coastguard Worker            locals())
1881*a65addddSAndroid Build Coastguard Worker
1882*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1883*a65addddSAndroid Build Coastguard Worker        ('X', 'X()', 'std::function<X()>'),
1884*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'X()', 'fruit::Annotated<Annotation1, std::function<X()>>'),
1885*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>', 'std::unique_ptr<X>(new X())', 'std::function<std::unique_ptr<X>()>'),
1886*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, std::unique_ptr<X>>', 'std::unique_ptr<X>(new X())', 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>'),
1887*a65addddSAndroid Build Coastguard Worker    ])
1888*a65addddSAndroid Build Coastguard Worker    def test_register_factory_success_factory_movable_only_explicit(self, XPtrAnnot, ConstructX, XPtrFactoryAnnot):
1889*a65addddSAndroid Build Coastguard Worker        source = '''
1890*a65addddSAndroid Build Coastguard Worker            struct X {
1891*a65addddSAndroid Build Coastguard Worker              X() = default;
1892*a65addddSAndroid Build Coastguard Worker              X(X&&) = default;
1893*a65addddSAndroid Build Coastguard Worker              X(const X&) = delete;
1894*a65addddSAndroid Build Coastguard Worker            };
1895*a65addddSAndroid Build Coastguard Worker
1896*a65addddSAndroid Build Coastguard Worker            fruit::Component<XPtrFactoryAnnot> getComponent() {
1897*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1898*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtrAnnot()>([](){return ConstructX;});
1899*a65addddSAndroid Build Coastguard Worker            }
1900*a65addddSAndroid Build Coastguard Worker
1901*a65addddSAndroid Build Coastguard Worker            int main() {
1902*a65addddSAndroid Build Coastguard Worker              fruit::Injector<XPtrFactoryAnnot> injector(getComponent);
1903*a65addddSAndroid Build Coastguard Worker              injector.get<XPtrFactoryAnnot>()();
1904*a65addddSAndroid Build Coastguard Worker            }
1905*a65addddSAndroid Build Coastguard Worker            '''
1906*a65addddSAndroid Build Coastguard Worker        expect_success(
1907*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1908*a65addddSAndroid Build Coastguard Worker            source,
1909*a65addddSAndroid Build Coastguard Worker            locals())
1910*a65addddSAndroid Build Coastguard Worker
1911*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1912*a65addddSAndroid Build Coastguard Worker        'std::function<std::unique_ptr<X>()>',
1913*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>',
1914*a65addddSAndroid Build Coastguard Worker    ])
1915*a65addddSAndroid Build Coastguard Worker    def test_register_factory_success_factory_not_movable_implicit(self, XPtrFactoryAnnot):
1916*a65addddSAndroid Build Coastguard Worker        source = '''
1917*a65addddSAndroid Build Coastguard Worker            struct X {
1918*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
1919*a65addddSAndroid Build Coastguard Worker              X(X&&) = delete;
1920*a65addddSAndroid Build Coastguard Worker              X(const X&) = delete;
1921*a65addddSAndroid Build Coastguard Worker            };
1922*a65addddSAndroid Build Coastguard Worker
1923*a65addddSAndroid Build Coastguard Worker            fruit::Component<XPtrFactoryAnnot> getComponent() {
1924*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
1925*a65addddSAndroid Build Coastguard Worker            }
1926*a65addddSAndroid Build Coastguard Worker
1927*a65addddSAndroid Build Coastguard Worker            int main() {
1928*a65addddSAndroid Build Coastguard Worker              fruit::Injector<XPtrFactoryAnnot> injector(getComponent);
1929*a65addddSAndroid Build Coastguard Worker              injector.get<XPtrFactoryAnnot>()();
1930*a65addddSAndroid Build Coastguard Worker            }
1931*a65addddSAndroid Build Coastguard Worker            '''
1932*a65addddSAndroid Build Coastguard Worker        expect_success(
1933*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1934*a65addddSAndroid Build Coastguard Worker            source,
1935*a65addddSAndroid Build Coastguard Worker            locals())
1936*a65addddSAndroid Build Coastguard Worker
1937*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
1938*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>', 'std::function<std::unique_ptr<X>()>'),
1939*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, std::unique_ptr<X>>', 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>'),
1940*a65addddSAndroid Build Coastguard Worker    ])
1941*a65addddSAndroid Build Coastguard Worker    def test_register_factory_success_factory_not_movable_explicit_returning_pointer(self, XPtrAnnot, XPtrFactoryAnnot):
1942*a65addddSAndroid Build Coastguard Worker        source = '''
1943*a65addddSAndroid Build Coastguard Worker            struct X {
1944*a65addddSAndroid Build Coastguard Worker              X() = default;
1945*a65addddSAndroid Build Coastguard Worker              X(X&&) = delete;
1946*a65addddSAndroid Build Coastguard Worker              X(const X&) = delete;
1947*a65addddSAndroid Build Coastguard Worker            };
1948*a65addddSAndroid Build Coastguard Worker
1949*a65addddSAndroid Build Coastguard Worker            fruit::Component<XPtrFactoryAnnot> getComponent() {
1950*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1951*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtrAnnot()>([](){return std::unique_ptr<X>(new X());});
1952*a65addddSAndroid Build Coastguard Worker            }
1953*a65addddSAndroid Build Coastguard Worker
1954*a65addddSAndroid Build Coastguard Worker            int main() {
1955*a65addddSAndroid Build Coastguard Worker              fruit::Injector<XPtrFactoryAnnot> injector(getComponent);
1956*a65addddSAndroid Build Coastguard Worker              injector.get<XPtrFactoryAnnot>()();
1957*a65addddSAndroid Build Coastguard Worker            }
1958*a65addddSAndroid Build Coastguard Worker            '''
1959*a65addddSAndroid Build Coastguard Worker        expect_success(
1960*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
1961*a65addddSAndroid Build Coastguard Worker            source,
1962*a65addddSAndroid Build Coastguard Worker            locals())
1963*a65addddSAndroid Build Coastguard Worker
1964*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
1965*a65addddSAndroid Build Coastguard Worker        ('X()', 'X'),
1966*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'),
1967*a65addddSAndroid Build Coastguard Worker    ], [
1968*a65addddSAndroid Build Coastguard Worker        'WithNoAnnotation',
1969*a65addddSAndroid Build Coastguard Worker        'WithAnnotation1',
1970*a65addddSAndroid Build Coastguard Worker    ], [
1971*a65addddSAndroid Build Coastguard Worker        'Y',
1972*a65addddSAndroid Build Coastguard Worker        'Y*',
1973*a65addddSAndroid Build Coastguard Worker        'const Y*',
1974*a65addddSAndroid Build Coastguard Worker        'Y&',
1975*a65addddSAndroid Build Coastguard Worker        'const Y&',
1976*a65addddSAndroid Build Coastguard Worker        'std::shared_ptr<Y>',
1977*a65addddSAndroid Build Coastguard Worker        'fruit::Provider<Y>',
1978*a65addddSAndroid Build Coastguard Worker        'fruit::Provider<const Y>',
1979*a65addddSAndroid Build Coastguard Worker    ])
1980*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_param_success(self, ConstructX, XPtr, WithAnnot, YVariant):
1981*a65addddSAndroid Build Coastguard Worker        source = '''
1982*a65addddSAndroid Build Coastguard Worker            struct Y {};
1983*a65addddSAndroid Build Coastguard Worker            struct X {};
1984*a65addddSAndroid Build Coastguard Worker
1985*a65addddSAndroid Build Coastguard Worker            fruit::Component<WithAnnot<Y>> getYComponent() {
1986*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1987*a65addddSAndroid Build Coastguard Worker                .registerConstructor<WithAnnot<Y>()>();
1988*a65addddSAndroid Build Coastguard Worker            }
1989*a65addddSAndroid Build Coastguard Worker
1990*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<XPtr()>> getComponent() {
1991*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
1992*a65addddSAndroid Build Coastguard Worker                .install(getYComponent)
1993*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; });
1994*a65addddSAndroid Build Coastguard Worker            }
1995*a65addddSAndroid Build Coastguard Worker
1996*a65addddSAndroid Build Coastguard Worker            int main() {
1997*a65addddSAndroid Build Coastguard Worker              fruit::Injector<std::function<XPtr()>> injector(getComponent);
1998*a65addddSAndroid Build Coastguard Worker              XPtr x = injector.get<std::function<XPtr()>>()();
1999*a65addddSAndroid Build Coastguard Worker              (void) x;
2000*a65addddSAndroid Build Coastguard Worker            }
2001*a65addddSAndroid Build Coastguard Worker            '''
2002*a65addddSAndroid Build Coastguard Worker        expect_success(
2003*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2004*a65addddSAndroid Build Coastguard Worker            source,
2005*a65addddSAndroid Build Coastguard Worker            locals())
2006*a65addddSAndroid Build Coastguard Worker
2007*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
2008*a65addddSAndroid Build Coastguard Worker        ('X()', 'X'),
2009*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'),
2010*a65addddSAndroid Build Coastguard Worker    ], [
2011*a65addddSAndroid Build Coastguard Worker        'WithNoAnnotation',
2012*a65addddSAndroid Build Coastguard Worker        'WithAnnotation1',
2013*a65addddSAndroid Build Coastguard Worker    ], [
2014*a65addddSAndroid Build Coastguard Worker        'Y',
2015*a65addddSAndroid Build Coastguard Worker        'const Y*',
2016*a65addddSAndroid Build Coastguard Worker        'const Y&',
2017*a65addddSAndroid Build Coastguard Worker        'fruit::Provider<const Y>',
2018*a65addddSAndroid Build Coastguard Worker    ])
2019*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_param_const_binding_success(self, ConstructX, XPtr, WithAnnot, YVariant):
2020*a65addddSAndroid Build Coastguard Worker        source = '''
2021*a65addddSAndroid Build Coastguard Worker            struct Y {};
2022*a65addddSAndroid Build Coastguard Worker            struct X {};
2023*a65addddSAndroid Build Coastguard Worker
2024*a65addddSAndroid Build Coastguard Worker            const Y y{};
2025*a65addddSAndroid Build Coastguard Worker
2026*a65addddSAndroid Build Coastguard Worker            fruit::Component<WithAnnot<const Y>> getYComponent() {
2027*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2028*a65addddSAndroid Build Coastguard Worker                .bindInstance<WithAnnot<Y>, Y>(y);
2029*a65addddSAndroid Build Coastguard Worker            }
2030*a65addddSAndroid Build Coastguard Worker
2031*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<XPtr()>> getComponent() {
2032*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2033*a65addddSAndroid Build Coastguard Worker                .install(getYComponent)
2034*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; });
2035*a65addddSAndroid Build Coastguard Worker            }
2036*a65addddSAndroid Build Coastguard Worker
2037*a65addddSAndroid Build Coastguard Worker            int main() {
2038*a65addddSAndroid Build Coastguard Worker              fruit::Injector<std::function<XPtr()>> injector(getComponent);
2039*a65addddSAndroid Build Coastguard Worker              XPtr x = injector.get<std::function<XPtr()>>()();
2040*a65addddSAndroid Build Coastguard Worker              (void) x;
2041*a65addddSAndroid Build Coastguard Worker            }
2042*a65addddSAndroid Build Coastguard Worker            '''
2043*a65addddSAndroid Build Coastguard Worker        expect_success(
2044*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2045*a65addddSAndroid Build Coastguard Worker            source,
2046*a65addddSAndroid Build Coastguard Worker            locals())
2047*a65addddSAndroid Build Coastguard Worker
2048*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
2049*a65addddSAndroid Build Coastguard Worker        ('X()', 'X'),
2050*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'),
2051*a65addddSAndroid Build Coastguard Worker    ], [
2052*a65addddSAndroid Build Coastguard Worker        ('WithNoAnnotation', 'Y'),
2053*a65addddSAndroid Build Coastguard Worker        ('WithAnnotation1', 'fruit::Annotated<Annotation1, Y>'),
2054*a65addddSAndroid Build Coastguard Worker    ], [
2055*a65addddSAndroid Build Coastguard Worker        'X',
2056*a65addddSAndroid Build Coastguard Worker        'std::unique_ptr<X>',
2057*a65addddSAndroid Build Coastguard Worker    ], [
2058*a65addddSAndroid Build Coastguard Worker        'Y*',
2059*a65addddSAndroid Build Coastguard Worker        'Y&',
2060*a65addddSAndroid Build Coastguard Worker        'std::shared_ptr<Y>',
2061*a65addddSAndroid Build Coastguard Worker        'fruit::Provider<Y>',
2062*a65addddSAndroid Build Coastguard Worker    ])
2063*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_param_error_nonconst_param_required(self, ConstructX, XPtr, WithAnnot, YAnnotRegex, XFactoryResult, YVariant):
2064*a65addddSAndroid Build Coastguard Worker        source = '''
2065*a65addddSAndroid Build Coastguard Worker            struct Y {};
2066*a65addddSAndroid Build Coastguard Worker            struct X {};
2067*a65addddSAndroid Build Coastguard Worker
2068*a65addddSAndroid Build Coastguard Worker            fruit::Component<WithAnnot<const Y>> getYComponent();
2069*a65addddSAndroid Build Coastguard Worker
2070*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<XFactoryResult()>> getComponent() {
2071*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2072*a65addddSAndroid Build Coastguard Worker                .install(getYComponent)
2073*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; });
2074*a65addddSAndroid Build Coastguard Worker            }
2075*a65addddSAndroid Build Coastguard Worker            '''
2076*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
2077*a65addddSAndroid Build Coastguard Worker            'NonConstBindingRequiredButConstBindingProvidedError<YAnnotRegex>',
2078*a65addddSAndroid Build Coastguard Worker            'The type T was provided as constant, however one of the constructors/providers/factories in this component',
2079*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2080*a65addddSAndroid Build Coastguard Worker            source,
2081*a65addddSAndroid Build Coastguard Worker            locals())
2082*a65addddSAndroid Build Coastguard Worker
2083*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
2084*a65addddSAndroid Build Coastguard Worker        ('X()', 'X'),
2085*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'),
2086*a65addddSAndroid Build Coastguard Worker    ], [
2087*a65addddSAndroid Build Coastguard Worker        'X',
2088*a65addddSAndroid Build Coastguard Worker        'std::unique_ptr<X>',
2089*a65addddSAndroid Build Coastguard Worker    ], [
2090*a65addddSAndroid Build Coastguard Worker        ('WithNoAnnotation', 'Y'),
2091*a65addddSAndroid Build Coastguard Worker        ('WithAnnotation1', 'fruit::Annotated<Annotation1, Y>'),
2092*a65addddSAndroid Build Coastguard Worker    ], [
2093*a65addddSAndroid Build Coastguard Worker        'Y*',
2094*a65addddSAndroid Build Coastguard Worker        'Y&',
2095*a65addddSAndroid Build Coastguard Worker        'std::shared_ptr<Y>',
2096*a65addddSAndroid Build Coastguard Worker        'fruit::Provider<Y>',
2097*a65addddSAndroid Build Coastguard Worker    ])
2098*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_param_error_nonconst_param_required_install_after(self, ConstructX, XPtr, XFactoryResult, WithAnnot, YAnnotRegex, YVariant):
2099*a65addddSAndroid Build Coastguard Worker        source = '''
2100*a65addddSAndroid Build Coastguard Worker            struct Y {};
2101*a65addddSAndroid Build Coastguard Worker            struct X {};
2102*a65addddSAndroid Build Coastguard Worker
2103*a65addddSAndroid Build Coastguard Worker            fruit::Component<WithAnnot<const Y>> getYComponent();
2104*a65addddSAndroid Build Coastguard Worker
2105*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<XFactoryResult()>> getComponent() {
2106*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2107*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; })
2108*a65addddSAndroid Build Coastguard Worker                .install(getYComponent);
2109*a65addddSAndroid Build Coastguard Worker            }
2110*a65addddSAndroid Build Coastguard Worker            '''
2111*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
2112*a65addddSAndroid Build Coastguard Worker            'NonConstBindingRequiredButConstBindingProvidedError<YAnnotRegex>',
2113*a65addddSAndroid Build Coastguard Worker            'The type T was provided as constant, however one of the constructors/providers/factories in this component',
2114*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2115*a65addddSAndroid Build Coastguard Worker            source,
2116*a65addddSAndroid Build Coastguard Worker            locals())
2117*a65addddSAndroid Build Coastguard Worker
2118*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
2119*a65addddSAndroid Build Coastguard Worker        ('X()', 'X'),
2120*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'),
2121*a65addddSAndroid Build Coastguard Worker    ], [
2122*a65addddSAndroid Build Coastguard Worker        'WithNoAnnotation',
2123*a65addddSAndroid Build Coastguard Worker        'WithAnnotation1',
2124*a65addddSAndroid Build Coastguard Worker    ])
2125*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_non_assignable_injected_param_success(self, ConstructX, XPtr, WithAnnot):
2126*a65addddSAndroid Build Coastguard Worker        source = '''
2127*a65addddSAndroid Build Coastguard Worker            struct Y {
2128*a65addddSAndroid Build Coastguard Worker              Y(const Y&) = delete;
2129*a65addddSAndroid Build Coastguard Worker              Y& operator=(const Y&) = delete;
2130*a65addddSAndroid Build Coastguard Worker
2131*a65addddSAndroid Build Coastguard Worker              Y() = default;
2132*a65addddSAndroid Build Coastguard Worker              Y(Y&&) = default;
2133*a65addddSAndroid Build Coastguard Worker              Y& operator=(Y&&) = default;
2134*a65addddSAndroid Build Coastguard Worker            };
2135*a65addddSAndroid Build Coastguard Worker            struct X {};
2136*a65addddSAndroid Build Coastguard Worker
2137*a65addddSAndroid Build Coastguard Worker            fruit::Component<WithAnnot<Y>> getYComponent() {
2138*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2139*a65addddSAndroid Build Coastguard Worker                .registerConstructor<WithAnnot<Y>()>();
2140*a65addddSAndroid Build Coastguard Worker            }
2141*a65addddSAndroid Build Coastguard Worker
2142*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<XPtr()>> getComponent() {
2143*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2144*a65addddSAndroid Build Coastguard Worker                .install(getYComponent)
2145*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtr(WithAnnot<Y&>)>([](Y&){ return ConstructX; });
2146*a65addddSAndroid Build Coastguard Worker            }
2147*a65addddSAndroid Build Coastguard Worker
2148*a65addddSAndroid Build Coastguard Worker            int main() {
2149*a65addddSAndroid Build Coastguard Worker              fruit::Injector<std::function<XPtr()>> injector(getComponent);
2150*a65addddSAndroid Build Coastguard Worker              XPtr x = injector.get<std::function<XPtr()>>()();
2151*a65addddSAndroid Build Coastguard Worker              (void) x;
2152*a65addddSAndroid Build Coastguard Worker            }
2153*a65addddSAndroid Build Coastguard Worker            '''
2154*a65addddSAndroid Build Coastguard Worker        expect_success(
2155*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2156*a65addddSAndroid Build Coastguard Worker            source,
2157*a65addddSAndroid Build Coastguard Worker            locals())
2158*a65addddSAndroid Build Coastguard Worker
2159*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
2160*a65addddSAndroid Build Coastguard Worker        ('X()', 'X'),
2161*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'),
2162*a65addddSAndroid Build Coastguard Worker    ])
2163*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_non_assignable_assisted_param_success(self, ConstructX, XPtr):
2164*a65addddSAndroid Build Coastguard Worker        source = '''
2165*a65addddSAndroid Build Coastguard Worker            struct Y {
2166*a65addddSAndroid Build Coastguard Worker              Y(const Y&) = delete;
2167*a65addddSAndroid Build Coastguard Worker              Y& operator=(const Y&) = delete;
2168*a65addddSAndroid Build Coastguard Worker
2169*a65addddSAndroid Build Coastguard Worker              Y() = default;
2170*a65addddSAndroid Build Coastguard Worker              Y(Y&&) = default;
2171*a65addddSAndroid Build Coastguard Worker              Y& operator=(Y&&) = default;
2172*a65addddSAndroid Build Coastguard Worker            };
2173*a65addddSAndroid Build Coastguard Worker            struct X {};
2174*a65addddSAndroid Build Coastguard Worker
2175*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<XPtr(Y)>> getComponent() {
2176*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2177*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtr(fruit::Assisted<Y>)>([](Y){ return ConstructX; });
2178*a65addddSAndroid Build Coastguard Worker            }
2179*a65addddSAndroid Build Coastguard Worker
2180*a65addddSAndroid Build Coastguard Worker            int main() {
2181*a65addddSAndroid Build Coastguard Worker              fruit::Injector<std::function<XPtr(Y)>> injector(getComponent);
2182*a65addddSAndroid Build Coastguard Worker              XPtr x = injector.get<std::function<XPtr(Y)>>()(Y());
2183*a65addddSAndroid Build Coastguard Worker              (void) x;
2184*a65addddSAndroid Build Coastguard Worker            }
2185*a65addddSAndroid Build Coastguard Worker            '''
2186*a65addddSAndroid Build Coastguard Worker        expect_success(
2187*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2188*a65addddSAndroid Build Coastguard Worker            source,
2189*a65addddSAndroid Build Coastguard Worker            locals())
2190*a65addddSAndroid Build Coastguard Worker
2191*a65addddSAndroid Build Coastguard Worker    def test_register_factory_requiring_nonconst_then_requiring_const_ok(self):
2192*a65addddSAndroid Build Coastguard Worker        source = '''
2193*a65addddSAndroid Build Coastguard Worker            struct X {};
2194*a65addddSAndroid Build Coastguard Worker            struct Y {};
2195*a65addddSAndroid Build Coastguard Worker            struct Z {};
2196*a65addddSAndroid Build Coastguard Worker
2197*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<Y()>, std::function<Z()>> getRootComponent() {
2198*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2199*a65addddSAndroid Build Coastguard Worker                .registerFactory<Y(X&)>([](X&) { return Y();})
2200*a65addddSAndroid Build Coastguard Worker                .registerFactory<Z(const X&)>([](const X&) { return Z();})
2201*a65addddSAndroid Build Coastguard Worker                .registerConstructor<X()>();
2202*a65addddSAndroid Build Coastguard Worker            }
2203*a65addddSAndroid Build Coastguard Worker
2204*a65addddSAndroid Build Coastguard Worker            int main() {
2205*a65addddSAndroid Build Coastguard Worker              fruit::Injector<std::function<Y()>, std::function<Z()>> injector(getRootComponent);
2206*a65addddSAndroid Build Coastguard Worker              std::function<Y()> yFactory = injector.get<std::function<Y()>>();
2207*a65addddSAndroid Build Coastguard Worker              yFactory();
2208*a65addddSAndroid Build Coastguard Worker              std::function<Z()> zFactory = injector.get<std::function<Z()>>();
2209*a65addddSAndroid Build Coastguard Worker              zFactory();
2210*a65addddSAndroid Build Coastguard Worker            }
2211*a65addddSAndroid Build Coastguard Worker            '''
2212*a65addddSAndroid Build Coastguard Worker        expect_success(
2213*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2214*a65addddSAndroid Build Coastguard Worker            source,
2215*a65addddSAndroid Build Coastguard Worker            locals())
2216*a65addddSAndroid Build Coastguard Worker
2217*a65addddSAndroid Build Coastguard Worker    def test_register_factory_requiring_nonconst_then_requiring_const_declaring_const_requirement_error(self):
2218*a65addddSAndroid Build Coastguard Worker        source = '''
2219*a65addddSAndroid Build Coastguard Worker            struct X {};
2220*a65addddSAndroid Build Coastguard Worker            struct Y {};
2221*a65addddSAndroid Build Coastguard Worker            struct Z {};
2222*a65addddSAndroid Build Coastguard Worker
2223*a65addddSAndroid Build Coastguard Worker            fruit::Component<fruit::Required<const X>, std::function<Y()>, std::function<Z()>> getRootComponent() {
2224*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2225*a65addddSAndroid Build Coastguard Worker                .registerFactory<Y(X&)>([](X&) { return Y();})
2226*a65addddSAndroid Build Coastguard Worker                .registerFactory<Z(const X&)>([](const X&) { return Z();});
2227*a65addddSAndroid Build Coastguard Worker            }
2228*a65addddSAndroid Build Coastguard Worker            '''
2229*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
2230*a65addddSAndroid Build Coastguard Worker            'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>',
2231*a65addddSAndroid Build Coastguard Worker            'The type T was declared as a const Required type in the returned Component, however',
2232*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2233*a65addddSAndroid Build Coastguard Worker            source,
2234*a65addddSAndroid Build Coastguard Worker            locals())
2235*a65addddSAndroid Build Coastguard Worker
2236*a65addddSAndroid Build Coastguard Worker    def test_register_factory_requiring_const_then_requiring_nonconst_ok(self):
2237*a65addddSAndroid Build Coastguard Worker        source = '''
2238*a65addddSAndroid Build Coastguard Worker            struct X {};
2239*a65addddSAndroid Build Coastguard Worker            struct Y {};
2240*a65addddSAndroid Build Coastguard Worker            struct Z {};
2241*a65addddSAndroid Build Coastguard Worker
2242*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<Y()>, std::function<Z()>> getRootComponent() {
2243*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2244*a65addddSAndroid Build Coastguard Worker                .registerFactory<Y(const X&)>([](const X&) { return Y();})
2245*a65addddSAndroid Build Coastguard Worker                .registerFactory<Z(X&)>([](X&) { return Z();})
2246*a65addddSAndroid Build Coastguard Worker                .registerConstructor<X()>();
2247*a65addddSAndroid Build Coastguard Worker            }
2248*a65addddSAndroid Build Coastguard Worker
2249*a65addddSAndroid Build Coastguard Worker            int main() {
2250*a65addddSAndroid Build Coastguard Worker              fruit::Injector<std::function<Y()>, std::function<Z()>> injector(getRootComponent);
2251*a65addddSAndroid Build Coastguard Worker              std::function<Y()> yFactory = injector.get<std::function<Y()>>();
2252*a65addddSAndroid Build Coastguard Worker              yFactory();
2253*a65addddSAndroid Build Coastguard Worker              std::function<Z()> zFactory = injector.get<std::function<Z()>>();
2254*a65addddSAndroid Build Coastguard Worker              zFactory();
2255*a65addddSAndroid Build Coastguard Worker            }
2256*a65addddSAndroid Build Coastguard Worker            '''
2257*a65addddSAndroid Build Coastguard Worker        expect_success(
2258*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2259*a65addddSAndroid Build Coastguard Worker            source,
2260*a65addddSAndroid Build Coastguard Worker            locals())
2261*a65addddSAndroid Build Coastguard Worker
2262*a65addddSAndroid Build Coastguard Worker    def test_register_factory_requiring_const_then_requiring_nonconst_declaring_const_requirement_error(self):
2263*a65addddSAndroid Build Coastguard Worker        source = '''
2264*a65addddSAndroid Build Coastguard Worker            struct X {};
2265*a65addddSAndroid Build Coastguard Worker            struct Y {};
2266*a65addddSAndroid Build Coastguard Worker            struct Z {};
2267*a65addddSAndroid Build Coastguard Worker
2268*a65addddSAndroid Build Coastguard Worker            fruit::Component<fruit::Required<const X>, std::function<Y()>, std::function<Z()>> getRootComponent() {
2269*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2270*a65addddSAndroid Build Coastguard Worker                .registerFactory<Y(const X&)>([](const X&) { return Y();})
2271*a65addddSAndroid Build Coastguard Worker                .registerFactory<Z(X&)>([](X&) { return Z();});
2272*a65addddSAndroid Build Coastguard Worker            }
2273*a65addddSAndroid Build Coastguard Worker            '''
2274*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
2275*a65addddSAndroid Build Coastguard Worker            'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>',
2276*a65addddSAndroid Build Coastguard Worker            'The type T was declared as a const Required type in the returned Component, however',
2277*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2278*a65addddSAndroid Build Coastguard Worker            source,
2279*a65addddSAndroid Build Coastguard Worker            locals())
2280*a65addddSAndroid Build Coastguard Worker
2281*a65addddSAndroid Build Coastguard Worker    def test_provider_get_error_type_unique_pointer_pointer_not_provided(self):
2282*a65addddSAndroid Build Coastguard Worker        source = '''
2283*a65addddSAndroid Build Coastguard Worker            struct X {};
2284*a65addddSAndroid Build Coastguard Worker
2285*a65addddSAndroid Build Coastguard Worker            void f(fruit::Provider<X> provider) {
2286*a65addddSAndroid Build Coastguard Worker              provider.get<std::unique_ptr<X>*>();
2287*a65addddSAndroid Build Coastguard Worker            }
2288*a65addddSAndroid Build Coastguard Worker            '''
2289*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
2290*a65addddSAndroid Build Coastguard Worker            r'TypeNotProvidedError<std::unique_ptr<X(,std::default_delete<X>)?>\*>',
2291*a65addddSAndroid Build Coastguard Worker            r'Trying to get an instance of T, but it is not provided by this Provider/Injector.',
2292*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2293*a65addddSAndroid Build Coastguard Worker            source)
2294*a65addddSAndroid Build Coastguard Worker
2295*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
2296*a65addddSAndroid Build Coastguard Worker        ('X()', 'X'),
2297*a65addddSAndroid Build Coastguard Worker        ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'),
2298*a65addddSAndroid Build Coastguard Worker    ], [
2299*a65addddSAndroid Build Coastguard Worker        'X',
2300*a65addddSAndroid Build Coastguard Worker        'std::unique_ptr<X>',
2301*a65addddSAndroid Build Coastguard Worker    ], [
2302*a65addddSAndroid Build Coastguard Worker        ('Y**', r'Y\*\*'),
2303*a65addddSAndroid Build Coastguard Worker        ('std::shared_ptr<Y>*', r'std::shared_ptr<Y>\*'),
2304*a65addddSAndroid Build Coastguard Worker        ('std::nullptr_t', r'(std::)?nullptr(_t)?'),
2305*a65addddSAndroid Build Coastguard Worker        ('Y*&', r'Y\*&'),
2306*a65addddSAndroid Build Coastguard Worker        ('Y(*)()', r'Y(\((__cdecl)?\*\))?\((void)?\)'),
2307*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Y**>', r'Y\*\*'),
2308*a65addddSAndroid Build Coastguard Worker    ])
2309*a65addddSAndroid Build Coastguard Worker    def test_register_factory_with_param_error_type_not_injectable(self,
2310*a65addddSAndroid Build Coastguard Worker            ConstructX, XPtr, XFactoryResult, YVariant, YVariantRegex):
2311*a65addddSAndroid Build Coastguard Worker        source = '''
2312*a65addddSAndroid Build Coastguard Worker            struct Y {};
2313*a65addddSAndroid Build Coastguard Worker            struct X {};
2314*a65addddSAndroid Build Coastguard Worker
2315*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent() {
2316*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2317*a65addddSAndroid Build Coastguard Worker                .registerFactory<XPtr(YVariant)>([](YVariant){ return ConstructX; });
2318*a65addddSAndroid Build Coastguard Worker            }
2319*a65addddSAndroid Build Coastguard Worker            '''
2320*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
2321*a65addddSAndroid Build Coastguard Worker            'NonInjectableTypeError<YVariantRegex>',
2322*a65addddSAndroid Build Coastguard Worker            'The type T is not injectable.',
2323*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2324*a65addddSAndroid Build Coastguard Worker            source,
2325*a65addddSAndroid Build Coastguard Worker            locals())
2326*a65addddSAndroid Build Coastguard Worker
2327*a65addddSAndroid Build Coastguard Worker    def test_register_factory_bind_nonconst_unique_ptr_factory_to_const_value_factory(self):
2328*a65addddSAndroid Build Coastguard Worker        source = '''
2329*a65addddSAndroid Build Coastguard Worker            struct X {
2330*a65addddSAndroid Build Coastguard Worker              INJECT(X()) = default;
2331*a65addddSAndroid Build Coastguard Worker            };
2332*a65addddSAndroid Build Coastguard Worker
2333*a65addddSAndroid Build Coastguard Worker            fruit::Component<const std::function<X()>> getChildComponent() {
2334*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
2335*a65addddSAndroid Build Coastguard Worker            }
2336*a65addddSAndroid Build Coastguard Worker
2337*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<std::unique_ptr<X>()>> getRootComponent() {
2338*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2339*a65addddSAndroid Build Coastguard Worker                  .install(getChildComponent);
2340*a65addddSAndroid Build Coastguard Worker            }
2341*a65addddSAndroid Build Coastguard Worker
2342*a65addddSAndroid Build Coastguard Worker            int main() {
2343*a65addddSAndroid Build Coastguard Worker              fruit::Injector<std::function<std::unique_ptr<X>()>> injector(getRootComponent);
2344*a65addddSAndroid Build Coastguard Worker              std::function<std::unique_ptr<X>()> xFactory(injector);
2345*a65addddSAndroid Build Coastguard Worker              xFactory();
2346*a65addddSAndroid Build Coastguard Worker            }
2347*a65addddSAndroid Build Coastguard Worker            '''
2348*a65addddSAndroid Build Coastguard Worker        expect_success(
2349*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2350*a65addddSAndroid Build Coastguard Worker            source,
2351*a65addddSAndroid Build Coastguard Worker            locals())
2352*a65addddSAndroid Build Coastguard Worker
2353*a65addddSAndroid Build Coastguard Worker    def test_register_factory_bind_const_interface_factory_to_nonconst_implementation_factory(self):
2354*a65addddSAndroid Build Coastguard Worker        source = '''
2355*a65addddSAndroid Build Coastguard Worker            struct X {
2356*a65addddSAndroid Build Coastguard Worker              virtual void foo() = 0;
2357*a65addddSAndroid Build Coastguard Worker              virtual ~X() = default;
2358*a65addddSAndroid Build Coastguard Worker            };
2359*a65addddSAndroid Build Coastguard Worker
2360*a65addddSAndroid Build Coastguard Worker            struct Y : public X {
2361*a65addddSAndroid Build Coastguard Worker              INJECT(Y()) = default;
2362*a65addddSAndroid Build Coastguard Worker
2363*a65addddSAndroid Build Coastguard Worker              void foo() override {
2364*a65addddSAndroid Build Coastguard Worker              }
2365*a65addddSAndroid Build Coastguard Worker            };
2366*a65addddSAndroid Build Coastguard Worker
2367*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<std::unique_ptr<Y>()>> getChildComponent() {
2368*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
2369*a65addddSAndroid Build Coastguard Worker            }
2370*a65addddSAndroid Build Coastguard Worker
2371*a65addddSAndroid Build Coastguard Worker            fruit::Component<const std::function<std::unique_ptr<X>()>> getRootComponent() {
2372*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2373*a65addddSAndroid Build Coastguard Worker                  .install(getChildComponent)
2374*a65addddSAndroid Build Coastguard Worker                  .bind<X, Y>();
2375*a65addddSAndroid Build Coastguard Worker            }
2376*a65addddSAndroid Build Coastguard Worker
2377*a65addddSAndroid Build Coastguard Worker            int main() {
2378*a65addddSAndroid Build Coastguard Worker              fruit::Injector<const std::function<std::unique_ptr<X>()>> injector(getRootComponent);
2379*a65addddSAndroid Build Coastguard Worker              std::function<std::unique_ptr<X>()> xFactory(injector);
2380*a65addddSAndroid Build Coastguard Worker              xFactory();
2381*a65addddSAndroid Build Coastguard Worker            }
2382*a65addddSAndroid Build Coastguard Worker            '''
2383*a65addddSAndroid Build Coastguard Worker        expect_success(
2384*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2385*a65addddSAndroid Build Coastguard Worker            source,
2386*a65addddSAndroid Build Coastguard Worker            locals())
2387*a65addddSAndroid Build Coastguard Worker
2388*a65addddSAndroid Build Coastguard Worker    def test_register_factory_bind_nonconst_interface_factory_to_const_implementation_factory(self):
2389*a65addddSAndroid Build Coastguard Worker        source = '''
2390*a65addddSAndroid Build Coastguard Worker            struct X {
2391*a65addddSAndroid Build Coastguard Worker              virtual void foo() = 0;
2392*a65addddSAndroid Build Coastguard Worker              virtual ~X() = default;
2393*a65addddSAndroid Build Coastguard Worker            };
2394*a65addddSAndroid Build Coastguard Worker
2395*a65addddSAndroid Build Coastguard Worker            struct Y : public X {
2396*a65addddSAndroid Build Coastguard Worker              INJECT(Y()) = default;
2397*a65addddSAndroid Build Coastguard Worker
2398*a65addddSAndroid Build Coastguard Worker              void foo() override {
2399*a65addddSAndroid Build Coastguard Worker              }
2400*a65addddSAndroid Build Coastguard Worker            };
2401*a65addddSAndroid Build Coastguard Worker
2402*a65addddSAndroid Build Coastguard Worker            fruit::Component<const std::function<std::unique_ptr<Y>()>> getChildComponent() {
2403*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
2404*a65addddSAndroid Build Coastguard Worker            }
2405*a65addddSAndroid Build Coastguard Worker
2406*a65addddSAndroid Build Coastguard Worker            fruit::Component<std::function<std::unique_ptr<X>()>> getRootComponent() {
2407*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2408*a65addddSAndroid Build Coastguard Worker                  .install(getChildComponent)
2409*a65addddSAndroid Build Coastguard Worker                  .bind<X, Y>();
2410*a65addddSAndroid Build Coastguard Worker            }
2411*a65addddSAndroid Build Coastguard Worker
2412*a65addddSAndroid Build Coastguard Worker            int main() {
2413*a65addddSAndroid Build Coastguard Worker              fruit::Injector<std::function<std::unique_ptr<X>()>> injector(getRootComponent);
2414*a65addddSAndroid Build Coastguard Worker              std::function<std::unique_ptr<X>()> xFactory(injector);
2415*a65addddSAndroid Build Coastguard Worker              xFactory();
2416*a65addddSAndroid Build Coastguard Worker            }
2417*a65addddSAndroid Build Coastguard Worker            '''
2418*a65addddSAndroid Build Coastguard Worker        expect_success(
2419*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2420*a65addddSAndroid Build Coastguard Worker            source,
2421*a65addddSAndroid Build Coastguard Worker            locals())
2422*a65addddSAndroid Build Coastguard Worker
2423*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
2424*a65addddSAndroid Build Coastguard Worker        'WithNoAnnotation',
2425*a65addddSAndroid Build Coastguard Worker        'WithAnnotation1',
2426*a65addddSAndroid Build Coastguard Worker    ])
2427*a65addddSAndroid Build Coastguard Worker    def test_register_factory_abstract_class_ok(self, WithAnnot):
2428*a65addddSAndroid Build Coastguard Worker        source = '''
2429*a65addddSAndroid Build Coastguard Worker            struct I {
2430*a65addddSAndroid Build Coastguard Worker              virtual int foo() = 0;
2431*a65addddSAndroid Build Coastguard Worker              virtual ~I() = default;
2432*a65addddSAndroid Build Coastguard Worker            };
2433*a65addddSAndroid Build Coastguard Worker
2434*a65addddSAndroid Build Coastguard Worker            struct X : public I {
2435*a65addddSAndroid Build Coastguard Worker              int foo() override {
2436*a65addddSAndroid Build Coastguard Worker                return 5;
2437*a65addddSAndroid Build Coastguard Worker              }
2438*a65addddSAndroid Build Coastguard Worker            };
2439*a65addddSAndroid Build Coastguard Worker
2440*a65addddSAndroid Build Coastguard Worker            fruit::Component<WithAnnot<std::function<std::unique_ptr<I>()>>> getComponent() {
2441*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2442*a65addddSAndroid Build Coastguard Worker                .registerFactory<WithAnnot<std::unique_ptr<I>>()>([](){return std::unique_ptr<I>(static_cast<I*>(new X()));});
2443*a65addddSAndroid Build Coastguard Worker            }
2444*a65addddSAndroid Build Coastguard Worker
2445*a65addddSAndroid Build Coastguard Worker            int main() {
2446*a65addddSAndroid Build Coastguard Worker              fruit::Injector<WithAnnot<std::function<std::unique_ptr<I>()>>> injector(getComponent);
2447*a65addddSAndroid Build Coastguard Worker
2448*a65addddSAndroid Build Coastguard Worker              Assert(injector.get<WithAnnot<std::function<std::unique_ptr<I>()>>>()()->foo() == 5);
2449*a65addddSAndroid Build Coastguard Worker            }
2450*a65addddSAndroid Build Coastguard Worker            '''
2451*a65addddSAndroid Build Coastguard Worker        expect_success(
2452*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2453*a65addddSAndroid Build Coastguard Worker            source,
2454*a65addddSAndroid Build Coastguard Worker            locals())
2455*a65addddSAndroid Build Coastguard Worker
2456*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
2457*a65addddSAndroid Build Coastguard Worker        'WithNoAnnotation',
2458*a65addddSAndroid Build Coastguard Worker        'WithAnnotation1',
2459*a65addddSAndroid Build Coastguard Worker    ])
2460*a65addddSAndroid Build Coastguard Worker    def test_register_factory_abstract_class_with_no_virtual_destructor_error(self, WithAnnot):
2461*a65addddSAndroid Build Coastguard Worker        if re.search('MSVC', CXX_COMPILER_NAME):
2462*a65addddSAndroid Build Coastguard Worker            # This is disabled in MSVC because it compiles cleanly with the latest MSVC.
2463*a65addddSAndroid Build Coastguard Worker            # TODO: investigate why this doesn't fail to compile with MSVC and then re-enable it for MSVC too.
2464*a65addddSAndroid Build Coastguard Worker            return
2465*a65addddSAndroid Build Coastguard Worker        source = '''
2466*a65addddSAndroid Build Coastguard Worker            struct I {
2467*a65addddSAndroid Build Coastguard Worker              virtual int foo() = 0;
2468*a65addddSAndroid Build Coastguard Worker            };
2469*a65addddSAndroid Build Coastguard Worker
2470*a65addddSAndroid Build Coastguard Worker            struct X : public I {
2471*a65addddSAndroid Build Coastguard Worker              int foo() override {
2472*a65addddSAndroid Build Coastguard Worker                return 5;
2473*a65addddSAndroid Build Coastguard Worker              }
2474*a65addddSAndroid Build Coastguard Worker            };
2475*a65addddSAndroid Build Coastguard Worker
2476*a65addddSAndroid Build Coastguard Worker            fruit::Component<WithAnnot<std::function<std::unique_ptr<I>()>>> getComponent() {
2477*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
2478*a65addddSAndroid Build Coastguard Worker                .registerFactory<WithAnnot<std::unique_ptr<I>>()>([](){return std::unique_ptr<I>(static_cast<I*>(new X()));});
2479*a65addddSAndroid Build Coastguard Worker            }
2480*a65addddSAndroid Build Coastguard Worker            '''
2481*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
2482*a65addddSAndroid Build Coastguard Worker            r'RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorError<I>',
2483*a65addddSAndroid Build Coastguard Worker            r'registerFactory\(\) was called with a lambda that returns a std::unique_ptr<T>, but T is an abstract class',
2484*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
2485*a65addddSAndroid Build Coastguard Worker            source,
2486*a65addddSAndroid Build Coastguard Worker            locals(),
2487*a65addddSAndroid Build Coastguard Worker            ignore_warnings=True,
2488*a65addddSAndroid Build Coastguard Worker            disable_error_line_number_check=True)
2489*a65addddSAndroid Build Coastguard Worker
2490*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__':
2491*a65addddSAndroid Build Coastguard Worker    absltest.main()
2492