xref: /aosp_15_r20/external/google-fruit/tests/test_register_instance.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 Annotation1 {};
23*a65addddSAndroid Build Coastguard Worker    '''
24*a65addddSAndroid Build Coastguard Worker
25*a65addddSAndroid Build Coastguard Workerdef escape_regex(regex):
26*a65addddSAndroid Build Coastguard Worker    # We un-escape the space because we strip the spaces in fruit_test_common, and this would otherwise leave a
27*a65addddSAndroid Build Coastguard Worker    # stray backslash.
28*a65addddSAndroid Build Coastguard Worker    return re.escape(regex).replace('\\ ', ' ')
29*a65addddSAndroid Build Coastguard Worker
30*a65addddSAndroid Build Coastguard Workerclass TestRegisterInstance(parameterized.TestCase):
31*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_success(self):
32*a65addddSAndroid Build Coastguard Worker        source = '''
33*a65addddSAndroid Build Coastguard Worker            struct X {
34*a65addddSAndroid Build Coastguard Worker              int n;
35*a65addddSAndroid Build Coastguard Worker
36*a65addddSAndroid Build Coastguard Worker              X(int n)
37*a65addddSAndroid Build Coastguard Worker                : n(n) {
38*a65addddSAndroid Build Coastguard Worker              }
39*a65addddSAndroid Build Coastguard Worker            };
40*a65addddSAndroid Build Coastguard Worker
41*a65addddSAndroid Build Coastguard Worker            fruit::Component<X> getComponent(X* x) {
42*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
43*a65addddSAndroid Build Coastguard Worker                .bindInstance(*x);
44*a65addddSAndroid Build Coastguard Worker            }
45*a65addddSAndroid Build Coastguard Worker
46*a65addddSAndroid Build Coastguard Worker            int main() {
47*a65addddSAndroid Build Coastguard Worker              X x(34);
48*a65addddSAndroid Build Coastguard Worker              fruit::Injector<X> injector(getComponent, &x);
49*a65addddSAndroid Build Coastguard Worker              X& x1 = injector.get<X&>();
50*a65addddSAndroid Build Coastguard Worker              Assert(&x == &x1);
51*a65addddSAndroid Build Coastguard Worker            }
52*a65addddSAndroid Build Coastguard Worker            '''
53*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source)
54*a65addddSAndroid Build Coastguard Worker
55*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_annotated_success(self):
56*a65addddSAndroid Build Coastguard Worker        source = '''
57*a65addddSAndroid Build Coastguard Worker            struct X {
58*a65addddSAndroid Build Coastguard Worker              int n;
59*a65addddSAndroid Build Coastguard Worker
60*a65addddSAndroid Build Coastguard Worker              X(int n)
61*a65addddSAndroid Build Coastguard Worker                : n(n) {
62*a65addddSAndroid Build Coastguard Worker              }
63*a65addddSAndroid Build Coastguard Worker            };
64*a65addddSAndroid Build Coastguard Worker
65*a65addddSAndroid Build Coastguard Worker            fruit::Component<fruit::Annotated<Annotation1, X>> getComponent(X* x) {
66*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
67*a65addddSAndroid Build Coastguard Worker                .bindInstance<fruit::Annotated<Annotation1, X>>(*x);
68*a65addddSAndroid Build Coastguard Worker            }
69*a65addddSAndroid Build Coastguard Worker
70*a65addddSAndroid Build Coastguard Worker            int main() {
71*a65addddSAndroid Build Coastguard Worker              X x(34);
72*a65addddSAndroid Build Coastguard Worker              fruit::Injector<fruit::Annotated<Annotation1, X>> injector(getComponent, &x);
73*a65addddSAndroid Build Coastguard Worker              X& x1 = injector.get<fruit::Annotated<Annotation1, X&>>();
74*a65addddSAndroid Build Coastguard Worker              Assert(&x == &x1);
75*a65addddSAndroid Build Coastguard Worker            }
76*a65addddSAndroid Build Coastguard Worker            '''
77*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source)
78*a65addddSAndroid Build Coastguard Worker
79*a65addddSAndroid Build Coastguard Worker    def test_bind_const_instance_success(self):
80*a65addddSAndroid Build Coastguard Worker        source = '''
81*a65addddSAndroid Build Coastguard Worker            struct X {
82*a65addddSAndroid Build Coastguard Worker              int n;
83*a65addddSAndroid Build Coastguard Worker
84*a65addddSAndroid Build Coastguard Worker              X(int n)
85*a65addddSAndroid Build Coastguard Worker                : n(n) {
86*a65addddSAndroid Build Coastguard Worker              }
87*a65addddSAndroid Build Coastguard Worker            };
88*a65addddSAndroid Build Coastguard Worker
89*a65addddSAndroid Build Coastguard Worker            fruit::Component<const X> getComponent(const X* x) {
90*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
91*a65addddSAndroid Build Coastguard Worker                .bindInstance(*x);
92*a65addddSAndroid Build Coastguard Worker            }
93*a65addddSAndroid Build Coastguard Worker
94*a65addddSAndroid Build Coastguard Worker            const X x(34);
95*a65addddSAndroid Build Coastguard Worker
96*a65addddSAndroid Build Coastguard Worker            int main() {
97*a65addddSAndroid Build Coastguard Worker              fruit::Injector<const X> injector(getComponent, &x);
98*a65addddSAndroid Build Coastguard Worker              const X& x1 = injector.get<const X&>();
99*a65addddSAndroid Build Coastguard Worker              Assert(&x == &x1);
100*a65addddSAndroid Build Coastguard Worker            }
101*a65addddSAndroid Build Coastguard Worker            '''
102*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source)
103*a65addddSAndroid Build Coastguard Worker
104*a65addddSAndroid Build Coastguard Worker    def test_bind_const_instance_annotated_success(self):
105*a65addddSAndroid Build Coastguard Worker        source = '''
106*a65addddSAndroid Build Coastguard Worker            struct X {
107*a65addddSAndroid Build Coastguard Worker              int n;
108*a65addddSAndroid Build Coastguard Worker
109*a65addddSAndroid Build Coastguard Worker              X(int n)
110*a65addddSAndroid Build Coastguard Worker                : n(n) {
111*a65addddSAndroid Build Coastguard Worker              }
112*a65addddSAndroid Build Coastguard Worker            };
113*a65addddSAndroid Build Coastguard Worker
114*a65addddSAndroid Build Coastguard Worker            fruit::Component<fruit::Annotated<Annotation1, const X>> getComponent(const X* x) {
115*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
116*a65addddSAndroid Build Coastguard Worker                .bindInstance<fruit::Annotated<Annotation1, X>>(*x);
117*a65addddSAndroid Build Coastguard Worker            }
118*a65addddSAndroid Build Coastguard Worker
119*a65addddSAndroid Build Coastguard Worker            const X x(34);
120*a65addddSAndroid Build Coastguard Worker
121*a65addddSAndroid Build Coastguard Worker            int main() {
122*a65addddSAndroid Build Coastguard Worker              fruit::Injector<fruit::Annotated<Annotation1, const X>> injector(getComponent, &x);
123*a65addddSAndroid Build Coastguard Worker              const X& x1 = injector.get<fruit::Annotated<Annotation1, const X&>>();
124*a65addddSAndroid Build Coastguard Worker              Assert(&x == &x1);
125*a65addddSAndroid Build Coastguard Worker            }
126*a65addddSAndroid Build Coastguard Worker            '''
127*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source)
128*a65addddSAndroid Build Coastguard Worker
129*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
130*a65addddSAndroid Build Coastguard Worker        ('X', 'X', 'X*', 'X*'),
131*a65addddSAndroid Build Coastguard Worker        ('X', 'const X', 'const X*', 'const X*'),
132*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>', 'X*', 'fruit::Annotated<Annotation1, X*>'),
133*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>', 'const X*', 'fruit::Annotated<Annotation1, const X*>'),
134*a65addddSAndroid Build Coastguard Worker    ])
135*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_two_explicit_type_arguments_success(self, XAnnot, MaybeConstXAnnot, XPtr, XPtrAnnot):
136*a65addddSAndroid Build Coastguard Worker        source = '''
137*a65addddSAndroid Build Coastguard Worker            struct X {
138*a65addddSAndroid Build Coastguard Worker              int n;
139*a65addddSAndroid Build Coastguard Worker
140*a65addddSAndroid Build Coastguard Worker              X(int n)
141*a65addddSAndroid Build Coastguard Worker                : n(n) {
142*a65addddSAndroid Build Coastguard Worker              }
143*a65addddSAndroid Build Coastguard Worker            };
144*a65addddSAndroid Build Coastguard Worker
145*a65addddSAndroid Build Coastguard Worker            fruit::Component<MaybeConstXAnnot> getComponent(XPtr x) {
146*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
147*a65addddSAndroid Build Coastguard Worker                .bindInstance<XAnnot, X>(*x);
148*a65addddSAndroid Build Coastguard Worker            }
149*a65addddSAndroid Build Coastguard Worker
150*a65addddSAndroid Build Coastguard Worker            int main() {
151*a65addddSAndroid Build Coastguard Worker              X x(34);
152*a65addddSAndroid Build Coastguard Worker              fruit::Injector<MaybeConstXAnnot> injector(getComponent, &x);
153*a65addddSAndroid Build Coastguard Worker              XPtr x1 = injector.get<XPtrAnnot>();
154*a65addddSAndroid Build Coastguard Worker              Assert(&x == x1);
155*a65addddSAndroid Build Coastguard Worker            }
156*a65addddSAndroid Build Coastguard Worker            '''
157*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source, locals())
158*a65addddSAndroid Build Coastguard Worker
159*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
160*a65addddSAndroid Build Coastguard Worker        'X',
161*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, X>',
162*a65addddSAndroid Build Coastguard Worker    ])
163*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_abstract_class_ok(self, XAnnot):
164*a65addddSAndroid Build Coastguard Worker        source = '''
165*a65addddSAndroid Build Coastguard Worker            struct X {
166*a65addddSAndroid Build Coastguard Worker              virtual void foo() = 0;
167*a65addddSAndroid Build Coastguard Worker            };
168*a65addddSAndroid Build Coastguard Worker
169*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentForInstanceHelper(X* x) {
170*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
171*a65addddSAndroid Build Coastguard Worker                .bindInstance<XAnnot, X>(*x);
172*a65addddSAndroid Build Coastguard Worker            }
173*a65addddSAndroid Build Coastguard Worker
174*a65addddSAndroid Build Coastguard Worker            fruit::Component<XAnnot> getComponentForInstance(X* x) {
175*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
176*a65addddSAndroid Build Coastguard Worker                .install(getComponentForInstanceHelper, x)
177*a65addddSAndroid Build Coastguard Worker                .bindInstance<XAnnot, X>(*x);
178*a65addddSAndroid Build Coastguard Worker            }
179*a65addddSAndroid Build Coastguard Worker            '''
180*a65addddSAndroid Build Coastguard Worker        expect_success(
181*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
182*a65addddSAndroid Build Coastguard Worker            source,
183*a65addddSAndroid Build Coastguard Worker            locals())
184*a65addddSAndroid Build Coastguard Worker
185*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
186*a65addddSAndroid Build Coastguard Worker        ('int', 'int*'),
187*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, int>', 'fruit::Annotated<Annotation1, int*>'),
188*a65addddSAndroid Build Coastguard Worker    ])
189*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_multiple_equivalent_bindings_success(self, intAnnot, intPtrAnnot):
190*a65addddSAndroid Build Coastguard Worker        source = '''
191*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentForInstanceHelper(int* n) {
192*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
193*a65addddSAndroid Build Coastguard Worker                .bindInstance<intAnnot, int>(*n);
194*a65addddSAndroid Build Coastguard Worker            }
195*a65addddSAndroid Build Coastguard Worker
196*a65addddSAndroid Build Coastguard Worker            fruit::Component<intAnnot> getComponentForInstance(int* n) {
197*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
198*a65addddSAndroid Build Coastguard Worker                .install(getComponentForInstanceHelper, n)
199*a65addddSAndroid Build Coastguard Worker                .bindInstance<intAnnot, int>(*n);
200*a65addddSAndroid Build Coastguard Worker            }
201*a65addddSAndroid Build Coastguard Worker
202*a65addddSAndroid Build Coastguard Worker            int main() {
203*a65addddSAndroid Build Coastguard Worker              int n = 5;
204*a65addddSAndroid Build Coastguard Worker              fruit::Injector<intAnnot> injector(getComponentForInstance, &n);
205*a65addddSAndroid Build Coastguard Worker              if (injector.get<intPtrAnnot>() != &n)
206*a65addddSAndroid Build Coastguard Worker                abort();
207*a65addddSAndroid Build Coastguard Worker            }
208*a65addddSAndroid Build Coastguard Worker            '''
209*a65addddSAndroid Build Coastguard Worker        expect_success(
210*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
211*a65addddSAndroid Build Coastguard Worker            source,
212*a65addddSAndroid Build Coastguard Worker            locals())
213*a65addddSAndroid Build Coastguard Worker
214*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
215*a65addddSAndroid Build Coastguard Worker        ('int', 'int*'),
216*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, int>', 'fruit::Annotated<Annotation1, int*>'),
217*a65addddSAndroid Build Coastguard Worker    ])
218*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_multiple_equivalent_bindings_different_constness_success(self, intAnnot, intPtrAnnot):
219*a65addddSAndroid Build Coastguard Worker        source = '''
220*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentForInstanceHelper(const int* n) {
221*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
222*a65addddSAndroid Build Coastguard Worker                .bindInstance<intAnnot, int>(*n);
223*a65addddSAndroid Build Coastguard Worker            }
224*a65addddSAndroid Build Coastguard Worker
225*a65addddSAndroid Build Coastguard Worker            fruit::Component<intAnnot> getComponentForInstance(int* n) {
226*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
227*a65addddSAndroid Build Coastguard Worker                .install(getComponentForInstanceHelper, n)
228*a65addddSAndroid Build Coastguard Worker                .bindInstance<intAnnot, int>(*n);
229*a65addddSAndroid Build Coastguard Worker            }
230*a65addddSAndroid Build Coastguard Worker
231*a65addddSAndroid Build Coastguard Worker            int main() {
232*a65addddSAndroid Build Coastguard Worker              int n = 5;
233*a65addddSAndroid Build Coastguard Worker              fruit::Injector<intAnnot> injector(getComponentForInstance, &n);
234*a65addddSAndroid Build Coastguard Worker              if (injector.get<intPtrAnnot>() != &n)
235*a65addddSAndroid Build Coastguard Worker                abort();
236*a65addddSAndroid Build Coastguard Worker            }
237*a65addddSAndroid Build Coastguard Worker            '''
238*a65addddSAndroid Build Coastguard Worker        expect_success(
239*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
240*a65addddSAndroid Build Coastguard Worker            source,
241*a65addddSAndroid Build Coastguard Worker            locals())
242*a65addddSAndroid Build Coastguard Worker
243*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
244*a65addddSAndroid Build Coastguard Worker        ('int', 'int*'),
245*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, int>', 'fruit::Annotated<Annotation1, int*>'),
246*a65addddSAndroid Build Coastguard Worker    ])
247*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_multiple_equivalent_bindings_different_constness_other_order_success(self, intAnnot, intPtrAnnot):
248*a65addddSAndroid Build Coastguard Worker        source = '''
249*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentForInstanceHelper(const int* n) {
250*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
251*a65addddSAndroid Build Coastguard Worker                .bindInstance<intAnnot, int>(*n);
252*a65addddSAndroid Build Coastguard Worker            }
253*a65addddSAndroid Build Coastguard Worker
254*a65addddSAndroid Build Coastguard Worker            fruit::Component<intAnnot> getComponentForInstance(int* n) {
255*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
256*a65addddSAndroid Build Coastguard Worker                .bindInstance<intAnnot, int>(*n)
257*a65addddSAndroid Build Coastguard Worker                .install(getComponentForInstanceHelper, n);
258*a65addddSAndroid Build Coastguard Worker            }
259*a65addddSAndroid Build Coastguard Worker
260*a65addddSAndroid Build Coastguard Worker            int main() {
261*a65addddSAndroid Build Coastguard Worker              int n = 5;
262*a65addddSAndroid Build Coastguard Worker              fruit::Injector<intAnnot> injector(getComponentForInstance, &n);
263*a65addddSAndroid Build Coastguard Worker              if (injector.get<intPtrAnnot>() != &n)
264*a65addddSAndroid Build Coastguard Worker                abort();
265*a65addddSAndroid Build Coastguard Worker            }
266*a65addddSAndroid Build Coastguard Worker            '''
267*a65addddSAndroid Build Coastguard Worker        expect_success(
268*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
269*a65addddSAndroid Build Coastguard Worker            source,
270*a65addddSAndroid Build Coastguard Worker            locals())
271*a65addddSAndroid Build Coastguard Worker
272*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
273*a65addddSAndroid Build Coastguard Worker        'X*',
274*a65addddSAndroid Build Coastguard Worker        'const X*',
275*a65addddSAndroid Build Coastguard Worker        'std::shared_ptr<X>',
276*a65addddSAndroid Build Coastguard Worker    ])
277*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_non_normalized_type_error(self, XVariant):
278*a65addddSAndroid Build Coastguard Worker        if XVariant.endswith('&'):
279*a65addddSAndroid Build Coastguard Worker            XVariantRegexp = escape_regex(XVariant[:-1])
280*a65addddSAndroid Build Coastguard Worker        else:
281*a65addddSAndroid Build Coastguard Worker            XVariantRegexp = escape_regex(XVariant)
282*a65addddSAndroid Build Coastguard Worker        source = '''
283*a65addddSAndroid Build Coastguard Worker            struct X {};
284*a65addddSAndroid Build Coastguard Worker
285*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent(XVariant x) {
286*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
287*a65addddSAndroid Build Coastguard Worker                .bindInstance(x);
288*a65addddSAndroid Build Coastguard Worker            }
289*a65addddSAndroid Build Coastguard Worker            '''
290*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
291*a65addddSAndroid Build Coastguard Worker            'NonClassTypeError<XVariantRegexp,X>',
292*a65addddSAndroid Build Coastguard Worker            'A non-class type T was specified. Use C instead.',
293*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
294*a65addddSAndroid Build Coastguard Worker            source,
295*a65addddSAndroid Build Coastguard Worker            locals())
296*a65addddSAndroid Build Coastguard Worker
297*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
298*a65addddSAndroid Build Coastguard Worker        ('const X', r'const X'),
299*a65addddSAndroid Build Coastguard Worker        ('X*', r'X\*'),
300*a65addddSAndroid Build Coastguard Worker        ('const X*', r'const X\*'),
301*a65addddSAndroid Build Coastguard Worker        ('X&', r'X&'),
302*a65addddSAndroid Build Coastguard Worker        ('const X&', r'const X&'),
303*a65addddSAndroid Build Coastguard Worker        ('std::shared_ptr<X>', r'std::shared_ptr<X>'),
304*a65addddSAndroid Build Coastguard Worker    ])
305*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_non_normalized_type_error_with_annotation(self, XVariant, XVariantRegexp):
306*a65addddSAndroid Build Coastguard Worker        source = '''
307*a65addddSAndroid Build Coastguard Worker            struct X {};
308*a65addddSAndroid Build Coastguard Worker
309*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent(XVariant x) {
310*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
311*a65addddSAndroid Build Coastguard Worker                .bindInstance<fruit::Annotated<Annotation1, XVariant>>(x);
312*a65addddSAndroid Build Coastguard Worker            }
313*a65addddSAndroid Build Coastguard Worker            '''
314*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
315*a65addddSAndroid Build Coastguard Worker            'NonClassTypeError<XVariantRegexp,X>',
316*a65addddSAndroid Build Coastguard Worker            'A non-class type T was specified. Use C instead.',
317*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
318*a65addddSAndroid Build Coastguard Worker            source,
319*a65addddSAndroid Build Coastguard Worker            locals())
320*a65addddSAndroid Build Coastguard Worker
321*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
322*a65addddSAndroid Build Coastguard Worker        ('const X', 'const X'),
323*a65addddSAndroid Build Coastguard Worker        ('X*', 'X*'),
324*a65addddSAndroid Build Coastguard Worker        ('const X*', 'const X*'),
325*a65addddSAndroid Build Coastguard Worker        ('X&', 'X&'),
326*a65addddSAndroid Build Coastguard Worker        ('const X&', 'const X&'),
327*a65addddSAndroid Build Coastguard Worker        ('std::shared_ptr<X>', 'std::shared_ptr<X>'),
328*a65addddSAndroid Build Coastguard Worker
329*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, const X>', 'const X'),
330*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X*>', 'X*'),
331*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, const X*>', 'const X*'),
332*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X&>', 'X&'),
333*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, const X&>', 'const X&'),
334*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, std::shared_ptr<X>>', 'std::shared_ptr<X>'),
335*a65addddSAndroid Build Coastguard Worker
336*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'const X'),
337*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'X*'),
338*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'const X*'),
339*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'X&'),
340*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'const X&'),
341*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'std::shared_ptr<X>'),
342*a65addddSAndroid Build Coastguard Worker    ])
343*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_non_normalized_type_error_two_explicit_type_arguments(self, XAnnotVariant, XVariant):
344*a65addddSAndroid Build Coastguard Worker        XVariantRegexp = escape_regex(XVariant)
345*a65addddSAndroid Build Coastguard Worker        source = '''
346*a65addddSAndroid Build Coastguard Worker            struct X {};
347*a65addddSAndroid Build Coastguard Worker
348*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent(XVariant x) {
349*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
350*a65addddSAndroid Build Coastguard Worker                .bindInstance<XAnnotVariant, XVariant>(x);
351*a65addddSAndroid Build Coastguard Worker            }
352*a65addddSAndroid Build Coastguard Worker            '''
353*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
354*a65addddSAndroid Build Coastguard Worker            'NonClassTypeError<XVariantRegexp,X>',
355*a65addddSAndroid Build Coastguard Worker            'A non-class type T was specified. Use C instead.',
356*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
357*a65addddSAndroid Build Coastguard Worker            source,
358*a65addddSAndroid Build Coastguard Worker            locals())
359*a65addddSAndroid Build Coastguard Worker
360*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
361*a65addddSAndroid Build Coastguard Worker        ('X*', r'X\*'),
362*a65addddSAndroid Build Coastguard Worker        ('const X*', r'const X\*'),
363*a65addddSAndroid Build Coastguard Worker        ('std::shared_ptr<X>', r'std::shared_ptr<X>'),
364*a65addddSAndroid Build Coastguard Worker    ])
365*a65addddSAndroid Build Coastguard Worker    def test_register_instance_error_must_be_reference(self, XVariant, XVariantRegex):
366*a65addddSAndroid Build Coastguard Worker        source = '''
367*a65addddSAndroid Build Coastguard Worker            struct X {};
368*a65addddSAndroid Build Coastguard Worker
369*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentForInstance(XVariant x) {
370*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
371*a65addddSAndroid Build Coastguard Worker                  .bindInstance(x);
372*a65addddSAndroid Build Coastguard Worker            }
373*a65addddSAndroid Build Coastguard Worker            '''
374*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
375*a65addddSAndroid Build Coastguard Worker            'NonClassTypeError<XVariantRegex,X>',
376*a65addddSAndroid Build Coastguard Worker            'A non-class type T was specified. Use C instead.',
377*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
378*a65addddSAndroid Build Coastguard Worker            source,
379*a65addddSAndroid Build Coastguard Worker            locals())
380*a65addddSAndroid Build Coastguard Worker
381*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
382*a65addddSAndroid Build Coastguard Worker        ('X*', r'X\*'),
383*a65addddSAndroid Build Coastguard Worker        ('const X*', r'const X\*'),
384*a65addddSAndroid Build Coastguard Worker        ('std::shared_ptr<X>', r'std::shared_ptr<X>'),
385*a65addddSAndroid Build Coastguard Worker    ])
386*a65addddSAndroid Build Coastguard Worker    def test_register_instance_error_must_be_reference_with_annotation(self, XVariant, XVariantRegex):
387*a65addddSAndroid Build Coastguard Worker        source = '''
388*a65addddSAndroid Build Coastguard Worker            struct X {};
389*a65addddSAndroid Build Coastguard Worker
390*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentForInstance(XVariant x) {
391*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
392*a65addddSAndroid Build Coastguard Worker                  .bindInstance<fruit::Annotated<Annotation1, X>>(x);
393*a65addddSAndroid Build Coastguard Worker            }
394*a65addddSAndroid Build Coastguard Worker            '''
395*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
396*a65addddSAndroid Build Coastguard Worker            'NonClassTypeError<XVariantRegex,X>',
397*a65addddSAndroid Build Coastguard Worker            'A non-class type T was specified. Use C instead.',
398*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
399*a65addddSAndroid Build Coastguard Worker            source,
400*a65addddSAndroid Build Coastguard Worker            locals())
401*a65addddSAndroid Build Coastguard Worker
402*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
403*a65addddSAndroid Build Coastguard Worker        'X',
404*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, X>',
405*a65addddSAndroid Build Coastguard Worker    ])
406*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_mismatched_type_arguments(self, XAnnot):
407*a65addddSAndroid Build Coastguard Worker        source = '''
408*a65addddSAndroid Build Coastguard Worker            struct X {};
409*a65addddSAndroid Build Coastguard Worker
410*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent(int* n) {
411*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
412*a65addddSAndroid Build Coastguard Worker                .bindInstance<XAnnot, int>(*n);
413*a65addddSAndroid Build Coastguard Worker            }
414*a65addddSAndroid Build Coastguard Worker            '''
415*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
416*a65addddSAndroid Build Coastguard Worker            'TypeMismatchInBindInstanceError<X,int>',
417*a65addddSAndroid Build Coastguard Worker            'A type parameter was specified in bindInstance.. but it doesn.t match the value type',
418*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
419*a65addddSAndroid Build Coastguard Worker            source,
420*a65addddSAndroid Build Coastguard Worker            locals())
421*a65addddSAndroid Build Coastguard Worker
422*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
423*a65addddSAndroid Build Coastguard Worker        ('Base', 'Base*'),
424*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, Base>', 'fruit::Annotated<Annotation1, Base*>'),
425*a65addddSAndroid Build Coastguard Worker    ])
426*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_to_subclass(self, BaseAnnot, BasePtrAnnot):
427*a65addddSAndroid Build Coastguard Worker        source = '''
428*a65addddSAndroid Build Coastguard Worker            struct Base {
429*a65addddSAndroid Build Coastguard Worker              virtual void f() = 0;
430*a65addddSAndroid Build Coastguard Worker              virtual ~Base() {
431*a65addddSAndroid Build Coastguard Worker              }
432*a65addddSAndroid Build Coastguard Worker            };
433*a65addddSAndroid Build Coastguard Worker
434*a65addddSAndroid Build Coastguard Worker            struct Derived : public Base {
435*a65addddSAndroid Build Coastguard Worker              void f() override {
436*a65addddSAndroid Build Coastguard Worker              }
437*a65addddSAndroid Build Coastguard Worker            };
438*a65addddSAndroid Build Coastguard Worker
439*a65addddSAndroid Build Coastguard Worker            fruit::Component<BaseAnnot> getComponent(Derived* derived) {
440*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
441*a65addddSAndroid Build Coastguard Worker                .bindInstance<BaseAnnot, Base>(*derived);
442*a65addddSAndroid Build Coastguard Worker            }
443*a65addddSAndroid Build Coastguard Worker
444*a65addddSAndroid Build Coastguard Worker            int main() {
445*a65addddSAndroid Build Coastguard Worker              Derived derived;
446*a65addddSAndroid Build Coastguard Worker              fruit::Injector<BaseAnnot> injector(getComponent, &derived);
447*a65addddSAndroid Build Coastguard Worker              Base* base = injector.get<BasePtrAnnot>();
448*a65addddSAndroid Build Coastguard Worker              base->f();
449*a65addddSAndroid Build Coastguard Worker            }
450*a65addddSAndroid Build Coastguard Worker            '''
451*a65addddSAndroid Build Coastguard Worker        expect_success(COMMON_DEFINITIONS, source, locals())
452*a65addddSAndroid Build Coastguard Worker
453*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
454*a65addddSAndroid Build Coastguard Worker        ('X**', r'X\*\*'),
455*a65addddSAndroid Build Coastguard Worker        ('std::shared_ptr<X>*', r'std::shared_ptr<X>\*'),
456*a65addddSAndroid Build Coastguard Worker        ('X*&', r'X\*&'),
457*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X**>', r'X\*\*'),
458*a65addddSAndroid Build Coastguard Worker    ])
459*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_type_not_normalized(self, XVariant, XVariantRegex):
460*a65addddSAndroid Build Coastguard Worker        source = '''
461*a65addddSAndroid Build Coastguard Worker            struct X {};
462*a65addddSAndroid Build Coastguard Worker
463*a65addddSAndroid Build Coastguard Worker            using XVariantT = XVariant;
464*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent(XVariantT x) {
465*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
466*a65addddSAndroid Build Coastguard Worker                .bindInstance<XVariant, XVariant>(x);
467*a65addddSAndroid Build Coastguard Worker            }
468*a65addddSAndroid Build Coastguard Worker            '''
469*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
470*a65addddSAndroid Build Coastguard Worker            'NonClassTypeError<XVariantRegex,X>',
471*a65addddSAndroid Build Coastguard Worker            'A non-class type T was specified.',
472*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
473*a65addddSAndroid Build Coastguard Worker            source,
474*a65addddSAndroid Build Coastguard Worker            locals())
475*a65addddSAndroid Build Coastguard Worker
476*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
477*a65addddSAndroid Build Coastguard Worker        ('X(*)()', r'X(\((__cdecl)?\*\))?\((void)?\)'),
478*a65addddSAndroid Build Coastguard Worker    ])
479*a65addddSAndroid Build Coastguard Worker    def test_bind_instance_type_not_injectable_error(self, XVariant, XVariantRegex):
480*a65addddSAndroid Build Coastguard Worker        source = '''
481*a65addddSAndroid Build Coastguard Worker            struct X {};
482*a65addddSAndroid Build Coastguard Worker
483*a65addddSAndroid Build Coastguard Worker            using XVariantT = XVariant;
484*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent(XVariantT x) {
485*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
486*a65addddSAndroid Build Coastguard Worker                .bindInstance<XVariant, XVariant>(x);
487*a65addddSAndroid Build Coastguard Worker            }
488*a65addddSAndroid Build Coastguard Worker            '''
489*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
490*a65addddSAndroid Build Coastguard Worker            'NonInjectableTypeError<XVariantRegex>',
491*a65addddSAndroid Build Coastguard Worker            'The type T is not injectable.',
492*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
493*a65addddSAndroid Build Coastguard Worker            source,
494*a65addddSAndroid Build Coastguard Worker            locals())
495*a65addddSAndroid Build Coastguard Worker
496*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__':
497*a65addddSAndroid Build Coastguard Worker    absltest.main()
498