xref: /aosp_15_r20/external/google-fruit/tests/test_component_replacement.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    '''
23*a65addddSAndroid Build Coastguard Worker
24*a65addddSAndroid Build Coastguard Workerclass TestComponentReplacement(parameterized.TestCase):
25*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
26*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
27*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
28*a65addddSAndroid Build Coastguard Worker    ], [
29*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
30*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
31*a65addddSAndroid Build Coastguard Worker    ])
32*a65addddSAndroid Build Coastguard Worker    def test_replace_component_success(self,
33*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
34*a65addddSAndroid Build Coastguard Worker        source = '''
35*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ReplacedComponentParamTypes) {
36*a65addddSAndroid Build Coastguard Worker              static int n = 10;
37*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
38*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
39*a65addddSAndroid Build Coastguard Worker            }
40*a65addddSAndroid Build Coastguard Worker
41*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ReplacementComponentParamTypes) {
42*a65addddSAndroid Build Coastguard Worker              static int n = 20;
43*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
44*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
45*a65addddSAndroid Build Coastguard Worker            }
46*a65addddSAndroid Build Coastguard Worker
47*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent() {
48*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
49*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
50*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
51*a65addddSAndroid Build Coastguard Worker            }
52*a65addddSAndroid Build Coastguard Worker
53*a65addddSAndroid Build Coastguard Worker            int main() {
54*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getRootComponent);
55*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
56*a65addddSAndroid Build Coastguard Worker              Assert(n == 20);
57*a65addddSAndroid Build Coastguard Worker            }
58*a65addddSAndroid Build Coastguard Worker            '''
59*a65addddSAndroid Build Coastguard Worker        expect_success(
60*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
61*a65addddSAndroid Build Coastguard Worker            source,
62*a65addddSAndroid Build Coastguard Worker            locals())
63*a65addddSAndroid Build Coastguard Worker
64*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
65*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
66*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
67*a65addddSAndroid Build Coastguard Worker    ], [
68*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
69*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
70*a65addddSAndroid Build Coastguard Worker    ])
71*a65addddSAndroid Build Coastguard Worker    def test_replace_component_success_across_normalized_component(self,
72*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
73*a65addddSAndroid Build Coastguard Worker        source = '''
74*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ReplacedComponentParamTypes) {
75*a65addddSAndroid Build Coastguard Worker              static int n = 10;
76*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
77*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
78*a65addddSAndroid Build Coastguard Worker            }
79*a65addddSAndroid Build Coastguard Worker
80*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ReplacementComponentParamTypes) {
81*a65addddSAndroid Build Coastguard Worker              static int n = 20;
82*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
83*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
84*a65addddSAndroid Build Coastguard Worker            }
85*a65addddSAndroid Build Coastguard Worker
86*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent1() {
87*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
88*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation);
89*a65addddSAndroid Build Coastguard Worker            }
90*a65addddSAndroid Build Coastguard Worker
91*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent2() {
92*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
93*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
94*a65addddSAndroid Build Coastguard Worker            }
95*a65addddSAndroid Build Coastguard Worker
96*a65addddSAndroid Build Coastguard Worker            int main() {
97*a65addddSAndroid Build Coastguard Worker              fruit::NormalizedComponent<> normalizedComponent(getRootComponent1);
98*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(normalizedComponent, getRootComponent2);
99*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
100*a65addddSAndroid Build Coastguard Worker              Assert(n == 20);
101*a65addddSAndroid Build Coastguard Worker            }
102*a65addddSAndroid Build Coastguard Worker            '''
103*a65addddSAndroid Build Coastguard Worker        expect_success(
104*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
105*a65addddSAndroid Build Coastguard Worker            source,
106*a65addddSAndroid Build Coastguard Worker            locals())
107*a65addddSAndroid Build Coastguard Worker
108*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
109*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
110*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
111*a65addddSAndroid Build Coastguard Worker    ], [
112*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
113*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
114*a65addddSAndroid Build Coastguard Worker    ])
115*a65addddSAndroid Build Coastguard Worker    def test_replace_component_installed_using_component_function_success(self,
116*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
117*a65addddSAndroid Build Coastguard Worker        source = '''
118*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ReplacedComponentParamTypes) {
119*a65addddSAndroid Build Coastguard Worker              static int n = 10;
120*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
121*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
122*a65addddSAndroid Build Coastguard Worker            }
123*a65addddSAndroid Build Coastguard Worker
124*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ReplacementComponentParamTypes) {
125*a65addddSAndroid Build Coastguard Worker              static int n = 20;
126*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
127*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
128*a65addddSAndroid Build Coastguard Worker            }
129*a65addddSAndroid Build Coastguard Worker
130*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent() {
131*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
132*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
133*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(fruit::componentFunction(ReplacedComponentInstallation));
134*a65addddSAndroid Build Coastguard Worker            }
135*a65addddSAndroid Build Coastguard Worker
136*a65addddSAndroid Build Coastguard Worker            int main() {
137*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getRootComponent);
138*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
139*a65addddSAndroid Build Coastguard Worker              Assert(n == 20);
140*a65addddSAndroid Build Coastguard Worker            }
141*a65addddSAndroid Build Coastguard Worker            '''
142*a65addddSAndroid Build Coastguard Worker        expect_success(
143*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
144*a65addddSAndroid Build Coastguard Worker            source,
145*a65addddSAndroid Build Coastguard Worker            locals())
146*a65addddSAndroid Build Coastguard Worker
147*a65addddSAndroid Build Coastguard Worker    def test_replace_component_success_with_conversion(self):
148*a65addddSAndroid Build Coastguard Worker        source = '''
149*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(std::string) {
150*a65addddSAndroid Build Coastguard Worker              static int n = 10;
151*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
152*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
153*a65addddSAndroid Build Coastguard Worker            }
154*a65addddSAndroid Build Coastguard Worker
155*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(double, std::string, int) {
156*a65addddSAndroid Build Coastguard Worker              static int n = 20;
157*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
158*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
159*a65addddSAndroid Build Coastguard Worker            }
160*a65addddSAndroid Build Coastguard Worker
161*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent() {
162*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
163*a65addddSAndroid Build Coastguard Worker                  .replace(getReplacedComponent, "Hi").with(getReplacementComponent, 2.0, "Hello", 12)
164*a65addddSAndroid Build Coastguard Worker                  .install(getReplacedComponent, "Hi");
165*a65addddSAndroid Build Coastguard Worker            }
166*a65addddSAndroid Build Coastguard Worker
167*a65addddSAndroid Build Coastguard Worker            int main() {
168*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getRootComponent);
169*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
170*a65addddSAndroid Build Coastguard Worker              Assert(n == 20);
171*a65addddSAndroid Build Coastguard Worker            }
172*a65addddSAndroid Build Coastguard Worker            '''
173*a65addddSAndroid Build Coastguard Worker        expect_success(
174*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
175*a65addddSAndroid Build Coastguard Worker            source,
176*a65addddSAndroid Build Coastguard Worker            locals())
177*a65addddSAndroid Build Coastguard Worker
178*a65addddSAndroid Build Coastguard Worker    def test_replace_component_installed_using_component_function_success_with_conversion(self):
179*a65addddSAndroid Build Coastguard Worker        source = '''
180*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(std::string) {
181*a65addddSAndroid Build Coastguard Worker              static int n = 10;
182*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
183*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
184*a65addddSAndroid Build Coastguard Worker            }
185*a65addddSAndroid Build Coastguard Worker
186*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(double, std::string, int) {
187*a65addddSAndroid Build Coastguard Worker              static int n = 20;
188*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
189*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
190*a65addddSAndroid Build Coastguard Worker            }
191*a65addddSAndroid Build Coastguard Worker
192*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent() {
193*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
194*a65addddSAndroid Build Coastguard Worker                  .replace(getReplacedComponent, "Hi").with(getReplacementComponent, 2.0, "Hello", 12)
195*a65addddSAndroid Build Coastguard Worker                  .installComponentFunctions(fruit::componentFunction(getReplacedComponent, "Hi"));
196*a65addddSAndroid Build Coastguard Worker            }
197*a65addddSAndroid Build Coastguard Worker
198*a65addddSAndroid Build Coastguard Worker            int main() {
199*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getRootComponent);
200*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
201*a65addddSAndroid Build Coastguard Worker              Assert(n == 20);
202*a65addddSAndroid Build Coastguard Worker            }
203*a65addddSAndroid Build Coastguard Worker            '''
204*a65addddSAndroid Build Coastguard Worker        expect_success(
205*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
206*a65addddSAndroid Build Coastguard Worker            source,
207*a65addddSAndroid Build Coastguard Worker            locals())
208*a65addddSAndroid Build Coastguard Worker
209*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
210*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent', 'getReplacementComponent', 'getReplacementReplacementComponent'),
211*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0', 'getReplacementComponent, 1.0', 'getReplacementReplacementComponent, 1.0'),
212*a65addddSAndroid Build Coastguard Worker    ])
213*a65addddSAndroid Build Coastguard Worker    def test_replace_component_chain_success(self,
214*a65addddSAndroid Build Coastguard Worker            ComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentInstallation, ReplacementReplacementComponentInstallation):
215*a65addddSAndroid Build Coastguard Worker        source = '''
216*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ComponentParamTypes) {
217*a65addddSAndroid Build Coastguard Worker              static int n = 10;
218*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
219*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
220*a65addddSAndroid Build Coastguard Worker            }
221*a65addddSAndroid Build Coastguard Worker
222*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ComponentParamTypes) {
223*a65addddSAndroid Build Coastguard Worker              static int n = 20;
224*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
225*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
226*a65addddSAndroid Build Coastguard Worker            }
227*a65addddSAndroid Build Coastguard Worker
228*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementReplacementComponent(ComponentParamTypes) {
229*a65addddSAndroid Build Coastguard Worker              static int n = 30;
230*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
231*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
232*a65addddSAndroid Build Coastguard Worker            }
233*a65addddSAndroid Build Coastguard Worker
234*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent() {
235*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
236*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
237*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacementComponentInstallation).with(ReplacementReplacementComponentInstallation)
238*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
239*a65addddSAndroid Build Coastguard Worker            }
240*a65addddSAndroid Build Coastguard Worker
241*a65addddSAndroid Build Coastguard Worker            int main() {
242*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getRootComponent);
243*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
244*a65addddSAndroid Build Coastguard Worker              Assert(n == 30);
245*a65addddSAndroid Build Coastguard Worker            }
246*a65addddSAndroid Build Coastguard Worker            '''
247*a65addddSAndroid Build Coastguard Worker        expect_success(
248*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
249*a65addddSAndroid Build Coastguard Worker            source,
250*a65addddSAndroid Build Coastguard Worker            locals())
251*a65addddSAndroid Build Coastguard Worker
252*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
253*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent', 'getReplacementComponent', 'getReplacementReplacementComponent'),
254*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0', 'getReplacementComponent, 1.0', 'getReplacementReplacementComponent, 1.0'),
255*a65addddSAndroid Build Coastguard Worker    ])
256*a65addddSAndroid Build Coastguard Worker    def test_replace_component_chain_other_order_success(self,
257*a65addddSAndroid Build Coastguard Worker            ComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentInstallation, ReplacementReplacementComponentInstallation):
258*a65addddSAndroid Build Coastguard Worker        source = '''
259*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ComponentParamTypes) {
260*a65addddSAndroid Build Coastguard Worker              static int n = 10;
261*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
262*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
263*a65addddSAndroid Build Coastguard Worker            }
264*a65addddSAndroid Build Coastguard Worker
265*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ComponentParamTypes) {
266*a65addddSAndroid Build Coastguard Worker              static int n = 20;
267*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
268*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
269*a65addddSAndroid Build Coastguard Worker            }
270*a65addddSAndroid Build Coastguard Worker
271*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementReplacementComponent(ComponentParamTypes) {
272*a65addddSAndroid Build Coastguard Worker              static int n = 30;
273*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
274*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
275*a65addddSAndroid Build Coastguard Worker            }
276*a65addddSAndroid Build Coastguard Worker
277*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent() {
278*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
279*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacementComponentInstallation).with(ReplacementReplacementComponentInstallation)
280*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
281*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
282*a65addddSAndroid Build Coastguard Worker            }
283*a65addddSAndroid Build Coastguard Worker
284*a65addddSAndroid Build Coastguard Worker            int main() {
285*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getRootComponent);
286*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
287*a65addddSAndroid Build Coastguard Worker              Assert(n == 30);
288*a65addddSAndroid Build Coastguard Worker            }
289*a65addddSAndroid Build Coastguard Worker            '''
290*a65addddSAndroid Build Coastguard Worker        expect_success(
291*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
292*a65addddSAndroid Build Coastguard Worker            source,
293*a65addddSAndroid Build Coastguard Worker            locals())
294*a65addddSAndroid Build Coastguard Worker
295*a65addddSAndroid Build Coastguard Worker    def test_replace_component_different_type_error(self):
296*a65addddSAndroid Build Coastguard Worker        source = '''
297*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent();
298*a65addddSAndroid Build Coastguard Worker            fruit::Component<double> getReplacementComponent();
299*a65addddSAndroid Build Coastguard Worker
300*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
301*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
302*a65addddSAndroid Build Coastguard Worker                  .replace(getReplacedComponent).with(getReplacementComponent);
303*a65addddSAndroid Build Coastguard Worker            }
304*a65addddSAndroid Build Coastguard Worker            '''
305*a65addddSAndroid Build Coastguard Worker        expect_generic_compile_error(
306*a65addddSAndroid Build Coastguard Worker            # Clang
307*a65addddSAndroid Build Coastguard Worker            r'candidate template ignored: could not match .Component<int>. against .Component<double>.'
308*a65addddSAndroid Build Coastguard Worker            # GCC
309*a65addddSAndroid Build Coastguard Worker            r'|mismatched types .int. and .double.'
310*a65addddSAndroid Build Coastguard Worker            # MSVC
311*a65addddSAndroid Build Coastguard Worker            r'|could not deduce template argument for .fruit::Component<int> \(__cdecl \*\)\(FormalArgs...\). from .fruit::Component<double> \(void\).',
312*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
313*a65addddSAndroid Build Coastguard Worker            source)
314*a65addddSAndroid Build Coastguard Worker
315*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
316*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
317*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
318*a65addddSAndroid Build Coastguard Worker    ], [
319*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
320*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
321*a65addddSAndroid Build Coastguard Worker    ])
322*a65addddSAndroid Build Coastguard Worker    def test_replace_component_already_replaced_consistent_ok(self,
323*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
324*a65addddSAndroid Build Coastguard Worker        source = '''
325*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ReplacedComponentParamTypes) {
326*a65addddSAndroid Build Coastguard Worker              static int n = 10;
327*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
328*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
329*a65addddSAndroid Build Coastguard Worker            }
330*a65addddSAndroid Build Coastguard Worker
331*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ReplacementComponentParamTypes) {
332*a65addddSAndroid Build Coastguard Worker              static int n = 20;
333*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
334*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
335*a65addddSAndroid Build Coastguard Worker            }
336*a65addddSAndroid Build Coastguard Worker
337*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent() {
338*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
339*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
340*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
341*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
342*a65addddSAndroid Build Coastguard Worker            }
343*a65addddSAndroid Build Coastguard Worker
344*a65addddSAndroid Build Coastguard Worker            int main() {
345*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getRootComponent);
346*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
347*a65addddSAndroid Build Coastguard Worker              Assert(n == 20);
348*a65addddSAndroid Build Coastguard Worker            }
349*a65addddSAndroid Build Coastguard Worker            '''
350*a65addddSAndroid Build Coastguard Worker        expect_success(
351*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
352*a65addddSAndroid Build Coastguard Worker            source,
353*a65addddSAndroid Build Coastguard Worker            locals())
354*a65addddSAndroid Build Coastguard Worker
355*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
356*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
357*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
358*a65addddSAndroid Build Coastguard Worker    ], [
359*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
360*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
361*a65addddSAndroid Build Coastguard Worker    ])
362*a65addddSAndroid Build Coastguard Worker    def test_replace_component_already_replaced_across_normalized_component_consistent_ok(self,
363*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
364*a65addddSAndroid Build Coastguard Worker        source = '''
365*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ReplacedComponentParamTypes) {
366*a65addddSAndroid Build Coastguard Worker              static int n = 10;
367*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
368*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
369*a65addddSAndroid Build Coastguard Worker            }
370*a65addddSAndroid Build Coastguard Worker
371*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ReplacementComponentParamTypes) {
372*a65addddSAndroid Build Coastguard Worker              static int n = 20;
373*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
374*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
375*a65addddSAndroid Build Coastguard Worker            }
376*a65addddSAndroid Build Coastguard Worker
377*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent1() {
378*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
379*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation);
380*a65addddSAndroid Build Coastguard Worker            }
381*a65addddSAndroid Build Coastguard Worker
382*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent2() {
383*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
384*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
385*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
386*a65addddSAndroid Build Coastguard Worker            }
387*a65addddSAndroid Build Coastguard Worker
388*a65addddSAndroid Build Coastguard Worker            int main() {
389*a65addddSAndroid Build Coastguard Worker              fruit::NormalizedComponent<> normalizedComponent(getRootComponent1);
390*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(normalizedComponent, getRootComponent2);
391*a65addddSAndroid Build Coastguard Worker              int n = injector.get<int>();
392*a65addddSAndroid Build Coastguard Worker              Assert(n == 20);
393*a65addddSAndroid Build Coastguard Worker            }
394*a65addddSAndroid Build Coastguard Worker            '''
395*a65addddSAndroid Build Coastguard Worker        expect_success(
396*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
397*a65addddSAndroid Build Coastguard Worker            source,
398*a65addddSAndroid Build Coastguard Worker            locals())
399*a65addddSAndroid Build Coastguard Worker
400*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
401*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
402*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
403*a65addddSAndroid Build Coastguard Worker    ], [
404*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent', 'getOtherReplacementComponent'),
405*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")', 'getOtherReplacementComponent, std::string("Hello, world")'),
406*a65addddSAndroid Build Coastguard Worker    ])
407*a65addddSAndroid Build Coastguard Worker    def test_replace_component_already_replaced_inconsistent_error(self,
408*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation, OtherReplacementComponentInstallation):
409*a65addddSAndroid Build Coastguard Worker        source = '''
410*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ReplacedComponentParamTypes) {
411*a65addddSAndroid Build Coastguard Worker              static int n = 10;
412*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
413*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
414*a65addddSAndroid Build Coastguard Worker            }
415*a65addddSAndroid Build Coastguard Worker
416*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ReplacementComponentParamTypes) {
417*a65addddSAndroid Build Coastguard Worker              static int n = 20;
418*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
419*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
420*a65addddSAndroid Build Coastguard Worker            }
421*a65addddSAndroid Build Coastguard Worker
422*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getOtherReplacementComponent(ReplacementComponentParamTypes) {
423*a65addddSAndroid Build Coastguard Worker              static int n = 30;
424*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
425*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
426*a65addddSAndroid Build Coastguard Worker            }
427*a65addddSAndroid Build Coastguard Worker
428*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
429*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
430*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
431*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(OtherReplacementComponentInstallation);
432*a65addddSAndroid Build Coastguard Worker            }
433*a65addddSAndroid Build Coastguard Worker
434*a65addddSAndroid Build Coastguard Worker            int main() {
435*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getRootComponent);
436*a65addddSAndroid Build Coastguard Worker              (void) injector;
437*a65addddSAndroid Build Coastguard Worker            }
438*a65addddSAndroid Build Coastguard Worker            '''
439*a65addddSAndroid Build Coastguard Worker        expect_runtime_error(
440*a65addddSAndroid Build Coastguard Worker            r'Fatal injection error: the component function at (0x)?[0-9a-fA-F]* with signature '
441*a65addddSAndroid Build Coastguard Worker            r'(class )?fruit::Component<int> \((__cdecl)?\*\)\((void)?ReplacedComponentParamTypes\) was replaced '
442*a65addddSAndroid Build Coastguard Worker            r'\(using .replace\(...\).with\(...\)\) with both the component function at (0x)?[0-9a-fA-F]* with signature '
443*a65addddSAndroid Build Coastguard Worker            r'(class )?fruit::Component<int> \((__cdecl)?\*\)\(.*\) and the component function at '
444*a65addddSAndroid Build Coastguard Worker            r'(0x)?[0-9a-fA-F]* with signature (class )?fruit::Component<int> \((__cdecl)?\*\)\(.*\) .',
445*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
446*a65addddSAndroid Build Coastguard Worker            source,
447*a65addddSAndroid Build Coastguard Worker            locals())
448*a65addddSAndroid Build Coastguard Worker
449*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
450*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
451*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
452*a65addddSAndroid Build Coastguard Worker    ], [
453*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent', 'getOtherReplacementComponent'),
454*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")', 'getOtherReplacementComponent, std::string("Hello, world")'),
455*a65addddSAndroid Build Coastguard Worker    ])
456*a65addddSAndroid Build Coastguard Worker    def test_replace_component_already_replaced_across_normalized_component_inconsistent_error(self,
457*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation, OtherReplacementComponentInstallation):
458*a65addddSAndroid Build Coastguard Worker        source = '''
459*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ReplacedComponentParamTypes) {
460*a65addddSAndroid Build Coastguard Worker              static int n = 10;
461*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
462*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
463*a65addddSAndroid Build Coastguard Worker            }
464*a65addddSAndroid Build Coastguard Worker
465*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ReplacementComponentParamTypes) {
466*a65addddSAndroid Build Coastguard Worker              static int n = 20;
467*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
468*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
469*a65addddSAndroid Build Coastguard Worker            }
470*a65addddSAndroid Build Coastguard Worker
471*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getOtherReplacementComponent(ReplacementComponentParamTypes) {
472*a65addddSAndroid Build Coastguard Worker              static int n = 30;
473*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
474*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
475*a65addddSAndroid Build Coastguard Worker            }
476*a65addddSAndroid Build Coastguard Worker
477*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent1() {
478*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
479*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation);
480*a65addddSAndroid Build Coastguard Worker            }
481*a65addddSAndroid Build Coastguard Worker
482*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent2() {
483*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
484*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(OtherReplacementComponentInstallation);
485*a65addddSAndroid Build Coastguard Worker            }
486*a65addddSAndroid Build Coastguard Worker
487*a65addddSAndroid Build Coastguard Worker            int main() {
488*a65addddSAndroid Build Coastguard Worker              fruit::NormalizedComponent<> normalizedComponent(getRootComponent1);
489*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(normalizedComponent, getRootComponent2);
490*a65addddSAndroid Build Coastguard Worker              (void) injector;
491*a65addddSAndroid Build Coastguard Worker            }
492*a65addddSAndroid Build Coastguard Worker            '''
493*a65addddSAndroid Build Coastguard Worker        expect_runtime_error(
494*a65addddSAndroid Build Coastguard Worker            r'Fatal injection error: the component function at (0x)?[0-9a-fA-F]* with signature '
495*a65addddSAndroid Build Coastguard Worker            r'(class )?fruit::Component<int> \((__cdecl)?\*\)\((void)?ReplacedComponentParamTypes\) was replaced '
496*a65addddSAndroid Build Coastguard Worker            r'\(using .replace\(...\).with\(...\)\) with both the component function at (0x)?[0-9a-fA-F]* with signature '
497*a65addddSAndroid Build Coastguard Worker            r'(class )?fruit::Component<int> \((__cdecl)?\*\)\(.*\) and the component function at '
498*a65addddSAndroid Build Coastguard Worker            r'(0x)?[0-9a-fA-F]* with signature (class )?fruit::Component<int> \((__cdecl)?\*\)\(.*\) .',
499*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
500*a65addddSAndroid Build Coastguard Worker            source,
501*a65addddSAndroid Build Coastguard Worker            locals())
502*a65addddSAndroid Build Coastguard Worker
503*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
504*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
505*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
506*a65addddSAndroid Build Coastguard Worker    ], [
507*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
508*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
509*a65addddSAndroid Build Coastguard Worker    ])
510*a65addddSAndroid Build Coastguard Worker    def test_replace_component_after_install_error(self,
511*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
512*a65addddSAndroid Build Coastguard Worker        source = '''
513*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ReplacedComponentParamTypes) {
514*a65addddSAndroid Build Coastguard Worker              static int n = 10;
515*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
516*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
517*a65addddSAndroid Build Coastguard Worker            }
518*a65addddSAndroid Build Coastguard Worker
519*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ReplacementComponentParamTypes) {
520*a65addddSAndroid Build Coastguard Worker              static int n = 20;
521*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
522*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
523*a65addddSAndroid Build Coastguard Worker            }
524*a65addddSAndroid Build Coastguard Worker
525*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent() {
526*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
527*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation)
528*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation);
529*a65addddSAndroid Build Coastguard Worker            }
530*a65addddSAndroid Build Coastguard Worker
531*a65addddSAndroid Build Coastguard Worker            int main() {
532*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(getRootComponent);
533*a65addddSAndroid Build Coastguard Worker              (void) injector;
534*a65addddSAndroid Build Coastguard Worker            }
535*a65addddSAndroid Build Coastguard Worker            '''
536*a65addddSAndroid Build Coastguard Worker        expect_runtime_error(
537*a65addddSAndroid Build Coastguard Worker            r'Fatal injection error: unable to replace \(using .replace\(...\).with\(...\)\) the component function at '
538*a65addddSAndroid Build Coastguard Worker            r'(0x)?[0-9a-fA-F]* with signature (class )?fruit::Component<int> \((__cdecl)?\*\)\((void)?ReplacedComponentParamTypes\) with the '
539*a65addddSAndroid Build Coastguard Worker            r'component function at (0x)?[0-9a-fA-F]* with signature '
540*a65addddSAndroid Build Coastguard Worker            r'(class )?fruit::Component<int> \((__cdecl)?\*\)\(.*\) because the former component function '
541*a65addddSAndroid Build Coastguard Worker            r'was installed before the .replace\(...\).with\(...\).',
542*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
543*a65addddSAndroid Build Coastguard Worker            source,
544*a65addddSAndroid Build Coastguard Worker            locals())
545*a65addddSAndroid Build Coastguard Worker
546*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
547*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
548*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
549*a65addddSAndroid Build Coastguard Worker    ], [
550*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
551*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
552*a65addddSAndroid Build Coastguard Worker    ])
553*a65addddSAndroid Build Coastguard Worker    def test_replace_component_after_install_across_normalized_component_error(self,
554*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
555*a65addddSAndroid Build Coastguard Worker        source = '''
556*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacedComponent(ReplacedComponentParamTypes) {
557*a65addddSAndroid Build Coastguard Worker              static int n = 10;
558*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
559*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
560*a65addddSAndroid Build Coastguard Worker            }
561*a65addddSAndroid Build Coastguard Worker
562*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getReplacementComponent(ReplacementComponentParamTypes) {
563*a65addddSAndroid Build Coastguard Worker              static int n = 20;
564*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
565*a65addddSAndroid Build Coastguard Worker                  .bindInstance(n);
566*a65addddSAndroid Build Coastguard Worker            }
567*a65addddSAndroid Build Coastguard Worker
568*a65addddSAndroid Build Coastguard Worker            fruit::Component<int> getRootComponent1() {
569*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
570*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
571*a65addddSAndroid Build Coastguard Worker            }
572*a65addddSAndroid Build Coastguard Worker
573*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent2() {
574*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
575*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation);
576*a65addddSAndroid Build Coastguard Worker            }
577*a65addddSAndroid Build Coastguard Worker
578*a65addddSAndroid Build Coastguard Worker            int main() {
579*a65addddSAndroid Build Coastguard Worker              fruit::NormalizedComponent<int> normalizedComponent(getRootComponent1);
580*a65addddSAndroid Build Coastguard Worker              fruit::Injector<int> injector(normalizedComponent, getRootComponent2);
581*a65addddSAndroid Build Coastguard Worker              (void) injector;
582*a65addddSAndroid Build Coastguard Worker            }
583*a65addddSAndroid Build Coastguard Worker            '''
584*a65addddSAndroid Build Coastguard Worker        expect_runtime_error(
585*a65addddSAndroid Build Coastguard Worker            r'Fatal injection error: unable to replace \(using .replace\(...\).with\(...\)\) the component function at '
586*a65addddSAndroid Build Coastguard Worker            r'(0x)?[0-9a-fA-F]* with signature (class )?fruit::Component<int> \((__cdecl)?\*\)\((void)?ReplacedComponentParamTypes\) with the '
587*a65addddSAndroid Build Coastguard Worker            r'component function at (0x)?[0-9a-fA-F]* with signature '
588*a65addddSAndroid Build Coastguard Worker            r'(class )?fruit::Component<int> \((__cdecl)?\*\)\(.*\) because the former component function '
589*a65addddSAndroid Build Coastguard Worker            r'was installed before the .replace\(...\).with\(...\).',
590*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
591*a65addddSAndroid Build Coastguard Worker            source,
592*a65addddSAndroid Build Coastguard Worker            locals())
593*a65addddSAndroid Build Coastguard Worker
594*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
595*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent', '', 'getReplacementComponent'),
596*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0', 'std::string', 'getReplacementComponent, std::string("Hello, world")'),
597*a65addddSAndroid Build Coastguard Worker    ])
598*a65addddSAndroid Build Coastguard Worker    def test_replace_component_unused_ok(self,
599*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
600*a65addddSAndroid Build Coastguard Worker        source = '''
601*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacedComponent(ReplacedComponentParamTypes) {
602*a65addddSAndroid Build Coastguard Worker              static int n = 10;
603*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
604*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
605*a65addddSAndroid Build Coastguard Worker            }
606*a65addddSAndroid Build Coastguard Worker
607*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacementComponent(ReplacementComponentParamTypes) {
608*a65addddSAndroid Build Coastguard Worker              static int n = 20;
609*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
610*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
611*a65addddSAndroid Build Coastguard Worker            }
612*a65addddSAndroid Build Coastguard Worker
613*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
614*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
615*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation);
616*a65addddSAndroid Build Coastguard Worker            }
617*a65addddSAndroid Build Coastguard Worker
618*a65addddSAndroid Build Coastguard Worker            int main() {
619*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getRootComponent);
620*a65addddSAndroid Build Coastguard Worker
621*a65addddSAndroid Build Coastguard Worker              std::vector<int*> multibindings = injector.getMultibindings<int>();
622*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 0);
623*a65addddSAndroid Build Coastguard Worker            }
624*a65addddSAndroid Build Coastguard Worker            '''
625*a65addddSAndroid Build Coastguard Worker        expect_success(
626*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
627*a65addddSAndroid Build Coastguard Worker            source,
628*a65addddSAndroid Build Coastguard Worker            locals())
629*a65addddSAndroid Build Coastguard Worker
630*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
631*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
632*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
633*a65addddSAndroid Build Coastguard Worker    ], [
634*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
635*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
636*a65addddSAndroid Build Coastguard Worker    ])
637*a65addddSAndroid Build Coastguard Worker    def test_replace_component_used_multiple_times_ok(self,
638*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
639*a65addddSAndroid Build Coastguard Worker        source = '''
640*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacedComponent(ReplacedComponentParamTypes) {
641*a65addddSAndroid Build Coastguard Worker              static int n = 10;
642*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
643*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
644*a65addddSAndroid Build Coastguard Worker            }
645*a65addddSAndroid Build Coastguard Worker
646*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacementComponent(ReplacementComponentParamTypes) {
647*a65addddSAndroid Build Coastguard Worker              static int n = 20;
648*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
649*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
650*a65addddSAndroid Build Coastguard Worker            }
651*a65addddSAndroid Build Coastguard Worker
652*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
653*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
654*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
655*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation)
656*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
657*a65addddSAndroid Build Coastguard Worker            }
658*a65addddSAndroid Build Coastguard Worker
659*a65addddSAndroid Build Coastguard Worker            int main() {
660*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getRootComponent);
661*a65addddSAndroid Build Coastguard Worker
662*a65addddSAndroid Build Coastguard Worker              std::vector<int*> multibindings = injector.getMultibindings<int>();
663*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 1);
664*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[0]) == 20);
665*a65addddSAndroid Build Coastguard Worker            }
666*a65addddSAndroid Build Coastguard Worker            '''
667*a65addddSAndroid Build Coastguard Worker        expect_success(
668*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
669*a65addddSAndroid Build Coastguard Worker            source,
670*a65addddSAndroid Build Coastguard Worker            locals())
671*a65addddSAndroid Build Coastguard Worker
672*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
673*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
674*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
675*a65addddSAndroid Build Coastguard Worker    ], [
676*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
677*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
678*a65addddSAndroid Build Coastguard Worker    ])
679*a65addddSAndroid Build Coastguard Worker    def test_replace_component_also_installed_directly_before_ok(self,
680*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
681*a65addddSAndroid Build Coastguard Worker        source = '''
682*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacedComponent(ReplacedComponentParamTypes) {
683*a65addddSAndroid Build Coastguard Worker              static int n = 10;
684*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
685*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
686*a65addddSAndroid Build Coastguard Worker            }
687*a65addddSAndroid Build Coastguard Worker
688*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacementComponent(ReplacementComponentParamTypes) {
689*a65addddSAndroid Build Coastguard Worker              static int n = 20;
690*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
691*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
692*a65addddSAndroid Build Coastguard Worker            }
693*a65addddSAndroid Build Coastguard Worker
694*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
695*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
696*a65addddSAndroid Build Coastguard Worker                  .install(ReplacementComponentInstallation)
697*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
698*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
699*a65addddSAndroid Build Coastguard Worker            }
700*a65addddSAndroid Build Coastguard Worker
701*a65addddSAndroid Build Coastguard Worker            int main() {
702*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getRootComponent);
703*a65addddSAndroid Build Coastguard Worker
704*a65addddSAndroid Build Coastguard Worker              std::vector<int*> multibindings = injector.getMultibindings<int>();
705*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 1);
706*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[0]) == 20);
707*a65addddSAndroid Build Coastguard Worker            }
708*a65addddSAndroid Build Coastguard Worker            '''
709*a65addddSAndroid Build Coastguard Worker        expect_success(
710*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
711*a65addddSAndroid Build Coastguard Worker            source,
712*a65addddSAndroid Build Coastguard Worker            locals())
713*a65addddSAndroid Build Coastguard Worker
714*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
715*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
716*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
717*a65addddSAndroid Build Coastguard Worker    ], [
718*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
719*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
720*a65addddSAndroid Build Coastguard Worker    ])
721*a65addddSAndroid Build Coastguard Worker    def test_replace_component_also_installed_directly_after_ok(self,
722*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
723*a65addddSAndroid Build Coastguard Worker        source = '''
724*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacedComponent(ReplacedComponentParamTypes) {
725*a65addddSAndroid Build Coastguard Worker              static int n = 10;
726*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
727*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
728*a65addddSAndroid Build Coastguard Worker            }
729*a65addddSAndroid Build Coastguard Worker
730*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacementComponent(ReplacementComponentParamTypes) {
731*a65addddSAndroid Build Coastguard Worker              static int n = 20;
732*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
733*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
734*a65addddSAndroid Build Coastguard Worker            }
735*a65addddSAndroid Build Coastguard Worker
736*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
737*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
738*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
739*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation)
740*a65addddSAndroid Build Coastguard Worker                  .install(ReplacementComponentInstallation);
741*a65addddSAndroid Build Coastguard Worker            }
742*a65addddSAndroid Build Coastguard Worker
743*a65addddSAndroid Build Coastguard Worker            int main() {
744*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getRootComponent);
745*a65addddSAndroid Build Coastguard Worker
746*a65addddSAndroid Build Coastguard Worker              std::vector<int*> multibindings = injector.getMultibindings<int>();
747*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 1);
748*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[0]) == 20);
749*a65addddSAndroid Build Coastguard Worker            }
750*a65addddSAndroid Build Coastguard Worker            '''
751*a65addddSAndroid Build Coastguard Worker        expect_success(
752*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
753*a65addddSAndroid Build Coastguard Worker            source,
754*a65addddSAndroid Build Coastguard Worker            locals())
755*a65addddSAndroid Build Coastguard Worker
756*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
757*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
758*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
759*a65addddSAndroid Build Coastguard Worker    ], [
760*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
761*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
762*a65addddSAndroid Build Coastguard Worker    ])
763*a65addddSAndroid Build Coastguard Worker    def test_replace_component_also_installed_directly_before_across_normalized_component_ok(self,
764*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
765*a65addddSAndroid Build Coastguard Worker        source = '''
766*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacedComponent(ReplacedComponentParamTypes) {
767*a65addddSAndroid Build Coastguard Worker              static int n = 10;
768*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
769*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
770*a65addddSAndroid Build Coastguard Worker            }
771*a65addddSAndroid Build Coastguard Worker
772*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacementComponent(ReplacementComponentParamTypes) {
773*a65addddSAndroid Build Coastguard Worker              static int n = 20;
774*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
775*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
776*a65addddSAndroid Build Coastguard Worker            }
777*a65addddSAndroid Build Coastguard Worker
778*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent1() {
779*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
780*a65addddSAndroid Build Coastguard Worker                  .install(ReplacementComponentInstallation);
781*a65addddSAndroid Build Coastguard Worker            }
782*a65addddSAndroid Build Coastguard Worker
783*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent2() {
784*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
785*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
786*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
787*a65addddSAndroid Build Coastguard Worker            }
788*a65addddSAndroid Build Coastguard Worker
789*a65addddSAndroid Build Coastguard Worker            int main() {
790*a65addddSAndroid Build Coastguard Worker              fruit::NormalizedComponent<> normalizedComponent(getRootComponent1);
791*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(normalizedComponent, getRootComponent2);
792*a65addddSAndroid Build Coastguard Worker
793*a65addddSAndroid Build Coastguard Worker              std::vector<int*> multibindings = injector.getMultibindings<int>();
794*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 1);
795*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[0]) == 20);
796*a65addddSAndroid Build Coastguard Worker            }
797*a65addddSAndroid Build Coastguard Worker            '''
798*a65addddSAndroid Build Coastguard Worker        expect_success(
799*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
800*a65addddSAndroid Build Coastguard Worker            source,
801*a65addddSAndroid Build Coastguard Worker            locals())
802*a65addddSAndroid Build Coastguard Worker
803*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
804*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent'),
805*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0'),
806*a65addddSAndroid Build Coastguard Worker    ], [
807*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
808*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
809*a65addddSAndroid Build Coastguard Worker    ])
810*a65addddSAndroid Build Coastguard Worker    def test_replace_component_also_installed_directly_after_across_normalized_component_ok(self,
811*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
812*a65addddSAndroid Build Coastguard Worker        source = '''
813*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacedComponent(ReplacedComponentParamTypes) {
814*a65addddSAndroid Build Coastguard Worker              static int n = 10;
815*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
816*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
817*a65addddSAndroid Build Coastguard Worker            }
818*a65addddSAndroid Build Coastguard Worker
819*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacementComponent(ReplacementComponentParamTypes) {
820*a65addddSAndroid Build Coastguard Worker              static int n = 20;
821*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
822*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
823*a65addddSAndroid Build Coastguard Worker            }
824*a65addddSAndroid Build Coastguard Worker
825*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent1() {
826*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
827*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
828*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation);
829*a65addddSAndroid Build Coastguard Worker            }
830*a65addddSAndroid Build Coastguard Worker
831*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent2() {
832*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
833*a65addddSAndroid Build Coastguard Worker                  .install(ReplacementComponentInstallation);
834*a65addddSAndroid Build Coastguard Worker            }
835*a65addddSAndroid Build Coastguard Worker
836*a65addddSAndroid Build Coastguard Worker            int main() {
837*a65addddSAndroid Build Coastguard Worker              fruit::NormalizedComponent<> normalizedComponent(getRootComponent1);
838*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(normalizedComponent, getRootComponent2);
839*a65addddSAndroid Build Coastguard Worker
840*a65addddSAndroid Build Coastguard Worker              std::vector<int*> multibindings = injector.getMultibindings<int>();
841*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 1);
842*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[0]) == 20);
843*a65addddSAndroid Build Coastguard Worker            }
844*a65addddSAndroid Build Coastguard Worker            '''
845*a65addddSAndroid Build Coastguard Worker        expect_success(
846*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
847*a65addddSAndroid Build Coastguard Worker            source,
848*a65addddSAndroid Build Coastguard Worker            locals())
849*a65addddSAndroid Build Coastguard Worker
850*a65addddSAndroid Build Coastguard Worker    @multiple_parameters([
851*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacedComponent', 'getOtherReplacementComponent'),
852*a65addddSAndroid Build Coastguard Worker        ('double', 'getReplacedComponent, 1.0', 'getOtherReplacementComponent, 1.0'),
853*a65addddSAndroid Build Coastguard Worker    ], [
854*a65addddSAndroid Build Coastguard Worker        ('', 'getReplacementComponent'),
855*a65addddSAndroid Build Coastguard Worker        ('std::string', 'getReplacementComponent, std::string("Hello, world")'),
856*a65addddSAndroid Build Coastguard Worker    ])
857*a65addddSAndroid Build Coastguard Worker    def test_replace_multiple_components_with_same(self,
858*a65addddSAndroid Build Coastguard Worker            ReplacedComponentParamTypes, ReplacedComponentInstallation, OtherReplacedComponentInstallation, ReplacementComponentParamTypes, ReplacementComponentInstallation):
859*a65addddSAndroid Build Coastguard Worker        source = '''
860*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacedComponent(ReplacedComponentParamTypes) {
861*a65addddSAndroid Build Coastguard Worker              static int n = 10;
862*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
863*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
864*a65addddSAndroid Build Coastguard Worker            }
865*a65addddSAndroid Build Coastguard Worker
866*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getOtherReplacementComponent(ReplacedComponentParamTypes) {
867*a65addddSAndroid Build Coastguard Worker              static int n = 20;
868*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
869*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
870*a65addddSAndroid Build Coastguard Worker            }
871*a65addddSAndroid Build Coastguard Worker
872*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacementComponent(ReplacementComponentParamTypes) {
873*a65addddSAndroid Build Coastguard Worker              static int n = 30;
874*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
875*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
876*a65addddSAndroid Build Coastguard Worker            }
877*a65addddSAndroid Build Coastguard Worker
878*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
879*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
880*a65addddSAndroid Build Coastguard Worker                  .replace(ReplacedComponentInstallation).with(ReplacementComponentInstallation)
881*a65addddSAndroid Build Coastguard Worker                  .replace(OtherReplacedComponentInstallation).with(ReplacementComponentInstallation)
882*a65addddSAndroid Build Coastguard Worker                  .install(ReplacedComponentInstallation)
883*a65addddSAndroid Build Coastguard Worker                  .install(OtherReplacedComponentInstallation);
884*a65addddSAndroid Build Coastguard Worker            }
885*a65addddSAndroid Build Coastguard Worker
886*a65addddSAndroid Build Coastguard Worker            int main() {
887*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getRootComponent);
888*a65addddSAndroid Build Coastguard Worker
889*a65addddSAndroid Build Coastguard Worker              std::vector<int*> multibindings = injector.getMultibindings<int>();
890*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 1);
891*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[0]) == 30);
892*a65addddSAndroid Build Coastguard Worker            }
893*a65addddSAndroid Build Coastguard Worker            '''
894*a65addddSAndroid Build Coastguard Worker        expect_success(
895*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
896*a65addddSAndroid Build Coastguard Worker            source,
897*a65addddSAndroid Build Coastguard Worker            locals())
898*a65addddSAndroid Build Coastguard Worker
899*a65addddSAndroid Build Coastguard Worker    def test_replace_component_one_set_of_args_only(self):
900*a65addddSAndroid Build Coastguard Worker        source = '''
901*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacedComponent(double) {
902*a65addddSAndroid Build Coastguard Worker              static int n = 10;
903*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
904*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
905*a65addddSAndroid Build Coastguard Worker            }
906*a65addddSAndroid Build Coastguard Worker
907*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacementComponent() {
908*a65addddSAndroid Build Coastguard Worker              static int n = 20;
909*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
910*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
911*a65addddSAndroid Build Coastguard Worker            }
912*a65addddSAndroid Build Coastguard Worker
913*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
914*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
915*a65addddSAndroid Build Coastguard Worker                  .replace(getReplacedComponent, 1.0).with(getReplacementComponent)
916*a65addddSAndroid Build Coastguard Worker                  .install(getReplacedComponent, 1.0)
917*a65addddSAndroid Build Coastguard Worker                  .install(getReplacedComponent, 5.0);
918*a65addddSAndroid Build Coastguard Worker            }
919*a65addddSAndroid Build Coastguard Worker
920*a65addddSAndroid Build Coastguard Worker            int main() {
921*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getRootComponent);
922*a65addddSAndroid Build Coastguard Worker
923*a65addddSAndroid Build Coastguard Worker              std::vector<int*> multibindings = injector.getMultibindings<int>();
924*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 2);
925*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[0]) == 20);
926*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[1]) == 10);
927*a65addddSAndroid Build Coastguard Worker            }
928*a65addddSAndroid Build Coastguard Worker            '''
929*a65addddSAndroid Build Coastguard Worker        expect_success(
930*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
931*a65addddSAndroid Build Coastguard Worker            source,
932*a65addddSAndroid Build Coastguard Worker            locals())
933*a65addddSAndroid Build Coastguard Worker
934*a65addddSAndroid Build Coastguard Worker    def test_replace_component_already_replaced_with_different_args(self):
935*a65addddSAndroid Build Coastguard Worker        source = '''
936*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacedComponent(double) {
937*a65addddSAndroid Build Coastguard Worker              static int n = 10;
938*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
939*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
940*a65addddSAndroid Build Coastguard Worker            }
941*a65addddSAndroid Build Coastguard Worker
942*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getReplacementComponent() {
943*a65addddSAndroid Build Coastguard Worker              static int n = 20;
944*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
945*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
946*a65addddSAndroid Build Coastguard Worker            }
947*a65addddSAndroid Build Coastguard Worker
948*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getOtherReplacementComponent() {
949*a65addddSAndroid Build Coastguard Worker              static int n = 30;
950*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
951*a65addddSAndroid Build Coastguard Worker                  .addInstanceMultibinding(n);
952*a65addddSAndroid Build Coastguard Worker            }
953*a65addddSAndroid Build Coastguard Worker
954*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
955*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
956*a65addddSAndroid Build Coastguard Worker                  .replace(getReplacedComponent, 1.0).with(getReplacementComponent)
957*a65addddSAndroid Build Coastguard Worker                  .replace(getReplacedComponent, 5.0).with(getOtherReplacementComponent)
958*a65addddSAndroid Build Coastguard Worker                  .install(getReplacedComponent, 1.0)
959*a65addddSAndroid Build Coastguard Worker                  .install(getReplacedComponent, 5.0);
960*a65addddSAndroid Build Coastguard Worker            }
961*a65addddSAndroid Build Coastguard Worker
962*a65addddSAndroid Build Coastguard Worker            int main() {
963*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getRootComponent);
964*a65addddSAndroid Build Coastguard Worker
965*a65addddSAndroid Build Coastguard Worker              std::vector<int*> multibindings = injector.getMultibindings<int>();
966*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 2);
967*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[0]) == 20);
968*a65addddSAndroid Build Coastguard Worker              Assert(*(multibindings[1]) == 30);
969*a65addddSAndroid Build Coastguard Worker            }
970*a65addddSAndroid Build Coastguard Worker            '''
971*a65addddSAndroid Build Coastguard Worker        expect_success(
972*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
973*a65addddSAndroid Build Coastguard Worker            source,
974*a65addddSAndroid Build Coastguard Worker            locals())
975*a65addddSAndroid Build Coastguard Worker
976*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__':
977*a65addddSAndroid Build Coastguard Worker    absltest.main()
978