1*a65addddSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*a65addddSAndroid Build Coastguard Worker# Copyright 2016 Google Inc. All Rights Reserved. 3*a65addddSAndroid Build Coastguard Worker# 4*a65addddSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*a65addddSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*a65addddSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*a65addddSAndroid Build Coastguard Worker# 8*a65addddSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*a65addddSAndroid Build Coastguard Worker# 10*a65addddSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*a65addddSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS-IS" BASIS, 12*a65addddSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*a65addddSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*a65addddSAndroid Build Coastguard Worker# limitations under the License. 15*a65addddSAndroid Build Coastguard Worker 16*a65addddSAndroid Build Coastguard Workerfrom absl.testing import parameterized 17*a65addddSAndroid Build Coastguard Workerfrom fruit_test_common import * 18*a65addddSAndroid Build Coastguard Worker 19*a65addddSAndroid Build Coastguard WorkerCOMMON_DEFINITIONS = ''' 20*a65addddSAndroid Build Coastguard Worker #include "test_common.h" 21*a65addddSAndroid Build Coastguard Worker 22*a65addddSAndroid Build Coastguard Worker struct X; 23*a65addddSAndroid Build Coastguard Worker 24*a65addddSAndroid Build Coastguard Worker struct Annotation1 {}; 25*a65addddSAndroid Build Coastguard Worker using XAnnot1 = fruit::Annotated<Annotation1, X>; 26*a65addddSAndroid Build Coastguard Worker ''' 27*a65addddSAndroid Build Coastguard Worker 28*a65addddSAndroid Build Coastguard Workerclass TestInstall(parameterized.TestCase): 29*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 30*a65addddSAndroid Build Coastguard Worker ('X', 'X'), 31*a65addddSAndroid Build Coastguard Worker ('X', 'const X'), 32*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 33*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>'), 34*a65addddSAndroid Build Coastguard Worker ]) 35*a65addddSAndroid Build Coastguard Worker def test_success(self, XParamInChildComponent, XParamInRootComponent): 36*a65addddSAndroid Build Coastguard Worker source = ''' 37*a65addddSAndroid Build Coastguard Worker struct X { 38*a65addddSAndroid Build Coastguard Worker int n; 39*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 40*a65addddSAndroid Build Coastguard Worker }; 41*a65addddSAndroid Build Coastguard Worker 42*a65addddSAndroid Build Coastguard Worker fruit::Component<XParamInChildComponent> getChildComponent() { 43*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 44*a65addddSAndroid Build Coastguard Worker .registerProvider<XParamInChildComponent()>([]() { return X(5); }); 45*a65addddSAndroid Build Coastguard Worker } 46*a65addddSAndroid Build Coastguard Worker 47*a65addddSAndroid Build Coastguard Worker fruit::Component<XParamInRootComponent> getRootComponent() { 48*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 49*a65addddSAndroid Build Coastguard Worker .install(getChildComponent); 50*a65addddSAndroid Build Coastguard Worker } 51*a65addddSAndroid Build Coastguard Worker 52*a65addddSAndroid Build Coastguard Worker int main() { 53*a65addddSAndroid Build Coastguard Worker fruit::Injector<XParamInRootComponent> injector(getRootComponent); 54*a65addddSAndroid Build Coastguard Worker X x = injector.get<XParamInRootComponent>(); 55*a65addddSAndroid Build Coastguard Worker Assert(x.n == 5); 56*a65addddSAndroid Build Coastguard Worker } 57*a65addddSAndroid Build Coastguard Worker ''' 58*a65addddSAndroid Build Coastguard Worker expect_success( 59*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 60*a65addddSAndroid Build Coastguard Worker source, 61*a65addddSAndroid Build Coastguard Worker locals()) 62*a65addddSAndroid Build Coastguard Worker 63*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 64*a65addddSAndroid Build Coastguard Worker ('const X', 'X'), 65*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, const X>', 'fruit::Annotated<Annotation1, X>'), 66*a65addddSAndroid Build Coastguard Worker ]) 67*a65addddSAndroid Build Coastguard Worker def test_install_error_child_component_provides_const(self, XParamInChildComponent, XParamInRootComponent): 68*a65addddSAndroid Build Coastguard Worker source = ''' 69*a65addddSAndroid Build Coastguard Worker struct X {}; 70*a65addddSAndroid Build Coastguard Worker 71*a65addddSAndroid Build Coastguard Worker fruit::Component<XParamInChildComponent> getChildComponent(); 72*a65addddSAndroid Build Coastguard Worker 73*a65addddSAndroid Build Coastguard Worker fruit::Component<XParamInRootComponent> getRootComponent() { 74*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 75*a65addddSAndroid Build Coastguard Worker .install(getChildComponent); 76*a65addddSAndroid Build Coastguard Worker } 77*a65addddSAndroid Build Coastguard Worker ''' 78*a65addddSAndroid Build Coastguard Worker expect_compile_error( 79*a65addddSAndroid Build Coastguard Worker 'NonConstBindingRequiredButConstBindingProvidedError<XParamInRootComponent>', 80*a65addddSAndroid Build Coastguard Worker 'The type T was provided as constant, however one of the constructors/providers/factories in this component', 81*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 82*a65addddSAndroid Build Coastguard Worker source, 83*a65addddSAndroid Build Coastguard Worker locals()) 84*a65addddSAndroid Build Coastguard Worker 85*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 86*a65addddSAndroid Build Coastguard Worker ('X', 'X'), 87*a65addddSAndroid Build Coastguard Worker ('X', 'const X'), 88*a65addddSAndroid Build Coastguard Worker ('const X', 'const X'), 89*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 90*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>'), 91*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, const X>', 'fruit::Annotated<Annotation1, const X>'), 92*a65addddSAndroid Build Coastguard Worker ]) 93*a65addddSAndroid Build Coastguard Worker def test_with_requirements_success(self, ProvidedXParam, RequiredXParam): 94*a65addddSAndroid Build Coastguard Worker ProvidedXParamWithoutConst = ProvidedXParam.replace('const ', '') 95*a65addddSAndroid Build Coastguard Worker source = ''' 96*a65addddSAndroid Build Coastguard Worker struct X { 97*a65addddSAndroid Build Coastguard Worker int n; 98*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 99*a65addddSAndroid Build Coastguard Worker }; 100*a65addddSAndroid Build Coastguard Worker 101*a65addddSAndroid Build Coastguard Worker struct Y { 102*a65addddSAndroid Build Coastguard Worker X x; 103*a65addddSAndroid Build Coastguard Worker Y(X x): x(x) {} 104*a65addddSAndroid Build Coastguard Worker }; 105*a65addddSAndroid Build Coastguard Worker 106*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<RequiredXParam>, Y> getChildComponent1() { 107*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 108*a65addddSAndroid Build Coastguard Worker .registerProvider<Y(RequiredXParam)>([](X x) { return Y(x); }); 109*a65addddSAndroid Build Coastguard Worker } 110*a65addddSAndroid Build Coastguard Worker 111*a65addddSAndroid Build Coastguard Worker fruit::Component<ProvidedXParam> getChildComponent2() { 112*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 113*a65addddSAndroid Build Coastguard Worker .registerProvider<ProvidedXParamWithoutConst()>([]() { return X(5); }); 114*a65addddSAndroid Build Coastguard Worker } 115*a65addddSAndroid Build Coastguard Worker 116*a65addddSAndroid Build Coastguard Worker fruit::Component<Y> getRootComponent() { 117*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 118*a65addddSAndroid Build Coastguard Worker .install(getChildComponent1) 119*a65addddSAndroid Build Coastguard Worker .install(getChildComponent2); 120*a65addddSAndroid Build Coastguard Worker } 121*a65addddSAndroid Build Coastguard Worker 122*a65addddSAndroid Build Coastguard Worker int main() { 123*a65addddSAndroid Build Coastguard Worker fruit::Injector<Y> injector(getRootComponent); 124*a65addddSAndroid Build Coastguard Worker Y y = injector.get<Y>(); 125*a65addddSAndroid Build Coastguard Worker Assert(y.x.n == 5); 126*a65addddSAndroid Build Coastguard Worker } 127*a65addddSAndroid Build Coastguard Worker ''' 128*a65addddSAndroid Build Coastguard Worker expect_success( 129*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 130*a65addddSAndroid Build Coastguard Worker source, 131*a65addddSAndroid Build Coastguard Worker locals()) 132*a65addddSAndroid Build Coastguard Worker 133*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 134*a65addddSAndroid Build Coastguard Worker ('const X', 'X'), 135*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, const X>', 'fruit::Annotated<Annotation1, X>'), 136*a65addddSAndroid Build Coastguard Worker ]) 137*a65addddSAndroid Build Coastguard Worker def test_with_requirements_error_only_nonconst_provided(self, ProvidedXParam, RequiredXParam): 138*a65addddSAndroid Build Coastguard Worker source = ''' 139*a65addddSAndroid Build Coastguard Worker struct X {}; 140*a65addddSAndroid Build Coastguard Worker struct Y {}; 141*a65addddSAndroid Build Coastguard Worker 142*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<RequiredXParam>, Y> getChildComponent1(); 143*a65addddSAndroid Build Coastguard Worker 144*a65addddSAndroid Build Coastguard Worker fruit::Component<ProvidedXParam> getChildComponent2(); 145*a65addddSAndroid Build Coastguard Worker 146*a65addddSAndroid Build Coastguard Worker fruit::Component<Y> getRootComponent() { 147*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 148*a65addddSAndroid Build Coastguard Worker .install(getChildComponent1) 149*a65addddSAndroid Build Coastguard Worker .install(getChildComponent2); 150*a65addddSAndroid Build Coastguard Worker } 151*a65addddSAndroid Build Coastguard Worker ''' 152*a65addddSAndroid Build Coastguard Worker expect_compile_error( 153*a65addddSAndroid Build Coastguard Worker 'NonConstBindingRequiredButConstBindingProvidedError<RequiredXParam>', 154*a65addddSAndroid Build Coastguard Worker 'The type T was provided as constant, however one of the constructors/providers/factories in this component', 155*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 156*a65addddSAndroid Build Coastguard Worker source, 157*a65addddSAndroid Build Coastguard Worker locals()) 158*a65addddSAndroid Build Coastguard Worker 159*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 160*a65addddSAndroid Build Coastguard Worker ('const X', 'X'), 161*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, const X>', 'fruit::Annotated<Annotation1, X>'), 162*a65addddSAndroid Build Coastguard Worker ]) 163*a65addddSAndroid Build Coastguard Worker def test_with_requirements_error_only_nonconst_provided_reversed_install_order(self, ProvidedXParam, RequiredXParam): 164*a65addddSAndroid Build Coastguard Worker source = ''' 165*a65addddSAndroid Build Coastguard Worker struct X {}; 166*a65addddSAndroid Build Coastguard Worker struct Y {}; 167*a65addddSAndroid Build Coastguard Worker 168*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<RequiredXParam>, Y> getChildComponent1(); 169*a65addddSAndroid Build Coastguard Worker 170*a65addddSAndroid Build Coastguard Worker fruit::Component<ProvidedXParam> getChildComponent2(); 171*a65addddSAndroid Build Coastguard Worker 172*a65addddSAndroid Build Coastguard Worker fruit::Component<Y> getRootComponent() { 173*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 174*a65addddSAndroid Build Coastguard Worker .install(getChildComponent2) 175*a65addddSAndroid Build Coastguard Worker .install(getChildComponent1); 176*a65addddSAndroid Build Coastguard Worker } 177*a65addddSAndroid Build Coastguard Worker ''' 178*a65addddSAndroid Build Coastguard Worker expect_compile_error( 179*a65addddSAndroid Build Coastguard Worker 'NonConstBindingRequiredButConstBindingProvidedError<RequiredXParam>', 180*a65addddSAndroid Build Coastguard Worker 'The type T was provided as constant, however one of the constructors/providers/factories in this component', 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 def test_with_requirements_not_specified_in_child_component_error(self): 186*a65addddSAndroid Build Coastguard Worker source = ''' 187*a65addddSAndroid Build Coastguard Worker struct X { 188*a65addddSAndroid Build Coastguard Worker int n; 189*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 190*a65addddSAndroid Build Coastguard Worker }; 191*a65addddSAndroid Build Coastguard Worker 192*a65addddSAndroid Build Coastguard Worker struct Y { 193*a65addddSAndroid Build Coastguard Worker X x; 194*a65addddSAndroid Build Coastguard Worker Y(X x): x(x) {} 195*a65addddSAndroid Build Coastguard Worker }; 196*a65addddSAndroid Build Coastguard Worker 197*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<X>, Y> getParentYComponent() { 198*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 199*a65addddSAndroid Build Coastguard Worker .registerProvider([](X x) { return Y(x); }); 200*a65addddSAndroid Build Coastguard Worker } 201*a65addddSAndroid Build Coastguard Worker 202*a65addddSAndroid Build Coastguard Worker // We intentionally don't have fruit::Required<X> here, we want to test that this results in an error. 203*a65addddSAndroid Build Coastguard Worker fruit::Component<Y> getYComponent() { 204*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 205*a65addddSAndroid Build Coastguard Worker .install(getParentYComponent); 206*a65addddSAndroid Build Coastguard Worker } 207*a65addddSAndroid Build Coastguard Worker ''' 208*a65addddSAndroid Build Coastguard Worker expect_compile_error( 209*a65addddSAndroid Build Coastguard Worker 'NoBindingFoundError<X>', 210*a65addddSAndroid Build Coastguard Worker 'No explicit binding nor C::Inject definition was found for T', 211*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 212*a65addddSAndroid Build Coastguard Worker source) 213*a65addddSAndroid Build Coastguard Worker 214*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 215*a65addddSAndroid Build Coastguard Worker ('X', 'const X'), 216*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>'), 217*a65addddSAndroid Build Coastguard Worker ]) 218*a65addddSAndroid Build Coastguard Worker def test_install_requiring_nonconst_then_install_requiring_const_ok(self, XAnnot, ConstXAnnot): 219*a65addddSAndroid Build Coastguard Worker source = ''' 220*a65addddSAndroid Build Coastguard Worker struct X {}; 221*a65addddSAndroid Build Coastguard Worker struct Y {}; 222*a65addddSAndroid Build Coastguard Worker struct Z {}; 223*a65addddSAndroid Build Coastguard Worker 224*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<XAnnot>, Y> getChildComponent1() { 225*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 226*a65addddSAndroid Build Coastguard Worker .registerConstructor<Y()>(); 227*a65addddSAndroid Build Coastguard Worker } 228*a65addddSAndroid Build Coastguard Worker 229*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<ConstXAnnot>, Z> getChildComponent2() { 230*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 231*a65addddSAndroid Build Coastguard Worker .registerConstructor<Z()>(); 232*a65addddSAndroid Build Coastguard Worker } 233*a65addddSAndroid Build Coastguard Worker 234*a65addddSAndroid Build Coastguard Worker fruit::Component<Y, Z> getRootComponent() { 235*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 236*a65addddSAndroid Build Coastguard Worker .install(getChildComponent1) 237*a65addddSAndroid Build Coastguard Worker .install(getChildComponent2) 238*a65addddSAndroid Build Coastguard Worker .registerConstructor<XAnnot()>(); 239*a65addddSAndroid Build Coastguard Worker } 240*a65addddSAndroid Build Coastguard Worker 241*a65addddSAndroid Build Coastguard Worker int main() { 242*a65addddSAndroid Build Coastguard Worker fruit::Injector<Y, Z> injector(getRootComponent); 243*a65addddSAndroid Build Coastguard Worker injector.get<Y>(); 244*a65addddSAndroid Build Coastguard Worker injector.get<Z>(); 245*a65addddSAndroid Build Coastguard Worker } 246*a65addddSAndroid Build Coastguard Worker ''' 247*a65addddSAndroid Build Coastguard Worker expect_success( 248*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 249*a65addddSAndroid Build Coastguard Worker source, 250*a65addddSAndroid Build Coastguard Worker locals()) 251*a65addddSAndroid Build Coastguard Worker 252*a65addddSAndroid Build Coastguard Worker def test_install_requiring_nonconst_then_install_requiring_const_declaring_const_requirement_error(self): 253*a65addddSAndroid Build Coastguard Worker source = ''' 254*a65addddSAndroid Build Coastguard Worker struct X {}; 255*a65addddSAndroid Build Coastguard Worker struct Y {}; 256*a65addddSAndroid Build Coastguard Worker struct Z {}; 257*a65addddSAndroid Build Coastguard Worker 258*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<X>, Y> getChildComponent1(); 259*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>, Z> getChildComponent2(); 260*a65addddSAndroid Build Coastguard Worker 261*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>, Y, Z> getRootComponent() { 262*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 263*a65addddSAndroid Build Coastguard Worker .install(getChildComponent1) 264*a65addddSAndroid Build Coastguard Worker .install(getChildComponent2); 265*a65addddSAndroid Build Coastguard Worker } 266*a65addddSAndroid Build Coastguard Worker ''' 267*a65addddSAndroid Build Coastguard Worker expect_compile_error( 268*a65addddSAndroid Build Coastguard Worker 'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>', 269*a65addddSAndroid Build Coastguard Worker 'The type T was declared as a const Required type in the returned Component, however', 270*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 271*a65addddSAndroid Build Coastguard Worker source, 272*a65addddSAndroid Build Coastguard Worker locals()) 273*a65addddSAndroid Build Coastguard Worker 274*a65addddSAndroid Build Coastguard Worker def test_install_requiring_const_then_install_requiring_nonconst_ok(self): 275*a65addddSAndroid Build Coastguard Worker source = ''' 276*a65addddSAndroid Build Coastguard Worker struct X {}; 277*a65addddSAndroid Build Coastguard Worker struct Y {}; 278*a65addddSAndroid Build Coastguard Worker struct Z {}; 279*a65addddSAndroid Build Coastguard Worker 280*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>, Y> getChildComponent1() { 281*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 282*a65addddSAndroid Build Coastguard Worker .registerConstructor<Y()>(); 283*a65addddSAndroid Build Coastguard Worker } 284*a65addddSAndroid Build Coastguard Worker 285*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<X>, Z> getChildComponent2() { 286*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 287*a65addddSAndroid Build Coastguard Worker .registerConstructor<Z()>(); 288*a65addddSAndroid Build Coastguard Worker } 289*a65addddSAndroid Build Coastguard Worker 290*a65addddSAndroid Build Coastguard Worker fruit::Component<Y, Z> getRootComponent() { 291*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 292*a65addddSAndroid Build Coastguard Worker .install(getChildComponent1) 293*a65addddSAndroid Build Coastguard Worker .install(getChildComponent2) 294*a65addddSAndroid Build Coastguard Worker .registerConstructor<X()>(); 295*a65addddSAndroid Build Coastguard Worker } 296*a65addddSAndroid Build Coastguard Worker 297*a65addddSAndroid Build Coastguard Worker int main() { 298*a65addddSAndroid Build Coastguard Worker fruit::Injector<Y, Z> injector(getRootComponent); 299*a65addddSAndroid Build Coastguard Worker injector.get<Y>(); 300*a65addddSAndroid Build Coastguard Worker injector.get<Z>(); 301*a65addddSAndroid Build Coastguard Worker } 302*a65addddSAndroid Build Coastguard Worker ''' 303*a65addddSAndroid Build Coastguard Worker expect_success( 304*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 305*a65addddSAndroid Build Coastguard Worker source, 306*a65addddSAndroid Build Coastguard Worker locals()) 307*a65addddSAndroid Build Coastguard Worker 308*a65addddSAndroid Build Coastguard Worker def test_install_requiring_const_then_install_requiring_nonconst_declaring_const_requirement_error(self): 309*a65addddSAndroid Build Coastguard Worker source = ''' 310*a65addddSAndroid Build Coastguard Worker struct X {}; 311*a65addddSAndroid Build Coastguard Worker struct Y {}; 312*a65addddSAndroid Build Coastguard Worker struct Z {}; 313*a65addddSAndroid Build Coastguard Worker 314*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>, Y> getChildComponent1(); 315*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<X>, Z> getChildComponent2(); 316*a65addddSAndroid Build Coastguard Worker 317*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>, Y, Z> getRootComponent() { 318*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 319*a65addddSAndroid Build Coastguard Worker .install(getChildComponent1) 320*a65addddSAndroid Build Coastguard Worker .install(getChildComponent2); 321*a65addddSAndroid Build Coastguard Worker } 322*a65addddSAndroid Build Coastguard Worker ''' 323*a65addddSAndroid Build Coastguard Worker expect_compile_error( 324*a65addddSAndroid Build Coastguard Worker 'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>', 325*a65addddSAndroid Build Coastguard Worker 'The type T was declared as a const Required type in the returned Component, however', 326*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 327*a65addddSAndroid Build Coastguard Worker source, 328*a65addddSAndroid Build Coastguard Worker locals()) 329*a65addddSAndroid Build Coastguard Worker 330*a65addddSAndroid Build Coastguard Worker def test_install_with_args_success(self): 331*a65addddSAndroid Build Coastguard Worker source = ''' 332*a65addddSAndroid Build Coastguard Worker struct X { 333*a65addddSAndroid Build Coastguard Worker int n; 334*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 335*a65addddSAndroid Build Coastguard Worker }; 336*a65addddSAndroid Build Coastguard Worker 337*a65addddSAndroid Build Coastguard Worker struct Arg { 338*a65addddSAndroid Build Coastguard Worker Arg(int) {} 339*a65addddSAndroid Build Coastguard Worker Arg() = default; 340*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 341*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 342*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 343*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 344*a65addddSAndroid Build Coastguard Worker }; 345*a65addddSAndroid Build Coastguard Worker 346*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&) { 347*a65addddSAndroid Build Coastguard Worker return true; 348*a65addddSAndroid Build Coastguard Worker } 349*a65addddSAndroid Build Coastguard Worker 350*a65addddSAndroid Build Coastguard Worker namespace std { 351*a65addddSAndroid Build Coastguard Worker template <> 352*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 353*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&) { 354*a65addddSAndroid Build Coastguard Worker return 0; 355*a65addddSAndroid Build Coastguard Worker } 356*a65addddSAndroid Build Coastguard Worker }; 357*a65addddSAndroid Build Coastguard Worker } 358*a65addddSAndroid Build Coastguard Worker 359*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg, Arg) { 360*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 361*a65addddSAndroid Build Coastguard Worker .registerProvider([]() { return X(5); }); 362*a65addddSAndroid Build Coastguard Worker } 363*a65addddSAndroid Build Coastguard Worker 364*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 365*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 366*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), Arg{}, 15); 367*a65addddSAndroid Build Coastguard Worker } 368*a65addddSAndroid Build Coastguard Worker 369*a65addddSAndroid Build Coastguard Worker int main() { 370*a65addddSAndroid Build Coastguard Worker fruit::Injector<X> injector(getComponent); 371*a65addddSAndroid Build Coastguard Worker X x = injector.get<X>(); 372*a65addddSAndroid Build Coastguard Worker Assert(x.n == 5); 373*a65addddSAndroid Build Coastguard Worker } 374*a65addddSAndroid Build Coastguard Worker ''' 375*a65addddSAndroid Build Coastguard Worker expect_success(COMMON_DEFINITIONS, source) 376*a65addddSAndroid Build Coastguard Worker 377*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_move_constructible(self): 378*a65addddSAndroid Build Coastguard Worker source = ''' 379*a65addddSAndroid Build Coastguard Worker struct Arg { 380*a65addddSAndroid Build Coastguard Worker Arg() = default; 381*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 382*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = delete; 383*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 384*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 385*a65addddSAndroid Build Coastguard Worker }; 386*a65addddSAndroid Build Coastguard Worker 387*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 388*a65addddSAndroid Build Coastguard Worker 389*a65addddSAndroid Build Coastguard Worker namespace std { 390*a65addddSAndroid Build Coastguard Worker template <> 391*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 392*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 393*a65addddSAndroid Build Coastguard Worker }; 394*a65addddSAndroid Build Coastguard Worker } 395*a65addddSAndroid Build Coastguard Worker 396*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 397*a65addddSAndroid Build Coastguard Worker 398*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 399*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 400*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), Arg{}); 401*a65addddSAndroid Build Coastguard Worker } 402*a65addddSAndroid Build Coastguard Worker ''' 403*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 404*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .Arg::Arg\(Arg&&\).' 405*a65addddSAndroid Build Coastguard Worker r'|error: call to deleted constructor of .Arg.' 406*a65addddSAndroid Build Coastguard Worker r'|.Arg::Arg\(const Arg &\).: cannot convert argument 1 from .std::_Tuple_val<Arg>. to .const Arg &.' 407*a65addddSAndroid Build Coastguard Worker r'|.Arg::Arg\(Arg &&\).: cannot convert argument 1 from .std::_Tuple_val<Arg>. to .const Arg &.', 408*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 409*a65addddSAndroid Build Coastguard Worker source) 410*a65addddSAndroid Build Coastguard Worker 411*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_move_constructible_with_conversion(self): 412*a65addddSAndroid Build Coastguard Worker source = ''' 413*a65addddSAndroid Build Coastguard Worker struct Arg { 414*a65addddSAndroid Build Coastguard Worker Arg(int) {} 415*a65addddSAndroid Build Coastguard Worker Arg() = default; 416*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 417*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = delete; 418*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 419*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 420*a65addddSAndroid Build Coastguard Worker }; 421*a65addddSAndroid Build Coastguard Worker 422*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 423*a65addddSAndroid Build Coastguard Worker 424*a65addddSAndroid Build Coastguard Worker namespace std { 425*a65addddSAndroid Build Coastguard Worker template <> 426*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 427*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 428*a65addddSAndroid Build Coastguard Worker }; 429*a65addddSAndroid Build Coastguard Worker } 430*a65addddSAndroid Build Coastguard Worker 431*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 432*a65addddSAndroid Build Coastguard Worker 433*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 434*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 435*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), 15); 436*a65addddSAndroid Build Coastguard Worker } 437*a65addddSAndroid Build Coastguard Worker ''' 438*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 439*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .Arg::Arg\(Arg&&\).' 440*a65addddSAndroid Build Coastguard Worker r'|error: call to deleted constructor of .Arg.' 441*a65addddSAndroid Build Coastguard Worker r'|.Arg::Arg\((int|Arg &&)\).: cannot convert argument 1 from .std::_Tuple_val<Arg>. to .int.', 442*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 443*a65addddSAndroid Build Coastguard Worker source) 444*a65addddSAndroid Build Coastguard Worker 445*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_copy_constructible(self): 446*a65addddSAndroid Build Coastguard Worker source = ''' 447*a65addddSAndroid Build Coastguard Worker struct X { 448*a65addddSAndroid Build Coastguard Worker int n; 449*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 450*a65addddSAndroid Build Coastguard Worker }; 451*a65addddSAndroid Build Coastguard Worker 452*a65addddSAndroid Build Coastguard Worker struct Arg { 453*a65addddSAndroid Build Coastguard Worker Arg() = default; 454*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = delete; 455*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 456*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 457*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 458*a65addddSAndroid Build Coastguard Worker }; 459*a65addddSAndroid Build Coastguard Worker 460*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 461*a65addddSAndroid Build Coastguard Worker 462*a65addddSAndroid Build Coastguard Worker namespace std { 463*a65addddSAndroid Build Coastguard Worker template <> 464*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 465*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 466*a65addddSAndroid Build Coastguard Worker }; 467*a65addddSAndroid Build Coastguard Worker } 468*a65addddSAndroid Build Coastguard Worker 469*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 470*a65addddSAndroid Build Coastguard Worker 471*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 472*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 473*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), Arg{}); 474*a65addddSAndroid Build Coastguard Worker } 475*a65addddSAndroid Build Coastguard Worker ''' 476*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 477*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .Arg::Arg\(const Arg&\).' 478*a65addddSAndroid Build Coastguard Worker r'|error: call to deleted constructor of .Arg.' 479*a65addddSAndroid Build Coastguard Worker r'|error C2280: .Arg::Arg\(const Arg &\).: attempting to reference a deleted function', 480*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 481*a65addddSAndroid Build Coastguard Worker source) 482*a65addddSAndroid Build Coastguard Worker 483*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_copy_constructible_with_conversion(self): 484*a65addddSAndroid Build Coastguard Worker source = ''' 485*a65addddSAndroid Build Coastguard Worker struct X { 486*a65addddSAndroid Build Coastguard Worker int n; 487*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 488*a65addddSAndroid Build Coastguard Worker }; 489*a65addddSAndroid Build Coastguard Worker 490*a65addddSAndroid Build Coastguard Worker struct Arg { 491*a65addddSAndroid Build Coastguard Worker Arg(int) {} 492*a65addddSAndroid Build Coastguard Worker Arg() = default; 493*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = delete; 494*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 495*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 496*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 497*a65addddSAndroid Build Coastguard Worker }; 498*a65addddSAndroid Build Coastguard Worker 499*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 500*a65addddSAndroid Build Coastguard Worker 501*a65addddSAndroid Build Coastguard Worker namespace std { 502*a65addddSAndroid Build Coastguard Worker template <> 503*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 504*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 505*a65addddSAndroid Build Coastguard Worker }; 506*a65addddSAndroid Build Coastguard Worker } 507*a65addddSAndroid Build Coastguard Worker 508*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 509*a65addddSAndroid Build Coastguard Worker 510*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 511*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 512*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), 15); 513*a65addddSAndroid Build Coastguard Worker } 514*a65addddSAndroid Build Coastguard Worker ''' 515*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 516*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .Arg::Arg\(const Arg&\).' 517*a65addddSAndroid Build Coastguard Worker r'|error: call to deleted constructor of .Arg.' 518*a65addddSAndroid Build Coastguard Worker r'|error C2280: .Arg::Arg\(const Arg &\).: attempting to reference a deleted function', 519*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 520*a65addddSAndroid Build Coastguard Worker source) 521*a65addddSAndroid Build Coastguard Worker 522*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_move_assignable(self): 523*a65addddSAndroid Build Coastguard Worker source = ''' 524*a65addddSAndroid Build Coastguard Worker struct Arg { 525*a65addddSAndroid Build Coastguard Worker Arg() = default; 526*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 527*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 528*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 529*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = delete; 530*a65addddSAndroid Build Coastguard Worker }; 531*a65addddSAndroid Build Coastguard Worker 532*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 533*a65addddSAndroid Build Coastguard Worker 534*a65addddSAndroid Build Coastguard Worker namespace std { 535*a65addddSAndroid Build Coastguard Worker template <> 536*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 537*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 538*a65addddSAndroid Build Coastguard Worker }; 539*a65addddSAndroid Build Coastguard Worker } 540*a65addddSAndroid Build Coastguard Worker 541*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 542*a65addddSAndroid Build Coastguard Worker 543*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 544*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 545*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), Arg{}); 546*a65addddSAndroid Build Coastguard Worker } 547*a65addddSAndroid Build Coastguard Worker ''' 548*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 549*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .Arg& Arg::operator=\(Arg&&\).' 550*a65addddSAndroid Build Coastguard Worker r'|error: overload resolution selected deleted operator .=.' 551*a65addddSAndroid Build Coastguard Worker r'|error C2280: .Arg &Arg::operator =\(Arg &&\).: attempting to reference a deleted function', 552*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 553*a65addddSAndroid Build Coastguard Worker source) 554*a65addddSAndroid Build Coastguard Worker 555*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_move_assignable_with_conversion(self): 556*a65addddSAndroid Build Coastguard Worker source = ''' 557*a65addddSAndroid Build Coastguard Worker struct Arg { 558*a65addddSAndroid Build Coastguard Worker Arg(int) {} 559*a65addddSAndroid Build Coastguard Worker Arg() = default; 560*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 561*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 562*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 563*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = delete; 564*a65addddSAndroid Build Coastguard Worker }; 565*a65addddSAndroid Build Coastguard Worker 566*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 567*a65addddSAndroid Build Coastguard Worker 568*a65addddSAndroid Build Coastguard Worker namespace std { 569*a65addddSAndroid Build Coastguard Worker template <> 570*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 571*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 572*a65addddSAndroid Build Coastguard Worker }; 573*a65addddSAndroid Build Coastguard Worker } 574*a65addddSAndroid Build Coastguard Worker 575*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 576*a65addddSAndroid Build Coastguard Worker 577*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 578*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 579*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), 15); 580*a65addddSAndroid Build Coastguard Worker } 581*a65addddSAndroid Build Coastguard Worker ''' 582*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 583*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .Arg& Arg::operator=\(Arg&&\).' 584*a65addddSAndroid Build Coastguard Worker r'|error: overload resolution selected deleted operator .=.' 585*a65addddSAndroid Build Coastguard Worker r'|error C2280: .Arg &Arg::operator =\(Arg &&\).: attempting to reference a deleted function', 586*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 587*a65addddSAndroid Build Coastguard Worker source) 588*a65addddSAndroid Build Coastguard Worker 589*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_copy_assignable(self): 590*a65addddSAndroid Build Coastguard Worker source = ''' 591*a65addddSAndroid Build Coastguard Worker struct X { 592*a65addddSAndroid Build Coastguard Worker int n; 593*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 594*a65addddSAndroid Build Coastguard Worker }; 595*a65addddSAndroid Build Coastguard Worker 596*a65addddSAndroid Build Coastguard Worker struct Arg { 597*a65addddSAndroid Build Coastguard Worker Arg() = default; 598*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 599*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 600*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = delete; 601*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 602*a65addddSAndroid Build Coastguard Worker }; 603*a65addddSAndroid Build Coastguard Worker 604*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 605*a65addddSAndroid Build Coastguard Worker 606*a65addddSAndroid Build Coastguard Worker namespace std { 607*a65addddSAndroid Build Coastguard Worker template <> 608*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 609*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 610*a65addddSAndroid Build Coastguard Worker }; 611*a65addddSAndroid Build Coastguard Worker } 612*a65addddSAndroid Build Coastguard Worker 613*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 614*a65addddSAndroid Build Coastguard Worker 615*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 616*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 617*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), Arg{}); 618*a65addddSAndroid Build Coastguard Worker } 619*a65addddSAndroid Build Coastguard Worker ''' 620*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 621*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .Arg& Arg::operator=\(const Arg&\).' 622*a65addddSAndroid Build Coastguard Worker r'|error: overload resolution selected deleted operator .=.' 623*a65addddSAndroid Build Coastguard Worker r'|error C2280: .Arg &Arg::operator =\(const Arg &\).: attempting to reference a deleted function', 624*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 625*a65addddSAndroid Build Coastguard Worker source) 626*a65addddSAndroid Build Coastguard Worker 627*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_copy_assignable_with_conversion(self): 628*a65addddSAndroid Build Coastguard Worker source = ''' 629*a65addddSAndroid Build Coastguard Worker struct X { 630*a65addddSAndroid Build Coastguard Worker int n; 631*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 632*a65addddSAndroid Build Coastguard Worker }; 633*a65addddSAndroid Build Coastguard Worker 634*a65addddSAndroid Build Coastguard Worker struct Arg { 635*a65addddSAndroid Build Coastguard Worker Arg(int) {} 636*a65addddSAndroid Build Coastguard Worker Arg() = default; 637*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 638*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 639*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = delete; 640*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 641*a65addddSAndroid Build Coastguard Worker }; 642*a65addddSAndroid Build Coastguard Worker 643*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 644*a65addddSAndroid Build Coastguard Worker 645*a65addddSAndroid Build Coastguard Worker namespace std { 646*a65addddSAndroid Build Coastguard Worker template <> 647*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 648*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 649*a65addddSAndroid Build Coastguard Worker }; 650*a65addddSAndroid Build Coastguard Worker } 651*a65addddSAndroid Build Coastguard Worker 652*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 653*a65addddSAndroid Build Coastguard Worker 654*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 655*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 656*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), 15); 657*a65addddSAndroid Build Coastguard Worker } 658*a65addddSAndroid Build Coastguard Worker ''' 659*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 660*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .Arg& Arg::operator=\(const Arg&\).' 661*a65addddSAndroid Build Coastguard Worker r'|error: overload resolution selected deleted operator .=.' 662*a65addddSAndroid Build Coastguard Worker r'|error C2280: .Arg &Arg::operator =\(const Arg &\).: attempting to reference a deleted function', 663*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 664*a65addddSAndroid Build Coastguard Worker source) 665*a65addddSAndroid Build Coastguard Worker 666*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_equality_comparable(self): 667*a65addddSAndroid Build Coastguard Worker source = ''' 668*a65addddSAndroid Build Coastguard Worker struct X { 669*a65addddSAndroid Build Coastguard Worker int n; 670*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 671*a65addddSAndroid Build Coastguard Worker }; 672*a65addddSAndroid Build Coastguard Worker 673*a65addddSAndroid Build Coastguard Worker struct Arg { 674*a65addddSAndroid Build Coastguard Worker Arg() = default; 675*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 676*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 677*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 678*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 679*a65addddSAndroid Build Coastguard Worker }; 680*a65addddSAndroid Build Coastguard Worker 681*a65addddSAndroid Build Coastguard Worker namespace std { 682*a65addddSAndroid Build Coastguard Worker template <> 683*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 684*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 685*a65addddSAndroid Build Coastguard Worker }; 686*a65addddSAndroid Build Coastguard Worker } 687*a65addddSAndroid Build Coastguard Worker 688*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 689*a65addddSAndroid Build Coastguard Worker 690*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 691*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 692*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), Arg{}); 693*a65addddSAndroid Build Coastguard Worker } 694*a65addddSAndroid Build Coastguard Worker ''' 695*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 696*a65addddSAndroid Build Coastguard Worker r'error: no match for .operator==. \(operand types are .const Arg. and .const Arg.\)' 697*a65addddSAndroid Build Coastguard Worker r'|error: invalid operands to binary expression \(.const Arg. and .const Arg.\)' 698*a65addddSAndroid Build Coastguard Worker r'|error C2676: binary .==.: .const Arg. does not define this operator', 699*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 700*a65addddSAndroid Build Coastguard Worker source) 701*a65addddSAndroid Build Coastguard Worker 702*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_equality_comparable_with_conversion(self): 703*a65addddSAndroid Build Coastguard Worker source = ''' 704*a65addddSAndroid Build Coastguard Worker struct X { 705*a65addddSAndroid Build Coastguard Worker int n; 706*a65addddSAndroid Build Coastguard Worker X(int n) : n(n) {} 707*a65addddSAndroid Build Coastguard Worker }; 708*a65addddSAndroid Build Coastguard Worker 709*a65addddSAndroid Build Coastguard Worker struct Arg { 710*a65addddSAndroid Build Coastguard Worker Arg(int) {} 711*a65addddSAndroid Build Coastguard Worker Arg() = default; 712*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 713*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 714*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 715*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 716*a65addddSAndroid Build Coastguard Worker }; 717*a65addddSAndroid Build Coastguard Worker 718*a65addddSAndroid Build Coastguard Worker namespace std { 719*a65addddSAndroid Build Coastguard Worker template <> 720*a65addddSAndroid Build Coastguard Worker struct hash<Arg> { 721*a65addddSAndroid Build Coastguard Worker size_t operator()(const Arg&); 722*a65addddSAndroid Build Coastguard Worker }; 723*a65addddSAndroid Build Coastguard Worker } 724*a65addddSAndroid Build Coastguard Worker 725*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 726*a65addddSAndroid Build Coastguard Worker 727*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 728*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 729*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), 15); 730*a65addddSAndroid Build Coastguard Worker } 731*a65addddSAndroid Build Coastguard Worker ''' 732*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 733*a65addddSAndroid Build Coastguard Worker r'error: no match for .operator==. \(operand types are .const Arg. and .const Arg.\)' 734*a65addddSAndroid Build Coastguard Worker r'|error: invalid operands to binary expression \(.const Arg. and .const Arg.\)' 735*a65addddSAndroid Build Coastguard Worker r'|error C2676: binary .==.: .const Arg. does not define this operator', 736*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 737*a65addddSAndroid Build Coastguard Worker source) 738*a65addddSAndroid Build Coastguard Worker 739*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_hashable(self): 740*a65addddSAndroid Build Coastguard Worker source = ''' 741*a65addddSAndroid Build Coastguard Worker struct Arg { 742*a65addddSAndroid Build Coastguard Worker Arg() = default; 743*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 744*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 745*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 746*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 747*a65addddSAndroid Build Coastguard Worker }; 748*a65addddSAndroid Build Coastguard Worker 749*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 750*a65addddSAndroid Build Coastguard Worker 751*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 752*a65addddSAndroid Build Coastguard Worker 753*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 754*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 755*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), Arg{}); 756*a65addddSAndroid Build Coastguard Worker } 757*a65addddSAndroid Build Coastguard Worker ''' 758*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 759*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .std::hash<Arg>::hash\(\).' 760*a65addddSAndroid Build Coastguard Worker r'|error: call to implicitly-deleted default constructor of .std::hash<Arg>.' 761*a65addddSAndroid Build Coastguard Worker r'|error: invalid use of incomplete type .struct std::hash<Arg>.' 762*a65addddSAndroid Build Coastguard Worker r'|error: implicit instantiation of undefined template .std::(__1::)?hash<Arg>.' 763*a65addddSAndroid Build Coastguard Worker r'|error C2338: The C\+\+ Standard doesn.t provide a hash for this type.' 764*a65addddSAndroid Build Coastguard Worker r'|error C2064: term does not evaluate to a function taking 1 arguments', 765*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 766*a65addddSAndroid Build Coastguard Worker source) 767*a65addddSAndroid Build Coastguard Worker 768*a65addddSAndroid Build Coastguard Worker def test_install_with_args_error_not_hashable_with_conversion(self): 769*a65addddSAndroid Build Coastguard Worker source = ''' 770*a65addddSAndroid Build Coastguard Worker struct Arg { 771*a65addddSAndroid Build Coastguard Worker Arg(int) {} 772*a65addddSAndroid Build Coastguard Worker Arg() = default; 773*a65addddSAndroid Build Coastguard Worker Arg(const Arg&) = default; 774*a65addddSAndroid Build Coastguard Worker Arg(Arg&&) = default; 775*a65addddSAndroid Build Coastguard Worker Arg& operator=(const Arg&) = default; 776*a65addddSAndroid Build Coastguard Worker Arg& operator=(Arg&&) = default; 777*a65addddSAndroid Build Coastguard Worker }; 778*a65addddSAndroid Build Coastguard Worker 779*a65addddSAndroid Build Coastguard Worker bool operator==(const Arg&, const Arg&); 780*a65addddSAndroid Build Coastguard Worker 781*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getParentComponent(int, std::string, Arg); 782*a65addddSAndroid Build Coastguard Worker 783*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 784*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 785*a65addddSAndroid Build Coastguard Worker .install(getParentComponent, 5, std::string("Hello"), 15); 786*a65addddSAndroid Build Coastguard Worker } 787*a65addddSAndroid Build Coastguard Worker ''' 788*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 789*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .std::hash<Arg>::hash\(\).' 790*a65addddSAndroid Build Coastguard Worker r'|error: call to implicitly-deleted default constructor of .std::hash<Arg>.' 791*a65addddSAndroid Build Coastguard Worker r'|error: invalid use of incomplete type .struct std::hash<Arg>.' 792*a65addddSAndroid Build Coastguard Worker r'|error: implicit instantiation of undefined template .std::(__1::)?hash<Arg>.' 793*a65addddSAndroid Build Coastguard Worker r'|error C2338: The C\+\+ Standard doesn.t provide a hash for this type.' 794*a65addddSAndroid Build Coastguard Worker r'|error C2064: term does not evaluate to a function taking 1 arguments', 795*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 796*a65addddSAndroid Build Coastguard Worker source) 797*a65addddSAndroid Build Coastguard Worker 798*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 799*a65addddSAndroid Build Coastguard Worker 'X', 800*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 801*a65addddSAndroid Build Coastguard Worker ]) 802*a65addddSAndroid Build Coastguard Worker def test_install_component_functions_deduped(self, XAnnot): 803*a65addddSAndroid Build Coastguard Worker source = ''' 804*a65addddSAndroid Build Coastguard Worker struct X {}; 805*a65addddSAndroid Build Coastguard Worker 806*a65addddSAndroid Build Coastguard Worker X x; 807*a65addddSAndroid Build Coastguard Worker 808*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 809*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 810*a65addddSAndroid Build Coastguard Worker .addInstanceMultibinding<XAnnot, X>(x); 811*a65addddSAndroid Build Coastguard Worker } 812*a65addddSAndroid Build Coastguard Worker 813*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent2() { 814*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 815*a65addddSAndroid Build Coastguard Worker .install(getComponent); 816*a65addddSAndroid Build Coastguard Worker } 817*a65addddSAndroid Build Coastguard Worker 818*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent3() { 819*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 820*a65addddSAndroid Build Coastguard Worker .install(getComponent); 821*a65addddSAndroid Build Coastguard Worker } 822*a65addddSAndroid Build Coastguard Worker 823*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent4() { 824*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 825*a65addddSAndroid Build Coastguard Worker .install(getComponent2) 826*a65addddSAndroid Build Coastguard Worker .install(getComponent3); 827*a65addddSAndroid Build Coastguard Worker } 828*a65addddSAndroid Build Coastguard Worker 829*a65addddSAndroid Build Coastguard Worker int main() { 830*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent4); 831*a65addddSAndroid Build Coastguard Worker 832*a65addddSAndroid Build Coastguard Worker // We test multibindings because the effect on other bindings is not user-visible (that only affects 833*a65addddSAndroid Build Coastguard Worker // performance). 834*a65addddSAndroid Build Coastguard Worker std::vector<X*> multibindings = injector.getMultibindings<XAnnot>(); 835*a65addddSAndroid Build Coastguard Worker Assert(multibindings.size() == 1); 836*a65addddSAndroid Build Coastguard Worker Assert(multibindings[0] == &x); 837*a65addddSAndroid Build Coastguard Worker } 838*a65addddSAndroid Build Coastguard Worker ''' 839*a65addddSAndroid Build Coastguard Worker expect_success( 840*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 841*a65addddSAndroid Build Coastguard Worker source, 842*a65addddSAndroid Build Coastguard Worker locals()) 843*a65addddSAndroid Build Coastguard Worker 844*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 845*a65addddSAndroid Build Coastguard Worker 'X', 846*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 847*a65addddSAndroid Build Coastguard Worker ]) 848*a65addddSAndroid Build Coastguard Worker def test_install_component_functions_deduped_across_normalized_component(self, XAnnot): 849*a65addddSAndroid Build Coastguard Worker source = ''' 850*a65addddSAndroid Build Coastguard Worker struct X {}; 851*a65addddSAndroid Build Coastguard Worker 852*a65addddSAndroid Build Coastguard Worker X x; 853*a65addddSAndroid Build Coastguard Worker 854*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 855*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 856*a65addddSAndroid Build Coastguard Worker .addInstanceMultibinding<XAnnot, X>(x); 857*a65addddSAndroid Build Coastguard Worker } 858*a65addddSAndroid Build Coastguard Worker 859*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent2() { 860*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 861*a65addddSAndroid Build Coastguard Worker .install(getComponent); 862*a65addddSAndroid Build Coastguard Worker } 863*a65addddSAndroid Build Coastguard Worker 864*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent3() { 865*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 866*a65addddSAndroid Build Coastguard Worker .install(getComponent); 867*a65addddSAndroid Build Coastguard Worker } 868*a65addddSAndroid Build Coastguard Worker 869*a65addddSAndroid Build Coastguard Worker int main() { 870*a65addddSAndroid Build Coastguard Worker fruit::NormalizedComponent<> normalizedComponent(getComponent2); 871*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(normalizedComponent, getComponent3); 872*a65addddSAndroid Build Coastguard Worker 873*a65addddSAndroid Build Coastguard Worker // We test multibindings because the effect on other bindings is not user-visible (that only affects 874*a65addddSAndroid Build Coastguard Worker // performance). 875*a65addddSAndroid Build Coastguard Worker std::vector<X*> multibindings = injector.getMultibindings<XAnnot>(); 876*a65addddSAndroid Build Coastguard Worker Assert(multibindings.size() == 1); 877*a65addddSAndroid Build Coastguard Worker Assert(multibindings[0] == &x); 878*a65addddSAndroid Build Coastguard Worker } 879*a65addddSAndroid Build Coastguard Worker ''' 880*a65addddSAndroid Build Coastguard Worker expect_success( 881*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 882*a65addddSAndroid Build Coastguard Worker source, 883*a65addddSAndroid Build Coastguard Worker locals()) 884*a65addddSAndroid Build Coastguard Worker 885*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 886*a65addddSAndroid Build Coastguard Worker 'X', 887*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 888*a65addddSAndroid Build Coastguard Worker ]) 889*a65addddSAndroid Build Coastguard Worker def test_install_component_functions_with_args_deduped(self, XAnnot): 890*a65addddSAndroid Build Coastguard Worker source = ''' 891*a65addddSAndroid Build Coastguard Worker struct X {}; 892*a65addddSAndroid Build Coastguard Worker 893*a65addddSAndroid Build Coastguard Worker X x; 894*a65addddSAndroid Build Coastguard Worker 895*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(int) { 896*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 897*a65addddSAndroid Build Coastguard Worker .addInstanceMultibinding<XAnnot, X>(x); 898*a65addddSAndroid Build Coastguard Worker } 899*a65addddSAndroid Build Coastguard Worker 900*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent2() { 901*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 902*a65addddSAndroid Build Coastguard Worker .install(getComponent, 1); 903*a65addddSAndroid Build Coastguard Worker } 904*a65addddSAndroid Build Coastguard Worker 905*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent3() { 906*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 907*a65addddSAndroid Build Coastguard Worker .install(getComponent, 1); 908*a65addddSAndroid Build Coastguard Worker } 909*a65addddSAndroid Build Coastguard Worker 910*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent4() { 911*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 912*a65addddSAndroid Build Coastguard Worker .install(getComponent2) 913*a65addddSAndroid Build Coastguard Worker .install(getComponent3); 914*a65addddSAndroid Build Coastguard Worker } 915*a65addddSAndroid Build Coastguard Worker 916*a65addddSAndroid Build Coastguard Worker int main() { 917*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent4); 918*a65addddSAndroid Build Coastguard Worker 919*a65addddSAndroid Build Coastguard Worker // We test multibindings because the effect on other bindings is not user-visible (that only affects 920*a65addddSAndroid Build Coastguard Worker // performance). 921*a65addddSAndroid Build Coastguard Worker std::vector<X*> multibindings = injector.getMultibindings<XAnnot>(); 922*a65addddSAndroid Build Coastguard Worker Assert(multibindings.size() == 1); 923*a65addddSAndroid Build Coastguard Worker Assert(multibindings[0] == &x); 924*a65addddSAndroid Build Coastguard Worker } 925*a65addddSAndroid Build Coastguard Worker ''' 926*a65addddSAndroid Build Coastguard Worker expect_success( 927*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 928*a65addddSAndroid Build Coastguard Worker source, 929*a65addddSAndroid Build Coastguard Worker locals()) 930*a65addddSAndroid Build Coastguard Worker 931*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 932*a65addddSAndroid Build Coastguard Worker 'X', 933*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 934*a65addddSAndroid Build Coastguard Worker ]) 935*a65addddSAndroid Build Coastguard Worker def test_install_component_functions_different_args_not_deduped(self, XAnnot): 936*a65addddSAndroid Build Coastguard Worker source = ''' 937*a65addddSAndroid Build Coastguard Worker struct X {}; 938*a65addddSAndroid Build Coastguard Worker 939*a65addddSAndroid Build Coastguard Worker X x; 940*a65addddSAndroid Build Coastguard Worker 941*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(int) { 942*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 943*a65addddSAndroid Build Coastguard Worker .addInstanceMultibinding<XAnnot, X>(x); 944*a65addddSAndroid Build Coastguard Worker } 945*a65addddSAndroid Build Coastguard Worker 946*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent2() { 947*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 948*a65addddSAndroid Build Coastguard Worker .install(getComponent, 1); 949*a65addddSAndroid Build Coastguard Worker } 950*a65addddSAndroid Build Coastguard Worker 951*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent3() { 952*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 953*a65addddSAndroid Build Coastguard Worker .install(getComponent, 2); 954*a65addddSAndroid Build Coastguard Worker } 955*a65addddSAndroid Build Coastguard Worker 956*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent4() { 957*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 958*a65addddSAndroid Build Coastguard Worker .install(getComponent2) 959*a65addddSAndroid Build Coastguard Worker .install(getComponent3); 960*a65addddSAndroid Build Coastguard Worker } 961*a65addddSAndroid Build Coastguard Worker 962*a65addddSAndroid Build Coastguard Worker int main() { 963*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent4); 964*a65addddSAndroid Build Coastguard Worker 965*a65addddSAndroid Build Coastguard Worker // We test multibindings because the effect on other bindings is not user-visible (it only affects 966*a65addddSAndroid Build Coastguard Worker // performance). 967*a65addddSAndroid Build Coastguard Worker std::vector<X*> multibindings = injector.getMultibindings<XAnnot>(); 968*a65addddSAndroid Build Coastguard Worker Assert(multibindings.size() == 2); 969*a65addddSAndroid Build Coastguard Worker Assert(multibindings[0] == &x); 970*a65addddSAndroid Build Coastguard Worker Assert(multibindings[1] == &x); 971*a65addddSAndroid Build Coastguard Worker } 972*a65addddSAndroid Build Coastguard Worker ''' 973*a65addddSAndroid Build Coastguard Worker expect_success( 974*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 975*a65addddSAndroid Build Coastguard Worker source, 976*a65addddSAndroid Build Coastguard Worker locals()) 977*a65addddSAndroid Build Coastguard Worker 978*a65addddSAndroid Build Coastguard Worker def test_install_component_functions_loop(self): 979*a65addddSAndroid Build Coastguard Worker source = ''' 980*a65addddSAndroid Build Coastguard Worker struct X {}; 981*a65addddSAndroid Build Coastguard Worker struct Y {}; 982*a65addddSAndroid Build Coastguard Worker struct Z {}; 983*a65addddSAndroid Build Coastguard Worker 984*a65addddSAndroid Build Coastguard Worker // X -> Y -> Z -> Y 985*a65addddSAndroid Build Coastguard Worker 986*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getXComponent(); 987*a65addddSAndroid Build Coastguard Worker fruit::Component<Y> getYComponent(); 988*a65addddSAndroid Build Coastguard Worker fruit::Component<Z> getZComponent(); 989*a65addddSAndroid Build Coastguard Worker 990*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getXComponent() { 991*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 992*a65addddSAndroid Build Coastguard Worker .registerConstructor<X()>() 993*a65addddSAndroid Build Coastguard Worker .install(getYComponent); 994*a65addddSAndroid Build Coastguard Worker } 995*a65addddSAndroid Build Coastguard Worker 996*a65addddSAndroid Build Coastguard Worker fruit::Component<Y> getYComponent() { 997*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 998*a65addddSAndroid Build Coastguard Worker .registerConstructor<Y()>() 999*a65addddSAndroid Build Coastguard Worker .install(getZComponent); 1000*a65addddSAndroid Build Coastguard Worker } 1001*a65addddSAndroid Build Coastguard Worker 1002*a65addddSAndroid Build Coastguard Worker fruit::Component<Z> getZComponent() { 1003*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1004*a65addddSAndroid Build Coastguard Worker .registerConstructor<Z()>() 1005*a65addddSAndroid Build Coastguard Worker .install(getYComponent); 1006*a65addddSAndroid Build Coastguard Worker } 1007*a65addddSAndroid Build Coastguard Worker 1008*a65addddSAndroid Build Coastguard Worker int main() { 1009*a65addddSAndroid Build Coastguard Worker fruit::Injector<X> injector(getXComponent); 1010*a65addddSAndroid Build Coastguard Worker (void)injector; 1011*a65addddSAndroid Build Coastguard Worker } 1012*a65addddSAndroid Build Coastguard Worker ''' 1013*a65addddSAndroid Build Coastguard Worker expect_runtime_error( 1014*a65addddSAndroid Build Coastguard Worker r'Component installation trace \(from top-level to the most deeply-nested\):\n' 1015*a65addddSAndroid Build Coastguard Worker r'(class )?fruit::Component<(struct )?X> ?\((__cdecl)?\*\)\((void)?\)\n' 1016*a65addddSAndroid Build Coastguard Worker r'<-- The loop starts here\n' 1017*a65addddSAndroid Build Coastguard Worker r'(class )?fruit::Component<(struct )?Y> ?\((__cdecl)?\*\)\((void)?\)\n' 1018*a65addddSAndroid Build Coastguard Worker r'(class )?fruit::Component<(struct )?Z> ?\((__cdecl)?\*\)\((void)?\)\n' 1019*a65addddSAndroid Build Coastguard Worker r'(class )?fruit::Component<(struct )?Y> ?\((__cdecl)?\*\)\((void)?\)\n', 1020*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1021*a65addddSAndroid Build Coastguard Worker source, 1022*a65addddSAndroid Build Coastguard Worker locals()) 1023*a65addddSAndroid Build Coastguard Worker 1024*a65addddSAndroid Build Coastguard Worker def test_install_component_functions_different_arguments_loop_not_reported(self): 1025*a65addddSAndroid Build Coastguard Worker source = ''' 1026*a65addddSAndroid Build Coastguard Worker struct X {}; 1027*a65addddSAndroid Build Coastguard Worker struct Y {}; 1028*a65addddSAndroid Build Coastguard Worker struct Z {}; 1029*a65addddSAndroid Build Coastguard Worker 1030*a65addddSAndroid Build Coastguard Worker // X -> Y(1) -> Z -> Y(2) 1031*a65addddSAndroid Build Coastguard Worker 1032*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getXComponent(); 1033*a65addddSAndroid Build Coastguard Worker fruit::Component<Y> getYComponent(int); 1034*a65addddSAndroid Build Coastguard Worker fruit::Component<Z> getZComponent(); 1035*a65addddSAndroid Build Coastguard Worker 1036*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getXComponent() { 1037*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1038*a65addddSAndroid Build Coastguard Worker .registerConstructor<X()>() 1039*a65addddSAndroid Build Coastguard Worker .install(getYComponent, 1); 1040*a65addddSAndroid Build Coastguard Worker } 1041*a65addddSAndroid Build Coastguard Worker 1042*a65addddSAndroid Build Coastguard Worker fruit::Component<Y> getYComponent(int n) { 1043*a65addddSAndroid Build Coastguard Worker if (n == 1) { 1044*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1045*a65addddSAndroid Build Coastguard Worker .registerConstructor<Y()>() 1046*a65addddSAndroid Build Coastguard Worker .install(getZComponent); 1047*a65addddSAndroid Build Coastguard Worker } else { 1048*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1049*a65addddSAndroid Build Coastguard Worker .registerConstructor<Y()>(); 1050*a65addddSAndroid Build Coastguard Worker } 1051*a65addddSAndroid Build Coastguard Worker } 1052*a65addddSAndroid Build Coastguard Worker 1053*a65addddSAndroid Build Coastguard Worker fruit::Component<Z> getZComponent() { 1054*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1055*a65addddSAndroid Build Coastguard Worker .registerConstructor<Z()>() 1056*a65addddSAndroid Build Coastguard Worker .install(getYComponent, 2); 1057*a65addddSAndroid Build Coastguard Worker } 1058*a65addddSAndroid Build Coastguard Worker 1059*a65addddSAndroid Build Coastguard Worker int main() { 1060*a65addddSAndroid Build Coastguard Worker fruit::Injector<X> injector(getXComponent); 1061*a65addddSAndroid Build Coastguard Worker injector.get<X>(); 1062*a65addddSAndroid Build Coastguard Worker } 1063*a65addddSAndroid Build Coastguard Worker ''' 1064*a65addddSAndroid Build Coastguard Worker expect_success( 1065*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1066*a65addddSAndroid Build Coastguard Worker source, 1067*a65addddSAndroid Build Coastguard Worker locals()) 1068*a65addddSAndroid Build Coastguard Worker 1069*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__': 1070*a65addddSAndroid Build Coastguard Worker absltest.main() 1071