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 struct Y; 24*a65addddSAndroid Build Coastguard Worker struct Z; 25*a65addddSAndroid Build Coastguard Worker 26*a65addddSAndroid Build Coastguard Worker struct Annotation1 {}; 27*a65addddSAndroid Build Coastguard Worker using XAnnot1 = fruit::Annotated<Annotation1, X>; 28*a65addddSAndroid Build Coastguard Worker using YAnnot1 = fruit::Annotated<Annotation1, Y>; 29*a65addddSAndroid Build Coastguard Worker using ZAnnot1 = fruit::Annotated<Annotation1, Z>; 30*a65addddSAndroid Build Coastguard Worker using ConstXAnnot1 = fruit::Annotated<Annotation1, const X>; 31*a65addddSAndroid Build Coastguard Worker using ConstYAnnot1 = fruit::Annotated<Annotation1, const Y>; 32*a65addddSAndroid Build Coastguard Worker using ConstZAnnot1 = fruit::Annotated<Annotation1, const Z>; 33*a65addddSAndroid Build Coastguard Worker 34*a65addddSAndroid Build Coastguard Worker struct Annotation2 {}; 35*a65addddSAndroid Build Coastguard Worker using XAnnot2 = fruit::Annotated<Annotation2, X>; 36*a65addddSAndroid Build Coastguard Worker using YAnnot2 = fruit::Annotated<Annotation2, Y>; 37*a65addddSAndroid Build Coastguard Worker using ZAnnot2 = fruit::Annotated<Annotation2, Z>; 38*a65addddSAndroid Build Coastguard Worker using ConstXAnnot2 = fruit::Annotated<Annotation2, const X>; 39*a65addddSAndroid Build Coastguard Worker using ConstYAnnot2 = fruit::Annotated<Annotation2, const Y>; 40*a65addddSAndroid Build Coastguard Worker using ConstZAnnot2 = fruit::Annotated<Annotation2, const Z>; 41*a65addddSAndroid Build Coastguard Worker 42*a65addddSAndroid Build Coastguard Worker struct Annotation3 {}; 43*a65addddSAndroid Build Coastguard Worker ''' 44*a65addddSAndroid Build Coastguard Worker 45*a65addddSAndroid Build Coastguard WorkerCONSTRUCTOR_BINDING = ( 46*a65addddSAndroid Build Coastguard Worker '', 47*a65addddSAndroid Build Coastguard Worker '.registerConstructor<XAnnot()>()') 48*a65addddSAndroid Build Coastguard WorkerINTERFACE_BINDING = ( 49*a65addddSAndroid Build Coastguard Worker ''' 50*a65addddSAndroid Build Coastguard Worker struct Y : public X {}; 51*a65addddSAndroid Build Coastguard Worker ''', 52*a65addddSAndroid Build Coastguard Worker ''' 53*a65addddSAndroid Build Coastguard Worker .bind<XAnnot, YAnnot>() 54*a65addddSAndroid Build Coastguard Worker .registerConstructor<YAnnot()>() 55*a65addddSAndroid Build Coastguard Worker ''') 56*a65addddSAndroid Build Coastguard WorkerINTERFACE_BINDING2 = ( 57*a65addddSAndroid Build Coastguard Worker ''' 58*a65addddSAndroid Build Coastguard Worker struct Y2 : public X {}; 59*a65addddSAndroid Build Coastguard Worker ''', 60*a65addddSAndroid Build Coastguard Worker ''' 61*a65addddSAndroid Build Coastguard Worker .bind<XAnnot, Y2Annot>() 62*a65addddSAndroid Build Coastguard Worker .registerConstructor<Y2Annot()>() 63*a65addddSAndroid Build Coastguard Worker ''') 64*a65addddSAndroid Build Coastguard WorkerINSTALL = ( 65*a65addddSAndroid Build Coastguard Worker ''' 66*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getParentComponent() { 67*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 68*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot()>(); 69*a65addddSAndroid Build Coastguard Worker } 70*a65addddSAndroid Build Coastguard Worker ''', 71*a65addddSAndroid Build Coastguard Worker '.install(getParentComponent)') 72*a65addddSAndroid Build Coastguard WorkerINSTALL2 = ( 73*a65addddSAndroid Build Coastguard Worker ''' 74*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getParentComponent2() { 75*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 76*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot()>(); 77*a65addddSAndroid Build Coastguard Worker } 78*a65addddSAndroid Build Coastguard Worker ''', 79*a65addddSAndroid Build Coastguard Worker '.install(getParentComponent2)') 80*a65addddSAndroid Build Coastguard WorkerCONST_BINDING_FROM_INSTALL = ( 81*a65addddSAndroid Build Coastguard Worker ''' 82*a65addddSAndroid Build Coastguard Worker fruit::Component<const XAnnot> getParentComponent() { 83*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 84*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot()>(); 85*a65addddSAndroid Build Coastguard Worker } 86*a65addddSAndroid Build Coastguard Worker ''', 87*a65addddSAndroid Build Coastguard Worker '.install(getParentComponent)') 88*a65addddSAndroid Build Coastguard WorkerCONST_BINDING_FROM_INSTALL2 = ( 89*a65addddSAndroid Build Coastguard Worker ''' 90*a65addddSAndroid Build Coastguard Worker fruit::Component<const XAnnot> getParentComponent2() { 91*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 92*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot()>(); 93*a65addddSAndroid Build Coastguard Worker } 94*a65addddSAndroid Build Coastguard Worker ''', 95*a65addddSAndroid Build Coastguard Worker '.install(getParentComponent2)') 96*a65addddSAndroid Build Coastguard WorkerCONST_BINDING = ( 97*a65addddSAndroid Build Coastguard Worker ''' 98*a65addddSAndroid Build Coastguard Worker const X x{}; 99*a65addddSAndroid Build Coastguard Worker ''', 100*a65addddSAndroid Build Coastguard Worker '.bindInstance<XAnnot, X>(x)') 101*a65addddSAndroid Build Coastguard WorkerCONST_BINDING2 = ( 102*a65addddSAndroid Build Coastguard Worker ''' 103*a65addddSAndroid Build Coastguard Worker const X x2{}; 104*a65addddSAndroid Build Coastguard Worker ''', 105*a65addddSAndroid Build Coastguard Worker '.bindInstance<XAnnot, X>(x2)') 106*a65addddSAndroid Build Coastguard Worker 107*a65addddSAndroid Build Coastguard Workerclass TestBindingClash(parameterized.TestCase): 108*a65addddSAndroid Build Coastguard Worker @multiple_named_parameters([ 109*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING + INSTALL',) + CONSTRUCTOR_BINDING + INSTALL, 110*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING + INSTALL',) + INTERFACE_BINDING + INSTALL, 111*a65addddSAndroid Build Coastguard Worker ('INSTALL + INSTALL2',) + INSTALL + INSTALL2, 112*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING + CONST_BINDING_FROM_INSTALL',) + CONSTRUCTOR_BINDING + CONST_BINDING_FROM_INSTALL, 113*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING + CONST_BINDING_FROM_INSTALL',) + INTERFACE_BINDING + CONST_BINDING_FROM_INSTALL, 114*a65addddSAndroid Build Coastguard Worker ('INSTALL2 + CONST_BINDING_FROM_INSTALL',) + INSTALL2 + CONST_BINDING_FROM_INSTALL, 115*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_FROM_INSTALL + INSTALL2',) + CONST_BINDING_FROM_INSTALL + INSTALL2, 116*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING + INSTALL2',) + CONST_BINDING + INSTALL2, 117*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_FROM_INSTALL + CONST_BINDING_FROM_INSTALL2',) + CONST_BINDING_FROM_INSTALL + CONST_BINDING_FROM_INSTALL2, 118*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING + CONST_BINDING_FROM_INSTALL',) + CONST_BINDING + CONST_BINDING_FROM_INSTALL, 119*a65addddSAndroid Build Coastguard Worker ], [ 120*a65addddSAndroid Build Coastguard Worker ('No annotation', 'X', 'Y', 'Y2'), 121*a65addddSAndroid Build Coastguard Worker ('With annotation', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation2, Y>', 'fruit::Annotated<Annotation3, Y2>'), 122*a65addddSAndroid Build Coastguard Worker ]) 123*a65addddSAndroid Build Coastguard Worker def test_clash_with_install(self, 124*a65addddSAndroid Build Coastguard Worker binding1_preparation, binding1, binding2_preparation, binding2, XAnnot, YAnnot, Y2Annot): 125*a65addddSAndroid Build Coastguard Worker source = ''' 126*a65addddSAndroid Build Coastguard Worker struct X{}; 127*a65addddSAndroid Build Coastguard Worker 128*a65addddSAndroid Build Coastguard Worker %s 129*a65addddSAndroid Build Coastguard Worker %s 130*a65addddSAndroid Build Coastguard Worker 131*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponent() { 132*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 133*a65addddSAndroid Build Coastguard Worker %s 134*a65addddSAndroid Build Coastguard Worker %s; 135*a65addddSAndroid Build Coastguard Worker } 136*a65addddSAndroid Build Coastguard Worker ''' % (binding1_preparation, binding2_preparation, binding1, binding2) 137*a65addddSAndroid Build Coastguard Worker expect_compile_error( 138*a65addddSAndroid Build Coastguard Worker 'DuplicateTypesInComponentError<XAnnot>', 139*a65addddSAndroid Build Coastguard Worker 'The installed component provides some types that are already provided by the current component.', 140*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 141*a65addddSAndroid Build Coastguard Worker source, 142*a65addddSAndroid Build Coastguard Worker locals()) 143*a65addddSAndroid Build Coastguard Worker 144*a65addddSAndroid Build Coastguard Worker @multiple_named_parameters([ 145*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING + CONSTRUCTOR_BINDING',) + CONSTRUCTOR_BINDING + CONSTRUCTOR_BINDING, 146*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING + INTERFACE_BINDING',) + CONSTRUCTOR_BINDING + INTERFACE_BINDING, 147*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING + CONSTRUCTOR_BINDING',) + INTERFACE_BINDING + CONSTRUCTOR_BINDING, 148*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING + INTERFACE_BINDING2',) + INTERFACE_BINDING + INTERFACE_BINDING2, 149*a65addddSAndroid Build Coastguard Worker ('INSTALL + CONSTRUCTOR_BINDING',) + INSTALL + CONSTRUCTOR_BINDING, 150*a65addddSAndroid Build Coastguard Worker ('INSTALL + INTERFACE_BINDING',) + INSTALL + INTERFACE_BINDING, 151*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_FROM_INSTALL + CONSTRUCTOR_BINDING',) + CONST_BINDING_FROM_INSTALL + CONSTRUCTOR_BINDING, 152*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_FROM_INSTALL + INTERFACE_BINDING',) + CONST_BINDING_FROM_INSTALL + INTERFACE_BINDING, 153*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING + CONSTRUCTOR_BINDING',) + CONST_BINDING + CONSTRUCTOR_BINDING, 154*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING + INTERFACE_BINDING',) + CONST_BINDING + INTERFACE_BINDING, 155*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING + CONST_BINDING',) + CONSTRUCTOR_BINDING + CONST_BINDING, 156*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING + CONST_BINDING',) + INTERFACE_BINDING + CONST_BINDING, 157*a65addddSAndroid Build Coastguard Worker ('INSTALL2 + CONST_BINDING',) + INSTALL2 + CONST_BINDING, 158*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_FROM_INSTALL + CONST_BINDING',) + CONST_BINDING_FROM_INSTALL + CONST_BINDING, 159*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING + CONST_BINDING2',) + CONST_BINDING + CONST_BINDING2, 160*a65addddSAndroid Build Coastguard Worker ], [ 161*a65addddSAndroid Build Coastguard Worker ('No annotation', 'X', 'Y', 'Y2'), 162*a65addddSAndroid Build Coastguard Worker ('With annotation', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation2, Y>', 'fruit::Annotated<Annotation3, Y2>'), 163*a65addddSAndroid Build Coastguard Worker ]) 164*a65addddSAndroid Build Coastguard Worker def test_clash_with_binding(self, binding1_preparation, binding1, binding2_preparation, binding2, XAnnot, YAnnot, Y2Annot): 165*a65addddSAndroid Build Coastguard Worker source = ''' 166*a65addddSAndroid Build Coastguard Worker struct X{}; 167*a65addddSAndroid Build Coastguard Worker 168*a65addddSAndroid Build Coastguard Worker %s 169*a65addddSAndroid Build Coastguard Worker %s 170*a65addddSAndroid Build Coastguard Worker 171*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponent() { 172*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 173*a65addddSAndroid Build Coastguard Worker %s 174*a65addddSAndroid Build Coastguard Worker %s; 175*a65addddSAndroid Build Coastguard Worker } 176*a65addddSAndroid Build Coastguard Worker 177*a65addddSAndroid Build Coastguard Worker ''' % (binding1_preparation, binding2_preparation, binding1, binding2) 178*a65addddSAndroid Build Coastguard Worker expect_compile_error( 179*a65addddSAndroid Build Coastguard Worker 'TypeAlreadyBoundError<XAnnot>', 180*a65addddSAndroid Build Coastguard Worker 'Trying to bind C but it is already bound.', 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 CONSTRUCTOR_BINDING_ANNOT1 = ( 186*a65addddSAndroid Build Coastguard Worker '', 187*a65addddSAndroid Build Coastguard Worker '.registerConstructor<XAnnot1()>()') 188*a65addddSAndroid Build Coastguard Worker CONSTRUCTOR_BINDING_ANNOT2 = ( 189*a65addddSAndroid Build Coastguard Worker '', 190*a65addddSAndroid Build Coastguard Worker '.registerConstructor<XAnnot2()>()') 191*a65addddSAndroid Build Coastguard Worker INTERFACE_BINDING_ANNOT1 = ( 192*a65addddSAndroid Build Coastguard Worker ''' 193*a65addddSAndroid Build Coastguard Worker struct Y : public X {}; 194*a65addddSAndroid Build Coastguard Worker ''', 195*a65addddSAndroid Build Coastguard Worker ''' 196*a65addddSAndroid Build Coastguard Worker .bind<XAnnot1, YAnnot1>() 197*a65addddSAndroid Build Coastguard Worker .registerConstructor<YAnnot1()>() 198*a65addddSAndroid Build Coastguard Worker ''') 199*a65addddSAndroid Build Coastguard Worker INTERFACE_BINDING_ANNOT2 = ( 200*a65addddSAndroid Build Coastguard Worker ''' 201*a65addddSAndroid Build Coastguard Worker struct Z : public X {}; 202*a65addddSAndroid Build Coastguard Worker ''', 203*a65addddSAndroid Build Coastguard Worker ''' 204*a65addddSAndroid Build Coastguard Worker .bind<XAnnot2, ZAnnot2>() 205*a65addddSAndroid Build Coastguard Worker .registerConstructor<ZAnnot2()>() 206*a65addddSAndroid Build Coastguard Worker ''') 207*a65addddSAndroid Build Coastguard Worker INSTALL_ANNOT1 = ( 208*a65addddSAndroid Build Coastguard Worker ''' 209*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot1> getParentComponent1() { 210*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 211*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot1()>(); 212*a65addddSAndroid Build Coastguard Worker } 213*a65addddSAndroid Build Coastguard Worker ''', 214*a65addddSAndroid Build Coastguard Worker '.install(getParentComponent1)') 215*a65addddSAndroid Build Coastguard Worker INSTALL_ANNOT2 = ( 216*a65addddSAndroid Build Coastguard Worker ''' 217*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot2> getParentComponent2() { 218*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 219*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot2()>(); 220*a65addddSAndroid Build Coastguard Worker } 221*a65addddSAndroid Build Coastguard Worker ''', 222*a65addddSAndroid Build Coastguard Worker '.install(getParentComponent2)') 223*a65addddSAndroid Build Coastguard Worker CONST_BINDING_FROM_INSTALL_ANNOT1 = ( 224*a65addddSAndroid Build Coastguard Worker ''' 225*a65addddSAndroid Build Coastguard Worker fruit::Component<ConstXAnnot1> getParentComponent1() { 226*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 227*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot1()>(); 228*a65addddSAndroid Build Coastguard Worker } 229*a65addddSAndroid Build Coastguard Worker ''', 230*a65addddSAndroid Build Coastguard Worker '.install(getParentComponent1)') 231*a65addddSAndroid Build Coastguard Worker CONST_BINDING_FROM_INSTALL_ANNOT2 = ( 232*a65addddSAndroid Build Coastguard Worker ''' 233*a65addddSAndroid Build Coastguard Worker fruit::Component<ConstXAnnot2> getParentComponent2() { 234*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 235*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot2()>(); 236*a65addddSAndroid Build Coastguard Worker } 237*a65addddSAndroid Build Coastguard Worker ''', 238*a65addddSAndroid Build Coastguard Worker '.install(getParentComponent2)') 239*a65addddSAndroid Build Coastguard Worker CONST_BINDING_ANNOT1 = ( 240*a65addddSAndroid Build Coastguard Worker ''' 241*a65addddSAndroid Build Coastguard Worker const X x1{}; 242*a65addddSAndroid Build Coastguard Worker ''', 243*a65addddSAndroid Build Coastguard Worker '.bindInstance<XAnnot1, X>(x1)') 244*a65addddSAndroid Build Coastguard Worker CONST_BINDING_ANNOT2 = ( 245*a65addddSAndroid Build Coastguard Worker ''' 246*a65addddSAndroid Build Coastguard Worker const X x2{}; 247*a65addddSAndroid Build Coastguard Worker ''', 248*a65addddSAndroid Build Coastguard Worker '.bindInstance<XAnnot2, X>(x2)') 249*a65addddSAndroid Build Coastguard Worker 250*a65addddSAndroid Build Coastguard Worker @parameterized.named_parameters([ 251*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2',) + CONSTRUCTOR_BINDING_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2, 252*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING_ANNOT1 + INTERFACE_BINDING_ANNOT2',) + CONSTRUCTOR_BINDING_ANNOT1 + INTERFACE_BINDING_ANNOT2, 253*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2',) + INTERFACE_BINDING_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2, 254*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING_ANNOT1 + INTERFACE_BINDING_ANNOT2',) + INTERFACE_BINDING_ANNOT1 + INTERFACE_BINDING_ANNOT2, 255*a65addddSAndroid Build Coastguard Worker ('INSTALL_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2',) + INSTALL_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2, 256*a65addddSAndroid Build Coastguard Worker ('INSTALL_ANNOT1 + INTERFACE_BINDING_ANNOT2',) + INSTALL_ANNOT1 + INTERFACE_BINDING_ANNOT2, 257*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_FROM_INSTALL_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2',) + CONST_BINDING_FROM_INSTALL_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2, 258*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2',) + CONST_BINDING_ANNOT1 + CONSTRUCTOR_BINDING_ANNOT2, 259*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_FROM_INSTALL_ANNOT1 + INTERFACE_BINDING_ANNOT2',) + CONST_BINDING_FROM_INSTALL_ANNOT1 + INTERFACE_BINDING_ANNOT2, 260*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_ANNOT1 + INTERFACE_BINDING_ANNOT2',) + CONST_BINDING_ANNOT1 + INTERFACE_BINDING_ANNOT2, 261*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING_ANNOT1 + INSTALL_ANNOT2',) + CONSTRUCTOR_BINDING_ANNOT1 + INSTALL_ANNOT2, 262*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING_ANNOT1 + INSTALL_ANNOT2',) + INTERFACE_BINDING_ANNOT1 + INSTALL_ANNOT2, 263*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2',) + CONSTRUCTOR_BINDING_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2, 264*a65addddSAndroid Build Coastguard Worker ('CONSTRUCTOR_BINDING_ANNOT1 + CONST_BINDING_ANNOT2',) + CONSTRUCTOR_BINDING_ANNOT1 + CONST_BINDING_ANNOT2, 265*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2',) + INTERFACE_BINDING_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2, 266*a65addddSAndroid Build Coastguard Worker ('INTERFACE_BINDING_ANNOT1 + CONST_BINDING_ANNOT2',) + INTERFACE_BINDING_ANNOT1 + CONST_BINDING_ANNOT2, 267*a65addddSAndroid Build Coastguard Worker ('INSTALL_ANNOT1 + INSTALL_ANNOT2',) + INSTALL_ANNOT1 + INSTALL_ANNOT2, 268*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_FROM_INSTALL_ANNOT1 + INSTALL_ANNOT2',) + CONST_BINDING_FROM_INSTALL_ANNOT1 + INSTALL_ANNOT2, 269*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_ANNOT1 + INSTALL_ANNOT2',) + CONST_BINDING_ANNOT1 + INSTALL_ANNOT2, 270*a65addddSAndroid Build Coastguard Worker ('INSTALL_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2',) + INSTALL_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2, 271*a65addddSAndroid Build Coastguard Worker ('INSTALL_ANNOT1 + CONST_BINDING_ANNOT2',) + INSTALL_ANNOT1 + CONST_BINDING_ANNOT2, 272*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_FROM_INSTALL_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2',) + CONST_BINDING_FROM_INSTALL_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2, 273*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_ANNOT1 + CONST_BINDING_ANNOT2',) + CONST_BINDING_ANNOT1 + CONST_BINDING_ANNOT2, 274*a65addddSAndroid Build Coastguard Worker ('CONST_BINDING_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2',) + CONST_BINDING_ANNOT1 + CONST_BINDING_FROM_INSTALL_ANNOT2, 275*a65addddSAndroid Build Coastguard Worker ]) 276*a65addddSAndroid Build Coastguard Worker def test_no_clash_with_different_annotations(self, binding1_preparation, binding1, binding2_preparation, binding2): 277*a65addddSAndroid Build Coastguard Worker source = ''' 278*a65addddSAndroid Build Coastguard Worker struct X {}; 279*a65addddSAndroid Build Coastguard Worker 280*a65addddSAndroid Build Coastguard Worker %s 281*a65addddSAndroid Build Coastguard Worker %s 282*a65addddSAndroid Build Coastguard Worker 283*a65addddSAndroid Build Coastguard Worker fruit::Component<const XAnnot1, const XAnnot2> getComponent() { 284*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 285*a65addddSAndroid Build Coastguard Worker %s 286*a65addddSAndroid Build Coastguard Worker %s; 287*a65addddSAndroid Build Coastguard Worker } 288*a65addddSAndroid Build Coastguard Worker 289*a65addddSAndroid Build Coastguard Worker int main() { 290*a65addddSAndroid Build Coastguard Worker fruit::Injector<const XAnnot1, const XAnnot2> injector(getComponent); 291*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot1>(); 292*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot2>(); 293*a65addddSAndroid Build Coastguard Worker } 294*a65addddSAndroid Build Coastguard Worker ''' % (binding1_preparation, binding2_preparation, binding1, binding2) 295*a65addddSAndroid Build Coastguard Worker expect_success( 296*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 297*a65addddSAndroid Build Coastguard Worker source) 298*a65addddSAndroid Build Coastguard Worker 299*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 300*a65addddSAndroid Build Coastguard Worker ('X', 'X', 'X'), 301*a65addddSAndroid Build Coastguard Worker ('const X', 'X', 'X'), 302*a65addddSAndroid Build Coastguard Worker ('X', 'const X', 'X'), 303*a65addddSAndroid Build Coastguard Worker ('const X', 'const X', 'X'), 304*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 305*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, const X>', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 306*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>', 'fruit::Annotated<Annotation1, X>'), 307*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, const X>', 'fruit::Annotated<Annotation1, const X>', 'fruit::Annotated<Annotation1, X>'), 308*a65addddSAndroid Build Coastguard Worker ]) 309*a65addddSAndroid Build Coastguard Worker def test_during_component_merge(self, NormalizedComponentXAnnot, ComponentXAnnot, XAnnot): 310*a65addddSAndroid Build Coastguard Worker source = ''' 311*a65addddSAndroid Build Coastguard Worker struct X {}; 312*a65addddSAndroid Build Coastguard Worker 313*a65addddSAndroid Build Coastguard Worker fruit::Component<NormalizedComponentXAnnot> getComponent1() { 314*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 315*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot()>(); 316*a65addddSAndroid Build Coastguard Worker } 317*a65addddSAndroid Build Coastguard Worker 318*a65addddSAndroid Build Coastguard Worker fruit::Component<ComponentXAnnot> getComponent2() { 319*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 320*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot()>(); 321*a65addddSAndroid Build Coastguard Worker } 322*a65addddSAndroid Build Coastguard Worker 323*a65addddSAndroid Build Coastguard Worker void f() { 324*a65addddSAndroid Build Coastguard Worker fruit::NormalizedComponent<NormalizedComponentXAnnot> nc(getComponent1); 325*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(nc, getComponent2); 326*a65addddSAndroid Build Coastguard Worker (void) injector; 327*a65addddSAndroid Build Coastguard Worker } 328*a65addddSAndroid Build Coastguard Worker ''' 329*a65addddSAndroid Build Coastguard Worker expect_compile_error( 330*a65addddSAndroid Build Coastguard Worker 'DuplicateTypesInComponentError<XAnnot>', 331*a65addddSAndroid Build Coastguard Worker 'The installed component provides some types that are already provided', 332*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 333*a65addddSAndroid Build Coastguard Worker source, 334*a65addddSAndroid Build Coastguard Worker locals()) 335*a65addddSAndroid Build Coastguard Worker 336*a65addddSAndroid Build Coastguard Worker def test_during_component_merge_with_different_annotation_ok(self): 337*a65addddSAndroid Build Coastguard Worker source = ''' 338*a65addddSAndroid Build Coastguard Worker struct X {}; 339*a65addddSAndroid Build Coastguard Worker 340*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot1> getComponent1() { 341*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 342*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot1()>(); 343*a65addddSAndroid Build Coastguard Worker } 344*a65addddSAndroid Build Coastguard Worker 345*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot2> getComponent2() { 346*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 347*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot2()>(); 348*a65addddSAndroid Build Coastguard Worker } 349*a65addddSAndroid Build Coastguard Worker 350*a65addddSAndroid Build Coastguard Worker int main() { 351*a65addddSAndroid Build Coastguard Worker fruit::NormalizedComponent<XAnnot1> nc(getComponent1); 352*a65addddSAndroid Build Coastguard Worker fruit::Injector<XAnnot1, XAnnot2> injector(nc, getComponent2); 353*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot1>(); 354*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot2>(); 355*a65addddSAndroid Build Coastguard Worker } 356*a65addddSAndroid Build Coastguard Worker ''' 357*a65addddSAndroid Build Coastguard Worker expect_success( 358*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 359*a65addddSAndroid Build Coastguard Worker source) 360*a65addddSAndroid Build Coastguard Worker 361*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 362*a65addddSAndroid Build Coastguard Worker ('X', '(struct )?X'), 363*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', '(struct )?fruit::Annotated<(struct )?Annotation1, ?(struct )?X>'), 364*a65addddSAndroid Build Coastguard Worker ]) 365*a65addddSAndroid Build Coastguard Worker def test_bind_instance_and_bind_instance_runtime(self, XAnnot, XAnnotRegex): 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<> getComponentForInstanceHelper() { 370*a65addddSAndroid Build Coastguard Worker // Note: don't do this in real code, leaks memory. 371*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 372*a65addddSAndroid Build Coastguard Worker .bindInstance<XAnnot, X>(*(new X())); 373*a65addddSAndroid Build Coastguard Worker } 374*a65addddSAndroid Build Coastguard Worker 375*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponentForInstance() { 376*a65addddSAndroid Build Coastguard Worker // Note: don't do this in real code, leaks memory. 377*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 378*a65addddSAndroid Build Coastguard Worker .install(getComponentForInstanceHelper) 379*a65addddSAndroid Build Coastguard Worker .bindInstance<XAnnot, X>(*(new X())); 380*a65addddSAndroid Build Coastguard Worker } 381*a65addddSAndroid Build Coastguard Worker 382*a65addddSAndroid Build Coastguard Worker int main() { 383*a65addddSAndroid Build Coastguard Worker fruit::Injector<XAnnot> injector(getComponentForInstance); 384*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot>(); 385*a65addddSAndroid Build Coastguard Worker } 386*a65addddSAndroid Build Coastguard Worker ''' 387*a65addddSAndroid Build Coastguard Worker expect_runtime_error( 388*a65addddSAndroid Build Coastguard Worker 'Fatal injection error: the type XAnnotRegex was provided more than once, with different bindings.', 389*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 390*a65addddSAndroid Build Coastguard Worker source, 391*a65addddSAndroid Build Coastguard Worker locals()) 392*a65addddSAndroid Build Coastguard Worker 393*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 394*a65addddSAndroid Build Coastguard Worker ('X', '(struct )?X'), 395*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', '(struct )?fruit::Annotated<(struct )?Annotation1, ?(struct )?X>'), 396*a65addddSAndroid Build Coastguard Worker ]) 397*a65addddSAndroid Build Coastguard Worker def test_bind_instance_and_binding_runtime(self, XAnnot, XAnnotRegex): 398*a65addddSAndroid Build Coastguard Worker source = ''' 399*a65addddSAndroid Build Coastguard Worker struct X {}; 400*a65addddSAndroid Build Coastguard Worker 401*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponentForInstanceHelper(X* x) { 402*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 403*a65addddSAndroid Build Coastguard Worker .bindInstance<XAnnot, X>(*x); 404*a65addddSAndroid Build Coastguard Worker } 405*a65addddSAndroid Build Coastguard Worker 406*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponentForInstance(X* x) { 407*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 408*a65addddSAndroid Build Coastguard Worker .install(getComponentForInstanceHelper, x) 409*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot()>(); 410*a65addddSAndroid Build Coastguard Worker } 411*a65addddSAndroid Build Coastguard Worker 412*a65addddSAndroid Build Coastguard Worker int main() { 413*a65addddSAndroid Build Coastguard Worker X x; 414*a65addddSAndroid Build Coastguard Worker fruit::Injector<XAnnot> injector(getComponentForInstance, &x); 415*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot>(); 416*a65addddSAndroid Build Coastguard Worker } 417*a65addddSAndroid Build Coastguard Worker ''' 418*a65addddSAndroid Build Coastguard Worker expect_runtime_error( 419*a65addddSAndroid Build Coastguard Worker 'Fatal injection error: the type XAnnotRegex was provided more than once, with different bindings.', 420*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 421*a65addddSAndroid Build Coastguard Worker source, 422*a65addddSAndroid Build Coastguard Worker locals()) 423*a65addddSAndroid Build Coastguard Worker 424*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 425*a65addddSAndroid Build Coastguard Worker 'X', 426*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 427*a65addddSAndroid Build Coastguard Worker ]) 428*a65addddSAndroid Build Coastguard Worker def test_during_component_merge_consistent_ok(self, XAnnot): 429*a65addddSAndroid Build Coastguard Worker source = ''' 430*a65addddSAndroid Build Coastguard Worker struct X : public ConstructionTracker<X> { 431*a65addddSAndroid Build Coastguard Worker using Inject = X(); 432*a65addddSAndroid Build Coastguard Worker }; 433*a65addddSAndroid Build Coastguard Worker 434*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponent() { 435*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 436*a65addddSAndroid Build Coastguard Worker } 437*a65addddSAndroid Build Coastguard Worker 438*a65addddSAndroid Build Coastguard Worker fruit::Component<> getRootComponent() { 439*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 440*a65addddSAndroid Build Coastguard Worker .install(getComponent); 441*a65addddSAndroid Build Coastguard Worker } 442*a65addddSAndroid Build Coastguard Worker 443*a65addddSAndroid Build Coastguard Worker int main() { 444*a65addddSAndroid Build Coastguard Worker fruit::NormalizedComponent<> normalizedComponent(getRootComponent); 445*a65addddSAndroid Build Coastguard Worker fruit::Injector<XAnnot> injector(normalizedComponent, getComponent); 446*a65addddSAndroid Build Coastguard Worker 447*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 0); 448*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot>(); 449*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 1); 450*a65addddSAndroid Build Coastguard Worker } 451*a65addddSAndroid Build Coastguard Worker ''' 452*a65addddSAndroid Build Coastguard Worker expect_success( 453*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 454*a65addddSAndroid Build Coastguard Worker source, 455*a65addddSAndroid Build Coastguard Worker locals()) 456*a65addddSAndroid Build Coastguard Worker 457*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__': 458*a65addddSAndroid Build Coastguard Worker absltest.main() 459