xref: /aosp_15_r20/external/google-fruit/tests/test_install_component_functions.py (revision a65addddcf69f38db5b288d787b6b7571a57bb8f)
1*a65addddSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*a65addddSAndroid Build Coastguard Worker#  Copyright 2016 Google Inc. All Rights Reserved.
3*a65addddSAndroid Build Coastguard Worker#
4*a65addddSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
5*a65addddSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
6*a65addddSAndroid Build Coastguard Worker# You may obtain a copy of the License at
7*a65addddSAndroid Build Coastguard Worker#
8*a65addddSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
9*a65addddSAndroid Build Coastguard Worker#
10*a65addddSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*a65addddSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS-IS" BASIS,
12*a65addddSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*a65addddSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
14*a65addddSAndroid Build Coastguard Worker# limitations under the License.
15*a65addddSAndroid Build Coastguard Worker
16*a65addddSAndroid Build Coastguard Workerfrom absl.testing import parameterized
17*a65addddSAndroid Build Coastguard Workerfrom fruit_test_common import *
18*a65addddSAndroid Build Coastguard Worker
19*a65addddSAndroid Build Coastguard WorkerCOMMON_DEFINITIONS = '''
20*a65addddSAndroid Build Coastguard Worker    #include "test_common.h"
21*a65addddSAndroid Build Coastguard Worker
22*a65addddSAndroid Build Coastguard Worker    struct X;
23*a65addddSAndroid Build Coastguard Worker
24*a65addddSAndroid Build Coastguard Worker    struct Annotation1 {};
25*a65addddSAndroid Build Coastguard Worker    using XAnnot1 = fruit::Annotated<Annotation1, X>;
26*a65addddSAndroid Build Coastguard Worker    '''
27*a65addddSAndroid Build Coastguard Worker
28*a65addddSAndroid Build Coastguard Workerclass TestInstallComponentFunctions(parameterized.TestCase):
29*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_deduped_against_previous_install_no_args(self):
30*a65addddSAndroid Build Coastguard Worker        source = '''
31*a65addddSAndroid Build Coastguard Worker            int num_executions = 0;
32*a65addddSAndroid Build Coastguard Worker
33*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getChildComponent() {
34*a65addddSAndroid Build Coastguard Worker              static int n = 5;
35*a65addddSAndroid Build Coastguard Worker              ++num_executions;
36*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
37*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
38*a65addddSAndroid Build Coastguard Worker            }
39*a65addddSAndroid Build Coastguard Worker
40*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getMiddleComponent() {
41*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
42*a65addddSAndroid Build Coastguard Worker                  .install(getChildComponent);
43*a65addddSAndroid Build Coastguard Worker            }
44*a65addddSAndroid Build Coastguard Worker
45*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getMainComponent() {
46*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
47*a65addddSAndroid Build Coastguard Worker                  .install(getMiddleComponent)
48*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(fruit::componentFunction(getChildComponent));
49*a65addddSAndroid Build Coastguard Worker            }
50*a65addddSAndroid Build Coastguard Worker
51*a65addddSAndroid Build Coastguard Worker            int main() {
52*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getMainComponent);
53*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
54*a65addddSAndroid Build Coastguard Worker              Assert(n == 5);
55*a65addddSAndroid Build Coastguard Worker              Assert(num_executions == 1);
56*a65addddSAndroid Build Coastguard Worker            }
57*a65addddSAndroid Build Coastguard Worker            '''
58*a65addddSAndroid Build Coastguard Worker        expect_success(
59*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
60*a65addddSAndroid Build Coastguard Worker            source,
61*a65addddSAndroid Build Coastguard Worker            locals())
62*a65addddSAndroid Build Coastguard Worker
63*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_deduped_against_following_install_no_args(self):
64*a65addddSAndroid Build Coastguard Worker        source = '''
65*a65addddSAndroid Build Coastguard Worker            int num_executions = 0;
66*a65addddSAndroid Build Coastguard Worker
67*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getChildComponent() {
68*a65addddSAndroid Build Coastguard Worker              static int n = 5;
69*a65addddSAndroid Build Coastguard Worker              ++num_executions;
70*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
71*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
72*a65addddSAndroid Build Coastguard Worker            }
73*a65addddSAndroid Build Coastguard Worker
74*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getMiddleComponent() {
75*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
76*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(fruit::componentFunction(getChildComponent));
77*a65addddSAndroid Build Coastguard Worker            }
78*a65addddSAndroid Build Coastguard Worker
79*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getMainComponent() {
80*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
81*a65addddSAndroid Build Coastguard Worker                  .install(getMiddleComponent)
82*a65addddSAndroid Build Coastguard Worker                  .install(getChildComponent);
83*a65addddSAndroid Build Coastguard Worker            }
84*a65addddSAndroid Build Coastguard Worker
85*a65addddSAndroid Build Coastguard Worker            int main() {
86*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getMainComponent);
87*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
88*a65addddSAndroid Build Coastguard Worker              Assert(n == 5);
89*a65addddSAndroid Build Coastguard Worker              Assert(num_executions == 1);
90*a65addddSAndroid Build Coastguard Worker            }
91*a65addddSAndroid Build Coastguard Worker            '''
92*a65addddSAndroid Build Coastguard Worker        expect_success(
93*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
94*a65addddSAndroid Build Coastguard Worker            source,
95*a65addddSAndroid Build Coastguard Worker            locals())
96*a65addddSAndroid Build Coastguard Worker
97*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_deduped_against_previous_install_with_args(self):
98*a65addddSAndroid Build Coastguard Worker        source = '''
99*a65addddSAndroid Build Coastguard Worker            int num_executions = 0;
100*a65addddSAndroid Build Coastguard Worker
101*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getChildComponent(int) {
102*a65addddSAndroid Build Coastguard Worker              static int n = 5;
103*a65addddSAndroid Build Coastguard Worker              ++num_executions;
104*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
105*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
106*a65addddSAndroid Build Coastguard Worker            }
107*a65addddSAndroid Build Coastguard Worker
108*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getMiddleComponent() {
109*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
110*a65addddSAndroid Build Coastguard Worker                  .install(getChildComponent, 42);
111*a65addddSAndroid Build Coastguard Worker            }
112*a65addddSAndroid Build Coastguard Worker
113*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getMainComponent() {
114*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
115*a65addddSAndroid Build Coastguard Worker                  .install(getMiddleComponent)
116*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(fruit::componentFunction(getChildComponent, 42));
117*a65addddSAndroid Build Coastguard Worker            }
118*a65addddSAndroid Build Coastguard Worker
119*a65addddSAndroid Build Coastguard Worker            int main() {
120*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getMainComponent);
121*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
122*a65addddSAndroid Build Coastguard Worker              Assert(n == 5);
123*a65addddSAndroid Build Coastguard Worker              Assert(num_executions == 1);
124*a65addddSAndroid Build Coastguard Worker            }
125*a65addddSAndroid Build Coastguard Worker            '''
126*a65addddSAndroid Build Coastguard Worker        expect_success(
127*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
128*a65addddSAndroid Build Coastguard Worker            source,
129*a65addddSAndroid Build Coastguard Worker            locals())
130*a65addddSAndroid Build Coastguard Worker
131*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_deduped_against_following_install_with_args(self):
132*a65addddSAndroid Build Coastguard Worker        source = '''
133*a65addddSAndroid Build Coastguard Worker            int num_executions = 0;
134*a65addddSAndroid Build Coastguard Worker
135*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getChildComponent(int) {
136*a65addddSAndroid Build Coastguard Worker              static int n = 5;
137*a65addddSAndroid Build Coastguard Worker              ++num_executions;
138*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
139*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
140*a65addddSAndroid Build Coastguard Worker            }
141*a65addddSAndroid Build Coastguard Worker
142*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getMiddleComponent() {
143*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
144*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(fruit::componentFunction(getChildComponent, 42));
145*a65addddSAndroid Build Coastguard Worker            }
146*a65addddSAndroid Build Coastguard Worker
147*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getMainComponent() {
148*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
149*a65addddSAndroid Build Coastguard Worker                  .install(getMiddleComponent)
150*a65addddSAndroid Build Coastguard Worker                  .install(getChildComponent, 42);
151*a65addddSAndroid Build Coastguard Worker            }
152*a65addddSAndroid Build Coastguard Worker
153*a65addddSAndroid Build Coastguard Worker            int main() {
154*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getMainComponent);
155*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
156*a65addddSAndroid Build Coastguard Worker              Assert(n == 5);
157*a65addddSAndroid Build Coastguard Worker              Assert(num_executions == 1);
158*a65addddSAndroid Build Coastguard Worker            }
159*a65addddSAndroid Build Coastguard Worker            '''
160*a65addddSAndroid Build Coastguard Worker        expect_success(
161*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
162*a65addddSAndroid Build Coastguard Worker            source,
163*a65addddSAndroid Build Coastguard Worker            locals())
164*a65addddSAndroid Build Coastguard Worker
165*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_same_as_with_previous_install_with_different_args(self):
166*a65addddSAndroid Build Coastguard Worker        source = '''
167*a65addddSAndroid Build Coastguard Worker            int num_executions = 0;
168*a65addddSAndroid Build Coastguard Worker
169*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getChildComponent(int) {
170*a65addddSAndroid Build Coastguard Worker              static int n = 5;
171*a65addddSAndroid Build Coastguard Worker              ++num_executions;
172*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
173*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
174*a65addddSAndroid Build Coastguard Worker            }
175*a65addddSAndroid Build Coastguard Worker
176*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getMiddleComponent() {
177*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
178*a65addddSAndroid Build Coastguard Worker                  .install(getChildComponent, 42);
179*a65addddSAndroid Build Coastguard Worker            }
180*a65addddSAndroid Build Coastguard Worker
181*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getMainComponent() {
182*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
183*a65addddSAndroid Build Coastguard Worker                  .install(getMiddleComponent)
184*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(fruit::componentFunction(getChildComponent, 2));
185*a65addddSAndroid Build Coastguard Worker            }
186*a65addddSAndroid Build Coastguard Worker
187*a65addddSAndroid Build Coastguard Worker            int main() {
188*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getMainComponent);
189*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
190*a65addddSAndroid Build Coastguard Worker              Assert(n == 5);
191*a65addddSAndroid Build Coastguard Worker              Assert(num_executions == 2);
192*a65addddSAndroid Build Coastguard Worker            }
193*a65addddSAndroid Build Coastguard Worker            '''
194*a65addddSAndroid Build Coastguard Worker        expect_success(
195*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
196*a65addddSAndroid Build Coastguard Worker            source,
197*a65addddSAndroid Build Coastguard Worker            locals())
198*a65addddSAndroid Build Coastguard Worker
199*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_same_as_following_install_with_different_args(self):
200*a65addddSAndroid Build Coastguard Worker        source = '''
201*a65addddSAndroid Build Coastguard Worker            int num_executions = 0;
202*a65addddSAndroid Build Coastguard Worker
203*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getChildComponent(int) {
204*a65addddSAndroid Build Coastguard Worker              static int n = 5;
205*a65addddSAndroid Build Coastguard Worker              ++num_executions;
206*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
207*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
208*a65addddSAndroid Build Coastguard Worker            }
209*a65addddSAndroid Build Coastguard Worker
210*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getMiddleComponent() {
211*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
212*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(fruit::componentFunction(getChildComponent, 42));
213*a65addddSAndroid Build Coastguard Worker            }
214*a65addddSAndroid Build Coastguard Worker
215*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getMainComponent() {
216*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
217*a65addddSAndroid Build Coastguard Worker                  .install(getMiddleComponent)
218*a65addddSAndroid Build Coastguard Worker                  .install(getChildComponent, 2);
219*a65addddSAndroid Build Coastguard Worker            }
220*a65addddSAndroid Build Coastguard Worker
221*a65addddSAndroid Build Coastguard Worker            int main() {
222*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getMainComponent);
223*a65addddSAndroid Build Coastguard Worker              (void)injector;
224*a65addddSAndroid Build Coastguard Worker              Assert(num_executions == 2);
225*a65addddSAndroid Build Coastguard Worker            }
226*a65addddSAndroid Build Coastguard Worker            '''
227*a65addddSAndroid Build Coastguard Worker        expect_success(
228*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
229*a65addddSAndroid Build Coastguard Worker            source,
230*a65addddSAndroid Build Coastguard Worker            locals())
231*a65addddSAndroid Build Coastguard Worker
232*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_no_component_functions(self):
233*a65addddSAndroid Build Coastguard Worker        source = '''
234*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent() {
235*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
236*a65addddSAndroid Build Coastguard Worker                .installComponentFunctions();
237*a65addddSAndroid Build Coastguard Worker            }
238*a65addddSAndroid Build Coastguard Worker
239*a65addddSAndroid Build Coastguard Worker            int main() {
240*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getComponent);
241*a65addddSAndroid Build Coastguard Worker              (void)injector;
242*a65addddSAndroid Build Coastguard Worker            }
243*a65addddSAndroid Build Coastguard Worker            '''
244*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source)
245*a65addddSAndroid Build Coastguard Worker
246*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_one_component_function(self):
247*a65addddSAndroid Build Coastguard Worker        source = '''
248*a65addddSAndroid Build Coastguard Worker            struct X {
249*a65addddSAndroid Build Coastguard Worker              int n;
250*a65addddSAndroid Build Coastguard Worker              X(int n) : n(n) {}
251*a65addddSAndroid Build Coastguard Worker            };
252*a65addddSAndroid Build Coastguard Worker
253*a65addddSAndroid Build Coastguard Worker            fruit::Component<X> getParentComponent(std::string) {
254*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
255*a65addddSAndroid Build Coastguard Worker                .registerProvider([]() { return X(5); });
256*a65addddSAndroid Build Coastguard Worker            }
257*a65addddSAndroid Build Coastguard Worker
258*a65addddSAndroid Build Coastguard Worker            fruit::Component<X> getComponent() {
259*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
260*a65addddSAndroid Build Coastguard Worker                .installComponentFunctions(fruit::componentFunction(getParentComponent, std::string("Hello")));
261*a65addddSAndroid Build Coastguard Worker            }
262*a65addddSAndroid Build Coastguard Worker
263*a65addddSAndroid Build Coastguard Worker            int main() {
264*a65addddSAndroid Build Coastguard Worker              fruit::Injector<X> injector(getComponent);
265*a65addddSAndroid Build Coastguard Worker              X x = injector.get<X>();
266*a65addddSAndroid Build Coastguard Worker              Assert(x.n == 5);
267*a65addddSAndroid Build Coastguard Worker            }
268*a65addddSAndroid Build Coastguard Worker            '''
269*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source)
270*a65addddSAndroid Build Coastguard Worker
271*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_two_component_functions(self):
272*a65addddSAndroid Build Coastguard Worker        source = '''
273*a65addddSAndroid Build Coastguard Worker            struct X {
274*a65addddSAndroid Build Coastguard Worker              int n;
275*a65addddSAndroid Build Coastguard Worker              X(int n) : n(n) {}
276*a65addddSAndroid Build Coastguard Worker            };
277*a65addddSAndroid Build Coastguard Worker
278*a65addddSAndroid Build Coastguard Worker            struct Y {
279*a65addddSAndroid Build Coastguard Worker              int n;
280*a65addddSAndroid Build Coastguard Worker              Y(int n) : n(n) {}
281*a65addddSAndroid Build Coastguard Worker            };
282*a65addddSAndroid Build Coastguard Worker
283*a65addddSAndroid Build Coastguard Worker            fruit::Component<X> getParentComponent1(std::string) {
284*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
285*a65addddSAndroid Build Coastguard Worker                .registerProvider([]() { return X(5); });
286*a65addddSAndroid Build Coastguard Worker            }
287*a65addddSAndroid Build Coastguard Worker
288*a65addddSAndroid Build Coastguard Worker            fruit::Component<Y> getParentComponent2(std::string) {
289*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
290*a65addddSAndroid Build Coastguard Worker                  .registerProvider([]() { return Y(42); });
291*a65addddSAndroid Build Coastguard Worker            }
292*a65addddSAndroid Build Coastguard Worker
293*a65addddSAndroid Build Coastguard Worker            fruit::Component<X, Y> getComponent() {
294*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
295*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(
296*a65addddSAndroid Build Coastguard Worker                      fruit::componentFunction(getParentComponent1, std::string("Hello")),
297*a65addddSAndroid Build Coastguard Worker                      fruit::componentFunction(getParentComponent2, std::string("World")));
298*a65addddSAndroid Build Coastguard Worker            }
299*a65addddSAndroid Build Coastguard Worker
300*a65addddSAndroid Build Coastguard Worker            int main() {
301*a65addddSAndroid Build Coastguard Worker              fruit::Injector<X, Y> injector(getComponent);
302*a65addddSAndroid Build Coastguard Worker              X x = injector.get<X>();
303*a65addddSAndroid Build Coastguard Worker              Y y = injector.get<Y>();
304*a65addddSAndroid Build Coastguard Worker              Assert(x.n == 5);
305*a65addddSAndroid Build Coastguard Worker              Assert(y.n == 42);
306*a65addddSAndroid Build Coastguard Worker            }
307*a65addddSAndroid Build Coastguard Worker            '''
308*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source)
309*a65addddSAndroid Build Coastguard Worker
310*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_with_template_parameter_pack_unpacking(self):
311*a65addddSAndroid Build Coastguard Worker        source = '''
312*a65addddSAndroid Build Coastguard Worker            template <typename T>
313*a65addddSAndroid Build Coastguard Worker            struct GetComponentHolder;
314*a65addddSAndroid Build Coastguard Worker
315*a65addddSAndroid Build Coastguard Worker            struct X {
316*a65addddSAndroid Build Coastguard Worker              int n;
317*a65addddSAndroid Build Coastguard Worker              X(int n) : n(n) {}
318*a65addddSAndroid Build Coastguard Worker            };
319*a65addddSAndroid Build Coastguard Worker
320*a65addddSAndroid Build Coastguard Worker            struct Y {
321*a65addddSAndroid Build Coastguard Worker              int n;
322*a65addddSAndroid Build Coastguard Worker              Y(int n) : n(n) {}
323*a65addddSAndroid Build Coastguard Worker            };
324*a65addddSAndroid Build Coastguard Worker
325*a65addddSAndroid Build Coastguard Worker            template <>
326*a65addddSAndroid Build Coastguard Worker            struct GetComponentHolder<X> {
327*a65addddSAndroid Build Coastguard Worker                static fruit::Component<X> getComponent(std::string) {
328*a65addddSAndroid Build Coastguard Worker                  return fruit::createComponent()
329*a65addddSAndroid Build Coastguard Worker                    .registerProvider([]() { return X(5); });
330*a65addddSAndroid Build Coastguard Worker                }
331*a65addddSAndroid Build Coastguard Worker            };
332*a65addddSAndroid Build Coastguard Worker
333*a65addddSAndroid Build Coastguard Worker            template <>
334*a65addddSAndroid Build Coastguard Worker            struct GetComponentHolder<Y> {
335*a65addddSAndroid Build Coastguard Worker                static fruit::Component<Y> getComponent(std::string) {
336*a65addddSAndroid Build Coastguard Worker                  return fruit::createComponent()
337*a65addddSAndroid Build Coastguard Worker                      .registerProvider([]() { return Y(42); });
338*a65addddSAndroid Build Coastguard Worker                }
339*a65addddSAndroid Build Coastguard Worker            };
340*a65addddSAndroid Build Coastguard Worker
341*a65addddSAndroid Build Coastguard Worker            template <typename... Ts>
342*a65addddSAndroid Build Coastguard Worker            fruit::Component<Ts...> getComponent() {
343*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
344*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(
345*a65addddSAndroid Build Coastguard Worker                      fruit::componentFunction(GetComponentHolder<Ts>::getComponent, std::string("Hello"))...);
346*a65addddSAndroid Build Coastguard Worker            }
347*a65addddSAndroid Build Coastguard Worker
348*a65addddSAndroid Build Coastguard Worker            int main() {
349*a65addddSAndroid Build Coastguard Worker              fruit::Injector<X, Y> injector(getComponent<X, Y>);
350*a65addddSAndroid Build Coastguard Worker              X x = injector.get<X>();
351*a65addddSAndroid Build Coastguard Worker              Y y = injector.get<Y>();
352*a65addddSAndroid Build Coastguard Worker              Assert(x.n == 5);
353*a65addddSAndroid Build Coastguard Worker              Assert(y.n == 42);
354*a65addddSAndroid Build Coastguard Worker            }
355*a65addddSAndroid Build Coastguard Worker            '''
356*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source)
357*a65addddSAndroid Build Coastguard Worker
358*a65addddSAndroid Build Coastguard Worker    def test_install_component_functions_wrong_argument_type(self):
359*a65addddSAndroid Build Coastguard Worker        source = '''
360*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getMainComponent() {
361*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
362*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(42);
363*a65addddSAndroid Build Coastguard Worker            }
364*a65addddSAndroid Build Coastguard Worker            '''
365*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
366*a65addddSAndroid Build Coastguard Worker            'IncorrectArgTypePassedToInstallComponentFuntionsError<int>',
367*a65addddSAndroid Build Coastguard Worker            'All arguments passed to installComponentFunctions.. must be fruit::ComponentFunction<...> objects but an '
368*a65addddSAndroid Build Coastguard Worker            'argument with type Arg was passed instead.',
369*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
370*a65addddSAndroid Build Coastguard Worker            source,
371*a65addddSAndroid Build Coastguard Worker            locals())
372*a65addddSAndroid Build Coastguard Worker
373*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__':
374*a65addddSAndroid Build Coastguard Worker    absltest.main()
375