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