Home | History | Annotate | Download | only in tests
      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.
     15 
     16 from fruit_test_common import *
     17 
     18 COMMON_DEFINITIONS = '''
     19     #include "test_common.h"
     20     
     21     template <typename T>
     22     class V {};
     23     
     24     template <typename T>
     25     class X {
     26     private:
     27       X() {}
     28       
     29     public:
     30       INJECT(X(ASSISTED(int))) {
     31       }
     32     };
     33     
     34     using XFactory = std::function<X<V<float>>(int)>;
     35     '''
     36 
     37 def test_misc():
     38     source = '''
     39         fruit::Component<X<V<float>>> getXProvider2() {
     40           return fruit::createComponent()
     41               .registerProvider([](){return X<V<float>>(1);});
     42         }
     43         
     44         struct AssistedMultiparamExample {
     45           INJECT(AssistedMultiparamExample(ASSISTED(std::map<int, float>))) {}
     46         };
     47         
     48         struct Implementation1 {
     49           bool constructed = true;
     50           
     51           Implementation1(V<int>&&, XFactory) {
     52             std::cout << "Called Implementation1() for object " << this << std::endl;
     53           }
     54           
     55           Implementation1() = delete;
     56           Implementation1(const Implementation1&) = delete;
     57           
     58           Implementation1& operator=(const Implementation1&) = delete;
     59           Implementation1& operator=(Implementation1&&) = delete;
     60           
     61           Implementation1(Implementation1&&) {
     62             std::cout << "Moving an Implementation1 into object" << this << std::endl;
     63           }
     64           
     65           ~Implementation1() {
     66             std::cout << "Called ~Implementation1() for object " << this << std::endl;
     67             constructed = 0;
     68           }
     69           
     70           int x;
     71         };
     72         
     73         struct Interface2 {
     74           virtual void f() = 0;
     75         };
     76         
     77         struct Implementation2 : public Interface2 {
     78           INJECT(Implementation2(std::function<Implementation1(int)>)) {
     79             std::cout << "Called Implementation2()" << std::endl;
     80           }
     81           
     82           virtual ~Implementation2() {}
     83           
     84           virtual void f() {};
     85         };
     86         
     87         fruit::Component<Interface2, XFactory, std::function<Implementation1(int)>> getParentComponent() {
     88           return fruit::createComponent()
     89               .registerFactory<Implementation1(fruit::Assisted<int>, XFactory)>(
     90                 [](int, XFactory xFactory) {
     91                   return Implementation1(V<int>(), xFactory);
     92                 })
     93               .bind<Interface2, Implementation2>();
     94         }
     95         
     96         //*************************************
     97         
     98         struct Interface3 {
     99           virtual void f() = 0;
    100         };
    101         
    102         struct Implementation3 : public Interface3 {
    103           INJECT(Implementation3(Implementation2*, fruit::Provider<Implementation2> provider)) {
    104             (void) provider.get();
    105             std::cout << "Called Implementation2()" << std::endl;
    106           }
    107           
    108           virtual ~Implementation3() {}
    109           
    110           virtual void f() {};
    111         };
    112         
    113         fruit::Component<Interface3, std::function<Implementation1(int)>> getMyComponent() {
    114           return fruit::createComponent()
    115               // Must fail at runtime.
    116               // .install(getXProvider2)
    117               .bind<Interface3, Implementation3>()
    118               .install(getParentComponent);
    119         }
    120         
    121         fruit::Component<std::function<AssistedMultiparamExample(std::map<int, float>)>> getAssistedMultiparamExampleComponent() {
    122           return fruit::createComponent();
    123         }
    124         
    125         int main() {
    126           fruit::Injector<
    127             Interface3,
    128             // XFactory,
    129             std::function<Implementation1(int)>
    130             > oldInjector(getMyComponent);
    131         
    132           // The move is completely unnecessary, it's just to check that it works.
    133           fruit::Injector<
    134             Interface3,
    135             // XFactory,
    136             std::function<Implementation1(int)>
    137             > injector(std::move(oldInjector));
    138           
    139           std::cout << "Constructing an Interface3" << std::endl;
    140           Interface3* interface3(injector);
    141           std::cout << std::endl;
    142           (void) interface3;
    143           
    144           std::cout << "Constructing another Interface3" << std::endl;
    145           Interface3* interface3_obj2 = injector.get<Interface3*>();
    146           std::cout << std::endl;
    147           (void) interface3_obj2;
    148           
    149           std::function<Implementation1(int)> implementation1Factory(injector);
    150           {
    151              std::cout << "Constructing another Implementation1" << std::endl;
    152              Implementation1 implementation1 = implementation1Factory(12);
    153              (void) implementation1;
    154           }
    155           std::cout << "Destroying injector" << std::endl;
    156           
    157           fruit::Injector<std::function<AssistedMultiparamExample(std::map<int, float>)>> assistedMultiparamExampleInjector(
    158             getAssistedMultiparamExampleComponent);
    159           
    160           return 0;
    161         }
    162         '''
    163     expect_success(
    164         COMMON_DEFINITIONS,
    165         source,
    166         locals())
    167 
    168 if __name__== '__main__':
    169     main(__file__)
    170