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 24*a65addddSAndroid Build Coastguard Worker template <typename T> 25*a65addddSAndroid Build Coastguard Worker using WithNoAnnot = T; 26*a65addddSAndroid Build Coastguard Worker 27*a65addddSAndroid Build Coastguard Worker template <typename T> 28*a65addddSAndroid Build Coastguard Worker using WithAnnot1 = fruit::Annotated<Annotation1, T>; 29*a65addddSAndroid Build Coastguard Worker ''' 30*a65addddSAndroid Build Coastguard Worker 31*a65addddSAndroid Build Coastguard Workerclass TestRegisterProvider(parameterized.TestCase): 32*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 33*a65addddSAndroid Build Coastguard Worker 'WithNoAnnot', 34*a65addddSAndroid Build Coastguard Worker 'WithAnnot1', 35*a65addddSAndroid Build Coastguard Worker ], [ 36*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 37*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 38*a65addddSAndroid Build Coastguard Worker ]) 39*a65addddSAndroid Build Coastguard Worker def test_register_provider_success(self, WithAnnot, ConstructX, XPtr): 40*a65addddSAndroid Build Coastguard Worker source = ''' 41*a65addddSAndroid Build Coastguard Worker struct X : public ConstructionTracker<X> { 42*a65addddSAndroid Build Coastguard Worker int value = 5; 43*a65addddSAndroid Build Coastguard Worker }; 44*a65addddSAndroid Build Coastguard Worker 45*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<X>> getComponent() { 46*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 47*a65addddSAndroid Build Coastguard Worker .registerProvider<WithAnnot<XPtr>()>([](){return ConstructX;}); 48*a65addddSAndroid Build Coastguard Worker } 49*a65addddSAndroid Build Coastguard Worker 50*a65addddSAndroid Build Coastguard Worker int main() { 51*a65addddSAndroid Build Coastguard Worker fruit::Injector<WithAnnot<X>> injector(getComponent); 52*a65addddSAndroid Build Coastguard Worker 53*a65addddSAndroid Build Coastguard Worker Assert((injector.get<WithAnnot<X >>(). value == 5)); 54*a65addddSAndroid Build Coastguard Worker Assert((injector.get<WithAnnot<X* >>()->value == 5)); 55*a65addddSAndroid Build Coastguard Worker Assert((injector.get<WithAnnot<X& >>(). value == 5)); 56*a65addddSAndroid Build Coastguard Worker Assert((injector.get<WithAnnot<const X >>(). value == 5)); 57*a65addddSAndroid Build Coastguard Worker Assert((injector.get<WithAnnot<const X* >>()->value == 5)); 58*a65addddSAndroid Build Coastguard Worker Assert((injector.get<WithAnnot<const X& >>(). value == 5)); 59*a65addddSAndroid Build Coastguard Worker Assert((injector.get<WithAnnot<std::shared_ptr<X>>>()->value == 5)); 60*a65addddSAndroid Build Coastguard Worker 61*a65addddSAndroid Build Coastguard Worker Assert(X::num_objects_constructed == 1); 62*a65addddSAndroid Build Coastguard Worker } 63*a65addddSAndroid Build Coastguard Worker ''' 64*a65addddSAndroid Build Coastguard Worker expect_success( 65*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 66*a65addddSAndroid Build Coastguard Worker source, 67*a65addddSAndroid Build Coastguard Worker locals()) 68*a65addddSAndroid Build Coastguard Worker 69*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 70*a65addddSAndroid Build Coastguard Worker 'WithNoAnnot', 71*a65addddSAndroid Build Coastguard Worker 'WithAnnot1', 72*a65addddSAndroid Build Coastguard Worker ]) 73*a65addddSAndroid Build Coastguard Worker def test_register_provider_abstract_class_ok(self, WithAnnot): 74*a65addddSAndroid Build Coastguard Worker source = ''' 75*a65addddSAndroid Build Coastguard Worker struct I { 76*a65addddSAndroid Build Coastguard Worker virtual int foo() = 0; 77*a65addddSAndroid Build Coastguard Worker virtual ~I() = default; 78*a65addddSAndroid Build Coastguard Worker }; 79*a65addddSAndroid Build Coastguard Worker 80*a65addddSAndroid Build Coastguard Worker struct X : public I { 81*a65addddSAndroid Build Coastguard Worker int foo() override { 82*a65addddSAndroid Build Coastguard Worker return 5; 83*a65addddSAndroid Build Coastguard Worker } 84*a65addddSAndroid Build Coastguard Worker }; 85*a65addddSAndroid Build Coastguard Worker 86*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<I>> getComponent() { 87*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 88*a65addddSAndroid Build Coastguard Worker .registerProvider<WithAnnot<I*>()>([](){return static_cast<I*>(new X());}); 89*a65addddSAndroid Build Coastguard Worker } 90*a65addddSAndroid Build Coastguard Worker 91*a65addddSAndroid Build Coastguard Worker int main() { 92*a65addddSAndroid Build Coastguard Worker fruit::Injector<WithAnnot<I>> injector(getComponent); 93*a65addddSAndroid Build Coastguard Worker 94*a65addddSAndroid Build Coastguard Worker Assert(injector.get<WithAnnot<I*>>()->foo() == 5); 95*a65addddSAndroid Build Coastguard Worker } 96*a65addddSAndroid Build Coastguard Worker ''' 97*a65addddSAndroid Build Coastguard Worker expect_success( 98*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 99*a65addddSAndroid Build Coastguard Worker source, 100*a65addddSAndroid Build Coastguard Worker locals()) 101*a65addddSAndroid Build Coastguard Worker 102*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 103*a65addddSAndroid Build Coastguard Worker 'WithNoAnnot', 104*a65addddSAndroid Build Coastguard Worker 'WithAnnot1', 105*a65addddSAndroid Build Coastguard Worker ]) 106*a65addddSAndroid Build Coastguard Worker def test_register_provider_abstract_class_with_no_virtual_destructor_error(self, WithAnnot): 107*a65addddSAndroid Build Coastguard Worker source = ''' 108*a65addddSAndroid Build Coastguard Worker struct I { 109*a65addddSAndroid Build Coastguard Worker virtual int foo() = 0; 110*a65addddSAndroid Build Coastguard Worker }; 111*a65addddSAndroid Build Coastguard Worker 112*a65addddSAndroid Build Coastguard Worker struct X : public I { 113*a65addddSAndroid Build Coastguard Worker int foo() override { 114*a65addddSAndroid Build Coastguard Worker return 5; 115*a65addddSAndroid Build Coastguard Worker } 116*a65addddSAndroid Build Coastguard Worker }; 117*a65addddSAndroid Build Coastguard Worker 118*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<I>> getComponent() { 119*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 120*a65addddSAndroid Build Coastguard Worker .registerProvider<WithAnnot<I*>()>([](){return static_cast<I*>(new X());}); 121*a65addddSAndroid Build Coastguard Worker } 122*a65addddSAndroid Build Coastguard Worker ''' 123*a65addddSAndroid Build Coastguard Worker expect_compile_error( 124*a65addddSAndroid Build Coastguard Worker r'ProviderReturningPointerToAbstractClassWithNoVirtualDestructorError<I>', 125*a65addddSAndroid Build Coastguard Worker r'registerProvider\(\) was called with a lambda that returns a pointer to T, but T is an abstract class', 126*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 127*a65addddSAndroid Build Coastguard Worker source, 128*a65addddSAndroid Build Coastguard Worker locals()) 129*a65addddSAndroid Build Coastguard Worker 130*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 131*a65addddSAndroid Build Coastguard Worker 'X()', 132*a65addddSAndroid Build Coastguard Worker 'new X()', 133*a65addddSAndroid Build Coastguard Worker ]) 134*a65addddSAndroid Build Coastguard Worker def test_register_provider_not_copyable_success(self, ConstructX): 135*a65addddSAndroid Build Coastguard Worker source = ''' 136*a65addddSAndroid Build Coastguard Worker struct X { 137*a65addddSAndroid Build Coastguard Worker X() = default; 138*a65addddSAndroid Build Coastguard Worker X(X&&) = default; 139*a65addddSAndroid Build Coastguard Worker X(const X&) = delete; 140*a65addddSAndroid Build Coastguard Worker }; 141*a65addddSAndroid Build Coastguard Worker 142*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 143*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 144*a65addddSAndroid Build Coastguard Worker .registerProvider([](){return ConstructX;}); 145*a65addddSAndroid Build Coastguard Worker } 146*a65addddSAndroid Build Coastguard Worker 147*a65addddSAndroid Build Coastguard Worker int main() { 148*a65addddSAndroid Build Coastguard Worker fruit::Injector<X> injector(getComponent); 149*a65addddSAndroid Build Coastguard Worker injector.get<X*>(); 150*a65addddSAndroid Build Coastguard Worker } 151*a65addddSAndroid Build Coastguard Worker ''' 152*a65addddSAndroid Build Coastguard Worker expect_success( 153*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 154*a65addddSAndroid Build Coastguard Worker source, 155*a65addddSAndroid Build Coastguard Worker locals()) 156*a65addddSAndroid Build Coastguard Worker 157*a65addddSAndroid Build Coastguard Worker def test_register_provider_not_movable_returning_pointer_success(self): 158*a65addddSAndroid Build Coastguard Worker source = ''' 159*a65addddSAndroid Build Coastguard Worker struct X { 160*a65addddSAndroid Build Coastguard Worker X() = default; 161*a65addddSAndroid Build Coastguard Worker X(X&&) = delete; 162*a65addddSAndroid Build Coastguard Worker X(const X&) = delete; 163*a65addddSAndroid Build Coastguard Worker }; 164*a65addddSAndroid Build Coastguard Worker 165*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 166*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 167*a65addddSAndroid Build Coastguard Worker .registerProvider([](){return new X();}); 168*a65addddSAndroid Build Coastguard Worker } 169*a65addddSAndroid Build Coastguard Worker 170*a65addddSAndroid Build Coastguard Worker int main() { 171*a65addddSAndroid Build Coastguard Worker fruit::Injector<X> injector(getComponent); 172*a65addddSAndroid Build Coastguard Worker injector.get<X*>(); 173*a65addddSAndroid Build Coastguard Worker } 174*a65addddSAndroid Build Coastguard Worker ''' 175*a65addddSAndroid Build Coastguard Worker expect_success( 176*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 177*a65addddSAndroid Build Coastguard Worker source) 178*a65addddSAndroid Build Coastguard Worker 179*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 180*a65addddSAndroid Build Coastguard Worker 'X', 181*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 182*a65addddSAndroid Build Coastguard Worker ]) 183*a65addddSAndroid Build Coastguard Worker def test_register_provider_error_not_function(self, XAnnot): 184*a65addddSAndroid Build Coastguard Worker source = ''' 185*a65addddSAndroid Build Coastguard Worker struct X { 186*a65addddSAndroid Build Coastguard Worker X(int) {} 187*a65addddSAndroid Build Coastguard Worker }; 188*a65addddSAndroid Build Coastguard Worker 189*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponent() { 190*a65addddSAndroid Build Coastguard Worker int n = 3; 191*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 192*a65addddSAndroid Build Coastguard Worker .registerProvider<XAnnot()>([=]{return X(n);}); 193*a65addddSAndroid Build Coastguard Worker } 194*a65addddSAndroid Build Coastguard Worker ''' 195*a65addddSAndroid Build Coastguard Worker expect_compile_error( 196*a65addddSAndroid Build Coastguard Worker 'FunctorUsedAsProviderError<.*>', 197*a65addddSAndroid Build Coastguard Worker 'A stateful lambda or a non-lambda functor was used as provider', 198*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 199*a65addddSAndroid Build Coastguard Worker source, 200*a65addddSAndroid Build Coastguard Worker locals()) 201*a65addddSAndroid Build Coastguard Worker 202*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 203*a65addddSAndroid Build Coastguard Worker 'int', 204*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, int>', 205*a65addddSAndroid Build Coastguard Worker ]) 206*a65addddSAndroid Build Coastguard Worker def test_register_provider_error_malformed_signature(self, intAnnot): 207*a65addddSAndroid Build Coastguard Worker source = ''' 208*a65addddSAndroid Build Coastguard Worker fruit::Component<intAnnot> getComponent() { 209*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 210*a65addddSAndroid Build Coastguard Worker .registerProvider<intAnnot>([](){return 42;}); 211*a65addddSAndroid Build Coastguard Worker } 212*a65addddSAndroid Build Coastguard Worker ''' 213*a65addddSAndroid Build Coastguard Worker expect_compile_error( 214*a65addddSAndroid Build Coastguard Worker 'NotASignatureError<intAnnot>', 215*a65addddSAndroid Build Coastguard Worker 'CandidateSignature was specified as parameter, but it.s not a signature. Signatures are of the form', 216*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 217*a65addddSAndroid Build Coastguard Worker source, 218*a65addddSAndroid Build Coastguard Worker locals()) 219*a65addddSAndroid Build Coastguard Worker 220*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 221*a65addddSAndroid Build Coastguard Worker ('X', 'X*', '(struct )?X'), 222*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X*>', '(struct )?fruit::Annotated<(struct )?Annotation1, ?(struct )?X>'), 223*a65addddSAndroid Build Coastguard Worker ]) 224*a65addddSAndroid Build Coastguard Worker def test_register_provider_error_returned_nullptr(self, XAnnot, XPtrAnnot, XAnnotRegex): 225*a65addddSAndroid Build Coastguard Worker source = ''' 226*a65addddSAndroid Build Coastguard Worker struct X {}; 227*a65addddSAndroid Build Coastguard Worker 228*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponent() { 229*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 230*a65addddSAndroid Build Coastguard Worker .registerProvider<XPtrAnnot()>([](){return (X*)nullptr;}); 231*a65addddSAndroid Build Coastguard Worker } 232*a65addddSAndroid Build Coastguard Worker 233*a65addddSAndroid Build Coastguard Worker int main() { 234*a65addddSAndroid Build Coastguard Worker fruit::Injector<XAnnot> injector(getComponent); 235*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot>(); 236*a65addddSAndroid Build Coastguard Worker } 237*a65addddSAndroid Build Coastguard Worker ''' 238*a65addddSAndroid Build Coastguard Worker expect_runtime_error( 239*a65addddSAndroid Build Coastguard Worker 'Fatal injection error: attempting to get an instance for the type XAnnotRegex but the provider returned nullptr', 240*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 241*a65addddSAndroid Build Coastguard Worker source, 242*a65addddSAndroid Build Coastguard Worker locals()) 243*a65addddSAndroid Build Coastguard Worker 244*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 245*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 246*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 247*a65addddSAndroid Build Coastguard Worker ], [ 248*a65addddSAndroid Build Coastguard Worker 'WithNoAnnot', 249*a65addddSAndroid Build Coastguard Worker 'WithAnnot1', 250*a65addddSAndroid Build Coastguard Worker ], [ 251*a65addddSAndroid Build Coastguard Worker 'Y', 252*a65addddSAndroid Build Coastguard Worker 'const Y', 253*a65addddSAndroid Build Coastguard Worker 'Y*', 254*a65addddSAndroid Build Coastguard Worker 'const Y*', 255*a65addddSAndroid Build Coastguard Worker 'Y&', 256*a65addddSAndroid Build Coastguard Worker 'const Y&', 257*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<Y>', 258*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<Y>', 259*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<const Y>', 260*a65addddSAndroid Build Coastguard Worker ]) 261*a65addddSAndroid Build Coastguard Worker def test_register_provider_with_param_success(self, ConstructX, XPtr, WithAnnot, YVariant): 262*a65addddSAndroid Build Coastguard Worker source = ''' 263*a65addddSAndroid Build Coastguard Worker struct Y {}; 264*a65addddSAndroid Build Coastguard Worker struct X {}; 265*a65addddSAndroid Build Coastguard Worker 266*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<Y>> getYComponent() { 267*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 268*a65addddSAndroid Build Coastguard Worker .registerConstructor<WithAnnot<Y>()>(); 269*a65addddSAndroid Build Coastguard Worker } 270*a65addddSAndroid Build Coastguard Worker 271*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 272*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 273*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 274*a65addddSAndroid Build Coastguard Worker .registerProvider<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }); 275*a65addddSAndroid Build Coastguard Worker } 276*a65addddSAndroid Build Coastguard Worker 277*a65addddSAndroid Build Coastguard Worker int main() { 278*a65addddSAndroid Build Coastguard Worker fruit::Injector<X> injector(getComponent); 279*a65addddSAndroid Build Coastguard Worker injector.get<X>(); 280*a65addddSAndroid Build Coastguard Worker } 281*a65addddSAndroid Build Coastguard Worker ''' 282*a65addddSAndroid Build Coastguard Worker expect_success( 283*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 284*a65addddSAndroid Build Coastguard Worker source, 285*a65addddSAndroid Build Coastguard Worker locals()) 286*a65addddSAndroid Build Coastguard Worker 287*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 288*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 289*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 290*a65addddSAndroid Build Coastguard Worker ], [ 291*a65addddSAndroid Build Coastguard Worker 'WithNoAnnot', 292*a65addddSAndroid Build Coastguard Worker 'WithAnnot1', 293*a65addddSAndroid Build Coastguard Worker ], [ 294*a65addddSAndroid Build Coastguard Worker 'Y', 295*a65addddSAndroid Build Coastguard Worker 'const Y', 296*a65addddSAndroid Build Coastguard Worker 'const Y*', 297*a65addddSAndroid Build Coastguard Worker 'const Y&', 298*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<const Y>', 299*a65addddSAndroid Build Coastguard Worker ]) 300*a65addddSAndroid Build Coastguard Worker def test_register_provider_with_param_const_binding_success(self, ConstructX, XPtr, WithAnnot, YVariant): 301*a65addddSAndroid Build Coastguard Worker source = ''' 302*a65addddSAndroid Build Coastguard Worker struct Y {}; 303*a65addddSAndroid Build Coastguard Worker struct X {}; 304*a65addddSAndroid Build Coastguard Worker 305*a65addddSAndroid Build Coastguard Worker const Y y{}; 306*a65addddSAndroid Build Coastguard Worker 307*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<const Y>> getYComponent() { 308*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 309*a65addddSAndroid Build Coastguard Worker .bindInstance<WithAnnot<Y>, Y>(y); 310*a65addddSAndroid Build Coastguard Worker } 311*a65addddSAndroid Build Coastguard Worker 312*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent() { 313*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 314*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 315*a65addddSAndroid Build Coastguard Worker .registerProvider<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }); 316*a65addddSAndroid Build Coastguard Worker } 317*a65addddSAndroid Build Coastguard Worker 318*a65addddSAndroid Build Coastguard Worker int main() { 319*a65addddSAndroid Build Coastguard Worker fruit::Injector<X> injector(getComponent); 320*a65addddSAndroid Build Coastguard Worker injector.get<X>(); 321*a65addddSAndroid Build Coastguard Worker } 322*a65addddSAndroid Build Coastguard Worker ''' 323*a65addddSAndroid Build Coastguard Worker expect_success( 324*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 325*a65addddSAndroid Build Coastguard Worker source, 326*a65addddSAndroid Build Coastguard Worker locals()) 327*a65addddSAndroid Build Coastguard Worker 328*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 329*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 330*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 331*a65addddSAndroid Build Coastguard Worker ], [ 332*a65addddSAndroid Build Coastguard Worker ('WithNoAnnot', 'Y'), 333*a65addddSAndroid Build Coastguard Worker ('WithAnnot1', 'fruit::Annotated<Annotation1, Y>'), 334*a65addddSAndroid Build Coastguard Worker ], [ 335*a65addddSAndroid Build Coastguard Worker 'Y*', 336*a65addddSAndroid Build Coastguard Worker 'Y&', 337*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<Y>', 338*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<Y>', 339*a65addddSAndroid Build Coastguard Worker ]) 340*a65addddSAndroid Build Coastguard Worker def test_register_provider_with_param_error_nonconst_param_required(self, ConstructX, XPtr, WithAnnot, YAnnotRegex, YVariant): 341*a65addddSAndroid Build Coastguard Worker source = ''' 342*a65addddSAndroid Build Coastguard Worker struct Y {}; 343*a65addddSAndroid Build Coastguard Worker struct X {}; 344*a65addddSAndroid Build Coastguard Worker 345*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<const Y>> getYComponent(); 346*a65addddSAndroid Build Coastguard Worker 347*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 348*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 349*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 350*a65addddSAndroid Build Coastguard Worker .registerProvider<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }); 351*a65addddSAndroid Build Coastguard Worker } 352*a65addddSAndroid Build Coastguard Worker ''' 353*a65addddSAndroid Build Coastguard Worker expect_compile_error( 354*a65addddSAndroid Build Coastguard Worker 'NonConstBindingRequiredButConstBindingProvidedError<YAnnotRegex>', 355*a65addddSAndroid Build Coastguard Worker 'The type T was provided as constant, however one of the constructors/providers/factories in this component', 356*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 357*a65addddSAndroid Build Coastguard Worker source, 358*a65addddSAndroid Build Coastguard Worker locals()) 359*a65addddSAndroid Build Coastguard Worker 360*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 361*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 362*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 363*a65addddSAndroid Build Coastguard Worker ], [ 364*a65addddSAndroid Build Coastguard Worker ('WithNoAnnot', 'Y'), 365*a65addddSAndroid Build Coastguard Worker ('WithAnnot1', 'fruit::Annotated<Annotation1, Y>'), 366*a65addddSAndroid Build Coastguard Worker ], [ 367*a65addddSAndroid Build Coastguard Worker 'Y*', 368*a65addddSAndroid Build Coastguard Worker 'Y&', 369*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<Y>', 370*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<Y>', 371*a65addddSAndroid Build Coastguard Worker ]) 372*a65addddSAndroid Build Coastguard Worker def test_register_provider_with_param_error_nonconst_param_required_install_after(self, ConstructX, XPtr, WithAnnot, YAnnotRegex, YVariant): 373*a65addddSAndroid Build Coastguard Worker source = ''' 374*a65addddSAndroid Build Coastguard Worker struct Y {}; 375*a65addddSAndroid Build Coastguard Worker struct X {}; 376*a65addddSAndroid Build Coastguard Worker 377*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<const Y>> getYComponent(); 378*a65addddSAndroid Build Coastguard Worker 379*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 380*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 381*a65addddSAndroid Build Coastguard Worker .registerProvider<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }) 382*a65addddSAndroid Build Coastguard Worker .install(getYComponent); 383*a65addddSAndroid Build Coastguard Worker } 384*a65addddSAndroid Build Coastguard Worker ''' 385*a65addddSAndroid Build Coastguard Worker expect_compile_error( 386*a65addddSAndroid Build Coastguard Worker 'NonConstBindingRequiredButConstBindingProvidedError<YAnnotRegex>', 387*a65addddSAndroid Build Coastguard Worker 'The type T was provided as constant, however one of the constructors/providers/factories in this component', 388*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 389*a65addddSAndroid Build Coastguard Worker source, 390*a65addddSAndroid Build Coastguard Worker locals()) 391*a65addddSAndroid Build Coastguard Worker 392*a65addddSAndroid Build Coastguard Worker def test_register_provider_requiring_nonconst_then_requiring_const_ok(self): 393*a65addddSAndroid Build Coastguard Worker source = ''' 394*a65addddSAndroid Build Coastguard Worker struct X {}; 395*a65addddSAndroid Build Coastguard Worker struct Y {}; 396*a65addddSAndroid Build Coastguard Worker struct Z {}; 397*a65addddSAndroid Build Coastguard Worker 398*a65addddSAndroid Build Coastguard Worker fruit::Component<Y, Z> getRootComponent() { 399*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 400*a65addddSAndroid Build Coastguard Worker .registerProvider([](X&) { return Y();}) 401*a65addddSAndroid Build Coastguard Worker .registerProvider([](const X&) { return Z();}) 402*a65addddSAndroid Build Coastguard Worker .registerConstructor<X()>(); 403*a65addddSAndroid Build Coastguard Worker } 404*a65addddSAndroid Build Coastguard Worker 405*a65addddSAndroid Build Coastguard Worker int main() { 406*a65addddSAndroid Build Coastguard Worker fruit::Injector<Y, Z> injector(getRootComponent); 407*a65addddSAndroid Build Coastguard Worker injector.get<Y>(); 408*a65addddSAndroid Build Coastguard Worker injector.get<Z>(); 409*a65addddSAndroid Build Coastguard Worker } 410*a65addddSAndroid Build Coastguard Worker ''' 411*a65addddSAndroid Build Coastguard Worker expect_success( 412*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 413*a65addddSAndroid Build Coastguard Worker source, 414*a65addddSAndroid Build Coastguard Worker locals()) 415*a65addddSAndroid Build Coastguard Worker 416*a65addddSAndroid Build Coastguard Worker def test_register_provider_requiring_nonconst_then_requiring_const_declaring_const_requirement_error(self): 417*a65addddSAndroid Build Coastguard Worker source = ''' 418*a65addddSAndroid Build Coastguard Worker struct X {}; 419*a65addddSAndroid Build Coastguard Worker struct Y {}; 420*a65addddSAndroid Build Coastguard Worker struct Z {}; 421*a65addddSAndroid Build Coastguard Worker 422*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>, Y, Z> getRootComponent() { 423*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 424*a65addddSAndroid Build Coastguard Worker .registerProvider([](X&) { return Y();}) 425*a65addddSAndroid Build Coastguard Worker .registerProvider([](const X&) { return Z();}); 426*a65addddSAndroid Build Coastguard Worker } 427*a65addddSAndroid Build Coastguard Worker ''' 428*a65addddSAndroid Build Coastguard Worker expect_compile_error( 429*a65addddSAndroid Build Coastguard Worker 'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>', 430*a65addddSAndroid Build Coastguard Worker 'The type T was declared as a const Required type in the returned Component, however', 431*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 432*a65addddSAndroid Build Coastguard Worker source, 433*a65addddSAndroid Build Coastguard Worker locals()) 434*a65addddSAndroid Build Coastguard Worker 435*a65addddSAndroid Build Coastguard Worker def test_register_provider_requiring_const_then_requiring_nonconst_ok(self): 436*a65addddSAndroid Build Coastguard Worker source = ''' 437*a65addddSAndroid Build Coastguard Worker struct X {}; 438*a65addddSAndroid Build Coastguard Worker struct Y {}; 439*a65addddSAndroid Build Coastguard Worker struct Z {}; 440*a65addddSAndroid Build Coastguard Worker 441*a65addddSAndroid Build Coastguard Worker fruit::Component<Y, Z> getRootComponent() { 442*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 443*a65addddSAndroid Build Coastguard Worker .registerProvider([](const X&) { return Y();}) 444*a65addddSAndroid Build Coastguard Worker .registerProvider([](X&) { return Z();}) 445*a65addddSAndroid Build Coastguard Worker .registerConstructor<X()>(); 446*a65addddSAndroid Build Coastguard Worker } 447*a65addddSAndroid Build Coastguard Worker 448*a65addddSAndroid Build Coastguard Worker int main() { 449*a65addddSAndroid Build Coastguard Worker fruit::Injector<Y, Z> injector(getRootComponent); 450*a65addddSAndroid Build Coastguard Worker injector.get<Y>(); 451*a65addddSAndroid Build Coastguard Worker injector.get<Z>(); 452*a65addddSAndroid Build Coastguard Worker } 453*a65addddSAndroid Build Coastguard Worker ''' 454*a65addddSAndroid Build Coastguard Worker expect_success( 455*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 456*a65addddSAndroid Build Coastguard Worker source, 457*a65addddSAndroid Build Coastguard Worker locals()) 458*a65addddSAndroid Build Coastguard Worker 459*a65addddSAndroid Build Coastguard Worker def test_register_provider_requiring_const_then_requiring_nonconst_declaring_const_requirement_error(self): 460*a65addddSAndroid Build Coastguard Worker source = ''' 461*a65addddSAndroid Build Coastguard Worker struct X {}; 462*a65addddSAndroid Build Coastguard Worker struct Y {}; 463*a65addddSAndroid Build Coastguard Worker struct Z {}; 464*a65addddSAndroid Build Coastguard Worker 465*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>, Y, Z> getRootComponent() { 466*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 467*a65addddSAndroid Build Coastguard Worker .registerProvider([](const X&) { return Y();}) 468*a65addddSAndroid Build Coastguard Worker .registerProvider([](X&) { return Z();}); 469*a65addddSAndroid Build Coastguard Worker } 470*a65addddSAndroid Build Coastguard Worker ''' 471*a65addddSAndroid Build Coastguard Worker expect_compile_error( 472*a65addddSAndroid Build Coastguard Worker 'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>', 473*a65addddSAndroid Build Coastguard Worker 'The type T was declared as a const Required type in the returned Component, however', 474*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 475*a65addddSAndroid Build Coastguard Worker source, 476*a65addddSAndroid Build Coastguard Worker locals()) 477*a65addddSAndroid Build Coastguard Worker 478*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 479*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 480*a65addddSAndroid Build Coastguard Worker ('new X()', 'X*'), 481*a65addddSAndroid Build Coastguard Worker ], [ 482*a65addddSAndroid Build Coastguard Worker ('Y**', r'Y\*\*'), 483*a65addddSAndroid Build Coastguard Worker ('std::shared_ptr<Y>*', r'std::shared_ptr<Y>\*'), 484*a65addddSAndroid Build Coastguard Worker ('std::nullptr_t', r'(std::)?nullptr(_t)?'), 485*a65addddSAndroid Build Coastguard Worker ('Y*&', r'Y\*&'), 486*a65addddSAndroid Build Coastguard Worker ('Y(*)()', r'Y(\((__cdecl)?\*\))?\((void)?\)'), 487*a65addddSAndroid Build Coastguard Worker ]) 488*a65addddSAndroid Build Coastguard Worker def test_register_provider_with_param_error_type_not_injectable(self, ConstructX, XPtr, YVariant, YVariantRegex): 489*a65addddSAndroid Build Coastguard Worker source = ''' 490*a65addddSAndroid Build Coastguard Worker struct Y {}; 491*a65addddSAndroid Build Coastguard Worker struct X {}; 492*a65addddSAndroid Build Coastguard Worker 493*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 494*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 495*a65addddSAndroid Build Coastguard Worker .registerProvider<XPtr(YVariant)>([](YVariant){ return ConstructX; }); 496*a65addddSAndroid Build Coastguard Worker } 497*a65addddSAndroid Build Coastguard Worker ''' 498*a65addddSAndroid Build Coastguard Worker expect_compile_error( 499*a65addddSAndroid Build Coastguard Worker 'NonInjectableTypeError<YVariantRegex>', 500*a65addddSAndroid Build Coastguard Worker 'The type T is not injectable.', 501*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 502*a65addddSAndroid Build Coastguard Worker source, 503*a65addddSAndroid Build Coastguard Worker locals()) 504*a65addddSAndroid Build Coastguard Worker 505*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__': 506*a65addddSAndroid Build Coastguard Worker absltest.main() 507