xref: /aosp_15_r20/external/google-fruit/tests/test_multibindings_misc.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 Listener;
23*a65addddSAndroid Build Coastguard Worker
24*a65addddSAndroid Build Coastguard Worker    struct X {};
25*a65addddSAndroid Build Coastguard Worker
26*a65addddSAndroid Build Coastguard Worker    struct Annotation {};
27*a65addddSAndroid Build Coastguard Worker    struct Annotation1 {};
28*a65addddSAndroid Build Coastguard Worker    using ListenerAnnot = fruit::Annotated<Annotation, Listener>;
29*a65addddSAndroid Build Coastguard Worker    '''
30*a65addddSAndroid Build Coastguard Worker
31*a65addddSAndroid Build Coastguard Workerclass TestMultibindingsMisc(parameterized.TestCase):
32*a65addddSAndroid Build Coastguard Worker    def test_get_none(self):
33*a65addddSAndroid Build Coastguard Worker        source = '''
34*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponent() {
35*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent();
36*a65addddSAndroid Build Coastguard Worker            }
37*a65addddSAndroid Build Coastguard Worker
38*a65addddSAndroid Build Coastguard Worker            int main() {
39*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getComponent);
40*a65addddSAndroid Build Coastguard Worker
41*a65addddSAndroid Build Coastguard Worker              std::vector<X*> multibindings = injector.getMultibindings<X>();
42*a65addddSAndroid Build Coastguard Worker              (void) multibindings;
43*a65addddSAndroid Build Coastguard Worker              Assert(multibindings.empty());
44*a65addddSAndroid Build Coastguard Worker            }
45*a65addddSAndroid Build Coastguard Worker            '''
46*a65addddSAndroid Build Coastguard Worker        expect_success(
47*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
48*a65addddSAndroid Build Coastguard Worker            source)
49*a65addddSAndroid Build Coastguard Worker
50*a65addddSAndroid Build Coastguard Worker    def test_multiple_various_kinds(self):
51*a65addddSAndroid Build Coastguard Worker        source = '''
52*a65addddSAndroid Build Coastguard Worker            static int numNotificationsToListener1 = 0;
53*a65addddSAndroid Build Coastguard Worker            static int numNotificationsToListener2 = 0;
54*a65addddSAndroid Build Coastguard Worker            static int numNotificationsToListener3 = 0;
55*a65addddSAndroid Build Coastguard Worker
56*a65addddSAndroid Build Coastguard Worker            struct Listener {
57*a65addddSAndroid Build Coastguard Worker            public:
58*a65addddSAndroid Build Coastguard Worker              virtual ~Listener() = default;
59*a65addddSAndroid Build Coastguard Worker
60*a65addddSAndroid Build Coastguard Worker              virtual void notify() = 0;
61*a65addddSAndroid Build Coastguard Worker            };
62*a65addddSAndroid Build Coastguard Worker
63*a65addddSAndroid Build Coastguard Worker            struct Listener1 : public Listener {
64*a65addddSAndroid Build Coastguard Worker            public:
65*a65addddSAndroid Build Coastguard Worker              INJECT(Listener1()) = default;
66*a65addddSAndroid Build Coastguard Worker
67*a65addddSAndroid Build Coastguard Worker              virtual ~Listener1() = default;
68*a65addddSAndroid Build Coastguard Worker
69*a65addddSAndroid Build Coastguard Worker              void notify() override {
70*a65addddSAndroid Build Coastguard Worker                ++numNotificationsToListener1;
71*a65addddSAndroid Build Coastguard Worker              }
72*a65addddSAndroid Build Coastguard Worker            };
73*a65addddSAndroid Build Coastguard Worker
74*a65addddSAndroid Build Coastguard Worker            struct Writer {
75*a65addddSAndroid Build Coastguard Worker            public:
76*a65addddSAndroid Build Coastguard Worker              virtual void write(std::string s) = 0;
77*a65addddSAndroid Build Coastguard Worker            };
78*a65addddSAndroid Build Coastguard Worker
79*a65addddSAndroid Build Coastguard Worker            struct StdoutWriter : public Writer {
80*a65addddSAndroid Build Coastguard Worker            public:
81*a65addddSAndroid Build Coastguard Worker              INJECT(StdoutWriter()) = default;
82*a65addddSAndroid Build Coastguard Worker
83*a65addddSAndroid Build Coastguard Worker              void write(std::string s) override {
84*a65addddSAndroid Build Coastguard Worker                std::cout << s << std::endl;
85*a65addddSAndroid Build Coastguard Worker              }
86*a65addddSAndroid Build Coastguard Worker            };
87*a65addddSAndroid Build Coastguard Worker
88*a65addddSAndroid Build Coastguard Worker            struct Listener2 : public Listener {
89*a65addddSAndroid Build Coastguard Worker            private:
90*a65addddSAndroid Build Coastguard Worker              Writer* writer;
91*a65addddSAndroid Build Coastguard Worker
92*a65addddSAndroid Build Coastguard Worker            public:
93*a65addddSAndroid Build Coastguard Worker              INJECT(Listener2(Writer* writer))
94*a65addddSAndroid Build Coastguard Worker                : writer(writer) {
95*a65addddSAndroid Build Coastguard Worker              }
96*a65addddSAndroid Build Coastguard Worker
97*a65addddSAndroid Build Coastguard Worker              virtual ~Listener2() = default;
98*a65addddSAndroid Build Coastguard Worker
99*a65addddSAndroid Build Coastguard Worker              void notify() override {
100*a65addddSAndroid Build Coastguard Worker                (void) writer;
101*a65addddSAndroid Build Coastguard Worker                ++numNotificationsToListener2;
102*a65addddSAndroid Build Coastguard Worker              }
103*a65addddSAndroid Build Coastguard Worker            };
104*a65addddSAndroid Build Coastguard Worker
105*a65addddSAndroid Build Coastguard Worker            struct Listener3 : public Listener {
106*a65addddSAndroid Build Coastguard Worker            private:
107*a65addddSAndroid Build Coastguard Worker              Writer* writer;
108*a65addddSAndroid Build Coastguard Worker
109*a65addddSAndroid Build Coastguard Worker            public:
110*a65addddSAndroid Build Coastguard Worker              INJECT(Listener3(Writer* writer))
111*a65addddSAndroid Build Coastguard Worker                : writer(writer) {
112*a65addddSAndroid Build Coastguard Worker              }
113*a65addddSAndroid Build Coastguard Worker
114*a65addddSAndroid Build Coastguard Worker              virtual ~Listener3() = default;
115*a65addddSAndroid Build Coastguard Worker
116*a65addddSAndroid Build Coastguard Worker              void notify() override {
117*a65addddSAndroid Build Coastguard Worker                (void) writer;
118*a65addddSAndroid Build Coastguard Worker                ++numNotificationsToListener3;
119*a65addddSAndroid Build Coastguard Worker              }
120*a65addddSAndroid Build Coastguard Worker            };
121*a65addddSAndroid Build Coastguard Worker
122*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getListenersComponent() {
123*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
124*a65addddSAndroid Build Coastguard Worker                .bind<Writer, StdoutWriter>()
125*a65addddSAndroid Build Coastguard Worker                // Note: this is just to exercise the other method, but in real code you should split this in
126*a65addddSAndroid Build Coastguard Worker                // an addMultibinding<Listener, Listener1> and a registerProvider with the lambda.
127*a65addddSAndroid Build Coastguard Worker                .addMultibindingProvider([]() {
128*a65addddSAndroid Build Coastguard Worker                  Listener1* listener1 = new Listener1();
129*a65addddSAndroid Build Coastguard Worker                  return static_cast<Listener*>(listener1);
130*a65addddSAndroid Build Coastguard Worker                })
131*a65addddSAndroid Build Coastguard Worker                .addMultibinding<Listener, Listener2>()
132*a65addddSAndroid Build Coastguard Worker                .addMultibinding<ListenerAnnot, Listener3>();
133*a65addddSAndroid Build Coastguard Worker            }
134*a65addddSAndroid Build Coastguard Worker
135*a65addddSAndroid Build Coastguard Worker            int main() {
136*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getListenersComponent);
137*a65addddSAndroid Build Coastguard Worker              std::vector<Listener*> listeners = injector.getMultibindings<Listener>();
138*a65addddSAndroid Build Coastguard Worker              for (Listener* listener : listeners) {
139*a65addddSAndroid Build Coastguard Worker                listener->notify();
140*a65addddSAndroid Build Coastguard Worker              }
141*a65addddSAndroid Build Coastguard Worker
142*a65addddSAndroid Build Coastguard Worker              std::vector<Listener*> listeners2 = injector.getMultibindings<Listener>();
143*a65addddSAndroid Build Coastguard Worker              Assert(listeners == listeners2);
144*a65addddSAndroid Build Coastguard Worker
145*a65addddSAndroid Build Coastguard Worker              if (numNotificationsToListener1 != 1 || numNotificationsToListener2 != 1
146*a65addddSAndroid Build Coastguard Worker                || numNotificationsToListener3 != 0) {
147*a65addddSAndroid Build Coastguard Worker                abort();
148*a65addddSAndroid Build Coastguard Worker              }
149*a65addddSAndroid Build Coastguard Worker
150*a65addddSAndroid Build Coastguard Worker              std::vector<Listener*> listenersWithAnnotation = injector.getMultibindings<ListenerAnnot>();
151*a65addddSAndroid Build Coastguard Worker              for (Listener* listener : listenersWithAnnotation) {
152*a65addddSAndroid Build Coastguard Worker                listener->notify();
153*a65addddSAndroid Build Coastguard Worker              }
154*a65addddSAndroid Build Coastguard Worker
155*a65addddSAndroid Build Coastguard Worker              if (numNotificationsToListener1 != 1 || numNotificationsToListener2 != 1
156*a65addddSAndroid Build Coastguard Worker                || numNotificationsToListener3 != 1) {
157*a65addddSAndroid Build Coastguard Worker                abort();
158*a65addddSAndroid Build Coastguard Worker              }
159*a65addddSAndroid Build Coastguard Worker            }
160*a65addddSAndroid Build Coastguard Worker            '''
161*a65addddSAndroid Build Coastguard Worker        expect_success(
162*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
163*a65addddSAndroid Build Coastguard Worker            source)
164*a65addddSAndroid Build Coastguard Worker
165*a65addddSAndroid Build Coastguard Worker    def test_order(self):
166*a65addddSAndroid Build Coastguard Worker        source = '''
167*a65addddSAndroid Build Coastguard Worker            std::vector<int> numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
168*a65addddSAndroid Build Coastguard Worker            // *
169*a65addddSAndroid Build Coastguard Worker            // |-- 0
170*a65addddSAndroid Build Coastguard Worker            // |-- A
171*a65addddSAndroid Build Coastguard Worker            // |   |-- 1
172*a65addddSAndroid Build Coastguard Worker            // |   |-- B
173*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 2
174*a65addddSAndroid Build Coastguard Worker            // |   |   `-- 3
175*a65addddSAndroid Build Coastguard Worker            // |   |-- 4
176*a65addddSAndroid Build Coastguard Worker            // |   |-- C
177*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 5
178*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 6
179*a65addddSAndroid Build Coastguard Worker            // |   |   |-- D
180*a65addddSAndroid Build Coastguard Worker            // |   |   |   |-- 7
181*a65addddSAndroid Build Coastguard Worker            // |   |   |   |-- E
182*a65addddSAndroid Build Coastguard Worker            // |   |   |   |   |-- 8
183*a65addddSAndroid Build Coastguard Worker            // |   |   |   |   `-- 9
184*a65addddSAndroid Build Coastguard Worker            // |   |   |   `-- 10
185*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 11
186*a65addddSAndroid Build Coastguard Worker            // |   |   |-- F
187*a65addddSAndroid Build Coastguard Worker            // |   |   |   |-- 12
188*a65addddSAndroid Build Coastguard Worker            // |   |   |   `-- 13
189*a65addddSAndroid Build Coastguard Worker            // |   |   `-- 14
190*a65addddSAndroid Build Coastguard Worker            // |   |-- 15
191*a65addddSAndroid Build Coastguard Worker            // |   |-- C (won't be expanded)
192*a65addddSAndroid Build Coastguard Worker            // |   `-- 16
193*a65addddSAndroid Build Coastguard Worker            // |-- 17
194*a65addddSAndroid Build Coastguard Worker            // |-- C (won't be expanded)
195*a65addddSAndroid Build Coastguard Worker            // `-- 18
196*a65addddSAndroid Build Coastguard Worker
197*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent();
198*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentA();
199*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentB();
200*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentC();
201*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentD();
202*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentE();
203*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentF();
204*a65addddSAndroid Build Coastguard Worker
205*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
206*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
207*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[0])
208*a65addddSAndroid Build Coastguard Worker                .install(getComponentA)
209*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[17])
210*a65addddSAndroid Build Coastguard Worker                .install(getComponentC)
211*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[18]);
212*a65addddSAndroid Build Coastguard Worker            }
213*a65addddSAndroid Build Coastguard Worker
214*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentA() {
215*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
216*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[1])
217*a65addddSAndroid Build Coastguard Worker                .install(getComponentB)
218*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[4])
219*a65addddSAndroid Build Coastguard Worker                .install(getComponentC)
220*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[15])
221*a65addddSAndroid Build Coastguard Worker                .install(getComponentC)
222*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[16]);
223*a65addddSAndroid Build Coastguard Worker            }
224*a65addddSAndroid Build Coastguard Worker
225*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentB() {
226*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
227*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[2])
228*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[3]);
229*a65addddSAndroid Build Coastguard Worker            }
230*a65addddSAndroid Build Coastguard Worker
231*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentC() {
232*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
233*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[5])
234*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[6])
235*a65addddSAndroid Build Coastguard Worker                .install(getComponentD)
236*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[11])
237*a65addddSAndroid Build Coastguard Worker                .install(getComponentF)
238*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[14]);
239*a65addddSAndroid Build Coastguard Worker            }
240*a65addddSAndroid Build Coastguard Worker
241*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentD() {
242*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
243*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[7])
244*a65addddSAndroid Build Coastguard Worker                .install(getComponentE)
245*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[10]);
246*a65addddSAndroid Build Coastguard Worker            }
247*a65addddSAndroid Build Coastguard Worker
248*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentE() {
249*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
250*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[8])
251*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[9]);
252*a65addddSAndroid Build Coastguard Worker            }
253*a65addddSAndroid Build Coastguard Worker
254*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentF() {
255*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
256*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[12])
257*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[13]);
258*a65addddSAndroid Build Coastguard Worker            }
259*a65addddSAndroid Build Coastguard Worker
260*a65addddSAndroid Build Coastguard Worker            int main() {
261*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(getRootComponent);
262*a65addddSAndroid Build Coastguard Worker              std::vector<int*> result_ptrs = injector.getMultibindings<int>();
263*a65addddSAndroid Build Coastguard Worker              std::vector<int> results;
264*a65addddSAndroid Build Coastguard Worker              std::cout << "Results: ";
265*a65addddSAndroid Build Coastguard Worker              for (int* result : result_ptrs) {
266*a65addddSAndroid Build Coastguard Worker                std::cout << *result << ", ";
267*a65addddSAndroid Build Coastguard Worker                results.push_back(*result);
268*a65addddSAndroid Build Coastguard Worker              }
269*a65addddSAndroid Build Coastguard Worker              std::cout << std::endl;
270*a65addddSAndroid Build Coastguard Worker              Assert(results == numbers);
271*a65addddSAndroid Build Coastguard Worker            }
272*a65addddSAndroid Build Coastguard Worker            '''
273*a65addddSAndroid Build Coastguard Worker        expect_success(
274*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
275*a65addddSAndroid Build Coastguard Worker            source)
276*a65addddSAndroid Build Coastguard Worker
277*a65addddSAndroid Build Coastguard Worker
278*a65addddSAndroid Build Coastguard Worker    def test_order_with_normalized_component(self):
279*a65addddSAndroid Build Coastguard Worker        source = '''
280*a65addddSAndroid Build Coastguard Worker            std::vector<int> numbers = {
281*a65addddSAndroid Build Coastguard Worker                0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
282*a65addddSAndroid Build Coastguard Worker                19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37};
283*a65addddSAndroid Build Coastguard Worker            // root1
284*a65addddSAndroid Build Coastguard Worker            // |-- 0
285*a65addddSAndroid Build Coastguard Worker            // |-- A
286*a65addddSAndroid Build Coastguard Worker            // |   |-- 1
287*a65addddSAndroid Build Coastguard Worker            // |   |-- B
288*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 2
289*a65addddSAndroid Build Coastguard Worker            // |   |   `-- 3
290*a65addddSAndroid Build Coastguard Worker            // |   |-- 4
291*a65addddSAndroid Build Coastguard Worker            // |   |-- C
292*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 5
293*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 6
294*a65addddSAndroid Build Coastguard Worker            // |   |   |-- D
295*a65addddSAndroid Build Coastguard Worker            // |   |   |   |-- 7
296*a65addddSAndroid Build Coastguard Worker            // |   |   |   |-- E
297*a65addddSAndroid Build Coastguard Worker            // |   |   |   |   |-- 8
298*a65addddSAndroid Build Coastguard Worker            // |   |   |   |   `-- 9
299*a65addddSAndroid Build Coastguard Worker            // |   |   |   `-- 10
300*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 11
301*a65addddSAndroid Build Coastguard Worker            // |   |   |-- F
302*a65addddSAndroid Build Coastguard Worker            // |   |   |   |-- 12
303*a65addddSAndroid Build Coastguard Worker            // |   |   |   `-- 13
304*a65addddSAndroid Build Coastguard Worker            // |   |   `-- 14
305*a65addddSAndroid Build Coastguard Worker            // |   |-- 15
306*a65addddSAndroid Build Coastguard Worker            // |   |-- C (won't be expanded)
307*a65addddSAndroid Build Coastguard Worker            // |   `-- 16
308*a65addddSAndroid Build Coastguard Worker            // |-- 17
309*a65addddSAndroid Build Coastguard Worker            // |-- C (won't be expanded)
310*a65addddSAndroid Build Coastguard Worker            // `-- 18
311*a65addddSAndroid Build Coastguard Worker
312*a65addddSAndroid Build Coastguard Worker            // root2
313*a65addddSAndroid Build Coastguard Worker            // |-- 19
314*a65addddSAndroid Build Coastguard Worker            // |-- A2
315*a65addddSAndroid Build Coastguard Worker            // |   |-- 20
316*a65addddSAndroid Build Coastguard Worker            // |   |-- B2
317*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 21
318*a65addddSAndroid Build Coastguard Worker            // |   |   `-- 22
319*a65addddSAndroid Build Coastguard Worker            // |   |-- 23
320*a65addddSAndroid Build Coastguard Worker            // |   |-- C2
321*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 24
322*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 25
323*a65addddSAndroid Build Coastguard Worker            // |   |   |-- D2
324*a65addddSAndroid Build Coastguard Worker            // |   |   |   |-- 26
325*a65addddSAndroid Build Coastguard Worker            // |   |   |   |-- E2
326*a65addddSAndroid Build Coastguard Worker            // |   |   |   |   |-- 27
327*a65addddSAndroid Build Coastguard Worker            // |   |   |   |   `-- 28
328*a65addddSAndroid Build Coastguard Worker            // |   |   |   `-- 29
329*a65addddSAndroid Build Coastguard Worker            // |   |   |-- 30
330*a65addddSAndroid Build Coastguard Worker            // |   |   |-- F2
331*a65addddSAndroid Build Coastguard Worker            // |   |   |   |-- 31
332*a65addddSAndroid Build Coastguard Worker            // |   |   |   `-- 32
333*a65addddSAndroid Build Coastguard Worker            // |   |   `-- 33
334*a65addddSAndroid Build Coastguard Worker            // |   |-- 34
335*a65addddSAndroid Build Coastguard Worker            // |   |-- C2 (won't be expanded)
336*a65addddSAndroid Build Coastguard Worker            // |   `-- 35
337*a65addddSAndroid Build Coastguard Worker            // |-- 36
338*a65addddSAndroid Build Coastguard Worker            // |-- C2 (won't be expanded)
339*a65addddSAndroid Build Coastguard Worker            // `-- 37
340*a65addddSAndroid Build Coastguard Worker
341*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent();
342*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentA();
343*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentB();
344*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentC();
345*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentD();
346*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentE();
347*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentF();
348*a65addddSAndroid Build Coastguard Worker
349*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent2();
350*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentA2();
351*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentB2();
352*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentC2();
353*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentD2();
354*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentE2();
355*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentF2();
356*a65addddSAndroid Build Coastguard Worker
357*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
358*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
359*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[0])
360*a65addddSAndroid Build Coastguard Worker                .install(getComponentA)
361*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[17])
362*a65addddSAndroid Build Coastguard Worker                .install(getComponentC)
363*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[18]);
364*a65addddSAndroid Build Coastguard Worker            }
365*a65addddSAndroid Build Coastguard Worker
366*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentA() {
367*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
368*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[1])
369*a65addddSAndroid Build Coastguard Worker                .install(getComponentB)
370*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[4])
371*a65addddSAndroid Build Coastguard Worker                .install(getComponentC)
372*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[15])
373*a65addddSAndroid Build Coastguard Worker                .install(getComponentC)
374*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[16]);
375*a65addddSAndroid Build Coastguard Worker            }
376*a65addddSAndroid Build Coastguard Worker
377*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentB() {
378*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
379*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[2])
380*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[3]);
381*a65addddSAndroid Build Coastguard Worker            }
382*a65addddSAndroid Build Coastguard Worker
383*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentC() {
384*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
385*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[5])
386*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[6])
387*a65addddSAndroid Build Coastguard Worker                .install(getComponentD)
388*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[11])
389*a65addddSAndroid Build Coastguard Worker                .install(getComponentF)
390*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[14]);
391*a65addddSAndroid Build Coastguard Worker            }
392*a65addddSAndroid Build Coastguard Worker
393*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentD() {
394*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
395*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[7])
396*a65addddSAndroid Build Coastguard Worker                .install(getComponentE)
397*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[10]);
398*a65addddSAndroid Build Coastguard Worker            }
399*a65addddSAndroid Build Coastguard Worker
400*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentE() {
401*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
402*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[8])
403*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[9]);
404*a65addddSAndroid Build Coastguard Worker            }
405*a65addddSAndroid Build Coastguard Worker
406*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentF() {
407*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
408*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[12])
409*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[13]);
410*a65addddSAndroid Build Coastguard Worker            }
411*a65addddSAndroid Build Coastguard Worker
412*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent2() {
413*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
414*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[19])
415*a65addddSAndroid Build Coastguard Worker                .install(getComponentA2)
416*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[36])
417*a65addddSAndroid Build Coastguard Worker                .install(getComponentC2)
418*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[37]);
419*a65addddSAndroid Build Coastguard Worker            }
420*a65addddSAndroid Build Coastguard Worker
421*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentA2() {
422*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
423*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[20])
424*a65addddSAndroid Build Coastguard Worker                .install(getComponentB2)
425*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[23])
426*a65addddSAndroid Build Coastguard Worker                .install(getComponentC2)
427*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[34])
428*a65addddSAndroid Build Coastguard Worker                .install(getComponentC2)
429*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[35]);
430*a65addddSAndroid Build Coastguard Worker            }
431*a65addddSAndroid Build Coastguard Worker
432*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentB2() {
433*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
434*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[21])
435*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[22]);
436*a65addddSAndroid Build Coastguard Worker            }
437*a65addddSAndroid Build Coastguard Worker
438*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentC2() {
439*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
440*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[24])
441*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[25])
442*a65addddSAndroid Build Coastguard Worker                .install(getComponentD2)
443*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[30])
444*a65addddSAndroid Build Coastguard Worker                .install(getComponentF2)
445*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[33]);
446*a65addddSAndroid Build Coastguard Worker            }
447*a65addddSAndroid Build Coastguard Worker
448*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentD2() {
449*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
450*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[26])
451*a65addddSAndroid Build Coastguard Worker                .install(getComponentE2)
452*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[29]);
453*a65addddSAndroid Build Coastguard Worker            }
454*a65addddSAndroid Build Coastguard Worker
455*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentE2() {
456*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
457*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[27])
458*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[28]);
459*a65addddSAndroid Build Coastguard Worker            }
460*a65addddSAndroid Build Coastguard Worker
461*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentF2() {
462*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
463*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[31])
464*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[32]);
465*a65addddSAndroid Build Coastguard Worker            }
466*a65addddSAndroid Build Coastguard Worker
467*a65addddSAndroid Build Coastguard Worker            int main() {
468*a65addddSAndroid Build Coastguard Worker              fruit::NormalizedComponent<> normalizedComponent(getRootComponent);
469*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(normalizedComponent, getRootComponent2);
470*a65addddSAndroid Build Coastguard Worker              std::vector<int*> result_ptrs = injector.getMultibindings<int>();
471*a65addddSAndroid Build Coastguard Worker              std::vector<int> results;
472*a65addddSAndroid Build Coastguard Worker              std::cout << "Results: ";
473*a65addddSAndroid Build Coastguard Worker              for (int* result : result_ptrs) {
474*a65addddSAndroid Build Coastguard Worker                std::cout << *result << ", ";
475*a65addddSAndroid Build Coastguard Worker                results.push_back(*result);
476*a65addddSAndroid Build Coastguard Worker              }
477*a65addddSAndroid Build Coastguard Worker              std::cout << std::endl;
478*a65addddSAndroid Build Coastguard Worker              Assert(results == numbers);
479*a65addddSAndroid Build Coastguard Worker            }
480*a65addddSAndroid Build Coastguard Worker            '''
481*a65addddSAndroid Build Coastguard Worker        expect_success(
482*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
483*a65addddSAndroid Build Coastguard Worker            source)
484*a65addddSAndroid Build Coastguard Worker
485*a65addddSAndroid Build Coastguard Worker    def test_with_normalized_component_lazy_components_not_deduped_across(self):
486*a65addddSAndroid Build Coastguard Worker        source = '''
487*a65addddSAndroid Build Coastguard Worker            std::vector<int> numbers = {0, 1, 2, 3, 4};
488*a65addddSAndroid Build Coastguard Worker
489*a65addddSAndroid Build Coastguard Worker            // *
490*a65addddSAndroid Build Coastguard Worker            // |-- 0
491*a65addddSAndroid Build Coastguard Worker            // |-- A (lazy)
492*a65addddSAndroid Build Coastguard Worker            // |   |-- 1
493*a65addddSAndroid Build Coastguard Worker            // |   `-- 2
494*a65addddSAndroid Build Coastguard Worker            // |-- 3
495*a65addddSAndroid Build Coastguard Worker            // |-- A (lazy, won't be expanded)
496*a65addddSAndroid Build Coastguard Worker            // `-- 4
497*a65addddSAndroid Build Coastguard Worker
498*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent();
499*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentA();
500*a65addddSAndroid Build Coastguard Worker
501*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getRootComponent() {
502*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
503*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[0])
504*a65addddSAndroid Build Coastguard Worker                .install(getComponentA)
505*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[3])
506*a65addddSAndroid Build Coastguard Worker                .install(getComponentA)
507*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[4]);
508*a65addddSAndroid Build Coastguard Worker            }
509*a65addddSAndroid Build Coastguard Worker
510*a65addddSAndroid Build Coastguard Worker            fruit::Component<> getComponentA() {
511*a65addddSAndroid Build Coastguard Worker              return fruit::createComponent()
512*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[1])
513*a65addddSAndroid Build Coastguard Worker                .addInstanceMultibinding(numbers[2]);
514*a65addddSAndroid Build Coastguard Worker            }
515*a65addddSAndroid Build Coastguard Worker
516*a65addddSAndroid Build Coastguard Worker            int main() {
517*a65addddSAndroid Build Coastguard Worker              fruit::NormalizedComponent<> normalizedComponent(getRootComponent);
518*a65addddSAndroid Build Coastguard Worker              fruit::Injector<> injector(normalizedComponent, getRootComponent);
519*a65addddSAndroid Build Coastguard Worker              std::vector<int*> result_ptrs = injector.getMultibindings<int>();
520*a65addddSAndroid Build Coastguard Worker              std::vector<int> results;
521*a65addddSAndroid Build Coastguard Worker              std::cout << "Results: ";
522*a65addddSAndroid Build Coastguard Worker              for (int* result : result_ptrs) {
523*a65addddSAndroid Build Coastguard Worker                std::cout << *result << ", ";
524*a65addddSAndroid Build Coastguard Worker                results.push_back(*result);
525*a65addddSAndroid Build Coastguard Worker              }
526*a65addddSAndroid Build Coastguard Worker              std::cout << std::endl;
527*a65addddSAndroid Build Coastguard Worker              std::vector<int> expected_numbers = {0, 1, 2, 3, 4};
528*a65addddSAndroid Build Coastguard Worker              Assert(results == expected_numbers);
529*a65addddSAndroid Build Coastguard Worker            }
530*a65addddSAndroid Build Coastguard Worker            '''
531*a65addddSAndroid Build Coastguard Worker        expect_success(
532*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
533*a65addddSAndroid Build Coastguard Worker            source)
534*a65addddSAndroid Build Coastguard Worker
535*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
536*a65addddSAndroid Build Coastguard Worker        ('const X', r'const X'),
537*a65addddSAndroid Build Coastguard Worker        ('X*', r'X\*'),
538*a65addddSAndroid Build Coastguard Worker        ('const X*', r'const X\*'),
539*a65addddSAndroid Build Coastguard Worker        ('std::shared_ptr<X>', r'std::shared_ptr<X>'),
540*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, const X>', r'const X'),
541*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X*>', r'X\*'),
542*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, const X*>', r'const X\*'),
543*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, std::shared_ptr<X>>', r'std::shared_ptr<X>'),
544*a65addddSAndroid Build Coastguard Worker    ])
545*a65addddSAndroid Build Coastguard Worker    def test_multibindings_get_error_non_class_type(self, XVariantAnnot, XVariantRegexp):
546*a65addddSAndroid Build Coastguard Worker        source = '''
547*a65addddSAndroid Build Coastguard Worker            void f(fruit::Injector<> injector) {
548*a65addddSAndroid Build Coastguard Worker              injector.getMultibindings<XVariantAnnot>();
549*a65addddSAndroid Build Coastguard Worker            }
550*a65addddSAndroid Build Coastguard Worker            '''
551*a65addddSAndroid Build Coastguard Worker        expect_compile_error(
552*a65addddSAndroid Build Coastguard Worker            'NonClassTypeError<XVariantRegexp,X>',
553*a65addddSAndroid Build Coastguard Worker            'A non-class type T was specified. Use C instead.',
554*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
555*a65addddSAndroid Build Coastguard Worker            source,
556*a65addddSAndroid Build Coastguard Worker            locals())
557*a65addddSAndroid Build Coastguard Worker
558*a65addddSAndroid Build Coastguard Worker    @parameterized.parameters([
559*a65addddSAndroid Build Coastguard Worker        ('X&', 'X&'),
560*a65addddSAndroid Build Coastguard Worker        ('const X&', 'const X&'),
561*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, X&>', 'X&'),
562*a65addddSAndroid Build Coastguard Worker        ('fruit::Annotated<Annotation1, const X&>', 'const X&'),
563*a65addddSAndroid Build Coastguard Worker    ])
564*a65addddSAndroid Build Coastguard Worker    def test_multibindings_get_error_reference_type(self, XVariantAnnot, XVariantRegexp):
565*a65addddSAndroid Build Coastguard Worker        source = '''
566*a65addddSAndroid Build Coastguard Worker            void f(fruit::Injector<> injector) {
567*a65addddSAndroid Build Coastguard Worker              injector.getMultibindings<XVariantAnnot>();
568*a65addddSAndroid Build Coastguard Worker            }
569*a65addddSAndroid Build Coastguard Worker            '''
570*a65addddSAndroid Build Coastguard Worker        expect_generic_compile_error(
571*a65addddSAndroid Build Coastguard Worker            'declared as a pointer to a reference of type'
572*a65addddSAndroid Build Coastguard Worker            '|forming pointer to reference type'
573*a65addddSAndroid Build Coastguard Worker            '|fruit::Injector<.*>::getMultibindings.: no matching overloaded function found',
574*a65addddSAndroid Build Coastguard Worker            COMMON_DEFINITIONS,
575*a65addddSAndroid Build Coastguard Worker            source,
576*a65addddSAndroid Build Coastguard Worker            locals())
577*a65addddSAndroid Build Coastguard Worker
578*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__':
579*a65addddSAndroid Build Coastguard Worker    absltest.main()
580