xref: /aosp_15_r20/external/google-fruit/tests/test_multibindings_bind_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 Workerclass TestMultibindingsBindInstance(parameterized.TestCase):
26*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
27*a65addddSAndroid Build Coastguard Worker        'X',
28*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, X>',
29*a65addddSAndroid Build Coastguard Worker    ])
30*a65addddSAndroid Build Coastguard Worker    def test_multibindings_bind_instance_ok(self, XAnnot):
31*a65addddSAndroid Build Coastguard Worker        source = '''
32*a65addddSAndroid Build Coastguard Worker            struct X {};
33*a65addddSAndroid Build Coastguard Worker
34*a65addddSAndroid Build Coastguard Worker            X x;
35*a65addddSAndroid Build Coastguard Worker
36*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent() {
37*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
38*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding<XAnnot, X>(x);
39*a65addddSAndroid Build Coastguard Worker            }
40*a65addddSAndroid Build Coastguard Worker
41*a65addddSAndroid Build Coastguard Worker            int main() {
42*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getComponent);
43*a65addddSAndroid Build Coastguard Worker
44*a65addddSAndroid Build Coastguard Worker              std::vector<X*> multibindings = injector.getMultibindings<XAnnot>();
45*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 1);
46*a65addddSAndroid Build Coastguard Worker              Assert(multibindings[0] == &x);
47*a65addddSAndroid Build Coastguard Worker            }
48*a65addddSAndroid Build Coastguard Worker            '''
49*a65addddSAndroid Build Coastguard Worker        expect_success(
50*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
51*a65addddSAndroid Build Coastguard Worker            source,
52*a65addddSAndroid Build Coastguard Worker            locals())
53*a65addddSAndroid Build Coastguard Worker
54*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
55*a65addddSAndroid Build Coastguard Worker        'X',
56*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, X>',
57*a65addddSAndroid Build Coastguard Worker    ])
58*a65addddSAndroid Build Coastguard Worker    def test_multibindings_bind_const_instance_error(self, XAnnot):
59*a65addddSAndroid Build Coastguard Worker        source = '''
60*a65addddSAndroid Build Coastguard Worker            struct X {};
61*a65addddSAndroid Build Coastguard Worker
62*a65addddSAndroid Build Coastguard Worker            const X x{};
63*a65addddSAndroid Build Coastguard Worker
64*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent() {
65*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
66*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding<XAnnot, X>(x);
67*a65addddSAndroid Build Coastguard Worker            }
68*a65addddSAndroid Build Coastguard Worker            '''
69*a65addddSAndroid Build Coastguard Worker        expect_generic_compile_error(
70*a65addddSAndroid Build Coastguard Worker            r'candidate function not viable: 1st argument \(.const X.\) would lose const qualifier'
71*a65addddSAndroid Build Coastguard Worker            r'|no matching function for call to .fruit::PartialComponent<.*>::addInstanceMultibinding(<XAnnot,X>)?\(const X&\).'
72*a65addddSAndroid Build Coastguard Worker            r'|error: no matching member function for call to .addInstanceMultibinding.'
73*a65addddSAndroid Build Coastguard Worker            r'|cannot convert argument 1 from .const X. to .X &.',
74*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
75*a65addddSAndroid Build Coastguard Worker            source,
76*a65addddSAndroid Build Coastguard Worker            locals())
77*a65addddSAndroid Build Coastguard Worker
78*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
79*a65addddSAndroid Build Coastguard Worker        'X',
80*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, X>',
81*a65addddSAndroid Build Coastguard Worker    ])
82*a65addddSAndroid Build Coastguard Worker    def test_multibindings_bind_instance_vector(self, XAnnot):
83*a65addddSAndroid Build Coastguard Worker        source = '''
84*a65addddSAndroid Build Coastguard Worker            struct X {};
85*a65addddSAndroid Build Coastguard Worker
86*a65addddSAndroid Build Coastguard Worker            std::vector<X> values = {X(), X()};
87*a65addddSAndroid Build Coastguard Worker
88*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent() {
89*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
90*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibindings<XAnnot, X>(values);
91*a65addddSAndroid Build Coastguard Worker            }
92*a65addddSAndroid Build Coastguard Worker
93*a65addddSAndroid Build Coastguard Worker            int main() {
94*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getComponent);
95*a65addddSAndroid Build Coastguard Worker
96*a65addddSAndroid Build Coastguard Worker              std::vector<X*> multibindings = injector.getMultibindings<XAnnot>();
97*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.size() == 2);
98*a65addddSAndroid Build Coastguard Worker              Assert(multibindings[0] == &(values[0]));
99*a65addddSAndroid Build Coastguard Worker              Assert(multibindings[1] == &(values[1]));
100*a65addddSAndroid Build Coastguard Worker            }
101*a65addddSAndroid Build Coastguard Worker            '''
102*a65addddSAndroid Build Coastguard Worker        expect_success(
103*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
104*a65addddSAndroid Build Coastguard Worker            source,
105*a65addddSAndroid Build Coastguard Worker            locals())
106*a65addddSAndroid Build Coastguard Worker
107*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
108*a65addddSAndroid Build Coastguard Worker        'X',
109*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, X>',
110*a65addddSAndroid Build Coastguard Worker    ])
111*a65addddSAndroid Build Coastguard Worker    def test_multibindings_bind_const_instance_vector_error(self, XAnnot):
112*a65addddSAndroid Build Coastguard Worker        source = '''
113*a65addddSAndroid Build Coastguard Worker            struct X {};
114*a65addddSAndroid Build Coastguard Worker
115*a65addddSAndroid Build Coastguard Worker            const std::vector<X> values{};
116*a65addddSAndroid Build Coastguard Worker
117*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent() {
118*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
119*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibindings<XAnnot, X>(values);
120*a65addddSAndroid Build Coastguard Worker            }
121*a65addddSAndroid Build Coastguard Worker            '''
122*a65addddSAndroid Build Coastguard Worker        expect_generic_compile_error(
123*a65addddSAndroid Build Coastguard Worker            r'candidate function not viable: 1st argument \(.const std::vector<X>.\) would lose const qualifier'
124*a65addddSAndroid Build Coastguard Worker            r'|cannot convert .values. \(type .const std::(__debug::)?vector<X>.\) to type .std::(__debug::)?vector<X>&.'
125*a65addddSAndroid Build Coastguard Worker            r'|no matching .*function for call to .*addInstanceMultibindings'
126*a65addddSAndroid Build Coastguard Worker            r'|cannot convert argument 1 from .const std::vector<X,std::allocator<.*>>. to .std::vector<X,std::allocator<.*>> &.',
127*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
128*a65addddSAndroid Build Coastguard Worker            source,
129*a65addddSAndroid Build Coastguard Worker            locals())
130*a65addddSAndroid Build Coastguard Worker
131*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
132*a65addddSAndroid Build Coastguard Worker        'X',
133*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, X>',
134*a65addddSAndroid Build Coastguard Worker    ])
135*a65addddSAndroid Build Coastguard Worker    def test_multibindings_bind_instance_vector_of_consts_error(self, XAnnot):
136*a65addddSAndroid Build Coastguard Worker        source = '''
137*a65addddSAndroid Build Coastguard Worker            struct X {};
138*a65addddSAndroid Build Coastguard Worker
139*a65addddSAndroid Build Coastguard Worker            std::vector<const X> values;
140*a65addddSAndroid Build Coastguard Worker
141*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent() {
142*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
143*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibindings<XAnnot, X>(values);
144*a65addddSAndroid Build Coastguard Worker            }
145*a65addddSAndroid Build Coastguard Worker            '''
146*a65addddSAndroid Build Coastguard Worker        expect_generic_compile_error(
147*a65addddSAndroid Build Coastguard Worker            '.*',
148*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
149*a65addddSAndroid Build Coastguard Worker            source,
150*a65addddSAndroid Build Coastguard Worker            locals())
151*a65addddSAndroid Build Coastguard Worker
152*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
153*a65addddSAndroid Build Coastguard Worker        ('X**', r'X\*\*'),
154*a65addddSAndroid Build Coastguard Worker        ('std::shared_ptr<X>*', r'std::shared_ptr<X>\*'),
155*a65addddSAndroid Build Coastguard Worker        ('const std::shared_ptr<X>', r'const std::shared_ptr<X>'),
156*a65addddSAndroid Build Coastguard Worker        ('X* const', r'X\* const'),
157*a65addddSAndroid Build Coastguard Worker        ('const X* const', r'const X\* const'),
158*a65addddSAndroid Build Coastguard Worker        ('X*&', r'X\*&'),
159*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X**>', r'X\*\*'),
160*a65addddSAndroid Build Coastguard Worker    ])
161*a65addddSAndroid Build Coastguard Worker    def test_multibindings_bind_instance_non_class_type_error(self, XVariant, XVariantRegex):
162*a65addddSAndroid Build Coastguard Worker        source = '''
163*a65addddSAndroid Build Coastguard Worker            struct X {};
164*a65addddSAndroid Build Coastguard Worker
165*a65addddSAndroid Build Coastguard Worker            using XVariantT = XVariant;
166*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent(XVariantT x) {
167*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
168*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding<XVariant, XVariant>(x);
169*a65addddSAndroid Build Coastguard Worker            }
170*a65addddSAndroid Build Coastguard Worker            '''
171*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
172*a65addddSAndroid Build Coastguard Worker            'NonClassTypeError<XVariantRegex,X>',
173*a65addddSAndroid Build Coastguard Worker            'A non-class type T was specified.',
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    @parameterized.parameters([
179*a65addddSAndroid Build Coastguard Worker        ('std::nullptr_t', r'(std::)?nullptr(_t)?'),
180*a65addddSAndroid Build Coastguard Worker        ('X(*)()', r'X(\((__cdecl)?\*\))?\((void)?\)'),
181*a65addddSAndroid Build Coastguard Worker    ])
182*a65addddSAndroid Build Coastguard Worker    def test_multibindings_bind_instance_non_injectable_type_error(self, XVariant, XVariantRegex):
183*a65addddSAndroid Build Coastguard Worker        source = '''
184*a65addddSAndroid Build Coastguard Worker            struct X {};
185*a65addddSAndroid Build Coastguard Worker
186*a65addddSAndroid Build Coastguard Worker            using XVariantT = XVariant;
187*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent(XVariantT x) {
188*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
189*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding<XVariant, XVariant>(x);
190*a65addddSAndroid Build Coastguard Worker            }
191*a65addddSAndroid Build Coastguard Worker            '''
192*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
193*a65addddSAndroid Build Coastguard Worker            'NonInjectableTypeError<XVariantRegex>',
194*a65addddSAndroid Build Coastguard Worker            'The type T is not injectable.',
195*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
196*a65addddSAndroid Build Coastguard Worker            source,
197*a65addddSAndroid Build Coastguard Worker            locals())
198*a65addddSAndroid Build Coastguard Worker
199*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__':
200*a65addddSAndroid Build Coastguard Worker    absltest.main()
201