• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
16from absl.testing import parameterized
17from fruit_test_common import *
18
19COMMON_DEFINITIONS = '''
20    #include "test_common.h"
21
22    // The shared_ptr objects below ensure (since these tests are run under Valgrind) that deletion occurs, and only once.
23
24    struct I1 {
25      std::shared_ptr<int> x = std::make_shared<int>(3);
26      virtual ~I1() {}
27    };
28
29    struct I2 {
30      std::shared_ptr<int> x = std::make_shared<int>(3);
31    };
32
33    struct I3 {
34      std::shared_ptr<int> x = std::make_shared<int>(3);
35    };
36
37    struct I4 {
38      std::shared_ptr<int> x = std::make_shared<int>(3);
39    };
40
41    struct X1 : I1 {
42      INJECT(X1()) = default;
43      std::shared_ptr<int> x = std::make_shared<int>(3);
44    };
45
46    struct X2 : I2 {
47      // Taking an X1 here prevents binding compression.
48      INJECT(X2(X1)) {}
49      std::shared_ptr<int> x = std::make_shared<int>(3);
50    };
51
52    struct X3 : public I3 {
53      std::shared_ptr<int> x = std::make_shared<int>(3);
54    };
55
56    struct X4 : public I4 {
57      // Taking an X3 here prevents binding compression.
58      X4(X3) {};
59      std::shared_ptr<int> x = std::make_shared<int>(3);
60    };
61
62    struct X5 {
63      std::shared_ptr<int> x = std::make_shared<int>(3);
64    };
65
66    struct X6 : public I1 {
67      INJECT(X6()) = default;
68      std::shared_ptr<int> x = std::make_shared<int>(3);
69    };
70
71    struct X7 : public I1 {
72      std::shared_ptr<int> x = std::make_shared<int>(3);
73    };
74
75    struct X8 : public I1 {
76      std::shared_ptr<int> x = std::make_shared<int>(3);
77      virtual ~X8() {}
78    };
79
80    struct Annotation {};
81
82    using I1Annot = fruit::Annotated<Annotation, I1>;
83    using I2Annot = fruit::Annotated<Annotation, I2>;
84    using I3Annot = fruit::Annotated<Annotation, I3>;
85    using I4Annot = fruit::Annotated<Annotation, I4>;
86
87    using X1Annot = fruit::Annotated<Annotation, X1>;
88    using X2Annot = fruit::Annotated<Annotation, X2>;
89    using X3Annot = fruit::Annotated<Annotation, X3>;
90    using X4Annot = fruit::Annotated<Annotation, X4>;
91    using X5Annot = fruit::Annotated<Annotation, X5>;
92    using X6Annot = fruit::Annotated<Annotation, X6>;
93    using X7Annot = fruit::Annotated<Annotation, X7>;
94    using X8Annot = fruit::Annotated<Annotation, X8>;
95
96    using X1PtrAnnot = fruit::Annotated<Annotation, X1*>;
97    '''
98
99class TestClassDestruction(parameterized.TestCase):
100    @parameterized.parameters([
101        ('I1', 'I2', 'I3', 'I4', 'X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X1*', 'bindInstance(x5)', 'addInstanceMultibinding(*x7)'),
102        ('I1Annot', 'I2Annot', 'I3Annot', 'I4Annot', 'X1Annot', 'X2Annot', 'X3Annot', 'X4Annot', 'X5Annot', 'X6Annot', 'X7Annot', 'X8Annot', 'X1PtrAnnot', 'bindInstance<X5Annot>(x5)', 'addInstanceMultibinding<X7Annot>(*x7)'),
103    ])
104    def test_injector_creation_no_injection(self,
105            I1Annot, I2Annot, I3Annot, I4Annot, X1Annot, X2Annot, X3Annot, X4Annot, X5Annot, X6Annot, X7Annot, X8Annot, X1PtrAnnot, bindX5Instance, addX7InstanceMultibinding):
106        source = '''
107            fruit::Component<I1Annot, I2Annot, I3Annot, I4Annot, X5Annot> getComponent() {
108              static X5 x5;
109              static std::unique_ptr<X7> x7(new X7());
110              return fruit::createComponent()
111                  .bind<I1Annot, X1Annot>()
112                  .bind<I2Annot, X2Annot>()
113                  .bind<I3Annot, X3Annot>()
114                  .bind<I4Annot, X4Annot>()
115                  .registerProvider<X3Annot()>([]() { return X3(); })
116                  .registerProvider<X4Annot(X3Annot)>([](X3 x3) { return X4(x3); })
117                  .bindX5Instance
118                  .addMultibinding<I1Annot, X6Annot>()
119                  .addX7InstanceMultibinding
120                  .addMultibindingProvider<X1PtrAnnot()>([]() { return (X1*) new X8(); });
121            }
122
123            int main() {
124              fruit::Injector<I1Annot, I2Annot, I3Annot, I4Annot, X5Annot> injector(getComponent);
125              (void)injector;
126            }
127            '''
128        expect_success(
129            COMMON_DEFINITIONS,
130            source,
131            locals())
132
133    @parameterized.parameters([
134        ('I1', 'I2', 'I3', 'I4', 'X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X1*', 'bindInstance(x5)', 'addInstanceMultibinding(*x7)'),
135        ('I1Annot', 'I2Annot', 'I3Annot', 'I4Annot', 'X1Annot', 'X2Annot', 'X3Annot', 'X4Annot', 'X5Annot', 'X6Annot', 'X7Annot', 'X8Annot', 'X1PtrAnnot', 'bindInstance<X5Annot>(x5)', 'addInstanceMultibinding<X7Annot>(*x7)'),
136    ])
137    def test_injector_creation_and_injection(self,
138            I1Annot, I2Annot, I3Annot, I4Annot, X1Annot, X2Annot, X3Annot, X4Annot, X5Annot, X6Annot, X7Annot, X8Annot, X1PtrAnnot, bindX5Instance, addX7InstanceMultibinding):
139        source = '''
140            fruit::Component<I1Annot, I2Annot, I3Annot, I4Annot, X5Annot> getComponent() {
141              static X5 x5;
142              static std::unique_ptr<X7> x7(new X7());
143              return fruit::createComponent()
144                  .bind<I1Annot, X1Annot>()
145                  .bind<I2Annot, X2Annot>()
146                  .bind<I3Annot, X3Annot>()
147                  .bind<I4Annot, X4Annot>()
148                  .registerProvider<X3Annot()>([]() { return X3(); })
149                  .registerProvider<X4Annot(X3Annot)>([](X3 x3) { return X4(x3); })
150                  .bindX5Instance
151                  .addMultibinding<I1Annot, X6Annot>()
152                  .addX7InstanceMultibinding
153                  .addMultibindingProvider<X1PtrAnnot()>([]() { return (X1*) new X8(); });
154            }
155
156            int main() {
157              fruit::Injector<I1Annot, I2Annot, I3Annot, I4Annot, X5Annot> injector(getComponent);
158
159              injector.get<I1Annot>();
160              injector.get<I2Annot>();
161              injector.get<I3Annot>();
162              injector.get<I4Annot>();
163              injector.get<X5Annot>();
164
165              injector.getMultibindings<I1Annot>();
166            }
167            '''
168        expect_success(
169            COMMON_DEFINITIONS,
170            source,
171            locals())
172
173if __name__ == '__main__':
174    absltest.main()
175