xref: /aosp_15_r20/external/google-fruit/tests/test_component.py (revision a65addddcf69f38db5b288d787b6b7571a57bb8f)
1*a65addddSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*a65addddSAndroid Build Coastguard Worker#  Copyright 2016 Google Inc. All Rights Reserved.
3*a65addddSAndroid Build Coastguard Worker#
4*a65addddSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
5*a65addddSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
6*a65addddSAndroid Build Coastguard Worker# You may obtain a copy of the License at
7*a65addddSAndroid Build Coastguard Worker#
8*a65addddSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
9*a65addddSAndroid Build Coastguard Worker#
10*a65addddSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*a65addddSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS-IS" BASIS,
12*a65addddSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*a65addddSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
14*a65addddSAndroid Build Coastguard Worker# limitations under the License.
15*a65addddSAndroid Build Coastguard Worker
16*a65addddSAndroid Build Coastguard Workerfrom absl.testing import parameterized
17*a65addddSAndroid Build Coastguard Workerfrom fruit_test_common import *
18*a65addddSAndroid Build Coastguard Worker
19*a65addddSAndroid Build Coastguard WorkerCOMMON_DEFINITIONS = '''
20*a65addddSAndroid Build Coastguard Worker    #include "test_common.h"
21*a65addddSAndroid Build Coastguard Worker
22*a65addddSAndroid Build Coastguard Worker    struct X;
23*a65addddSAndroid Build Coastguard Worker
24*a65addddSAndroid Build Coastguard Worker    struct Annotation1 {};
25*a65addddSAndroid Build Coastguard Worker    using XAnnot1 = fruit::Annotated<Annotation1, X>;
26*a65addddSAndroid Build Coastguard Worker
27*a65addddSAndroid Build Coastguard Worker    struct Annotation2 {};
28*a65addddSAndroid Build Coastguard Worker    using XAnnot2 = fruit::Annotated<Annotation2, X>;
29*a65addddSAndroid Build Coastguard Worker    '''
30*a65addddSAndroid Build Coastguard Worker
31*a65addddSAndroid Build Coastguard Workerclass TestComponent(parameterized.TestCase):
32*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
33*a65addddSAndroid Build Coastguard Worker        'X',
34*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, X>',
35*a65addddSAndroid Build Coastguard Worker    ])
36*a65addddSAndroid Build Coastguard Worker    def test_move(self, XAnnot):
37*a65addddSAndroid Build Coastguard Worker        source = '''
38*a65addddSAndroid Build Coastguard Worker            struct X {
39*a65addddSAndroid Build Coastguard Worker              using Inject = X();
40*a65addddSAndroid Build Coastguard Worker            };
41*a65addddSAndroid Build Coastguard Worker
42*a65addddSAndroid Build Coastguard Worker            fruit::Component<XAnnot> getComponent() {
43*a65addddSAndroid Build Coastguard Worker              fruit::Component<XAnnot> c = fruit::createComponent();
44*a65addddSAndroid Build Coastguard Worker              fruit::Component<XAnnot> c2 = std::move(c);
45*a65addddSAndroid Build Coastguard Worker              return fruit::Component<XAnnot>(std::move(c2));
46*a65addddSAndroid Build Coastguard Worker            }
47*a65addddSAndroid Build Coastguard Worker
48*a65addddSAndroid Build Coastguard Worker            int main() {
49*a65addddSAndroid Build Coastguard Worker              fruit::Injector<XAnnot> injector(getComponent);
50*a65addddSAndroid Build Coastguard Worker              injector.get<XAnnot>();
51*a65addddSAndroid Build Coastguard Worker            }
52*a65addddSAndroid Build Coastguard Worker            '''
53*a65addddSAndroid Build Coastguard Worker        expect_success(
54*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
55*a65addddSAndroid Build Coastguard Worker            source,
56*a65addddSAndroid Build Coastguard Worker            locals())
57*a65addddSAndroid Build Coastguard Worker
58*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
59*a65addddSAndroid Build Coastguard Worker        'X',
60*a65addddSAndroid Build Coastguard Worker        'fruit::Annotated<Annotation1, X>',
61*a65addddSAndroid Build Coastguard Worker    ])
62*a65addddSAndroid Build Coastguard Worker    def test_move_partial_component(self, XAnnot):
63*a65addddSAndroid Build Coastguard Worker        source = '''
64*a65addddSAndroid Build Coastguard Worker            struct X {
65*a65addddSAndroid Build Coastguard Worker              using Inject = X();
66*a65addddSAndroid Build Coastguard Worker            };
67*a65addddSAndroid Build Coastguard Worker
68*a65addddSAndroid Build Coastguard Worker            fruit::Component<XAnnot> getComponent() {
69*a65addddSAndroid Build Coastguard Worker              auto c = fruit::createComponent();
70*a65addddSAndroid Build Coastguard Worker              auto c1 = std::move(c);
71*a65addddSAndroid Build Coastguard Worker              return std::move(c1);
72*a65addddSAndroid Build Coastguard Worker            }
73*a65addddSAndroid Build Coastguard Worker
74*a65addddSAndroid Build Coastguard Worker            int main() {
75*a65addddSAndroid Build Coastguard Worker              fruit::Injector<XAnnot> injector(getComponent);
76*a65addddSAndroid Build Coastguard Worker              injector.get<XAnnot>();
77*a65addddSAndroid Build Coastguard Worker            }
78*a65addddSAndroid Build Coastguard Worker            '''
79*a65addddSAndroid Build Coastguard Worker        expect_generic_compile_error(
80*a65addddSAndroid Build Coastguard Worker            r'error: use of deleted function .fruit::PartialComponent<Bindings>::PartialComponent\(fruit::PartialComponent<Bindings>&&\).'
81*a65addddSAndroid Build Coastguard Worker            r'|error: call to deleted constructor of .(fruit::)?PartialComponent<>.'
82*a65addddSAndroid Build Coastguard Worker            # MSVC 2017
83*a65addddSAndroid Build Coastguard Worker            r'|error C2280: .fruit::PartialComponent<>::PartialComponent\(fruit::PartialComponent<> &&\).: attempting to reference a deleted function'
84*a65addddSAndroid Build Coastguard Worker            # MSVC 2015
85*a65addddSAndroid Build Coastguard Worker            r'|error C2248: .fruit::PartialComponent<>::PartialComponent.: cannot access private member declared in class .fruit::PartialComponent<>.',
86*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
87*a65addddSAndroid Build Coastguard Worker            source,
88*a65addddSAndroid Build Coastguard Worker            locals())
89*a65addddSAndroid Build Coastguard Worker
90*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
91*a65addddSAndroid Build Coastguard Worker        ('X', 'X'),
92*a65addddSAndroid Build Coastguard Worker        ('X', 'const X'),
93*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'),
94*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>'),
95*a65addddSAndroid Build Coastguard Worker    ])
96*a65addddSAndroid Build Coastguard Worker    def test_error_no_binding_found(self, XAnnot, ConstXAnnot):
97*a65addddSAndroid Build Coastguard Worker        source = '''
98*a65addddSAndroid Build Coastguard Worker            struct X {};
99*a65addddSAndroid Build Coastguard Worker
100*a65addddSAndroid Build Coastguard Worker            fruit::Component<ConstXAnnot> getComponent() {
101*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
102*a65addddSAndroid Build Coastguard Worker            }
103*a65addddSAndroid Build Coastguard Worker            '''
104*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
105*a65addddSAndroid Build Coastguard Worker            'NoBindingFoundError<XAnnot>',
106*a65addddSAndroid Build Coastguard Worker            'No explicit binding nor C::Inject definition was found for T.',
107*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
108*a65addddSAndroid Build Coastguard Worker            source,
109*a65addddSAndroid Build Coastguard Worker            locals())
110*a65addddSAndroid Build Coastguard Worker
111*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
112*a65addddSAndroid Build Coastguard Worker        ('X', 'X'),
113*a65addddSAndroid Build Coastguard Worker        ('X', 'const X'),
114*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'),
115*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>'),
116*a65addddSAndroid Build Coastguard Worker    ])
117*a65addddSAndroid Build Coastguard Worker    def test_error_no_binding_found_abstract_class(self, XAnnot, ConstXAnnot):
118*a65addddSAndroid Build Coastguard Worker        source = '''
119*a65addddSAndroid Build Coastguard Worker            struct X {
120*a65addddSAndroid Build Coastguard Worker              virtual void f() = 0;
121*a65addddSAndroid Build Coastguard Worker            };
122*a65addddSAndroid Build Coastguard Worker
123*a65addddSAndroid Build Coastguard Worker            fruit::Component<ConstXAnnot> getComponent() {
124*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
125*a65addddSAndroid Build Coastguard Worker            }
126*a65addddSAndroid Build Coastguard Worker            '''
127*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
128*a65addddSAndroid Build Coastguard Worker            'NoBindingFoundForAbstractClassError<XAnnot,X>',
129*a65addddSAndroid Build Coastguard Worker            'No explicit binding was found for T, and note that C is an abstract class',
130*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
131*a65addddSAndroid Build Coastguard Worker            source,
132*a65addddSAndroid Build Coastguard Worker            locals())
133*a65addddSAndroid Build Coastguard Worker
134*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
135*a65addddSAndroid Build Coastguard Worker        '',
136*a65addddSAndroid Build Coastguard Worker        'const',
137*a65addddSAndroid Build Coastguard Worker    ])
138*a65addddSAndroid Build Coastguard Worker    def test_error_no_factory_binding_found(self, MaybeConst):
139*a65addddSAndroid Build Coastguard Worker        source = '''
140*a65addddSAndroid Build Coastguard Worker            struct X {};
141*a65addddSAndroid Build Coastguard Worker
142*a65addddSAndroid Build Coastguard Worker            fruit::Component<MaybeConst std::function<std::unique_ptr<X>()>> getComponent() {
143*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
144*a65addddSAndroid Build Coastguard Worker            }
145*a65addddSAndroid Build Coastguard Worker            '''
146*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
147*a65addddSAndroid Build Coastguard Worker            r'NoBindingFoundError<std::function<std::unique_ptr<X(,std::default_delete<X>)?>\((void)?\)>',
148*a65addddSAndroid Build Coastguard Worker            'No explicit binding nor C::Inject definition was found for T.',
149*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
150*a65addddSAndroid Build Coastguard Worker            source,
151*a65addddSAndroid Build Coastguard Worker            locals())
152*a65addddSAndroid Build Coastguard Worker
153*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
154*a65addddSAndroid Build Coastguard Worker        '',
155*a65addddSAndroid Build Coastguard Worker        'const',
156*a65addddSAndroid Build Coastguard Worker    ])
157*a65addddSAndroid Build Coastguard Worker    def test_error_no_factory_binding_found_with_annotation(self, MaybeConst):
158*a65addddSAndroid Build Coastguard Worker        source = '''
159*a65addddSAndroid Build Coastguard Worker            struct X {};
160*a65addddSAndroid Build Coastguard Worker
161*a65addddSAndroid Build Coastguard Worker            fruit::Component<fruit::Annotated<Annotation1, MaybeConst std::function<std::unique_ptr<X>()>>> getComponent() {
162*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
163*a65addddSAndroid Build Coastguard Worker            }
164*a65addddSAndroid Build Coastguard Worker            '''
165*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
166*a65addddSAndroid Build Coastguard Worker            r'NoBindingFoundError<fruit::Annotated<Annotation1,std::function<std::unique_ptr<X(,std::default_delete<X>)?>\((void)?\)>>',
167*a65addddSAndroid Build Coastguard Worker            'No explicit binding nor C::Inject definition was found for T.',
168*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
169*a65addddSAndroid Build Coastguard Worker            source,
170*a65addddSAndroid Build Coastguard Worker            locals())
171*a65addddSAndroid Build Coastguard Worker
172*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__':
173*a65addddSAndroid Build Coastguard Worker    absltest.main()
174