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     struct X;
     22 
     23     struct Annotation1 {};
     24     using XAnnot1 = fruit::Annotated<Annotation1, X>;
     25     '''
     26 
     27 def test_install_component_functions_deduped_against_previous_install_no_args():
     28     source = '''
     29         int num_executions = 0;
     30         
     31         fruit::Component<int> getChildComponent() {
     32           static int n = 5;
     33           ++num_executions;
     34           return fruit::createComponent()
     35               .bindInstance(n);
     36         }
     37         
     38         fruit::Component<> getMiddleComponent() {
     39           return fruit::createComponent()
     40               .install(getChildComponent);
     41         }
     42         
     43         fruit::Component<int> getMainComponent() {
     44           return fruit::createComponent()
     45               .install(getMiddleComponent)
     46               .installComponentFunctions(fruit::componentFunction(getChildComponent));
     47         }
     48 
     49         int main() {
     50           fruit::Injector<int> injector(getMainComponent);
     51           int n = injector.get<int>();
     52           Assert(n == 5);
     53           Assert(num_executions == 1);
     54         }
     55         '''
     56     expect_success(
     57         COMMON_DEFINITIONS,
     58         source,
     59         locals())
     60 
     61 def test_install_component_functions_deduped_against_following_install_no_args():
     62     source = '''
     63         int num_executions = 0;
     64         
     65         fruit::Component<int> getChildComponent() {
     66           static int n = 5;
     67           ++num_executions;
     68           return fruit::createComponent()
     69               .bindInstance(n);
     70         }
     71         
     72         fruit::Component<> getMiddleComponent() {
     73           return fruit::createComponent()
     74               .installComponentFunctions(fruit::componentFunction(getChildComponent));
     75         }
     76         
     77         fruit::Component<int> getMainComponent() {
     78           return fruit::createComponent()
     79               .install(getMiddleComponent)
     80               .install(getChildComponent);
     81         }
     82 
     83         int main() {
     84           fruit::Injector<int> injector(getMainComponent);
     85           int n = injector.get<int>();
     86           Assert(n == 5);
     87           Assert(num_executions == 1);
     88         }
     89         '''
     90     expect_success(
     91         COMMON_DEFINITIONS,
     92         source,
     93         locals())
     94 
     95 def test_install_component_functions_deduped_against_previous_install_with_args():
     96     source = '''
     97         int num_executions = 0;
     98         
     99         fruit::Component<int> getChildComponent(int) {
    100           static int n = 5;
    101           ++num_executions;
    102           return fruit::createComponent()
    103               .bindInstance(n);
    104         }
    105         
    106         fruit::Component<> getMiddleComponent() {
    107           return fruit::createComponent()
    108               .install(getChildComponent, 42);
    109         }
    110                 
    111         fruit::Component<int> getMainComponent() {
    112           return fruit::createComponent()
    113               .install(getMiddleComponent)
    114               .installComponentFunctions(fruit::componentFunction(getChildComponent, 42));
    115         }
    116 
    117         int main() {
    118           fruit::Injector<int> injector(getMainComponent);
    119           int n = injector.get<int>();
    120           Assert(n == 5);
    121           Assert(num_executions == 1);
    122         }
    123         '''
    124     expect_success(
    125         COMMON_DEFINITIONS,
    126         source,
    127         locals())
    128 
    129 def test_install_component_functions_deduped_against_following_install_with_args():
    130     source = '''
    131         int num_executions = 0;
    132         
    133         fruit::Component<int> getChildComponent(int) {
    134           static int n = 5;
    135           ++num_executions;
    136           return fruit::createComponent()
    137               .bindInstance(n);
    138         }
    139         
    140         fruit::Component<> getMiddleComponent() {
    141           return fruit::createComponent()
    142               .installComponentFunctions(fruit::componentFunction(getChildComponent, 42));
    143         }
    144                         
    145         fruit::Component<int> getMainComponent() {
    146           return fruit::createComponent()
    147               .install(getMiddleComponent)
    148               .install(getChildComponent, 42);
    149         }
    150 
    151         int main() {
    152           fruit::Injector<int> injector(getMainComponent);
    153           int n = injector.get<int>();
    154           Assert(n == 5);
    155           Assert(num_executions == 1);
    156         }
    157         '''
    158     expect_success(
    159         COMMON_DEFINITIONS,
    160         source,
    161         locals())
    162 
    163 def test_install_component_functions_same_as_with_previous_install_with_different_args():
    164     source = '''
    165         int num_executions = 0;
    166         
    167         fruit::Component<int> getChildComponent(int) {
    168           static int n = 5;
    169           ++num_executions;
    170           return fruit::createComponent()
    171               .bindInstance(n);
    172         }
    173 
    174         fruit::Component<> getMiddleComponent() {
    175           return fruit::createComponent()
    176               .install(getChildComponent, 42);
    177         }
    178         
    179         fruit::Component<int> getMainComponent() {
    180           return fruit::createComponent()
    181               .install(getMiddleComponent)
    182               .installComponentFunctions(fruit::componentFunction(getChildComponent, 2));
    183         }
    184 
    185         int main() {
    186           fruit::Injector<int> injector(getMainComponent);
    187           int n = injector.get<int>();
    188           Assert(n == 5);
    189           Assert(num_executions == 2);
    190         }
    191         '''
    192     expect_success(
    193         COMMON_DEFINITIONS,
    194         source,
    195         locals())
    196 
    197 def test_install_component_functions_same_as_following_install_with_different_args():
    198     source = '''
    199         int num_executions = 0;
    200         
    201         fruit::Component<int> getChildComponent(int) {
    202           static int n = 5;
    203           ++num_executions;
    204           return fruit::createComponent()
    205               .bindInstance(n);
    206         }
    207 
    208         fruit::Component<> getMiddleComponent() {
    209           return fruit::createComponent()
    210               .installComponentFunctions(fruit::componentFunction(getChildComponent, 42));
    211         }
    212                 
    213         fruit::Component<int> getMainComponent() {
    214           return fruit::createComponent()
    215               .install(getMiddleComponent)
    216               .install(getChildComponent, 2);
    217         }
    218 
    219         int main() {
    220           fruit::Injector<int> injector(getMainComponent);
    221           (void)injector;
    222           Assert(num_executions == 2);
    223         }
    224         '''
    225     expect_success(
    226         COMMON_DEFINITIONS,
    227         source,
    228         locals())
    229 
    230 def test_install_component_functions_no_component_functions():
    231     source = '''
    232         fruit::Component<> getComponent() {
    233           return fruit::createComponent()
    234             .installComponentFunctions();
    235         }
    236 
    237         int main() {
    238           fruit::Injector<> injector(getComponent);
    239           (void)injector;
    240         }
    241         '''
    242     expect_success(COMMON_DEFINITIONS, source)
    243 
    244 def test_install_component_functions_one_component_function():
    245     source = '''
    246         struct X {
    247           int n;
    248           X(int n) : n(n) {}
    249         };
    250         
    251         fruit::Component<X> getParentComponent(std::string) {
    252           return fruit::createComponent()
    253             .registerProvider([]() { return X(5); });
    254         }
    255 
    256         fruit::Component<X> getComponent() {
    257           return fruit::createComponent()
    258             .installComponentFunctions(fruit::componentFunction(getParentComponent, std::string("Hello")));
    259         }
    260 
    261         int main() {
    262           fruit::Injector<X> injector(getComponent);
    263           X x = injector.get<X>();
    264           Assert(x.n == 5);
    265         }
    266         '''
    267     expect_success(COMMON_DEFINITIONS, source)
    268 
    269 def test_install_component_functions_two_component_functions():
    270     source = '''
    271         struct X {
    272           int n;
    273           X(int n) : n(n) {}
    274         };
    275         
    276         struct Y {
    277           int n;
    278           Y(int n) : n(n) {}
    279         };
    280         
    281         fruit::Component<X> getParentComponent1(std::string) {
    282           return fruit::createComponent()
    283             .registerProvider([]() { return X(5); });
    284         }
    285 
    286         fruit::Component<Y> getParentComponent2(std::string) {
    287           return fruit::createComponent()
    288               .registerProvider([]() { return Y(42); });
    289         }
    290 
    291         fruit::Component<X, Y> getComponent() {
    292           return fruit::createComponent()
    293               .installComponentFunctions(
    294                   fruit::componentFunction(getParentComponent1, std::string("Hello")),
    295                   fruit::componentFunction(getParentComponent2, std::string("World")));
    296         }
    297 
    298         int main() {
    299           fruit::Injector<X, Y> injector(getComponent);
    300           X x = injector.get<X>();
    301           Y y = injector.get<Y>();
    302           Assert(x.n == 5);
    303           Assert(y.n == 42);
    304         }
    305         '''
    306     expect_success(COMMON_DEFINITIONS, source)
    307 
    308 def test_install_component_functions_with_template_parameter_pack_unpacking():
    309     source = '''
    310         template <typename T>
    311         struct GetComponentHolder;
    312     
    313         struct X {
    314           int n;
    315           X(int n) : n(n) {}
    316         };
    317         
    318         struct Y {
    319           int n;
    320           Y(int n) : n(n) {}
    321         };
    322         
    323         template <>
    324         struct GetComponentHolder<X> {
    325             static fruit::Component<X> getComponent(std::string) {
    326               return fruit::createComponent()
    327                 .registerProvider([]() { return X(5); });
    328             }
    329         };
    330 
    331         template <>
    332         struct GetComponentHolder<Y> {
    333             static fruit::Component<Y> getComponent(std::string) {
    334               return fruit::createComponent()
    335                   .registerProvider([]() { return Y(42); });
    336             } 
    337         };
    338 
    339         template <typename... Ts>
    340         fruit::Component<Ts...> getComponent() {
    341           return fruit::createComponent()
    342               .installComponentFunctions(
    343                   fruit::componentFunction(GetComponentHolder<Ts>::getComponent, std::string("Hello"))...);
    344         }
    345 
    346         int main() {
    347           fruit::Injector<X, Y> injector(getComponent<X, Y>);
    348           X x = injector.get<X>();
    349           Y y = injector.get<Y>();
    350           Assert(x.n == 5);
    351           Assert(y.n == 42);
    352         }
    353         '''
    354     expect_success(COMMON_DEFINITIONS, source)
    355 
    356 def test_install_component_functions_wrong_argument_type():
    357     source = '''
    358         fruit::Component<> getMainComponent() {
    359           return fruit::createComponent()
    360               .installComponentFunctions(42);
    361         }
    362         '''
    363     expect_compile_error(
    364         'IncorrectArgTypePassedToInstallComponentFuntionsError<int>',
    365         'All arguments passed to installComponentFunctions.. must be fruit::ComponentFunction<...> objects but an '
    366         'argument with type Arg was passed instead.',
    367         COMMON_DEFINITIONS,
    368         source,
    369         locals())
    370 
    371 if __name__== '__main__':
    372     main(__file__)
    373