1*a65addddSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*a65addddSAndroid Build Coastguard Worker# Copyright 2016 Google Inc. All Rights Reserved. 3*a65addddSAndroid Build Coastguard Worker# 4*a65addddSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*a65addddSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*a65addddSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*a65addddSAndroid Build Coastguard Worker# 8*a65addddSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*a65addddSAndroid Build Coastguard Worker# 10*a65addddSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*a65addddSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS-IS" BASIS, 12*a65addddSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*a65addddSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*a65addddSAndroid Build Coastguard Worker# limitations under the License. 15*a65addddSAndroid Build Coastguard Worker 16*a65addddSAndroid Build Coastguard Workerfrom absl.testing import parameterized 17*a65addddSAndroid Build Coastguard Workerfrom fruit_test_common import * 18*a65addddSAndroid Build Coastguard Worker 19*a65addddSAndroid Build Coastguard WorkerCOMMON_DEFINITIONS = ''' 20*a65addddSAndroid Build Coastguard Worker #include "test_common.h" 21*a65addddSAndroid Build Coastguard Worker 22*a65addddSAndroid Build Coastguard Worker struct Annotation1 {}; 23*a65addddSAndroid Build Coastguard Worker struct Annotation2 {}; 24*a65addddSAndroid Build Coastguard Worker 25*a65addddSAndroid Build Coastguard Worker template <typename T> 26*a65addddSAndroid Build Coastguard Worker using WithNoAnnot = T; 27*a65addddSAndroid Build Coastguard Worker 28*a65addddSAndroid Build Coastguard Worker template <typename T> 29*a65addddSAndroid Build Coastguard Worker using WithAnnot1 = fruit::Annotated<Annotation1, T>; 30*a65addddSAndroid Build Coastguard Worker ''' 31*a65addddSAndroid Build Coastguard Worker 32*a65addddSAndroid Build Coastguard Workerclass TestMultibindingsBindProvider(parameterized.TestCase): 33*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 34*a65addddSAndroid Build Coastguard Worker 'X()', 35*a65addddSAndroid Build Coastguard Worker 'new X()', 36*a65addddSAndroid Build Coastguard Worker ]) 37*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_success(self, ConstructX): 38*a65addddSAndroid Build Coastguard Worker source = ''' 39*a65addddSAndroid Build Coastguard Worker struct X : public ConstructionTracker<X> { 40*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 41*a65addddSAndroid Build Coastguard Worker }; 42*a65addddSAndroid Build Coastguard Worker 43*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 44*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 45*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider([](){return ConstructX;}); 46*a65addddSAndroid Build Coastguard Worker } 47*a65addddSAndroid Build Coastguard Worker 48*a65addddSAndroid Build Coastguard Worker int main() { 49*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent); 50*a65addddSAndroid Build Coastguard Worker 51*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 0); 52*a65addddSAndroid Build Coastguard Worker Assert(injector.getMultibindings<X>().size() == 1); 53*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 1); 54*a65addddSAndroid Build Coastguard Worker } 55*a65addddSAndroid Build Coastguard Worker ''' 56*a65addddSAndroid Build Coastguard Worker expect_success( 57*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 58*a65addddSAndroid Build Coastguard Worker source, 59*a65addddSAndroid Build Coastguard Worker locals()) 60*a65addddSAndroid Build Coastguard Worker 61*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 62*a65addddSAndroid Build Coastguard Worker 'WithNoAnnot', 63*a65addddSAndroid Build Coastguard Worker 'WithAnnot1', 64*a65addddSAndroid Build Coastguard Worker ]) 65*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_abstract_class_success(self, WithAnnot): 66*a65addddSAndroid Build Coastguard Worker source = ''' 67*a65addddSAndroid Build Coastguard Worker struct I { 68*a65addddSAndroid Build Coastguard Worker virtual int foo() = 0; 69*a65addddSAndroid Build Coastguard Worker virtual ~I() = default; 70*a65addddSAndroid Build Coastguard Worker }; 71*a65addddSAndroid Build Coastguard Worker 72*a65addddSAndroid Build Coastguard Worker struct X : public I { 73*a65addddSAndroid Build Coastguard Worker int foo() override { 74*a65addddSAndroid Build Coastguard Worker return 5; 75*a65addddSAndroid Build Coastguard Worker } 76*a65addddSAndroid Build Coastguard Worker }; 77*a65addddSAndroid Build Coastguard Worker 78*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 79*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 80*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<WithAnnot<I*>()>([](){return static_cast<I*>(new X());}); 81*a65addddSAndroid Build Coastguard Worker } 82*a65addddSAndroid Build Coastguard Worker 83*a65addddSAndroid Build Coastguard Worker int main() { 84*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent); 85*a65addddSAndroid Build Coastguard Worker 86*a65addddSAndroid Build Coastguard Worker Assert(injector.getMultibindings<WithAnnot<I>>().size() == 1); 87*a65addddSAndroid Build Coastguard Worker Assert(injector.getMultibindings<WithAnnot<I>>()[0]->foo() == 5); 88*a65addddSAndroid Build Coastguard Worker } 89*a65addddSAndroid Build Coastguard Worker ''' 90*a65addddSAndroid Build Coastguard Worker expect_success( 91*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 92*a65addddSAndroid Build Coastguard Worker source, 93*a65addddSAndroid Build Coastguard Worker locals()) 94*a65addddSAndroid Build Coastguard Worker 95*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 96*a65addddSAndroid Build Coastguard Worker 'WithNoAnnot', 97*a65addddSAndroid Build Coastguard Worker 'WithAnnot1', 98*a65addddSAndroid Build Coastguard Worker ]) 99*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_abstract_class_with_no_virtual_destructor_error(self, WithAnnot): 100*a65addddSAndroid Build Coastguard Worker source = ''' 101*a65addddSAndroid Build Coastguard Worker struct I { 102*a65addddSAndroid Build Coastguard Worker virtual int foo() = 0; 103*a65addddSAndroid Build Coastguard Worker }; 104*a65addddSAndroid Build Coastguard Worker 105*a65addddSAndroid Build Coastguard Worker struct X : public I { 106*a65addddSAndroid Build Coastguard Worker int foo() override { 107*a65addddSAndroid Build Coastguard Worker return 5; 108*a65addddSAndroid Build Coastguard Worker } 109*a65addddSAndroid Build Coastguard Worker }; 110*a65addddSAndroid Build Coastguard Worker 111*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 112*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 113*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<WithAnnot<I*>()>([](){return static_cast<I*>(new X());}); 114*a65addddSAndroid Build Coastguard Worker } 115*a65addddSAndroid Build Coastguard Worker ''' 116*a65addddSAndroid Build Coastguard Worker expect_compile_error( 117*a65addddSAndroid Build Coastguard Worker 'MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorError<I>', 118*a65addddSAndroid Build Coastguard Worker r'registerMultibindingProvider\(\) was called with a lambda that returns a pointer to T, but T is an abstract class with no virtual destructor', 119*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 120*a65addddSAndroid Build Coastguard Worker source, 121*a65addddSAndroid Build Coastguard Worker locals()) 122*a65addddSAndroid Build Coastguard Worker 123*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 124*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 125*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 126*a65addddSAndroid Build Coastguard Worker ], [ 127*a65addddSAndroid Build Coastguard Worker 'WithNoAnnot', 128*a65addddSAndroid Build Coastguard Worker 'WithAnnot1', 129*a65addddSAndroid Build Coastguard Worker ], [ 130*a65addddSAndroid Build Coastguard Worker 'Y', 131*a65addddSAndroid Build Coastguard Worker 'const Y', 132*a65addddSAndroid Build Coastguard Worker 'Y*', 133*a65addddSAndroid Build Coastguard Worker 'const Y*', 134*a65addddSAndroid Build Coastguard Worker 'Y&', 135*a65addddSAndroid Build Coastguard Worker 'const Y&', 136*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<Y>', 137*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<Y>', 138*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<const Y>', 139*a65addddSAndroid Build Coastguard Worker ]) 140*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_with_param_success(self, ConstructX, XPtr, WithAnnot, YVariant): 141*a65addddSAndroid Build Coastguard Worker source = ''' 142*a65addddSAndroid Build Coastguard Worker struct Y {}; 143*a65addddSAndroid Build Coastguard Worker 144*a65addddSAndroid Build Coastguard Worker struct X : public ConstructionTracker<X> {}; 145*a65addddSAndroid Build Coastguard Worker 146*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<Y>> getYComponent() { 147*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 148*a65addddSAndroid Build Coastguard Worker .registerConstructor<WithAnnot<Y>()>(); 149*a65addddSAndroid Build Coastguard Worker } 150*a65addddSAndroid Build Coastguard Worker 151*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 152*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 153*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 154*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }); 155*a65addddSAndroid Build Coastguard Worker } 156*a65addddSAndroid Build Coastguard Worker 157*a65addddSAndroid Build Coastguard Worker int main() { 158*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent); 159*a65addddSAndroid Build Coastguard Worker 160*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 0); 161*a65addddSAndroid Build Coastguard Worker Assert(injector.getMultibindings<X>().size() == 1); 162*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 1); 163*a65addddSAndroid Build Coastguard Worker } 164*a65addddSAndroid Build Coastguard Worker ''' 165*a65addddSAndroid Build Coastguard Worker expect_success( 166*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 167*a65addddSAndroid Build Coastguard Worker source, 168*a65addddSAndroid Build Coastguard Worker locals()) 169*a65addddSAndroid Build Coastguard Worker 170*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 171*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 172*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 173*a65addddSAndroid Build Coastguard Worker ], [ 174*a65addddSAndroid Build Coastguard Worker 'WithNoAnnot', 175*a65addddSAndroid Build Coastguard Worker 'WithAnnot1', 176*a65addddSAndroid Build Coastguard Worker ], [ 177*a65addddSAndroid Build Coastguard Worker 'Y', 178*a65addddSAndroid Build Coastguard Worker 'const Y', 179*a65addddSAndroid Build Coastguard Worker 'const Y*', 180*a65addddSAndroid Build Coastguard Worker 'const Y&', 181*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<const Y>', 182*a65addddSAndroid Build Coastguard Worker ]) 183*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_with_param_const_binding_success(self, ConstructX, XPtr, WithAnnot, YVariant): 184*a65addddSAndroid Build Coastguard Worker source = ''' 185*a65addddSAndroid Build Coastguard Worker struct Y {}; 186*a65addddSAndroid Build Coastguard Worker 187*a65addddSAndroid Build Coastguard Worker struct X : public ConstructionTracker<X> {}; 188*a65addddSAndroid Build Coastguard Worker 189*a65addddSAndroid Build Coastguard Worker const Y y{}; 190*a65addddSAndroid Build Coastguard Worker 191*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<const Y>> getYComponent() { 192*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 193*a65addddSAndroid Build Coastguard Worker .bindInstance<WithAnnot<Y>, Y>(y); 194*a65addddSAndroid Build Coastguard Worker } 195*a65addddSAndroid Build Coastguard Worker 196*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 197*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 198*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 199*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }); 200*a65addddSAndroid Build Coastguard Worker } 201*a65addddSAndroid Build Coastguard Worker 202*a65addddSAndroid Build Coastguard Worker int main() { 203*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent); 204*a65addddSAndroid Build Coastguard Worker 205*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 0); 206*a65addddSAndroid Build Coastguard Worker Assert(injector.getMultibindings<X>().size() == 1); 207*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 1); 208*a65addddSAndroid Build Coastguard Worker } 209*a65addddSAndroid Build Coastguard Worker ''' 210*a65addddSAndroid Build Coastguard Worker expect_success( 211*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 212*a65addddSAndroid Build Coastguard Worker source, 213*a65addddSAndroid Build Coastguard Worker locals()) 214*a65addddSAndroid Build Coastguard Worker 215*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 216*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 217*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 218*a65addddSAndroid Build Coastguard Worker ], [ 219*a65addddSAndroid Build Coastguard Worker ('WithNoAnnot', 'Y'), 220*a65addddSAndroid Build Coastguard Worker ('WithAnnot1', 'fruit::Annotated<Annotation1, Y>'), 221*a65addddSAndroid Build Coastguard Worker ], [ 222*a65addddSAndroid Build Coastguard Worker 'Y*', 223*a65addddSAndroid Build Coastguard Worker 'Y&', 224*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<Y>', 225*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<Y>', 226*a65addddSAndroid Build Coastguard Worker ]) 227*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_with_param_error_nonconst_param_required(self, ConstructX, XPtr, WithAnnot, YAnnotRegex, YVariant): 228*a65addddSAndroid Build Coastguard Worker source = ''' 229*a65addddSAndroid Build Coastguard Worker struct Y {}; 230*a65addddSAndroid Build Coastguard Worker struct X {}; 231*a65addddSAndroid Build Coastguard Worker 232*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<const Y>> getYComponent(); 233*a65addddSAndroid Build Coastguard Worker 234*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 235*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 236*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 237*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }); 238*a65addddSAndroid Build Coastguard Worker } 239*a65addddSAndroid Build Coastguard Worker ''' 240*a65addddSAndroid Build Coastguard Worker expect_compile_error( 241*a65addddSAndroid Build Coastguard Worker 'NonConstBindingRequiredButConstBindingProvidedError<YAnnotRegex>', 242*a65addddSAndroid Build Coastguard Worker 'The type T was provided as constant, however one of the constructors/providers/factories in this component', 243*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 244*a65addddSAndroid Build Coastguard Worker source, 245*a65addddSAndroid Build Coastguard Worker locals()) 246*a65addddSAndroid Build Coastguard Worker 247*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 248*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 249*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 250*a65addddSAndroid Build Coastguard Worker ], [ 251*a65addddSAndroid Build Coastguard Worker ('WithNoAnnot', 'Y'), 252*a65addddSAndroid Build Coastguard Worker ('WithAnnot1', 'fruit::Annotated<Annotation1, Y>'), 253*a65addddSAndroid Build Coastguard Worker ], [ 254*a65addddSAndroid Build Coastguard Worker 'Y*', 255*a65addddSAndroid Build Coastguard Worker 'Y&', 256*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<Y>', 257*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<Y>', 258*a65addddSAndroid Build Coastguard Worker ]) 259*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_with_param_error_nonconst_param_required_install_after(self, ConstructX, XPtr, WithAnnot, YAnnotRegex, YVariant): 260*a65addddSAndroid Build Coastguard Worker source = ''' 261*a65addddSAndroid Build Coastguard Worker struct Y {}; 262*a65addddSAndroid Build Coastguard Worker struct X {}; 263*a65addddSAndroid Build Coastguard Worker 264*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<const Y>> getYComponent(); 265*a65addddSAndroid Build Coastguard Worker 266*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 267*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 268*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }) 269*a65addddSAndroid Build Coastguard Worker .install(getYComponent); 270*a65addddSAndroid Build Coastguard Worker } 271*a65addddSAndroid Build Coastguard Worker ''' 272*a65addddSAndroid Build Coastguard Worker expect_compile_error( 273*a65addddSAndroid Build Coastguard Worker 'NonConstBindingRequiredButConstBindingProvidedError<YAnnotRegex>', 274*a65addddSAndroid Build Coastguard Worker 'The type T was provided as constant, however one of the constructors/providers/factories in this component', 275*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 276*a65addddSAndroid Build Coastguard Worker source, 277*a65addddSAndroid Build Coastguard Worker locals()) 278*a65addddSAndroid Build Coastguard Worker 279*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_requiring_nonconst_then_requiring_const_ok(self): 280*a65addddSAndroid Build Coastguard Worker source = ''' 281*a65addddSAndroid Build Coastguard Worker struct X {}; 282*a65addddSAndroid Build Coastguard Worker struct Y {}; 283*a65addddSAndroid Build Coastguard Worker 284*a65addddSAndroid Build Coastguard Worker fruit::Component<> getRootComponent() { 285*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 286*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider([](X&) { return Y(); }) 287*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider([](const X&) { return Y(); }) 288*a65addddSAndroid Build Coastguard Worker .registerConstructor<X()>(); 289*a65addddSAndroid Build Coastguard Worker } 290*a65addddSAndroid Build Coastguard Worker 291*a65addddSAndroid Build Coastguard Worker int main() { 292*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getRootComponent); 293*a65addddSAndroid Build Coastguard Worker injector.getMultibindings<Y>(); 294*a65addddSAndroid Build Coastguard Worker } 295*a65addddSAndroid Build Coastguard Worker ''' 296*a65addddSAndroid Build Coastguard Worker expect_success( 297*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 298*a65addddSAndroid Build Coastguard Worker source, 299*a65addddSAndroid Build Coastguard Worker locals()) 300*a65addddSAndroid Build Coastguard Worker 301*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_requiring_nonconst_then_requiring_const_declaring_const_requirement_error(self): 302*a65addddSAndroid Build Coastguard Worker source = ''' 303*a65addddSAndroid Build Coastguard Worker struct X {}; 304*a65addddSAndroid Build Coastguard Worker struct Y {}; 305*a65addddSAndroid Build Coastguard Worker 306*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>> getRootComponent() { 307*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 308*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider([](X&) { return Y(); }) 309*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider([](const X&) { return Y(); }); 310*a65addddSAndroid Build Coastguard Worker } 311*a65addddSAndroid Build Coastguard Worker ''' 312*a65addddSAndroid Build Coastguard Worker expect_compile_error( 313*a65addddSAndroid Build Coastguard Worker 'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>', 314*a65addddSAndroid Build Coastguard Worker 'The type T was declared as a const Required type in the returned Component, however', 315*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 316*a65addddSAndroid Build Coastguard Worker source, 317*a65addddSAndroid Build Coastguard Worker locals()) 318*a65addddSAndroid Build Coastguard Worker 319*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_requiring_const_then_requiring_nonconst_ok(self): 320*a65addddSAndroid Build Coastguard Worker source = ''' 321*a65addddSAndroid Build Coastguard Worker struct X {}; 322*a65addddSAndroid Build Coastguard Worker struct Y {}; 323*a65addddSAndroid Build Coastguard Worker 324*a65addddSAndroid Build Coastguard Worker fruit::Component<> getRootComponent() { 325*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 326*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider([](const X&) { return Y(); }) 327*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider([](X&) { return Y(); }) 328*a65addddSAndroid Build Coastguard Worker .registerConstructor<X()>(); 329*a65addddSAndroid Build Coastguard Worker } 330*a65addddSAndroid Build Coastguard Worker 331*a65addddSAndroid Build Coastguard Worker int main() { 332*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getRootComponent); 333*a65addddSAndroid Build Coastguard Worker injector.getMultibindings<Y>(); 334*a65addddSAndroid Build Coastguard Worker } 335*a65addddSAndroid Build Coastguard Worker ''' 336*a65addddSAndroid Build Coastguard Worker expect_success( 337*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 338*a65addddSAndroid Build Coastguard Worker source, 339*a65addddSAndroid Build Coastguard Worker locals()) 340*a65addddSAndroid Build Coastguard Worker 341*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_requiring_const_then_requiring_nonconst_declaring_const_requirement_error(self): 342*a65addddSAndroid Build Coastguard Worker source = ''' 343*a65addddSAndroid Build Coastguard Worker struct X {}; 344*a65addddSAndroid Build Coastguard Worker struct Y {}; 345*a65addddSAndroid Build Coastguard Worker 346*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>> getRootComponent() { 347*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 348*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider([](const X&) { return Y(); }) 349*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider([](X&) { return Y(); }); 350*a65addddSAndroid Build Coastguard Worker } 351*a65addddSAndroid Build Coastguard Worker ''' 352*a65addddSAndroid Build Coastguard Worker expect_compile_error( 353*a65addddSAndroid Build Coastguard Worker 'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>', 354*a65addddSAndroid Build Coastguard Worker 'The type T was declared as a const Required type in the returned Component, however', 355*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 356*a65addddSAndroid Build Coastguard Worker source, 357*a65addddSAndroid Build Coastguard Worker locals()) 358*a65addddSAndroid Build Coastguard Worker 359*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 360*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 361*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 362*a65addddSAndroid Build Coastguard Worker ], [ 363*a65addddSAndroid Build Coastguard Worker ('Y', 'Y', 'Y**', r'Y\*\*'), 364*a65addddSAndroid Build Coastguard Worker ('Y', 'Y', 'std::shared_ptr<Y>*', r'std::shared_ptr<Y>\*'), 365*a65addddSAndroid Build Coastguard Worker ('Y', 'const Y', 'Y**', r'Y\*\*'), 366*a65addddSAndroid Build Coastguard Worker ('Y', 'const Y', 'std::shared_ptr<Y>*', r'std::shared_ptr<Y>\*'), 367*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Y>', 'fruit::Annotated<Annotation1, Y>', 'Y**', r'Y\*\*'), 368*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Y>', 'fruit::Annotated<Annotation1, const Y>', 'Y**', r'Y\*\*'), 369*a65addddSAndroid Build Coastguard Worker ]) 370*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_with_param_error_type_not_injectable(self, ConstructX, XPtr, YAnnot, ConstYAnnot, YVariant, YVariantRegex): 371*a65addddSAndroid Build Coastguard Worker source = ''' 372*a65addddSAndroid Build Coastguard Worker struct Y {}; 373*a65addddSAndroid Build Coastguard Worker struct X {}; 374*a65addddSAndroid Build Coastguard Worker 375*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 376*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 377*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XPtr(YVariant)>([](YVariant){ return ConstructX; }); 378*a65addddSAndroid Build Coastguard Worker } 379*a65addddSAndroid Build Coastguard Worker ''' 380*a65addddSAndroid Build Coastguard Worker expect_compile_error( 381*a65addddSAndroid Build Coastguard Worker 'NonInjectableTypeError<YVariantRegex>', 382*a65addddSAndroid Build Coastguard Worker 'The type T is not injectable.', 383*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 384*a65addddSAndroid Build Coastguard Worker source, 385*a65addddSAndroid Build Coastguard Worker locals()) 386*a65addddSAndroid Build Coastguard Worker 387*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 388*a65addddSAndroid Build Coastguard Worker ('X()', 'X', 'X'), 389*a65addddSAndroid Build Coastguard Worker ('X()', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 390*a65addddSAndroid Build Coastguard Worker ('new X()', 'X', 'X*'), 391*a65addddSAndroid Build Coastguard Worker ('new X()', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X*>'), 392*a65addddSAndroid Build Coastguard Worker ]) 393*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_explicit_signature_success(self, ConstructX, XAnnot, XPtrAnnot): 394*a65addddSAndroid Build Coastguard Worker source = ''' 395*a65addddSAndroid Build Coastguard Worker struct X : public ConstructionTracker<X> { 396*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 397*a65addddSAndroid Build Coastguard Worker 398*a65addddSAndroid Build Coastguard Worker static bool constructed; 399*a65addddSAndroid Build Coastguard Worker }; 400*a65addddSAndroid Build Coastguard Worker 401*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 402*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 403*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XPtrAnnot()>([](){return ConstructX;}); 404*a65addddSAndroid Build Coastguard Worker } 405*a65addddSAndroid Build Coastguard Worker 406*a65addddSAndroid Build Coastguard Worker int main() { 407*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent); 408*a65addddSAndroid Build Coastguard Worker 409*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 0); 410*a65addddSAndroid Build Coastguard Worker Assert(injector.getMultibindings<XAnnot>().size() == 1); 411*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 1); 412*a65addddSAndroid Build Coastguard Worker } 413*a65addddSAndroid Build Coastguard Worker ''' 414*a65addddSAndroid Build Coastguard Worker expect_success( 415*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 416*a65addddSAndroid Build Coastguard Worker source, 417*a65addddSAndroid Build Coastguard Worker locals()) 418*a65addddSAndroid Build Coastguard Worker 419*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 420*a65addddSAndroid Build Coastguard Worker ('X()', 'X', 'X'), 421*a65addddSAndroid Build Coastguard Worker ('X()', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 422*a65addddSAndroid Build Coastguard Worker ('new X()', 'X', 'X*'), 423*a65addddSAndroid Build Coastguard Worker ('new X()', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X*>'), 424*a65addddSAndroid Build Coastguard Worker ]) 425*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_explicit_signature_with_normalized_component_success(self, ConstructX, XAnnot, XPtrAnnot): 426*a65addddSAndroid Build Coastguard Worker source = ''' 427*a65addddSAndroid Build Coastguard Worker struct X : public ConstructionTracker<X> { 428*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 429*a65addddSAndroid Build Coastguard Worker 430*a65addddSAndroid Build Coastguard Worker static bool constructed; 431*a65addddSAndroid Build Coastguard Worker }; 432*a65addddSAndroid Build Coastguard Worker 433*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 434*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 435*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XPtrAnnot()>([](){return ConstructX;}); 436*a65addddSAndroid Build Coastguard Worker } 437*a65addddSAndroid Build Coastguard Worker 438*a65addddSAndroid Build Coastguard Worker fruit::Component<> getEmptyComponent() { 439*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 440*a65addddSAndroid Build Coastguard Worker } 441*a65addddSAndroid Build Coastguard Worker 442*a65addddSAndroid Build Coastguard Worker int main() { 443*a65addddSAndroid Build Coastguard Worker fruit::NormalizedComponent<> normalizedComponent(getComponent); 444*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(normalizedComponent, getEmptyComponent); 445*a65addddSAndroid Build Coastguard Worker 446*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 0); 447*a65addddSAndroid Build Coastguard Worker Assert(injector.getMultibindings<XAnnot>().size() == 1); 448*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 1); 449*a65addddSAndroid Build Coastguard Worker } 450*a65addddSAndroid Build Coastguard Worker ''' 451*a65addddSAndroid Build Coastguard Worker expect_success( 452*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 453*a65addddSAndroid Build Coastguard Worker source, 454*a65addddSAndroid Build Coastguard Worker locals()) 455*a65addddSAndroid Build Coastguard Worker 456*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 457*a65addddSAndroid Build Coastguard Worker ('X', 'X*', 'int'), 458*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X*>', 'fruit::Annotated<Annotation2, int>'), 459*a65addddSAndroid Build Coastguard Worker ]) 460*a65addddSAndroid Build Coastguard Worker def test_multiple_providers(self, XAnnot, XPtrAnnot, intAnnot): 461*a65addddSAndroid Build Coastguard Worker source = ''' 462*a65addddSAndroid Build Coastguard Worker struct X {}; 463*a65addddSAndroid Build Coastguard Worker 464*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 465*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 466*a65addddSAndroid Build Coastguard Worker .registerProvider<intAnnot()>([](){return 42;}) 467*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XAnnot(intAnnot)>([](int){return X();}) 468*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XPtrAnnot(intAnnot)>([](int){return new X();}); 469*a65addddSAndroid Build Coastguard Worker } 470*a65addddSAndroid Build Coastguard Worker 471*a65addddSAndroid Build Coastguard Worker int main() { 472*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent); 473*a65addddSAndroid Build Coastguard Worker 474*a65addddSAndroid Build Coastguard Worker std::vector<X*> multibindings = injector.getMultibindings<XAnnot>(); 475*a65addddSAndroid Build Coastguard Worker Assert(multibindings.size() == 2); 476*a65addddSAndroid Build Coastguard Worker } 477*a65addddSAndroid Build Coastguard Worker ''' 478*a65addddSAndroid Build Coastguard Worker expect_success( 479*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 480*a65addddSAndroid Build Coastguard Worker source, 481*a65addddSAndroid Build Coastguard Worker locals()) 482*a65addddSAndroid Build Coastguard Worker 483*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 484*a65addddSAndroid Build Coastguard Worker 'X()', 485*a65addddSAndroid Build Coastguard Worker 'new X()', 486*a65addddSAndroid Build Coastguard Worker ], [ 487*a65addddSAndroid Build Coastguard Worker 'X', 488*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 489*a65addddSAndroid Build Coastguard Worker ]) 490*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_malformed_signature(self, ConstructX, XAnnot): 491*a65addddSAndroid Build Coastguard Worker source = ''' 492*a65addddSAndroid Build Coastguard Worker struct X {}; 493*a65addddSAndroid Build Coastguard Worker 494*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 495*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 496*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XAnnot>([](){return ConstructX;}); 497*a65addddSAndroid Build Coastguard Worker } 498*a65addddSAndroid Build Coastguard Worker ''' 499*a65addddSAndroid Build Coastguard Worker expect_compile_error( 500*a65addddSAndroid Build Coastguard Worker 'NotASignatureError<XAnnot>', 501*a65addddSAndroid Build Coastguard Worker 'CandidateSignature was specified as parameter, but it.s not a signature.', 502*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 503*a65addddSAndroid Build Coastguard Worker source, 504*a65addddSAndroid Build Coastguard Worker locals()) 505*a65addddSAndroid Build Coastguard Worker 506*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 507*a65addddSAndroid Build Coastguard Worker 'X(n)', 508*a65addddSAndroid Build Coastguard Worker 'new X(n)', 509*a65addddSAndroid Build Coastguard Worker ], [ 510*a65addddSAndroid Build Coastguard Worker 'X', 511*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 512*a65addddSAndroid Build Coastguard Worker ]) 513*a65addddSAndroid Build Coastguard Worker def test_bind_multibinding_provider_lambda_with_captures_error(self, ConstructX, XAnnot): 514*a65addddSAndroid Build Coastguard Worker source = ''' 515*a65addddSAndroid Build Coastguard Worker struct X { 516*a65addddSAndroid Build Coastguard Worker X(int) {} 517*a65addddSAndroid Build Coastguard Worker }; 518*a65addddSAndroid Build Coastguard Worker 519*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 520*a65addddSAndroid Build Coastguard Worker int n = 3; 521*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 522*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XAnnot()>([=]{return ConstructX;}); 523*a65addddSAndroid Build Coastguard Worker } 524*a65addddSAndroid Build Coastguard Worker ''' 525*a65addddSAndroid Build Coastguard Worker expect_compile_error( 526*a65addddSAndroid Build Coastguard Worker 'FunctorUsedAsProviderError<.*>', 527*a65addddSAndroid Build Coastguard Worker 'A stateful lambda or a non-lambda functor was used as provider', 528*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 529*a65addddSAndroid Build Coastguard Worker source, 530*a65addddSAndroid Build Coastguard Worker locals()) 531*a65addddSAndroid Build Coastguard Worker 532*a65addddSAndroid Build Coastguard Worker # TODO: should XPtrAnnot be just XAnnot in the signature? 533*a65addddSAndroid Build Coastguard Worker # Make sure the behavior here is consistent with registerProvider() and registerFactory(). 534*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 535*a65addddSAndroid Build Coastguard Worker ('X', 'X*', '(struct )?X'), 536*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X*>', '(struct )?fruit::Annotated<(struct )?Annotation1, ?(struct )?X>'), 537*a65addddSAndroid Build Coastguard Worker ]) 538*a65addddSAndroid Build Coastguard Worker def test_provider_returns_nullptr_error(self, XAnnot, XPtrAnnot, XAnnotRegex): 539*a65addddSAndroid Build Coastguard Worker source = ''' 540*a65addddSAndroid Build Coastguard Worker struct X {}; 541*a65addddSAndroid Build Coastguard Worker 542*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 543*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 544*a65addddSAndroid Build Coastguard Worker .addMultibindingProvider<XPtrAnnot()>([](){return (X*)nullptr;}); 545*a65addddSAndroid Build Coastguard Worker } 546*a65addddSAndroid Build Coastguard Worker 547*a65addddSAndroid Build Coastguard Worker int main() { 548*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent); 549*a65addddSAndroid Build Coastguard Worker injector.getMultibindings<XAnnot>(); 550*a65addddSAndroid Build Coastguard Worker } 551*a65addddSAndroid Build Coastguard Worker ''' 552*a65addddSAndroid Build Coastguard Worker expect_runtime_error( 553*a65addddSAndroid Build Coastguard Worker 'Fatal injection error: attempting to get an instance for the type XAnnotRegex but the provider returned nullptr', 554*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 555*a65addddSAndroid Build Coastguard Worker source, 556*a65addddSAndroid Build Coastguard Worker locals()) 557*a65addddSAndroid Build Coastguard Worker 558*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__': 559*a65addddSAndroid Build Coastguard Worker absltest.main() 560