xref: /aosp_15_r20/external/google-fruit/tests/test_binding_compression.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    struct Annotation2 {};
24*a65addddSAndroid Build Coastguard Worker
25*a65addddSAndroid Build Coastguard Worker    template <typename T>
26*a65addddSAndroid Build Coastguard Worker    using WithNoAnnot = T;
27*a65addddSAndroid Build Coastguard Worker
28*a65addddSAndroid Build Coastguard Worker    template <typename T>
29*a65addddSAndroid Build Coastguard Worker    using WithAnnot1 = fruit::Annotated<Annotation1, T>;
30*a65addddSAndroid Build Coastguard Worker
31*a65addddSAndroid Build Coastguard Worker    template <typename T>
32*a65addddSAndroid Build Coastguard Worker    using WithAnnot2 = fruit::Annotated<Annotation2, T>;
33*a65addddSAndroid Build Coastguard Worker    '''
34*a65addddSAndroid Build Coastguard Worker
35*a65addddSAndroid Build Coastguard Workerclass TestBindingCompression(parameterized.TestCase):
36*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
37*a65addddSAndroid Build Coastguard Worker        ('I', 'X', 'WithNoAnnot'),
38*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, I>', 'fruit::Annotated<Annotation2, X>', 'WithAnnot1'),
39*a65addddSAndroid Build Coastguard Worker    ])
40*a65addddSAndroid Build Coastguard Worker    def test_provider_returning_value_success_with_annotation(self, IAnnot, XAnnot, WithAnnot):
41*a65addddSAndroid Build Coastguard Worker        source = '''
42*a65addddSAndroid Build Coastguard Worker            struct I {
43*a65addddSAndroid Build Coastguard Worker              int value = 5;
44*a65addddSAndroid Build Coastguard Worker            };
45*a65addddSAndroid Build Coastguard Worker
46*a65addddSAndroid Build Coastguard Worker            struct X : public I, ConstructionTracker<X> {
47*a65addddSAndroid Build Coastguard Worker            };
48*a65addddSAndroid Build Coastguard Worker
49*a65addddSAndroid Build Coastguard Worker            fruit::Component<IAnnot> getComponent() {
50*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
51*a65addddSAndroid Build Coastguard Worker                .registerProvider<XAnnot()>([](){return X();})
52*a65addddSAndroid Build Coastguard Worker                .bind<IAnnot, XAnnot>();
53*a65addddSAndroid Build Coastguard Worker            }
54*a65addddSAndroid Build Coastguard Worker
55*a65addddSAndroid Build Coastguard Worker            int main() {
56*a65addddSAndroid Build Coastguard Worker              fruit::Injector<IAnnot> injector(getComponent);
57*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<I                 >>() .value == 5));
58*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<I*                >>()->value == 5));
59*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<I&                >>() .value == 5));
60*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<const I           >>() .value == 5));
61*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<const I*          >>()->value == 5));
62*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<const I&          >>() .value == 5));
63*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<std::shared_ptr<I>>>()->value == 5));
64*a65addddSAndroid Build Coastguard Worker              Assert(fruit::impl::InjectorAccessorForTests::unsafeGet<WithAnnot<X>>(injector) == nullptr);
65*a65addddSAndroid Build Coastguard Worker
66*a65addddSAndroid Build Coastguard Worker              Assert(X::num_objects_constructed == 1);
67*a65addddSAndroid Build Coastguard Worker            }
68*a65addddSAndroid Build Coastguard Worker            '''
69*a65addddSAndroid Build Coastguard Worker        expect_success(
70*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
71*a65addddSAndroid Build Coastguard Worker            source,
72*a65addddSAndroid Build Coastguard Worker            locals())
73*a65addddSAndroid Build Coastguard Worker
74*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
75*a65addddSAndroid Build Coastguard Worker        ('I', 'X', 'X*', 'WithNoAnnot'),
76*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, I>', 'fruit::Annotated<Annotation2, X>', 'fruit::Annotated<Annotation2, X*>', 'WithAnnot1'),
77*a65addddSAndroid Build Coastguard Worker    ])
78*a65addddSAndroid Build Coastguard Worker    def test_provider_returning_pointer_success_with_annotation(self, IAnnot, XAnnot, XPtrAnnot, WithAnnot):
79*a65addddSAndroid Build Coastguard Worker        source = '''
80*a65addddSAndroid Build Coastguard Worker            struct I {
81*a65addddSAndroid Build Coastguard Worker              int value = 5;
82*a65addddSAndroid Build Coastguard Worker            };
83*a65addddSAndroid Build Coastguard Worker
84*a65addddSAndroid Build Coastguard Worker            struct X : public I, ConstructionTracker<X> {
85*a65addddSAndroid Build Coastguard Worker            };
86*a65addddSAndroid Build Coastguard Worker
87*a65addddSAndroid Build Coastguard Worker            fruit::Component<IAnnot> getComponent() {
88*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
89*a65addddSAndroid Build Coastguard Worker                .registerProvider<XPtrAnnot()>([](){return new X();})
90*a65addddSAndroid Build Coastguard Worker                .bind<IAnnot, XAnnot>();
91*a65addddSAndroid Build Coastguard Worker            }
92*a65addddSAndroid Build Coastguard Worker
93*a65addddSAndroid Build Coastguard Worker            int main() {
94*a65addddSAndroid Build Coastguard Worker              fruit::Injector<IAnnot> injector(getComponent);
95*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<I                 >>() .value == 5));
96*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<I*                >>()->value == 5));
97*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<I&                >>() .value == 5));
98*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<const I           >>() .value == 5));
99*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<const I*          >>()->value == 5));
100*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<const I&          >>() .value == 5));
101*a65addddSAndroid Build Coastguard Worker              Assert((injector.get<WithAnnot<std::shared_ptr<I>>>()->value == 5));
102*a65addddSAndroid Build Coastguard Worker              Assert(fruit::impl::InjectorAccessorForTests::unsafeGet<WithAnnot<X>>(injector) == nullptr);
103*a65addddSAndroid Build Coastguard Worker              Assert(X::num_objects_constructed == 1);
104*a65addddSAndroid Build Coastguard Worker            }
105*a65addddSAndroid Build Coastguard Worker            '''
106*a65addddSAndroid Build Coastguard Worker        expect_success(
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    def test_compression_undone(self):
112*a65addddSAndroid Build Coastguard Worker        source = '''
113*a65addddSAndroid Build Coastguard Worker            struct I1 {};
114*a65addddSAndroid Build Coastguard Worker            struct C1 : public I1, ConstructionTracker<C1> {
115*a65addddSAndroid Build Coastguard Worker              INJECT(C1()) = default;
116*a65addddSAndroid Build Coastguard Worker            };
117*a65addddSAndroid Build Coastguard Worker
118*a65addddSAndroid Build Coastguard Worker            struct I2 {};
119*a65addddSAndroid Build Coastguard Worker            struct C2 : public I2 {
120*a65addddSAndroid Build Coastguard Worker              INJECT(C2(I1*)) {}
121*a65addddSAndroid Build Coastguard Worker            };
122*a65addddSAndroid Build Coastguard Worker
123*a65addddSAndroid Build Coastguard Worker            fruit::Component<I1> getI1Component() {
124*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
125*a65addddSAndroid Build Coastguard Worker                  .bind<I1, C1>();
126*a65addddSAndroid Build Coastguard Worker            }
127*a65addddSAndroid Build Coastguard Worker
128*a65addddSAndroid Build Coastguard Worker            fruit::Component<I2> getI2Component() {
129*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
130*a65addddSAndroid Build Coastguard Worker                  .install(getI1Component)
131*a65addddSAndroid Build Coastguard Worker                  .bind<I2, C2>();
132*a65addddSAndroid Build Coastguard Worker            }
133*a65addddSAndroid Build Coastguard Worker
134*a65addddSAndroid Build Coastguard Worker            struct X {
135*a65addddSAndroid Build Coastguard Worker              // Intentionally C1 and not I1. This prevents binding compression for the I1->C1 edge.
136*a65addddSAndroid Build Coastguard Worker              INJECT(X(C1*)) {}
137*a65addddSAndroid Build Coastguard Worker            };
138*a65addddSAndroid Build Coastguard Worker
139*a65addddSAndroid Build Coastguard Worker            fruit::Component<X> getXComponent() {
140*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
141*a65addddSAndroid Build Coastguard Worker            }
142*a65addddSAndroid Build Coastguard Worker
143*a65addddSAndroid Build Coastguard Worker            int main() {
144*a65addddSAndroid Build Coastguard Worker              // Here the binding C2->I1->C1 is compressed into C2->C1.
145*a65addddSAndroid Build Coastguard Worker              fruit::NormalizedComponent<I2> normalizedComponent(getI2Component);
146*a65addddSAndroid Build Coastguard Worker
147*a65addddSAndroid Build Coastguard Worker              // However the binding X->C1 prevents binding compression on I1->C1, the binding compression must be undone.
148*a65addddSAndroid Build Coastguard Worker              fruit::Injector<I2, X> injector(normalizedComponent, getXComponent);
149*a65addddSAndroid Build Coastguard Worker
150*a65addddSAndroid Build Coastguard Worker              Assert(C1::num_objects_constructed == 0);
151*a65addddSAndroid Build Coastguard Worker              injector.get<I2*>();
152*a65addddSAndroid Build Coastguard Worker              injector.get<X*>();
153*a65addddSAndroid Build Coastguard Worker              Assert(fruit::impl::InjectorAccessorForTests::unsafeGet<C1>(injector) != nullptr);
154*a65addddSAndroid Build Coastguard Worker              Assert(C1::num_objects_constructed == 1);
155*a65addddSAndroid Build Coastguard Worker            }
156*a65addddSAndroid Build Coastguard Worker            '''
157*a65addddSAndroid Build Coastguard Worker        expect_success(
158*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
159*a65addddSAndroid Build Coastguard Worker            source)
160*a65addddSAndroid Build Coastguard Worker
161*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__':
162*a65addddSAndroid Build Coastguard Worker    absltest.main()
163