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 Workerimport pytest 16*a65addddSAndroid Build Coastguard Workerfrom absl.testing import parameterized 17*a65addddSAndroid Build Coastguard Workerfrom fruit_test_common import * 18*a65addddSAndroid Build Coastguard Workerfrom fruit_test_config import CXX_COMPILER_NAME 19*a65addddSAndroid Build Coastguard Worker 20*a65addddSAndroid Build Coastguard WorkerCOMMON_DEFINITIONS = ''' 21*a65addddSAndroid Build Coastguard Worker #include "test_common.h" 22*a65addddSAndroid Build Coastguard Worker 23*a65addddSAndroid Build Coastguard Worker struct Scaler; 24*a65addddSAndroid Build Coastguard Worker struct ScalerImpl; 25*a65addddSAndroid Build Coastguard Worker 26*a65addddSAndroid Build Coastguard Worker struct Annotation1 {}; 27*a65addddSAndroid Build Coastguard Worker using ScalerAnnot1 = fruit::Annotated<Annotation1, Scaler>; 28*a65addddSAndroid Build Coastguard Worker using ScalerImplAnnot1 = fruit::Annotated<Annotation1, ScalerImpl>; 29*a65addddSAndroid Build Coastguard Worker 30*a65addddSAndroid Build Coastguard Worker struct Annotation2 {}; 31*a65addddSAndroid Build Coastguard Worker using ScalerAnnot2 = fruit::Annotated<Annotation2, Scaler>; 32*a65addddSAndroid Build Coastguard Worker using ScalerImplAnnot2 = fruit::Annotated<Annotation2, ScalerImpl>; 33*a65addddSAndroid Build Coastguard Worker 34*a65addddSAndroid Build Coastguard Worker template <typename T> 35*a65addddSAndroid Build Coastguard Worker using WithNoAnnotation = T; 36*a65addddSAndroid Build Coastguard Worker 37*a65addddSAndroid Build Coastguard Worker template <typename T> 38*a65addddSAndroid Build Coastguard Worker using WithAnnotation1 = fruit::Annotated<Annotation1, T>; 39*a65addddSAndroid Build Coastguard Worker ''' 40*a65addddSAndroid Build Coastguard Worker 41*a65addddSAndroid Build Coastguard Workerclass TestRegisterFactory(parameterized.TestCase): 42*a65addddSAndroid Build Coastguard Worker 43*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 44*a65addddSAndroid Build Coastguard Worker 'std::function<X()>', 45*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<X()>>', 46*a65addddSAndroid Build Coastguard Worker ]) 47*a65addddSAndroid Build Coastguard Worker def test_register_factory_success_no_params_autoinject(self, XFactoryAnnot): 48*a65addddSAndroid Build Coastguard Worker source = ''' 49*a65addddSAndroid Build Coastguard Worker struct X { 50*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 51*a65addddSAndroid Build Coastguard Worker }; 52*a65addddSAndroid Build Coastguard Worker 53*a65addddSAndroid Build Coastguard Worker fruit::Component<XFactoryAnnot> getComponent() { 54*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 55*a65addddSAndroid Build Coastguard Worker } 56*a65addddSAndroid Build Coastguard Worker 57*a65addddSAndroid Build Coastguard Worker int main() { 58*a65addddSAndroid Build Coastguard Worker fruit::Injector<XFactoryAnnot> injector(getComponent); 59*a65addddSAndroid Build Coastguard Worker injector.get<XFactoryAnnot>()(); 60*a65addddSAndroid Build Coastguard Worker } 61*a65addddSAndroid Build Coastguard Worker ''' 62*a65addddSAndroid Build Coastguard Worker expect_success( 63*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 64*a65addddSAndroid Build Coastguard Worker source, 65*a65addddSAndroid Build Coastguard Worker locals()) 66*a65addddSAndroid Build Coastguard Worker 67*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 68*a65addddSAndroid Build Coastguard Worker ('X()', 'X', 'std::function<X()>'), 69*a65addddSAndroid Build Coastguard Worker ('X()', 'fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, std::function<X()>>'), 70*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>()', 'std::unique_ptr<X>', 'std::function<std::unique_ptr<X>()>'), 71*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>()', 'fruit::Annotated<Annotation1, std::unique_ptr<X>>', 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>'), 72*a65addddSAndroid Build Coastguard Worker ]) 73*a65addddSAndroid Build Coastguard Worker def test_register_factory_success_no_params(self, ConstructX, XPtrAnnot, XPtrFactoryAnnot): 74*a65addddSAndroid Build Coastguard Worker source = ''' 75*a65addddSAndroid Build Coastguard Worker struct X {}; 76*a65addddSAndroid Build Coastguard Worker 77*a65addddSAndroid Build Coastguard Worker fruit::Component<XPtrFactoryAnnot> getComponent() { 78*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 79*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtrAnnot()>([](){return ConstructX;}); 80*a65addddSAndroid Build Coastguard Worker } 81*a65addddSAndroid Build Coastguard Worker 82*a65addddSAndroid Build Coastguard Worker int main() { 83*a65addddSAndroid Build Coastguard Worker fruit::Injector<XPtrFactoryAnnot> injector(getComponent); 84*a65addddSAndroid Build Coastguard Worker injector.get<XPtrFactoryAnnot>()(); 85*a65addddSAndroid Build Coastguard Worker } 86*a65addddSAndroid Build Coastguard Worker ''' 87*a65addddSAndroid Build Coastguard Worker expect_success( 88*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 89*a65addddSAndroid Build Coastguard Worker source, 90*a65addddSAndroid Build Coastguard Worker locals()) 91*a65addddSAndroid Build Coastguard Worker 92*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 93*a65addddSAndroid Build Coastguard Worker '', 94*a65addddSAndroid Build Coastguard Worker 'const', 95*a65addddSAndroid Build Coastguard Worker ]) 96*a65addddSAndroid Build Coastguard Worker def test_register_factory_autoinject_success(self, MaybeConst): 97*a65addddSAndroid Build Coastguard Worker source = ''' 98*a65addddSAndroid Build Coastguard Worker struct Scaler { 99*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 100*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 101*a65addddSAndroid Build Coastguard Worker }; 102*a65addddSAndroid Build Coastguard Worker 103*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 104*a65addddSAndroid Build Coastguard Worker private: 105*a65addddSAndroid Build Coastguard Worker double factor; 106*a65addddSAndroid Build Coastguard Worker 107*a65addddSAndroid Build Coastguard Worker public: 108*a65addddSAndroid Build Coastguard Worker INJECT(ScalerImpl(ASSISTED(double) factor)) 109*a65addddSAndroid Build Coastguard Worker : factor(factor) { 110*a65addddSAndroid Build Coastguard Worker } 111*a65addddSAndroid Build Coastguard Worker 112*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 113*a65addddSAndroid Build Coastguard Worker return x * factor; 114*a65addddSAndroid Build Coastguard Worker } 115*a65addddSAndroid Build Coastguard Worker }; 116*a65addddSAndroid Build Coastguard Worker 117*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 118*a65addddSAndroid Build Coastguard Worker 119*a65addddSAndroid Build Coastguard Worker fruit::Component<MaybeConst ScalerFactory> getScalerComponent() { 120*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 121*a65addddSAndroid Build Coastguard Worker .bind<Scaler, ScalerImpl>(); 122*a65addddSAndroid Build Coastguard Worker } 123*a65addddSAndroid Build Coastguard Worker 124*a65addddSAndroid Build Coastguard Worker int main() { 125*a65addddSAndroid Build Coastguard Worker fruit::Injector<MaybeConst ScalerFactory> injector(getScalerComponent); 126*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 127*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 128*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 129*a65addddSAndroid Build Coastguard Worker } 130*a65addddSAndroid Build Coastguard Worker ''' 131*a65addddSAndroid Build Coastguard Worker expect_success( 132*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 133*a65addddSAndroid Build Coastguard Worker source, 134*a65addddSAndroid Build Coastguard Worker locals()) 135*a65addddSAndroid Build Coastguard Worker 136*a65addddSAndroid Build Coastguard Worker def test_register_factory_autoinject_abstract_class_with_no_virtual_destructor_error(self): 137*a65addddSAndroid Build Coastguard Worker source = ''' 138*a65addddSAndroid Build Coastguard Worker struct Scaler { 139*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 140*a65addddSAndroid Build Coastguard Worker }; 141*a65addddSAndroid Build Coastguard Worker 142*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 143*a65addddSAndroid Build Coastguard Worker public: 144*a65addddSAndroid Build Coastguard Worker INJECT(ScalerImpl(ASSISTED(double))) { 145*a65addddSAndroid Build Coastguard Worker } 146*a65addddSAndroid Build Coastguard Worker 147*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 148*a65addddSAndroid Build Coastguard Worker return x; 149*a65addddSAndroid Build Coastguard Worker } 150*a65addddSAndroid Build Coastguard Worker }; 151*a65addddSAndroid Build Coastguard Worker 152*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 153*a65addddSAndroid Build Coastguard Worker 154*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 155*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 156*a65addddSAndroid Build Coastguard Worker .bind<Scaler, ScalerImpl>(); 157*a65addddSAndroid Build Coastguard Worker } 158*a65addddSAndroid Build Coastguard Worker ''' 159*a65addddSAndroid Build Coastguard Worker expect_compile_error( 160*a65addddSAndroid Build Coastguard Worker r'FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError<std::function<std::unique_ptr<Scaler(,std::default_delete<Scaler>)?>\(double\)>,std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>>', 161*a65addddSAndroid Build Coastguard Worker r'Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr of a class with no virtual destructor', 162*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 163*a65addddSAndroid Build Coastguard Worker source, 164*a65addddSAndroid Build Coastguard Worker locals()) 165*a65addddSAndroid Build Coastguard Worker 166*a65addddSAndroid Build Coastguard Worker def test_register_factory_autoinject_non_abstract_class_with_no_virtual_destructor_error(self): 167*a65addddSAndroid Build Coastguard Worker source = ''' 168*a65addddSAndroid Build Coastguard Worker struct Scaler { 169*a65addddSAndroid Build Coastguard Worker }; 170*a65addddSAndroid Build Coastguard Worker 171*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 172*a65addddSAndroid Build Coastguard Worker public: 173*a65addddSAndroid Build Coastguard Worker INJECT(ScalerImpl(ASSISTED(double))) { 174*a65addddSAndroid Build Coastguard Worker } 175*a65addddSAndroid Build Coastguard Worker }; 176*a65addddSAndroid Build Coastguard Worker 177*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 178*a65addddSAndroid Build Coastguard Worker 179*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 180*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 181*a65addddSAndroid Build Coastguard Worker .bind<Scaler, ScalerImpl>(); 182*a65addddSAndroid Build Coastguard Worker } 183*a65addddSAndroid Build Coastguard Worker ''' 184*a65addddSAndroid Build Coastguard Worker expect_compile_error( 185*a65addddSAndroid Build Coastguard Worker r'FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError<std::function<std::unique_ptr<Scaler(,std::default_delete<Scaler>)?>\(double\)>,std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>>', 186*a65addddSAndroid Build Coastguard Worker r'Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr of a class with no virtual destructor', 187*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 188*a65addddSAndroid Build Coastguard Worker source, 189*a65addddSAndroid Build Coastguard Worker locals()) 190*a65addddSAndroid Build Coastguard Worker 191*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 192*a65addddSAndroid Build Coastguard Worker ('Scaler', 193*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>', 194*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>'), 195*a65addddSAndroid Build Coastguard Worker ('Scaler', 196*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>', 197*a65addddSAndroid Build Coastguard Worker 'const std::function<std::unique_ptr<Scaler>(double)>'), 198*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 199*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>', 200*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>'), 201*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 202*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>', 203*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, const std::function<std::unique_ptr<Scaler>(double)>>'), 204*a65addddSAndroid Build Coastguard Worker ]) 205*a65addddSAndroid Build Coastguard Worker def test_autoinject(self, ScalerAnnot, ScalerFactoryAnnot, MaybeConstScalerFactoryAnnot): 206*a65addddSAndroid Build Coastguard Worker source = ''' 207*a65addddSAndroid Build Coastguard Worker struct Scaler { 208*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 209*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 210*a65addddSAndroid Build Coastguard Worker }; 211*a65addddSAndroid Build Coastguard Worker 212*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 213*a65addddSAndroid Build Coastguard Worker private: 214*a65addddSAndroid Build Coastguard Worker double factor; 215*a65addddSAndroid Build Coastguard Worker 216*a65addddSAndroid Build Coastguard Worker public: 217*a65addddSAndroid Build Coastguard Worker INJECT(ScalerImpl(ASSISTED(double) factor)) 218*a65addddSAndroid Build Coastguard Worker : factor(factor) { 219*a65addddSAndroid Build Coastguard Worker } 220*a65addddSAndroid Build Coastguard Worker 221*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 222*a65addddSAndroid Build Coastguard Worker return x * factor; 223*a65addddSAndroid Build Coastguard Worker } 224*a65addddSAndroid Build Coastguard Worker }; 225*a65addddSAndroid Build Coastguard Worker 226*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 227*a65addddSAndroid Build Coastguard Worker 228*a65addddSAndroid Build Coastguard Worker fruit::Component<MaybeConstScalerFactoryAnnot> getScalerComponent() { 229*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 230*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot, ScalerImpl>(); 231*a65addddSAndroid Build Coastguard Worker } 232*a65addddSAndroid Build Coastguard Worker 233*a65addddSAndroid Build Coastguard Worker int main() { 234*a65addddSAndroid Build Coastguard Worker fruit::Injector<MaybeConstScalerFactoryAnnot> injector(getScalerComponent); 235*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 236*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 237*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 238*a65addddSAndroid Build Coastguard Worker } 239*a65addddSAndroid Build Coastguard Worker ''' 240*a65addddSAndroid Build Coastguard Worker expect_success( 241*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 242*a65addddSAndroid Build Coastguard Worker source, 243*a65addddSAndroid Build Coastguard Worker locals()) 244*a65addddSAndroid Build Coastguard Worker 245*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 246*a65addddSAndroid Build Coastguard Worker '', 247*a65addddSAndroid Build Coastguard Worker 'const', 248*a65addddSAndroid Build Coastguard Worker ]) 249*a65addddSAndroid Build Coastguard Worker def test_autoinject_returning_value(self, MaybeConst): 250*a65addddSAndroid Build Coastguard Worker source = ''' 251*a65addddSAndroid Build Coastguard Worker struct X { 252*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 253*a65addddSAndroid Build Coastguard Worker }; 254*a65addddSAndroid Build Coastguard Worker 255*a65addddSAndroid Build Coastguard Worker struct Scaler { 256*a65addddSAndroid Build Coastguard Worker private: 257*a65addddSAndroid Build Coastguard Worker double factor; 258*a65addddSAndroid Build Coastguard Worker 259*a65addddSAndroid Build Coastguard Worker public: 260*a65addddSAndroid Build Coastguard Worker INJECT(Scaler(ASSISTED(double) factor, X)) 261*a65addddSAndroid Build Coastguard Worker : factor(factor) { 262*a65addddSAndroid Build Coastguard Worker } 263*a65addddSAndroid Build Coastguard Worker 264*a65addddSAndroid Build Coastguard Worker double scale(double x) { 265*a65addddSAndroid Build Coastguard Worker return x * factor; 266*a65addddSAndroid Build Coastguard Worker } 267*a65addddSAndroid Build Coastguard Worker }; 268*a65addddSAndroid Build Coastguard Worker 269*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<Scaler(double)>; 270*a65addddSAndroid Build Coastguard Worker 271*a65addddSAndroid Build Coastguard Worker fruit::Component<MaybeConst ScalerFactory> getScalerComponent() { 272*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 273*a65addddSAndroid Build Coastguard Worker } 274*a65addddSAndroid Build Coastguard Worker 275*a65addddSAndroid Build Coastguard Worker int main() { 276*a65addddSAndroid Build Coastguard Worker fruit::Injector<MaybeConst ScalerFactory> injector(getScalerComponent); 277*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 278*a65addddSAndroid Build Coastguard Worker Scaler scaler = scalerFactory(12.1); 279*a65addddSAndroid Build Coastguard Worker std::cout << scaler.scale(3) << std::endl; 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 @parameterized.parameters([ 288*a65addddSAndroid Build Coastguard Worker ('Scaler', 289*a65addddSAndroid Build Coastguard Worker 'ScalerImpl', 290*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>', 291*a65addddSAndroid Build Coastguard Worker r'std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>', 292*a65addddSAndroid Build Coastguard Worker ), 293*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 294*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, ScalerImpl>', 295*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>', 296*a65addddSAndroid Build Coastguard Worker r'fruit::Annotated<Annotation2,std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>>', 297*a65addddSAndroid Build Coastguard Worker ), 298*a65addddSAndroid Build Coastguard Worker ]) 299*a65addddSAndroid Build Coastguard Worker def test_autoinject_error_abstract_class(self, ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot, ScalerImplFactoryAnnotRegex): 300*a65addddSAndroid Build Coastguard Worker source = ''' 301*a65addddSAndroid Build Coastguard Worker struct Scaler { 302*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 303*a65addddSAndroid Build Coastguard Worker }; 304*a65addddSAndroid Build Coastguard Worker 305*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 306*a65addddSAndroid Build Coastguard Worker private: 307*a65addddSAndroid Build Coastguard Worker double factor; 308*a65addddSAndroid Build Coastguard Worker 309*a65addddSAndroid Build Coastguard Worker public: 310*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 311*a65addddSAndroid Build Coastguard Worker : factor(factor) { 312*a65addddSAndroid Build Coastguard Worker } 313*a65addddSAndroid Build Coastguard Worker 314*a65addddSAndroid Build Coastguard Worker // Note: here we "forgot" to implement scale() (on purpose, for this test) so ScalerImpl is an abstract class. 315*a65addddSAndroid Build Coastguard Worker }; 316*a65addddSAndroid Build Coastguard Worker 317*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot> getScalerComponent() { 318*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 319*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot, ScalerImplAnnot>(); 320*a65addddSAndroid Build Coastguard Worker } 321*a65addddSAndroid Build Coastguard Worker ''' 322*a65addddSAndroid Build Coastguard Worker expect_compile_error( 323*a65addddSAndroid Build Coastguard Worker 'NoBindingFoundForAbstractClassError<ScalerImplFactoryAnnotRegex,ScalerImpl>', 324*a65addddSAndroid Build Coastguard Worker 'No explicit binding was found for T, and note that C is an abstract class', 325*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 326*a65addddSAndroid Build Coastguard Worker source, 327*a65addddSAndroid Build Coastguard Worker locals()) 328*a65addddSAndroid Build Coastguard Worker 329*a65addddSAndroid Build Coastguard Worker def test_autoinject_nonmovable_ok(self): 330*a65addddSAndroid Build Coastguard Worker source = ''' 331*a65addddSAndroid Build Coastguard Worker struct I { 332*a65addddSAndroid Build Coastguard Worker virtual ~I() = default; 333*a65addddSAndroid Build Coastguard Worker }; 334*a65addddSAndroid Build Coastguard Worker 335*a65addddSAndroid Build Coastguard Worker struct C : public I { 336*a65addddSAndroid Build Coastguard Worker INJECT(C()) = default; 337*a65addddSAndroid Build Coastguard Worker 338*a65addddSAndroid Build Coastguard Worker C(const C&) = delete; 339*a65addddSAndroid Build Coastguard Worker C(C&&) = delete; 340*a65addddSAndroid Build Coastguard Worker C& operator=(const C&) = delete; 341*a65addddSAndroid Build Coastguard Worker C& operator=(C&&) = delete; 342*a65addddSAndroid Build Coastguard Worker }; 343*a65addddSAndroid Build Coastguard Worker 344*a65addddSAndroid Build Coastguard Worker using IFactory = std::function<std::unique_ptr<I>()>; 345*a65addddSAndroid Build Coastguard Worker 346*a65addddSAndroid Build Coastguard Worker fruit::Component<IFactory> getIFactory() { 347*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 348*a65addddSAndroid Build Coastguard Worker .bind<I, C>(); 349*a65addddSAndroid Build Coastguard Worker } 350*a65addddSAndroid Build Coastguard Worker 351*a65addddSAndroid Build Coastguard Worker int main() { 352*a65addddSAndroid Build Coastguard Worker fruit::Injector<IFactory> injector(getIFactory); 353*a65addddSAndroid Build Coastguard Worker IFactory iFactory(injector); 354*a65addddSAndroid Build Coastguard Worker std::unique_ptr<I> i = iFactory(); 355*a65addddSAndroid Build Coastguard Worker (void)i; 356*a65addddSAndroid Build Coastguard Worker } 357*a65addddSAndroid Build Coastguard Worker ''' 358*a65addddSAndroid Build Coastguard Worker expect_success( 359*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 360*a65addddSAndroid Build Coastguard Worker source) 361*a65addddSAndroid Build Coastguard Worker 362*a65addddSAndroid Build Coastguard Worker def test_autoinject_moveonly_ref(self): 363*a65addddSAndroid Build Coastguard Worker source = ''' 364*a65addddSAndroid Build Coastguard Worker struct Bar { 365*a65addddSAndroid Build Coastguard Worker Bar() = default; 366*a65addddSAndroid Build Coastguard Worker 367*a65addddSAndroid Build Coastguard Worker Bar(const Bar&) = delete; 368*a65addddSAndroid Build Coastguard Worker Bar(Bar&&) = default; 369*a65addddSAndroid Build Coastguard Worker Bar& operator=(const Bar&) = delete; 370*a65addddSAndroid Build Coastguard Worker Bar& operator=(Bar&&) = default; 371*a65addddSAndroid Build Coastguard Worker }; 372*a65addddSAndroid Build Coastguard Worker 373*a65addddSAndroid Build Coastguard Worker struct Foo { 374*a65addddSAndroid Build Coastguard Worker Foo(Bar&& bar) { 375*a65addddSAndroid Build Coastguard Worker Bar b(std::move(bar)); 376*a65addddSAndroid Build Coastguard Worker (void)b; 377*a65addddSAndroid Build Coastguard Worker } 378*a65addddSAndroid Build Coastguard Worker }; 379*a65addddSAndroid Build Coastguard Worker 380*a65addddSAndroid Build Coastguard Worker using FooFactory = std::function<Foo(Bar&&)>; 381*a65addddSAndroid Build Coastguard Worker 382*a65addddSAndroid Build Coastguard Worker fruit::Component<FooFactory> getComponent() { 383*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 384*a65addddSAndroid Build Coastguard Worker .registerFactory<Foo(fruit::Assisted<Bar&&>)>( 385*a65addddSAndroid Build Coastguard Worker [](Bar&& bar) { 386*a65addddSAndroid Build Coastguard Worker return Foo(std::move(bar)); 387*a65addddSAndroid Build Coastguard Worker }); 388*a65addddSAndroid Build Coastguard Worker } 389*a65addddSAndroid Build Coastguard Worker 390*a65addddSAndroid Build Coastguard Worker int main() { 391*a65addddSAndroid Build Coastguard Worker fruit::Injector<FooFactory> injector(getComponent); 392*a65addddSAndroid Build Coastguard Worker FooFactory fooFactory(injector); 393*a65addddSAndroid Build Coastguard Worker Foo foo = fooFactory(Bar()); 394*a65addddSAndroid Build Coastguard Worker (void)foo; 395*a65addddSAndroid Build Coastguard Worker } 396*a65addddSAndroid Build Coastguard Worker ''' 397*a65addddSAndroid Build Coastguard Worker expect_success( 398*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 399*a65addddSAndroid Build Coastguard Worker source) 400*a65addddSAndroid Build Coastguard Worker 401*a65addddSAndroid Build Coastguard Worker def test_autoinject_nonmovable_ref(self): 402*a65addddSAndroid Build Coastguard Worker source = ''' 403*a65addddSAndroid Build Coastguard Worker struct Bar { 404*a65addddSAndroid Build Coastguard Worker Bar() = default; 405*a65addddSAndroid Build Coastguard Worker 406*a65addddSAndroid Build Coastguard Worker Bar(const Bar&) = delete; 407*a65addddSAndroid Build Coastguard Worker Bar(Bar&&) = delete; 408*a65addddSAndroid Build Coastguard Worker Bar& operator=(const Bar&) = delete; 409*a65addddSAndroid Build Coastguard Worker Bar& operator=(Bar&&) = delete; 410*a65addddSAndroid Build Coastguard Worker }; 411*a65addddSAndroid Build Coastguard Worker 412*a65addddSAndroid Build Coastguard Worker struct Foo { 413*a65addddSAndroid Build Coastguard Worker Foo(Bar& bar) { 414*a65addddSAndroid Build Coastguard Worker (void)bar; 415*a65addddSAndroid Build Coastguard Worker } 416*a65addddSAndroid Build Coastguard Worker }; 417*a65addddSAndroid Build Coastguard Worker 418*a65addddSAndroid Build Coastguard Worker using FooFactory = std::function<Foo(Bar&)>; 419*a65addddSAndroid Build Coastguard Worker 420*a65addddSAndroid Build Coastguard Worker fruit::Component<FooFactory> getComponent() { 421*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 422*a65addddSAndroid Build Coastguard Worker .registerFactory<Foo(fruit::Assisted<Bar&>)>( 423*a65addddSAndroid Build Coastguard Worker [](Bar& bar) { 424*a65addddSAndroid Build Coastguard Worker return Foo(bar); 425*a65addddSAndroid Build Coastguard Worker }); 426*a65addddSAndroid Build Coastguard Worker } 427*a65addddSAndroid Build Coastguard Worker 428*a65addddSAndroid Build Coastguard Worker int main() { 429*a65addddSAndroid Build Coastguard Worker fruit::Injector<FooFactory> injector(getComponent); 430*a65addddSAndroid Build Coastguard Worker FooFactory fooFactory(injector); 431*a65addddSAndroid Build Coastguard Worker Bar bar; 432*a65addddSAndroid Build Coastguard Worker Foo foo = fooFactory(bar); 433*a65addddSAndroid Build Coastguard Worker (void)foo; 434*a65addddSAndroid Build Coastguard Worker } 435*a65addddSAndroid Build Coastguard Worker ''' 436*a65addddSAndroid Build Coastguard Worker expect_success( 437*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 438*a65addddSAndroid Build Coastguard Worker source) 439*a65addddSAndroid Build Coastguard Worker 440*a65addddSAndroid Build Coastguard Worker def test_autoinject_2_assisted_params(self): 441*a65addddSAndroid Build Coastguard Worker source = ''' 442*a65addddSAndroid Build Coastguard Worker struct Foo { 443*a65addddSAndroid Build Coastguard Worker Foo(int x, float y) { 444*a65addddSAndroid Build Coastguard Worker (void)x; 445*a65addddSAndroid Build Coastguard Worker (void)y; 446*a65addddSAndroid Build Coastguard Worker } 447*a65addddSAndroid Build Coastguard Worker }; 448*a65addddSAndroid Build Coastguard Worker 449*a65addddSAndroid Build Coastguard Worker using FooFactory = std::function<Foo(int, float)>; 450*a65addddSAndroid Build Coastguard Worker 451*a65addddSAndroid Build Coastguard Worker fruit::Component<FooFactory> getComponent() { 452*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 453*a65addddSAndroid Build Coastguard Worker .registerFactory<Foo(fruit::Assisted<int>, fruit::Assisted<float>)>( 454*a65addddSAndroid Build Coastguard Worker [](int x, float y) { 455*a65addddSAndroid Build Coastguard Worker return Foo(x, y); 456*a65addddSAndroid Build Coastguard Worker }); 457*a65addddSAndroid Build Coastguard Worker } 458*a65addddSAndroid Build Coastguard Worker 459*a65addddSAndroid Build Coastguard Worker int main() { 460*a65addddSAndroid Build Coastguard Worker fruit::Injector<FooFactory> injector(getComponent); 461*a65addddSAndroid Build Coastguard Worker FooFactory fooFactory(injector); 462*a65addddSAndroid Build Coastguard Worker Foo foo = fooFactory(1, 2.3f); 463*a65addddSAndroid Build Coastguard Worker (void)foo; 464*a65addddSAndroid Build Coastguard Worker } 465*a65addddSAndroid Build Coastguard Worker ''' 466*a65addddSAndroid Build Coastguard Worker expect_success( 467*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 468*a65addddSAndroid Build Coastguard Worker source) 469*a65addddSAndroid Build Coastguard Worker 470*a65addddSAndroid Build Coastguard Worker def test_autoinject_assisted_params_ref(self): 471*a65addddSAndroid Build Coastguard Worker source = ''' 472*a65addddSAndroid Build Coastguard Worker struct Foo { 473*a65addddSAndroid Build Coastguard Worker Foo(int x, float y, char z) { 474*a65addddSAndroid Build Coastguard Worker (void)x; 475*a65addddSAndroid Build Coastguard Worker (void)y; 476*a65addddSAndroid Build Coastguard Worker (void)z; 477*a65addddSAndroid Build Coastguard Worker } 478*a65addddSAndroid Build Coastguard Worker }; 479*a65addddSAndroid Build Coastguard Worker 480*a65addddSAndroid Build Coastguard Worker using FooFactory = std::function<Foo(int&, float&&, char)>; 481*a65addddSAndroid Build Coastguard Worker 482*a65addddSAndroid Build Coastguard Worker fruit::Component<FooFactory> getComponent() { 483*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 484*a65addddSAndroid Build Coastguard Worker .registerFactory<Foo(fruit::Assisted<int&>, fruit::Assisted<float&&>, fruit::Assisted<char>)>( 485*a65addddSAndroid Build Coastguard Worker [](int& x, float&& y, char z) { 486*a65addddSAndroid Build Coastguard Worker return Foo(x, std::move(y), z); 487*a65addddSAndroid Build Coastguard Worker }); 488*a65addddSAndroid Build Coastguard Worker } 489*a65addddSAndroid Build Coastguard Worker 490*a65addddSAndroid Build Coastguard Worker int main() { 491*a65addddSAndroid Build Coastguard Worker fruit::Injector<FooFactory> injector(getComponent); 492*a65addddSAndroid Build Coastguard Worker FooFactory fooFactory(injector); 493*a65addddSAndroid Build Coastguard Worker int x = 1; 494*a65addddSAndroid Build Coastguard Worker Foo foo = fooFactory(x, 2.3f, 'z'); 495*a65addddSAndroid Build Coastguard Worker (void)foo; 496*a65addddSAndroid Build Coastguard Worker } 497*a65addddSAndroid Build Coastguard Worker ''' 498*a65addddSAndroid Build Coastguard Worker expect_success( 499*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 500*a65addddSAndroid Build Coastguard Worker source) 501*a65addddSAndroid Build Coastguard Worker 502*a65addddSAndroid Build Coastguard Worker def test_autoinject_2_assisted_params_returning_value(self): 503*a65addddSAndroid Build Coastguard Worker source = ''' 504*a65addddSAndroid Build Coastguard Worker struct Foo { 505*a65addddSAndroid Build Coastguard Worker Foo(int x, float y) { 506*a65addddSAndroid Build Coastguard Worker (void)x; 507*a65addddSAndroid Build Coastguard Worker (void)y; 508*a65addddSAndroid Build Coastguard Worker } 509*a65addddSAndroid Build Coastguard Worker }; 510*a65addddSAndroid Build Coastguard Worker 511*a65addddSAndroid Build Coastguard Worker using FooFactory = std::function<Foo(int, float)>; 512*a65addddSAndroid Build Coastguard Worker 513*a65addddSAndroid Build Coastguard Worker fruit::Component<FooFactory> getComponent() { 514*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 515*a65addddSAndroid Build Coastguard Worker .registerFactory<Foo(fruit::Assisted<int>, fruit::Assisted<float>)>( 516*a65addddSAndroid Build Coastguard Worker [](int x, float y) { 517*a65addddSAndroid Build Coastguard Worker return Foo(x, y); 518*a65addddSAndroid Build Coastguard Worker }); 519*a65addddSAndroid Build Coastguard Worker } 520*a65addddSAndroid Build Coastguard Worker 521*a65addddSAndroid Build Coastguard Worker int main() { 522*a65addddSAndroid Build Coastguard Worker fruit::Injector<FooFactory> injector(getComponent); 523*a65addddSAndroid Build Coastguard Worker FooFactory fooFactory(injector); 524*a65addddSAndroid Build Coastguard Worker Foo foo = fooFactory(1, 2.3f); 525*a65addddSAndroid Build Coastguard Worker (void)foo; 526*a65addddSAndroid Build Coastguard Worker } 527*a65addddSAndroid Build Coastguard Worker ''' 528*a65addddSAndroid Build Coastguard Worker expect_success( 529*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 530*a65addddSAndroid Build Coastguard Worker source) 531*a65addddSAndroid Build Coastguard Worker 532*a65addddSAndroid Build Coastguard Worker def test_autoinject_instances_bound_to_assisted_params(self): 533*a65addddSAndroid Build Coastguard Worker source = ''' 534*a65addddSAndroid Build Coastguard Worker struct X {}; 535*a65addddSAndroid Build Coastguard Worker struct Y {}; 536*a65addddSAndroid Build Coastguard Worker 537*a65addddSAndroid Build Coastguard Worker struct Foo { 538*a65addddSAndroid Build Coastguard Worker Foo(X x, Y y) { 539*a65addddSAndroid Build Coastguard Worker (void)x; 540*a65addddSAndroid Build Coastguard Worker (void)y; 541*a65addddSAndroid Build Coastguard Worker } 542*a65addddSAndroid Build Coastguard Worker }; 543*a65addddSAndroid Build Coastguard Worker 544*a65addddSAndroid Build Coastguard Worker using FooFactory = std::function<Foo()>; 545*a65addddSAndroid Build Coastguard Worker 546*a65addddSAndroid Build Coastguard Worker fruit::Component<FooFactory> getComponent() { 547*a65addddSAndroid Build Coastguard Worker static X x = X(); 548*a65addddSAndroid Build Coastguard Worker static Y y = Y(); 549*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 550*a65addddSAndroid Build Coastguard Worker .bindInstance(x) 551*a65addddSAndroid Build Coastguard Worker .bindInstance(y) 552*a65addddSAndroid Build Coastguard Worker .registerFactory<Foo(X, Y)>( 553*a65addddSAndroid Build Coastguard Worker [](X x, Y y) { 554*a65addddSAndroid Build Coastguard Worker return Foo(x, y); 555*a65addddSAndroid Build Coastguard Worker }); 556*a65addddSAndroid Build Coastguard Worker } 557*a65addddSAndroid Build Coastguard Worker 558*a65addddSAndroid Build Coastguard Worker 559*a65addddSAndroid Build Coastguard Worker int main() { 560*a65addddSAndroid Build Coastguard Worker fruit::Injector<FooFactory> injector(getComponent); 561*a65addddSAndroid Build Coastguard Worker FooFactory fooFactory(injector); 562*a65addddSAndroid Build Coastguard Worker Foo foo = fooFactory(); 563*a65addddSAndroid Build Coastguard Worker (void)foo; 564*a65addddSAndroid Build Coastguard Worker } 565*a65addddSAndroid Build Coastguard Worker ''' 566*a65addddSAndroid Build Coastguard Worker expect_success( 567*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 568*a65addddSAndroid Build Coastguard Worker source) 569*a65addddSAndroid Build Coastguard Worker 570*a65addddSAndroid Build Coastguard Worker def test_autoinject_2_assisted_params_plus_nonassisted_params(self): 571*a65addddSAndroid Build Coastguard Worker source = ''' 572*a65addddSAndroid Build Coastguard Worker struct X {}; 573*a65addddSAndroid Build Coastguard Worker struct Y {}; 574*a65addddSAndroid Build Coastguard Worker struct Z {}; 575*a65addddSAndroid Build Coastguard Worker 576*a65addddSAndroid Build Coastguard Worker struct Foo { 577*a65addddSAndroid Build Coastguard Worker Foo(X, Y, int, float, Z) { 578*a65addddSAndroid Build Coastguard Worker } 579*a65addddSAndroid Build Coastguard Worker }; 580*a65addddSAndroid Build Coastguard Worker 581*a65addddSAndroid Build Coastguard Worker using FooPtrFactory = std::function<std::unique_ptr<Foo>(int, float)>; 582*a65addddSAndroid Build Coastguard Worker 583*a65addddSAndroid Build Coastguard Worker fruit::Component<FooPtrFactory> getComponent() { 584*a65addddSAndroid Build Coastguard Worker static X x = X(); 585*a65addddSAndroid Build Coastguard Worker static Y y = Y(); 586*a65addddSAndroid Build Coastguard Worker static Z z = Z(); 587*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 588*a65addddSAndroid Build Coastguard Worker .bindInstance(x) 589*a65addddSAndroid Build Coastguard Worker .bindInstance(y) 590*a65addddSAndroid Build Coastguard Worker .bindInstance(z) 591*a65addddSAndroid Build Coastguard Worker .registerFactory<std::unique_ptr<Foo>(X, Y, fruit::Assisted<int>, fruit::Assisted<float>, Z)>( 592*a65addddSAndroid Build Coastguard Worker [](X x, Y y, int n, float a, Z z) { 593*a65addddSAndroid Build Coastguard Worker return std::unique_ptr<Foo>(new Foo(x, y, n, a, z)); 594*a65addddSAndroid Build Coastguard Worker }); 595*a65addddSAndroid Build Coastguard Worker } 596*a65addddSAndroid Build Coastguard Worker 597*a65addddSAndroid Build Coastguard Worker int main() { 598*a65addddSAndroid Build Coastguard Worker fruit::Injector<FooPtrFactory> injector(getComponent); 599*a65addddSAndroid Build Coastguard Worker FooPtrFactory fooPtrFactory(injector); 600*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Foo> foo = fooPtrFactory(1, 3.4f); 601*a65addddSAndroid Build Coastguard Worker (void)foo; 602*a65addddSAndroid Build Coastguard Worker } 603*a65addddSAndroid Build Coastguard Worker ''' 604*a65addddSAndroid Build Coastguard Worker expect_success( 605*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 606*a65addddSAndroid Build Coastguard Worker source) 607*a65addddSAndroid Build Coastguard Worker 608*a65addddSAndroid Build Coastguard Worker def test_autoinject_2_assisted_params_plus_nonassisted_params_returning_value(self): 609*a65addddSAndroid Build Coastguard Worker source = ''' 610*a65addddSAndroid Build Coastguard Worker struct X {}; 611*a65addddSAndroid Build Coastguard Worker struct Y {}; 612*a65addddSAndroid Build Coastguard Worker struct Z {}; 613*a65addddSAndroid Build Coastguard Worker 614*a65addddSAndroid Build Coastguard Worker struct Foo { 615*a65addddSAndroid Build Coastguard Worker Foo(X, Y, int, float, Z) { 616*a65addddSAndroid Build Coastguard Worker } 617*a65addddSAndroid Build Coastguard Worker }; 618*a65addddSAndroid Build Coastguard Worker 619*a65addddSAndroid Build Coastguard Worker using FooFactory = std::function<Foo(int, float)>; 620*a65addddSAndroid Build Coastguard Worker 621*a65addddSAndroid Build Coastguard Worker fruit::Component<FooFactory> getComponent() { 622*a65addddSAndroid Build Coastguard Worker static X x = X(); 623*a65addddSAndroid Build Coastguard Worker static Y y = Y(); 624*a65addddSAndroid Build Coastguard Worker static Z z = Z(); 625*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 626*a65addddSAndroid Build Coastguard Worker .bindInstance(x) 627*a65addddSAndroid Build Coastguard Worker .bindInstance(y) 628*a65addddSAndroid Build Coastguard Worker .bindInstance(z) 629*a65addddSAndroid Build Coastguard Worker .registerFactory<Foo(X, Y, fruit::Assisted<int>, fruit::Assisted<float>, Z)>( 630*a65addddSAndroid Build Coastguard Worker [](X x, Y y, int n, float a, Z z) { 631*a65addddSAndroid Build Coastguard Worker return Foo(x, y, n, a, z); 632*a65addddSAndroid Build Coastguard Worker }); 633*a65addddSAndroid Build Coastguard Worker } 634*a65addddSAndroid Build Coastguard Worker 635*a65addddSAndroid Build Coastguard Worker int main() { 636*a65addddSAndroid Build Coastguard Worker fruit::Injector<FooFactory> injector(getComponent); 637*a65addddSAndroid Build Coastguard Worker FooFactory fooFactory(injector); 638*a65addddSAndroid Build Coastguard Worker Foo foo = fooFactory(1, 3.4f); 639*a65addddSAndroid Build Coastguard Worker (void)foo; 640*a65addddSAndroid Build Coastguard Worker } 641*a65addddSAndroid Build Coastguard Worker ''' 642*a65addddSAndroid Build Coastguard Worker expect_success( 643*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 644*a65addddSAndroid Build Coastguard Worker source) 645*a65addddSAndroid Build Coastguard Worker 646*a65addddSAndroid Build Coastguard Worker def test_autoinject_mixed_assisted_and_injected_params(self): 647*a65addddSAndroid Build Coastguard Worker source = ''' 648*a65addddSAndroid Build Coastguard Worker struct X {}; 649*a65addddSAndroid Build Coastguard Worker struct Y {}; 650*a65addddSAndroid Build Coastguard Worker 651*a65addddSAndroid Build Coastguard Worker struct Foo { 652*a65addddSAndroid Build Coastguard Worker Foo(int, float, X, Y, double) { 653*a65addddSAndroid Build Coastguard Worker } 654*a65addddSAndroid Build Coastguard Worker }; 655*a65addddSAndroid Build Coastguard Worker 656*a65addddSAndroid Build Coastguard Worker using FooFactory = std::function<Foo(int, float, double)>; 657*a65addddSAndroid Build Coastguard Worker 658*a65addddSAndroid Build Coastguard Worker fruit::Component<FooFactory> getComponent() { 659*a65addddSAndroid Build Coastguard Worker static X x = X(); 660*a65addddSAndroid Build Coastguard Worker static Y y = Y(); 661*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 662*a65addddSAndroid Build Coastguard Worker .bindInstance(x) 663*a65addddSAndroid Build Coastguard Worker .bindInstance(y) 664*a65addddSAndroid Build Coastguard Worker .registerFactory<Foo(fruit::Assisted<int>, fruit::Assisted<float>, X, Y, fruit::Assisted<double>)>( 665*a65addddSAndroid Build Coastguard Worker [](int n, float a, X x, Y y, double d) { 666*a65addddSAndroid Build Coastguard Worker return Foo(n, a, x, y, d); 667*a65addddSAndroid Build Coastguard Worker }); 668*a65addddSAndroid Build Coastguard Worker } 669*a65addddSAndroid Build Coastguard Worker 670*a65addddSAndroid Build Coastguard Worker int main() { 671*a65addddSAndroid Build Coastguard Worker fruit::Injector<FooFactory> injector(getComponent); 672*a65addddSAndroid Build Coastguard Worker FooFactory fooFactory(injector); 673*a65addddSAndroid Build Coastguard Worker Foo foo = fooFactory(1, 3.4f, 3.456); 674*a65addddSAndroid Build Coastguard Worker (void)foo; 675*a65addddSAndroid Build Coastguard Worker } 676*a65addddSAndroid Build Coastguard Worker ''' 677*a65addddSAndroid Build Coastguard Worker expect_success( 678*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 679*a65addddSAndroid Build Coastguard Worker source) 680*a65addddSAndroid Build Coastguard Worker 681*a65addddSAndroid Build Coastguard Worker def test_autoinject_annotation_in_signature_return_type(self): 682*a65addddSAndroid Build Coastguard Worker source = ''' 683*a65addddSAndroid Build Coastguard Worker struct X { 684*a65addddSAndroid Build Coastguard Worker using Inject = fruit::Annotated<Annotation1, X>(); 685*a65addddSAndroid Build Coastguard Worker }; 686*a65addddSAndroid Build Coastguard Worker 687*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>> getComponent() { 688*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 689*a65addddSAndroid Build Coastguard Worker } 690*a65addddSAndroid Build Coastguard Worker ''' 691*a65addddSAndroid Build Coastguard Worker expect_compile_error( 692*a65addddSAndroid Build Coastguard Worker 'InjectTypedefWithAnnotationError<X>', 693*a65addddSAndroid Build Coastguard Worker 'C::Inject is a signature that returns an annotated type', 694*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 695*a65addddSAndroid Build Coastguard Worker source) 696*a65addddSAndroid Build Coastguard Worker 697*a65addddSAndroid Build Coastguard Worker def test_autoinject_annotation_in_signature_return_type_returning_value(self): 698*a65addddSAndroid Build Coastguard Worker source = ''' 699*a65addddSAndroid Build Coastguard Worker struct X { 700*a65addddSAndroid Build Coastguard Worker using Inject = fruit::Annotated<Annotation1, X>(); 701*a65addddSAndroid Build Coastguard Worker }; 702*a65addddSAndroid Build Coastguard Worker 703*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Annotated<Annotation1, std::function<X()>>> getComponent() { 704*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 705*a65addddSAndroid Build Coastguard Worker } 706*a65addddSAndroid Build Coastguard Worker ''' 707*a65addddSAndroid Build Coastguard Worker expect_compile_error( 708*a65addddSAndroid Build Coastguard Worker 'InjectTypedefWithAnnotationError<X>', 709*a65addddSAndroid Build Coastguard Worker 'C::Inject is a signature that returns an annotated type', 710*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 711*a65addddSAndroid Build Coastguard Worker source) 712*a65addddSAndroid Build Coastguard Worker 713*a65addddSAndroid Build Coastguard Worker def test_autoinject_from_provider_simple(self): 714*a65addddSAndroid Build Coastguard Worker source = ''' 715*a65addddSAndroid Build Coastguard Worker struct X { 716*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 717*a65addddSAndroid Build Coastguard Worker }; 718*a65addddSAndroid Build Coastguard Worker 719*a65addddSAndroid Build Coastguard Worker struct Scaler { 720*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 721*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 722*a65addddSAndroid Build Coastguard Worker }; 723*a65addddSAndroid Build Coastguard Worker 724*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 725*a65addddSAndroid Build Coastguard Worker private: 726*a65addddSAndroid Build Coastguard Worker double factor; 727*a65addddSAndroid Build Coastguard Worker 728*a65addddSAndroid Build Coastguard Worker public: 729*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor, X) 730*a65addddSAndroid Build Coastguard Worker : factor(factor) { 731*a65addddSAndroid Build Coastguard Worker } 732*a65addddSAndroid Build Coastguard Worker 733*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 734*a65addddSAndroid Build Coastguard Worker return x * factor; 735*a65addddSAndroid Build Coastguard Worker } 736*a65addddSAndroid Build Coastguard Worker }; 737*a65addddSAndroid Build Coastguard Worker 738*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 739*a65addddSAndroid Build Coastguard Worker 740*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 741*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 742*a65addddSAndroid Build Coastguard Worker .registerProvider([](X x) { 743*a65addddSAndroid Build Coastguard Worker return std::function<std::unique_ptr<ScalerImpl>(double)>([x](double n){ 744*a65addddSAndroid Build Coastguard Worker return std::unique_ptr<ScalerImpl>(new ScalerImpl(n, x)); 745*a65addddSAndroid Build Coastguard Worker }); 746*a65addddSAndroid Build Coastguard Worker }) 747*a65addddSAndroid Build Coastguard Worker .bind<Scaler, ScalerImpl>(); 748*a65addddSAndroid Build Coastguard Worker } 749*a65addddSAndroid Build Coastguard Worker 750*a65addddSAndroid Build Coastguard Worker int main() { 751*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactory> injector(getScalerComponent); 752*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 753*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 754*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 755*a65addddSAndroid Build Coastguard Worker } 756*a65addddSAndroid Build Coastguard Worker ''' 757*a65addddSAndroid Build Coastguard Worker expect_success( 758*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 759*a65addddSAndroid Build Coastguard Worker source) 760*a65addddSAndroid Build Coastguard Worker 761*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 762*a65addddSAndroid Build Coastguard Worker ('Scaler', 763*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>', 764*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>', 765*a65addddSAndroid Build Coastguard Worker 'ScalerImpl', 766*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<ScalerImpl>(double)>'), 767*a65addddSAndroid Build Coastguard Worker ('Scaler', 768*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>', 769*a65addddSAndroid Build Coastguard Worker 'const std::function<std::unique_ptr<Scaler>(double)>', 770*a65addddSAndroid Build Coastguard Worker 'ScalerImpl', 771*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<ScalerImpl>(double)>'), 772*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 773*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>', 774*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>', 775*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, ScalerImpl>', 776*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, std::function<std::unique_ptr<ScalerImpl>(double)>>'), 777*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 778*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>', 779*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, const std::function<std::unique_ptr<Scaler>(double)>>', 780*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, ScalerImpl>', 781*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, std::function<std::unique_ptr<ScalerImpl>(double)>>'), 782*a65addddSAndroid Build Coastguard Worker ]) 783*a65addddSAndroid Build Coastguard Worker def test_autoinject_from_provider(self, ScalerAnnot, ScalerFactoryAnnot, MaybeConstScalerFactoryAnnot, ScalerImplAnnot, ScalerImplFactoryAnnot): 784*a65addddSAndroid Build Coastguard Worker source = ''' 785*a65addddSAndroid Build Coastguard Worker struct X { 786*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 787*a65addddSAndroid Build Coastguard Worker }; 788*a65addddSAndroid Build Coastguard Worker 789*a65addddSAndroid Build Coastguard Worker struct Scaler { 790*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 791*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 792*a65addddSAndroid Build Coastguard Worker }; 793*a65addddSAndroid Build Coastguard Worker 794*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 795*a65addddSAndroid Build Coastguard Worker private: 796*a65addddSAndroid Build Coastguard Worker double factor; 797*a65addddSAndroid Build Coastguard Worker 798*a65addddSAndroid Build Coastguard Worker public: 799*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor, X) 800*a65addddSAndroid Build Coastguard Worker : factor(factor) { 801*a65addddSAndroid Build Coastguard Worker } 802*a65addddSAndroid Build Coastguard Worker 803*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 804*a65addddSAndroid Build Coastguard Worker return x * factor; 805*a65addddSAndroid Build Coastguard Worker } 806*a65addddSAndroid Build Coastguard Worker }; 807*a65addddSAndroid Build Coastguard Worker 808*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 809*a65addddSAndroid Build Coastguard Worker using ScalerImplFactory = std::function<std::unique_ptr<ScalerImpl>(double)>; 810*a65addddSAndroid Build Coastguard Worker 811*a65addddSAndroid Build Coastguard Worker fruit::Component<MaybeConstScalerFactoryAnnot> getScalerComponent() { 812*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 813*a65addddSAndroid Build Coastguard Worker .registerProvider<ScalerImplFactoryAnnot(X)>([](X x) { 814*a65addddSAndroid Build Coastguard Worker return std::function<std::unique_ptr<ScalerImpl>(double)>([x](double n){ 815*a65addddSAndroid Build Coastguard Worker return std::unique_ptr<ScalerImpl>(new ScalerImpl(n, x)); 816*a65addddSAndroid Build Coastguard Worker }); 817*a65addddSAndroid Build Coastguard Worker }) 818*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot, ScalerImplAnnot>(); 819*a65addddSAndroid Build Coastguard Worker } 820*a65addddSAndroid Build Coastguard Worker 821*a65addddSAndroid Build Coastguard Worker int main() { 822*a65addddSAndroid Build Coastguard Worker fruit::Injector<MaybeConstScalerFactoryAnnot> injector(getScalerComponent); 823*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 824*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 825*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 826*a65addddSAndroid Build Coastguard Worker } 827*a65addddSAndroid Build Coastguard Worker ''' 828*a65addddSAndroid Build Coastguard Worker expect_success( 829*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 830*a65addddSAndroid Build Coastguard Worker source, 831*a65addddSAndroid Build Coastguard Worker locals()) 832*a65addddSAndroid Build Coastguard Worker 833*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 834*a65addddSAndroid Build Coastguard Worker 'ScalerFactory', 835*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, ScalerFactory>', 836*a65addddSAndroid Build Coastguard Worker ]) 837*a65addddSAndroid Build Coastguard Worker def test_autoinject_from_provider_returning_value(self, ScalerFactoryAnnot): 838*a65addddSAndroid Build Coastguard Worker source = ''' 839*a65addddSAndroid Build Coastguard Worker struct X { 840*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 841*a65addddSAndroid Build Coastguard Worker }; 842*a65addddSAndroid Build Coastguard Worker 843*a65addddSAndroid Build Coastguard Worker struct Scaler { 844*a65addddSAndroid Build Coastguard Worker private: 845*a65addddSAndroid Build Coastguard Worker double factor; 846*a65addddSAndroid Build Coastguard Worker 847*a65addddSAndroid Build Coastguard Worker public: 848*a65addddSAndroid Build Coastguard Worker Scaler(double factor, X) 849*a65addddSAndroid Build Coastguard Worker : factor(factor) { 850*a65addddSAndroid Build Coastguard Worker } 851*a65addddSAndroid Build Coastguard Worker 852*a65addddSAndroid Build Coastguard Worker double scale(double x) { 853*a65addddSAndroid Build Coastguard Worker return x * factor; 854*a65addddSAndroid Build Coastguard Worker } 855*a65addddSAndroid Build Coastguard Worker }; 856*a65addddSAndroid Build Coastguard Worker 857*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<Scaler(double)>; 858*a65addddSAndroid Build Coastguard Worker 859*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot> getScalerComponent() { 860*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 861*a65addddSAndroid Build Coastguard Worker .registerProvider<ScalerFactoryAnnot(X)>([](X x) { 862*a65addddSAndroid Build Coastguard Worker return std::function<Scaler(double)>([x](double n){ 863*a65addddSAndroid Build Coastguard Worker return Scaler(n, x); 864*a65addddSAndroid Build Coastguard Worker }); 865*a65addddSAndroid Build Coastguard Worker }); 866*a65addddSAndroid Build Coastguard Worker } 867*a65addddSAndroid Build Coastguard Worker 868*a65addddSAndroid Build Coastguard Worker int main() { 869*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent); 870*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 871*a65addddSAndroid Build Coastguard Worker Scaler scaler = scalerFactory(12.1); 872*a65addddSAndroid Build Coastguard Worker std::cout << scaler.scale(3) << std::endl; 873*a65addddSAndroid Build Coastguard Worker } 874*a65addddSAndroid Build Coastguard Worker ''' 875*a65addddSAndroid Build Coastguard Worker expect_success( 876*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 877*a65addddSAndroid Build Coastguard Worker source, 878*a65addddSAndroid Build Coastguard Worker locals()) 879*a65addddSAndroid Build Coastguard Worker 880*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 881*a65addddSAndroid Build Coastguard Worker '', 882*a65addddSAndroid Build Coastguard Worker 'const', 883*a65addddSAndroid Build Coastguard Worker ], [ 884*a65addddSAndroid Build Coastguard Worker 'X', 885*a65addddSAndroid Build Coastguard Worker 'ANNOTATED(Annotation1, X)', 886*a65addddSAndroid Build Coastguard Worker ]) 887*a65addddSAndroid Build Coastguard Worker def test_autoinject_with_binding(self, MaybeConst, X_ANNOT): 888*a65addddSAndroid Build Coastguard Worker source = ''' 889*a65addddSAndroid Build Coastguard Worker struct X { 890*a65addddSAndroid Build Coastguard Worker using Inject = X(); 891*a65addddSAndroid Build Coastguard Worker }; 892*a65addddSAndroid Build Coastguard Worker 893*a65addddSAndroid Build Coastguard Worker struct Scaler { 894*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 895*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 896*a65addddSAndroid Build Coastguard Worker }; 897*a65addddSAndroid Build Coastguard Worker 898*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 899*a65addddSAndroid Build Coastguard Worker private: 900*a65addddSAndroid Build Coastguard Worker double factor; 901*a65addddSAndroid Build Coastguard Worker 902*a65addddSAndroid Build Coastguard Worker public: 903*a65addddSAndroid Build Coastguard Worker INJECT(ScalerImpl(ASSISTED(double) factor, X_ANNOT x)) 904*a65addddSAndroid Build Coastguard Worker : factor(factor) { 905*a65addddSAndroid Build Coastguard Worker (void)x; 906*a65addddSAndroid Build Coastguard Worker } 907*a65addddSAndroid Build Coastguard Worker 908*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 909*a65addddSAndroid Build Coastguard Worker return x * factor; 910*a65addddSAndroid Build Coastguard Worker } 911*a65addddSAndroid Build Coastguard Worker }; 912*a65addddSAndroid Build Coastguard Worker 913*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 914*a65addddSAndroid Build Coastguard Worker 915*a65addddSAndroid Build Coastguard Worker fruit::Component<MaybeConst ScalerFactory> getScalerComponent() { 916*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 917*a65addddSAndroid Build Coastguard Worker .bind<Scaler, ScalerImpl>(); 918*a65addddSAndroid Build Coastguard Worker } 919*a65addddSAndroid Build Coastguard Worker 920*a65addddSAndroid Build Coastguard Worker int main() { 921*a65addddSAndroid Build Coastguard Worker fruit::Injector<MaybeConst ScalerFactory> injector(getScalerComponent); 922*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 923*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 924*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 925*a65addddSAndroid Build Coastguard Worker } 926*a65addddSAndroid Build Coastguard Worker ''' 927*a65addddSAndroid Build Coastguard Worker expect_success( 928*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 929*a65addddSAndroid Build Coastguard Worker source, 930*a65addddSAndroid Build Coastguard Worker locals()) 931*a65addddSAndroid Build Coastguard Worker 932*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 933*a65addddSAndroid Build Coastguard Worker '', 934*a65addddSAndroid Build Coastguard Worker 'const', 935*a65addddSAndroid Build Coastguard Worker ], [ 936*a65addddSAndroid Build Coastguard Worker 'X', 937*a65addddSAndroid Build Coastguard Worker 'ANNOTATED(Annotation1, X)', 938*a65addddSAndroid Build Coastguard Worker ]) 939*a65addddSAndroid Build Coastguard Worker def test_autoinject_with_binding_returning_value(self, MaybeConst, X_ANNOT): 940*a65addddSAndroid Build Coastguard Worker source = ''' 941*a65addddSAndroid Build Coastguard Worker struct X { 942*a65addddSAndroid Build Coastguard Worker using Inject = X(); 943*a65addddSAndroid Build Coastguard Worker }; 944*a65addddSAndroid Build Coastguard Worker 945*a65addddSAndroid Build Coastguard Worker struct Scaler { 946*a65addddSAndroid Build Coastguard Worker private: 947*a65addddSAndroid Build Coastguard Worker double factor; 948*a65addddSAndroid Build Coastguard Worker 949*a65addddSAndroid Build Coastguard Worker public: 950*a65addddSAndroid Build Coastguard Worker INJECT(Scaler(ASSISTED(double) factor, X_ANNOT x)) 951*a65addddSAndroid Build Coastguard Worker : factor(factor) { 952*a65addddSAndroid Build Coastguard Worker (void)x; 953*a65addddSAndroid Build Coastguard Worker } 954*a65addddSAndroid Build Coastguard Worker 955*a65addddSAndroid Build Coastguard Worker double scale(double x) { 956*a65addddSAndroid Build Coastguard Worker return x * factor; 957*a65addddSAndroid Build Coastguard Worker } 958*a65addddSAndroid Build Coastguard Worker }; 959*a65addddSAndroid Build Coastguard Worker 960*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<Scaler(double)>; 961*a65addddSAndroid Build Coastguard Worker 962*a65addddSAndroid Build Coastguard Worker fruit::Component<MaybeConst ScalerFactory> getScalerComponent() { 963*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 964*a65addddSAndroid Build Coastguard Worker } 965*a65addddSAndroid Build Coastguard Worker 966*a65addddSAndroid Build Coastguard Worker int main() { 967*a65addddSAndroid Build Coastguard Worker fruit::Injector<MaybeConst ScalerFactory> injector(getScalerComponent); 968*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 969*a65addddSAndroid Build Coastguard Worker Scaler scaler = scalerFactory(12.1); 970*a65addddSAndroid Build Coastguard Worker std::cout << scaler.scale(3) << std::endl; 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_autoinject_with_binding_variant(self): 979*a65addddSAndroid Build Coastguard Worker source = ''' 980*a65addddSAndroid Build Coastguard Worker struct X { 981*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 982*a65addddSAndroid Build Coastguard Worker }; 983*a65addddSAndroid Build Coastguard Worker 984*a65addddSAndroid Build Coastguard Worker struct Scaler { 985*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 986*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 987*a65addddSAndroid Build Coastguard Worker }; 988*a65addddSAndroid Build Coastguard Worker 989*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 990*a65addddSAndroid Build Coastguard Worker private: 991*a65addddSAndroid Build Coastguard Worker double factor; 992*a65addddSAndroid Build Coastguard Worker 993*a65addddSAndroid Build Coastguard Worker public: 994*a65addddSAndroid Build Coastguard Worker INJECT(ScalerImpl(X, ASSISTED(double) factor)) 995*a65addddSAndroid Build Coastguard Worker : factor(factor) { 996*a65addddSAndroid Build Coastguard Worker } 997*a65addddSAndroid Build Coastguard Worker 998*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 999*a65addddSAndroid Build Coastguard Worker return x * factor; 1000*a65addddSAndroid Build Coastguard Worker } 1001*a65addddSAndroid Build Coastguard Worker }; 1002*a65addddSAndroid Build Coastguard Worker 1003*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1004*a65addddSAndroid Build Coastguard Worker 1005*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 1006*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1007*a65addddSAndroid Build Coastguard Worker .bind<Scaler, ScalerImpl>(); 1008*a65addddSAndroid Build Coastguard Worker } 1009*a65addddSAndroid Build Coastguard Worker 1010*a65addddSAndroid Build Coastguard Worker int main() { 1011*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactory> injector(getScalerComponent); 1012*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 1013*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 1014*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 1015*a65addddSAndroid Build Coastguard Worker } 1016*a65addddSAndroid Build Coastguard Worker ''' 1017*a65addddSAndroid Build Coastguard Worker expect_success( 1018*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1019*a65addddSAndroid Build Coastguard Worker source) 1020*a65addddSAndroid Build Coastguard Worker 1021*a65addddSAndroid Build Coastguard Worker def test_autoinject_with_binding_variant_returning_value(self): 1022*a65addddSAndroid Build Coastguard Worker source = ''' 1023*a65addddSAndroid Build Coastguard Worker struct X { 1024*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 1025*a65addddSAndroid Build Coastguard Worker }; 1026*a65addddSAndroid Build Coastguard Worker 1027*a65addddSAndroid Build Coastguard Worker struct Scaler { 1028*a65addddSAndroid Build Coastguard Worker private: 1029*a65addddSAndroid Build Coastguard Worker double factor; 1030*a65addddSAndroid Build Coastguard Worker 1031*a65addddSAndroid Build Coastguard Worker public: 1032*a65addddSAndroid Build Coastguard Worker INJECT(Scaler(X, ASSISTED(double) factor)) 1033*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1034*a65addddSAndroid Build Coastguard Worker } 1035*a65addddSAndroid Build Coastguard Worker 1036*a65addddSAndroid Build Coastguard Worker double scale(double x) { 1037*a65addddSAndroid Build Coastguard Worker return x * factor; 1038*a65addddSAndroid Build Coastguard Worker } 1039*a65addddSAndroid Build Coastguard Worker }; 1040*a65addddSAndroid Build Coastguard Worker 1041*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<Scaler(double)>; 1042*a65addddSAndroid Build Coastguard Worker 1043*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 1044*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 1045*a65addddSAndroid Build Coastguard Worker } 1046*a65addddSAndroid Build Coastguard Worker 1047*a65addddSAndroid Build Coastguard Worker int main() { 1048*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactory> injector(getScalerComponent); 1049*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 1050*a65addddSAndroid Build Coastguard Worker Scaler scaler = scalerFactory(12.1); 1051*a65addddSAndroid Build Coastguard Worker std::cout << scaler.scale(3) << std::endl; 1052*a65addddSAndroid Build Coastguard Worker } 1053*a65addddSAndroid Build Coastguard Worker ''' 1054*a65addddSAndroid Build Coastguard Worker expect_success( 1055*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1056*a65addddSAndroid Build Coastguard Worker source) 1057*a65addddSAndroid Build Coastguard Worker 1058*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1059*a65addddSAndroid Build Coastguard Worker ('Scaler', 1060*a65addddSAndroid Build Coastguard Worker 'ScalerImpl', 1061*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>'), 1062*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 1063*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, ScalerImpl>', 1064*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>'), 1065*a65addddSAndroid Build Coastguard Worker ]) 1066*a65addddSAndroid Build Coastguard Worker def test_register_factory_success(self, ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot): 1067*a65addddSAndroid Build Coastguard Worker source = ''' 1068*a65addddSAndroid Build Coastguard Worker struct Scaler { 1069*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1070*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 1071*a65addddSAndroid Build Coastguard Worker }; 1072*a65addddSAndroid Build Coastguard Worker 1073*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1074*a65addddSAndroid Build Coastguard Worker private: 1075*a65addddSAndroid Build Coastguard Worker double factor; 1076*a65addddSAndroid Build Coastguard Worker 1077*a65addddSAndroid Build Coastguard Worker public: 1078*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1079*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1080*a65addddSAndroid Build Coastguard Worker } 1081*a65addddSAndroid Build Coastguard Worker 1082*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 1083*a65addddSAndroid Build Coastguard Worker return x * factor; 1084*a65addddSAndroid Build Coastguard Worker } 1085*a65addddSAndroid Build Coastguard Worker }; 1086*a65addddSAndroid Build Coastguard Worker 1087*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1088*a65addddSAndroid Build Coastguard Worker 1089*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot> getScalerComponent() { 1090*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1091*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot, ScalerImplAnnot>() 1092*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerImplAnnot(fruit::Assisted<double>)>([](double factor) { return ScalerImpl(factor); }); 1093*a65addddSAndroid Build Coastguard Worker } 1094*a65addddSAndroid Build Coastguard Worker 1095*a65addddSAndroid Build Coastguard Worker int main() { 1096*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent); 1097*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 1098*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 1099*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 1100*a65addddSAndroid Build Coastguard Worker } 1101*a65addddSAndroid Build Coastguard Worker ''' 1102*a65addddSAndroid Build Coastguard Worker expect_success( 1103*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1104*a65addddSAndroid Build Coastguard Worker source, 1105*a65addddSAndroid Build Coastguard Worker locals()) 1106*a65addddSAndroid Build Coastguard Worker 1107*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_annotation_returning_value(self): 1108*a65addddSAndroid Build Coastguard Worker source = ''' 1109*a65addddSAndroid Build Coastguard Worker struct Scaler { 1110*a65addddSAndroid Build Coastguard Worker private: 1111*a65addddSAndroid Build Coastguard Worker double factor; 1112*a65addddSAndroid Build Coastguard Worker 1113*a65addddSAndroid Build Coastguard Worker public: 1114*a65addddSAndroid Build Coastguard Worker Scaler(double factor) 1115*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1116*a65addddSAndroid Build Coastguard Worker } 1117*a65addddSAndroid Build Coastguard Worker 1118*a65addddSAndroid Build Coastguard Worker double scale(double x) { 1119*a65addddSAndroid Build Coastguard Worker return x * factor; 1120*a65addddSAndroid Build Coastguard Worker } 1121*a65addddSAndroid Build Coastguard Worker }; 1122*a65addddSAndroid Build Coastguard Worker 1123*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<Scaler(double)>; 1124*a65addddSAndroid Build Coastguard Worker using ScalerFactoryAnnot1 = fruit::Annotated<Annotation1, ScalerFactory>; 1125*a65addddSAndroid Build Coastguard Worker 1126*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot1> getScalerComponent() { 1127*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1128*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerAnnot1(fruit::Assisted<double>)>( 1129*a65addddSAndroid Build Coastguard Worker [](double factor) { 1130*a65addddSAndroid Build Coastguard Worker return Scaler(factor); 1131*a65addddSAndroid Build Coastguard Worker }); 1132*a65addddSAndroid Build Coastguard Worker } 1133*a65addddSAndroid Build Coastguard Worker 1134*a65addddSAndroid Build Coastguard Worker int main() { 1135*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot1> injector(getScalerComponent); 1136*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot1>(); 1137*a65addddSAndroid Build Coastguard Worker Scaler scaler = scalerFactory(12.1); 1138*a65addddSAndroid Build Coastguard Worker std::cout << scaler.scale(3) << std::endl; 1139*a65addddSAndroid Build Coastguard Worker } 1140*a65addddSAndroid Build Coastguard Worker ''' 1141*a65addddSAndroid Build Coastguard Worker expect_success( 1142*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1143*a65addddSAndroid Build Coastguard Worker source) 1144*a65addddSAndroid Build Coastguard Worker 1145*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_different_annotation(self): 1146*a65addddSAndroid Build Coastguard Worker source = ''' 1147*a65addddSAndroid Build Coastguard Worker struct Scaler { 1148*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1149*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 1150*a65addddSAndroid Build Coastguard Worker }; 1151*a65addddSAndroid Build Coastguard Worker 1152*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1153*a65addddSAndroid Build Coastguard Worker private: 1154*a65addddSAndroid Build Coastguard Worker double factor; 1155*a65addddSAndroid Build Coastguard Worker 1156*a65addddSAndroid Build Coastguard Worker public: 1157*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1158*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1159*a65addddSAndroid Build Coastguard Worker } 1160*a65addddSAndroid Build Coastguard Worker 1161*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 1162*a65addddSAndroid Build Coastguard Worker return x * factor; 1163*a65addddSAndroid Build Coastguard Worker } 1164*a65addddSAndroid Build Coastguard Worker }; 1165*a65addddSAndroid Build Coastguard Worker 1166*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1167*a65addddSAndroid Build Coastguard Worker using ScalerFactoryAnnot1 = fruit::Annotated<Annotation1, ScalerFactory>; 1168*a65addddSAndroid Build Coastguard Worker 1169*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot1> getScalerComponent() { 1170*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1171*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot1, ScalerImplAnnot2>() 1172*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerImplAnnot2(fruit::Assisted<double>)>( 1173*a65addddSAndroid Build Coastguard Worker [](double factor) { 1174*a65addddSAndroid Build Coastguard Worker return ScalerImpl(factor); 1175*a65addddSAndroid Build Coastguard Worker }); 1176*a65addddSAndroid Build Coastguard Worker } 1177*a65addddSAndroid Build Coastguard Worker 1178*a65addddSAndroid Build Coastguard Worker int main() { 1179*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot1> injector(getScalerComponent); 1180*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot1>(); 1181*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 1182*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 1183*a65addddSAndroid Build Coastguard Worker } 1184*a65addddSAndroid Build Coastguard Worker ''' 1185*a65addddSAndroid Build Coastguard Worker expect_success( 1186*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1187*a65addddSAndroid Build Coastguard Worker source) 1188*a65addddSAndroid Build Coastguard Worker 1189*a65addddSAndroid Build Coastguard Worker 1190*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1191*a65addddSAndroid Build Coastguard Worker ('Scaler', 1192*a65addddSAndroid Build Coastguard Worker 'ScalerImpl', 1193*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double, double)>'), 1194*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 1195*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, ScalerImpl>', 1196*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double, double)>>'), 1197*a65addddSAndroid Build Coastguard Worker ]) 1198*a65addddSAndroid Build Coastguard Worker def test_register_factory_2arg_success(self, ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot): 1199*a65addddSAndroid Build Coastguard Worker source = ''' 1200*a65addddSAndroid Build Coastguard Worker struct Scaler { 1201*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1202*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 1203*a65addddSAndroid Build Coastguard Worker }; 1204*a65addddSAndroid Build Coastguard Worker 1205*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1206*a65addddSAndroid Build Coastguard Worker private: 1207*a65addddSAndroid Build Coastguard Worker double factor; 1208*a65addddSAndroid Build Coastguard Worker 1209*a65addddSAndroid Build Coastguard Worker public: 1210*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1211*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1212*a65addddSAndroid Build Coastguard Worker } 1213*a65addddSAndroid Build Coastguard Worker 1214*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 1215*a65addddSAndroid Build Coastguard Worker return x * factor; 1216*a65addddSAndroid Build Coastguard Worker } 1217*a65addddSAndroid Build Coastguard Worker }; 1218*a65addddSAndroid Build Coastguard Worker 1219*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double, double)>; 1220*a65addddSAndroid Build Coastguard Worker 1221*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot> getScalerComponent() { 1222*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1223*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot, ScalerImplAnnot>() 1224*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerImplAnnot(fruit::Assisted<double>, fruit::Assisted<double>)>( 1225*a65addddSAndroid Build Coastguard Worker [](double factor, double) { 1226*a65addddSAndroid Build Coastguard Worker return ScalerImpl(factor); 1227*a65addddSAndroid Build Coastguard Worker }); 1228*a65addddSAndroid Build Coastguard Worker } 1229*a65addddSAndroid Build Coastguard Worker 1230*a65addddSAndroid Build Coastguard Worker int main() { 1231*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent); 1232*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 1233*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1, 34.2); 1234*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 1235*a65addddSAndroid Build Coastguard Worker } 1236*a65addddSAndroid Build Coastguard Worker ''' 1237*a65addddSAndroid Build Coastguard Worker expect_success( 1238*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1239*a65addddSAndroid Build Coastguard Worker source, 1240*a65addddSAndroid Build Coastguard Worker locals()) 1241*a65addddSAndroid Build Coastguard Worker 1242*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_different_annotation_error(self): 1243*a65addddSAndroid Build Coastguard Worker source = ''' 1244*a65addddSAndroid Build Coastguard Worker struct Scaler { 1245*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1246*a65addddSAndroid Build Coastguard Worker }; 1247*a65addddSAndroid Build Coastguard Worker 1248*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1249*a65addddSAndroid Build Coastguard Worker private: 1250*a65addddSAndroid Build Coastguard Worker double factor; 1251*a65addddSAndroid Build Coastguard Worker 1252*a65addddSAndroid Build Coastguard Worker public: 1253*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1254*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1255*a65addddSAndroid Build Coastguard Worker } 1256*a65addddSAndroid Build Coastguard Worker 1257*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 1258*a65addddSAndroid Build Coastguard Worker return x * factor; 1259*a65addddSAndroid Build Coastguard Worker } 1260*a65addddSAndroid Build Coastguard Worker }; 1261*a65addddSAndroid Build Coastguard Worker 1262*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1263*a65addddSAndroid Build Coastguard Worker using ScalerFactoryAnnot1 = fruit::Annotated<Annotation1, ScalerFactory>; 1264*a65addddSAndroid Build Coastguard Worker 1265*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot1> getScalerComponent() { 1266*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1267*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot1, ScalerImplAnnot1>() 1268*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerImplAnnot2(fruit::Assisted<double>)>([](double factor) { return ScalerImpl(factor); }); 1269*a65addddSAndroid Build Coastguard Worker } 1270*a65addddSAndroid Build Coastguard Worker 1271*a65addddSAndroid Build Coastguard Worker int main() { 1272*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot1> injector(getScalerComponent); 1273*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot1>(); 1274*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 1275*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 1276*a65addddSAndroid Build Coastguard Worker } 1277*a65addddSAndroid Build Coastguard Worker ''' 1278*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1279*a65addddSAndroid Build Coastguard Worker r'NoBindingFoundError<fruit::Annotated<Annotation1,std::function<std::unique_ptr<ScalerImpl(,std::default_delete<ScalerImpl>)?>\(double\)>>>', 1280*a65addddSAndroid Build Coastguard Worker r'', 1281*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1282*a65addddSAndroid Build Coastguard Worker source) 1283*a65addddSAndroid Build Coastguard Worker 1284*a65addddSAndroid Build Coastguard Worker 1285*a65addddSAndroid Build Coastguard Worker def test_register_factory_dep_on_provider(self): 1286*a65addddSAndroid Build Coastguard Worker source = ''' 1287*a65addddSAndroid Build Coastguard Worker struct Scaler { 1288*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1289*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 1290*a65addddSAndroid Build Coastguard Worker }; 1291*a65addddSAndroid Build Coastguard Worker 1292*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1293*a65addddSAndroid Build Coastguard Worker private: 1294*a65addddSAndroid Build Coastguard Worker double factor; 1295*a65addddSAndroid Build Coastguard Worker 1296*a65addddSAndroid Build Coastguard Worker public: 1297*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1298*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1299*a65addddSAndroid Build Coastguard Worker } 1300*a65addddSAndroid Build Coastguard Worker 1301*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 1302*a65addddSAndroid Build Coastguard Worker return x * factor; 1303*a65addddSAndroid Build Coastguard Worker } 1304*a65addddSAndroid Build Coastguard Worker }; 1305*a65addddSAndroid Build Coastguard Worker 1306*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1307*a65addddSAndroid Build Coastguard Worker 1308*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 1309*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1310*a65addddSAndroid Build Coastguard Worker .bind<Scaler, ScalerImpl>() 1311*a65addddSAndroid Build Coastguard Worker .registerProvider([](){return 23;}) 1312*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerImpl(fruit::Assisted<double>, fruit::Provider<int>)>( 1313*a65addddSAndroid Build Coastguard Worker [](double factor, fruit::Provider<int> provider) { 1314*a65addddSAndroid Build Coastguard Worker return ScalerImpl(factor * provider.get<int>()); 1315*a65addddSAndroid Build Coastguard Worker }); 1316*a65addddSAndroid Build Coastguard Worker } 1317*a65addddSAndroid Build Coastguard Worker 1318*a65addddSAndroid Build Coastguard Worker int main() { 1319*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactory> injector(getScalerComponent); 1320*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 1321*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 1322*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 1323*a65addddSAndroid Build Coastguard Worker } 1324*a65addddSAndroid Build Coastguard Worker ''' 1325*a65addddSAndroid Build Coastguard Worker expect_success( 1326*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1327*a65addddSAndroid Build Coastguard Worker source) 1328*a65addddSAndroid Build Coastguard Worker 1329*a65addddSAndroid Build Coastguard Worker def test_register_factory_dep_on_provider_returning_value(self): 1330*a65addddSAndroid Build Coastguard Worker source = ''' 1331*a65addddSAndroid Build Coastguard Worker struct Scaler { 1332*a65addddSAndroid Build Coastguard Worker private: 1333*a65addddSAndroid Build Coastguard Worker double factor; 1334*a65addddSAndroid Build Coastguard Worker 1335*a65addddSAndroid Build Coastguard Worker public: 1336*a65addddSAndroid Build Coastguard Worker Scaler(double factor) 1337*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1338*a65addddSAndroid Build Coastguard Worker } 1339*a65addddSAndroid Build Coastguard Worker 1340*a65addddSAndroid Build Coastguard Worker double scale(double x) { 1341*a65addddSAndroid Build Coastguard Worker return x * factor; 1342*a65addddSAndroid Build Coastguard Worker } 1343*a65addddSAndroid Build Coastguard Worker }; 1344*a65addddSAndroid Build Coastguard Worker 1345*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<Scaler(double)>; 1346*a65addddSAndroid Build Coastguard Worker 1347*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 1348*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1349*a65addddSAndroid Build Coastguard Worker .registerProvider([](){return 23;}) 1350*a65addddSAndroid Build Coastguard Worker .registerFactory<Scaler(fruit::Assisted<double>, fruit::Provider<int>)>( 1351*a65addddSAndroid Build Coastguard Worker [](double factor, fruit::Provider<int> provider) { 1352*a65addddSAndroid Build Coastguard Worker return Scaler(factor * provider.get<int>()); 1353*a65addddSAndroid Build Coastguard Worker }); 1354*a65addddSAndroid Build Coastguard Worker } 1355*a65addddSAndroid Build Coastguard Worker 1356*a65addddSAndroid Build Coastguard Worker int main() { 1357*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactory> injector(getScalerComponent); 1358*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 1359*a65addddSAndroid Build Coastguard Worker Scaler scaler = scalerFactory(12.1); 1360*a65addddSAndroid Build Coastguard Worker std::cout << scaler.scale(3) << std::endl; 1361*a65addddSAndroid Build Coastguard Worker } 1362*a65addddSAndroid Build Coastguard Worker ''' 1363*a65addddSAndroid Build Coastguard Worker expect_success( 1364*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1365*a65addddSAndroid Build Coastguard Worker source) 1366*a65addddSAndroid Build Coastguard Worker 1367*a65addddSAndroid Build Coastguard Worker def test_register_factory_error_abstract_class(self): 1368*a65addddSAndroid Build Coastguard Worker source = ''' 1369*a65addddSAndroid Build Coastguard Worker struct Scaler { 1370*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1371*a65addddSAndroid Build Coastguard Worker }; 1372*a65addddSAndroid Build Coastguard Worker 1373*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1374*a65addddSAndroid Build Coastguard Worker private: 1375*a65addddSAndroid Build Coastguard Worker double factor; 1376*a65addddSAndroid Build Coastguard Worker 1377*a65addddSAndroid Build Coastguard Worker public: 1378*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1379*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1380*a65addddSAndroid Build Coastguard Worker } 1381*a65addddSAndroid Build Coastguard Worker 1382*a65addddSAndroid Build Coastguard Worker // Note: here we "forgot" to implement scale() (on purpose, for this test) so ScalerImpl is an abstract class. 1383*a65addddSAndroid Build Coastguard Worker }; 1384*a65addddSAndroid Build Coastguard Worker 1385*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1386*a65addddSAndroid Build Coastguard Worker 1387*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 1388*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1389*a65addddSAndroid Build Coastguard Worker .bind<Scaler, ScalerImpl>() 1390*a65addddSAndroid Build Coastguard Worker .registerFactory<fruit::Annotated<Annotation1, ScalerImpl>(fruit::Assisted<double>)>([](double) { return (ScalerImpl*)nullptr; }); 1391*a65addddSAndroid Build Coastguard Worker } 1392*a65addddSAndroid Build Coastguard Worker ''' 1393*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1394*a65addddSAndroid Build Coastguard Worker 'CannotConstructAbstractClassError<ScalerImpl>', 1395*a65addddSAndroid Build Coastguard Worker 'The specified class can.t be constructed because it.s an abstract class.', 1396*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1397*a65addddSAndroid Build Coastguard Worker source) 1398*a65addddSAndroid Build Coastguard Worker 1399*a65addddSAndroid Build Coastguard Worker def test_register_factory_error_not_function(self): 1400*a65addddSAndroid Build Coastguard Worker source = ''' 1401*a65addddSAndroid Build Coastguard Worker struct X { 1402*a65addddSAndroid Build Coastguard Worker X(int) {} 1403*a65addddSAndroid Build Coastguard Worker }; 1404*a65addddSAndroid Build Coastguard Worker 1405*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<X()>> getComponent() { 1406*a65addddSAndroid Build Coastguard Worker int n = 3; 1407*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1408*a65addddSAndroid Build Coastguard Worker .registerFactory<X()>([=]{return X(n);}); 1409*a65addddSAndroid Build Coastguard Worker } 1410*a65addddSAndroid Build Coastguard Worker ''' 1411*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1412*a65addddSAndroid Build Coastguard Worker 'LambdaWithCapturesError<.*>', 1413*a65addddSAndroid Build Coastguard Worker 'Only lambdas with no captures are supported', 1414*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1415*a65addddSAndroid Build Coastguard Worker source) 1416*a65addddSAndroid Build Coastguard Worker 1417*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1418*a65addddSAndroid Build Coastguard Worker ('Scaler', 1419*a65addddSAndroid Build Coastguard Worker 'ScalerImpl', 1420*a65addddSAndroid Build Coastguard Worker 'ScalerImpl*', 1421*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>', 1422*a65addddSAndroid Build Coastguard Worker r'ScalerImpl\*\(fruit::Assisted<double>\)'), 1423*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 1424*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, ScalerImpl>', 1425*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, ScalerImpl*>', 1426*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, std::function<std::unique_ptr<Scaler>(double)>>', 1427*a65addddSAndroid Build Coastguard Worker r'fruit::Annotated<Annotation2,ScalerImpl\*>\(fruit::Assisted<double>\)') 1428*a65addddSAndroid Build Coastguard Worker ]) 1429*a65addddSAndroid Build Coastguard Worker def test_register_factory_for_pointer(self, ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, ScalerFactoryAnnot, ScalerImplFactorySignatureAnnotRegex): 1430*a65addddSAndroid Build Coastguard Worker source = ''' 1431*a65addddSAndroid Build Coastguard Worker struct Scaler { 1432*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1433*a65addddSAndroid Build Coastguard Worker }; 1434*a65addddSAndroid Build Coastguard Worker 1435*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1436*a65addddSAndroid Build Coastguard Worker private: 1437*a65addddSAndroid Build Coastguard Worker double factor; 1438*a65addddSAndroid Build Coastguard Worker 1439*a65addddSAndroid Build Coastguard Worker public: 1440*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1441*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1442*a65addddSAndroid Build Coastguard Worker } 1443*a65addddSAndroid Build Coastguard Worker 1444*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 1445*a65addddSAndroid Build Coastguard Worker return x * factor; 1446*a65addddSAndroid Build Coastguard Worker } 1447*a65addddSAndroid Build Coastguard Worker }; 1448*a65addddSAndroid Build Coastguard Worker 1449*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1450*a65addddSAndroid Build Coastguard Worker 1451*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot> getScalerComponent() { 1452*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1453*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot, ScalerImplAnnot>() 1454*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerImplPtrAnnot(fruit::Assisted<double>)>([](double factor) { return new ScalerImpl(factor); }); 1455*a65addddSAndroid Build Coastguard Worker } 1456*a65addddSAndroid Build Coastguard Worker 1457*a65addddSAndroid Build Coastguard Worker int main() { 1458*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent); 1459*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 1460*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 1461*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 1462*a65addddSAndroid Build Coastguard Worker } 1463*a65addddSAndroid Build Coastguard Worker ''' 1464*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1465*a65addddSAndroid Build Coastguard Worker 'FactoryReturningPointerError<ScalerImplFactorySignatureAnnotRegex>', 1466*a65addddSAndroid Build Coastguard Worker 'The specified factory returns a pointer. This is not supported', 1467*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1468*a65addddSAndroid Build Coastguard Worker source, 1469*a65addddSAndroid Build Coastguard Worker locals()) 1470*a65addddSAndroid Build Coastguard Worker 1471*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1472*a65addddSAndroid Build Coastguard Worker ('Scaler*', 1473*a65addddSAndroid Build Coastguard Worker 'std::function<Scaler(double)>', 1474*a65addddSAndroid Build Coastguard Worker r'Scaler\*\(fruit::Assisted<double>\)'), 1475*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler*>', 1476*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<Scaler(double)>>', 1477*a65addddSAndroid Build Coastguard Worker r'fruit::Annotated<Annotation1,Scaler\*>\(fruit::Assisted<double>\)'), 1478*a65addddSAndroid Build Coastguard Worker ]) 1479*a65addddSAndroid Build Coastguard Worker def test_register_factory_for_pointer_returning_value(self, ScalerPtrAnnot, ScalerFactoryAnnot, ScalerFactorySignatureAnnotRegex): 1480*a65addddSAndroid Build Coastguard Worker source = ''' 1481*a65addddSAndroid Build Coastguard Worker struct Scaler { 1482*a65addddSAndroid Build Coastguard Worker private: 1483*a65addddSAndroid Build Coastguard Worker double factor; 1484*a65addddSAndroid Build Coastguard Worker 1485*a65addddSAndroid Build Coastguard Worker public: 1486*a65addddSAndroid Build Coastguard Worker Scaler(double factor) 1487*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1488*a65addddSAndroid Build Coastguard Worker } 1489*a65addddSAndroid Build Coastguard Worker 1490*a65addddSAndroid Build Coastguard Worker double scale(double x) { 1491*a65addddSAndroid Build Coastguard Worker return x * factor; 1492*a65addddSAndroid Build Coastguard Worker } 1493*a65addddSAndroid Build Coastguard Worker }; 1494*a65addddSAndroid Build Coastguard Worker 1495*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<Scaler(double)>; 1496*a65addddSAndroid Build Coastguard Worker 1497*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot> getScalerComponent() { 1498*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1499*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerPtrAnnot(fruit::Assisted<double>)>([](double factor) { return new Scaler(factor); }); 1500*a65addddSAndroid Build Coastguard Worker } 1501*a65addddSAndroid Build Coastguard Worker 1502*a65addddSAndroid Build Coastguard Worker int main() { 1503*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent); 1504*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 1505*a65addddSAndroid Build Coastguard Worker Scaler scaler = scalerFactory(12.1); 1506*a65addddSAndroid Build Coastguard Worker std::cout << scaler.scale(3) << std::endl; 1507*a65addddSAndroid Build Coastguard Worker } 1508*a65addddSAndroid Build Coastguard Worker ''' 1509*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1510*a65addddSAndroid Build Coastguard Worker 'FactoryReturningPointerError<ScalerFactorySignatureAnnotRegex>', 1511*a65addddSAndroid Build Coastguard Worker 'The specified factory returns a pointer. This is not supported', 1512*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1513*a65addddSAndroid Build Coastguard Worker source, 1514*a65addddSAndroid Build Coastguard Worker locals()) 1515*a65addddSAndroid Build Coastguard Worker 1516*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1517*a65addddSAndroid Build Coastguard Worker ('Scaler', 1518*a65addddSAndroid Build Coastguard Worker 'ScalerImpl', 1519*a65addddSAndroid Build Coastguard Worker 'std::unique_ptr<ScalerImpl>', 1520*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>'), 1521*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 1522*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, ScalerImpl>', 1523*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, std::unique_ptr<ScalerImpl>>', 1524*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>'), 1525*a65addddSAndroid Build Coastguard Worker ]) 1526*a65addddSAndroid Build Coastguard Worker def test_register_factory_for_unique_pointer(self, ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, ScalerFactoryAnnot): 1527*a65addddSAndroid Build Coastguard Worker source = ''' 1528*a65addddSAndroid Build Coastguard Worker struct Scaler { 1529*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1530*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 1531*a65addddSAndroid Build Coastguard Worker }; 1532*a65addddSAndroid Build Coastguard Worker 1533*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1534*a65addddSAndroid Build Coastguard Worker private: 1535*a65addddSAndroid Build Coastguard Worker double factor; 1536*a65addddSAndroid Build Coastguard Worker 1537*a65addddSAndroid Build Coastguard Worker public: 1538*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1539*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1540*a65addddSAndroid Build Coastguard Worker } 1541*a65addddSAndroid Build Coastguard Worker 1542*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 1543*a65addddSAndroid Build Coastguard Worker return x * factor; 1544*a65addddSAndroid Build Coastguard Worker } 1545*a65addddSAndroid Build Coastguard Worker }; 1546*a65addddSAndroid Build Coastguard Worker 1547*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1548*a65addddSAndroid Build Coastguard Worker 1549*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot> getScalerComponent() { 1550*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1551*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot, ScalerImplAnnot>() 1552*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerImplPtrAnnot(fruit::Assisted<double>)>( 1553*a65addddSAndroid Build Coastguard Worker [](double factor) { 1554*a65addddSAndroid Build Coastguard Worker return std::unique_ptr<ScalerImpl>(new ScalerImpl(factor)); 1555*a65addddSAndroid Build Coastguard Worker }); 1556*a65addddSAndroid Build Coastguard Worker } 1557*a65addddSAndroid Build Coastguard Worker 1558*a65addddSAndroid Build Coastguard Worker int main() { 1559*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent); 1560*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 1561*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 1562*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 1563*a65addddSAndroid Build Coastguard Worker } 1564*a65addddSAndroid Build Coastguard Worker ''' 1565*a65addddSAndroid Build Coastguard Worker expect_success( 1566*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1567*a65addddSAndroid Build Coastguard Worker source, 1568*a65addddSAndroid Build Coastguard Worker locals()) 1569*a65addddSAndroid Build Coastguard Worker 1570*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1571*a65addddSAndroid Build Coastguard Worker ('Scaler', 1572*a65addddSAndroid Build Coastguard Worker 'ScalerImpl', 1573*a65addddSAndroid Build Coastguard Worker 'std::unique_ptr<ScalerImpl>', 1574*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<Scaler>(double)>'), 1575*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 1576*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, ScalerImpl>', 1577*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation2, std::unique_ptr<ScalerImpl>>', 1578*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>'), 1579*a65addddSAndroid Build Coastguard Worker ]) 1580*a65addddSAndroid Build Coastguard Worker def test_register_factory_for_unique_pointer_returning_invalid_unique_ptr_ok(self, ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, ScalerFactoryAnnot): 1581*a65addddSAndroid Build Coastguard Worker source = ''' 1582*a65addddSAndroid Build Coastguard Worker struct Scaler { 1583*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1584*a65addddSAndroid Build Coastguard Worker virtual ~Scaler() = default; 1585*a65addddSAndroid Build Coastguard Worker }; 1586*a65addddSAndroid Build Coastguard Worker 1587*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1588*a65addddSAndroid Build Coastguard Worker private: 1589*a65addddSAndroid Build Coastguard Worker double factor; 1590*a65addddSAndroid Build Coastguard Worker 1591*a65addddSAndroid Build Coastguard Worker public: 1592*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1593*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1594*a65addddSAndroid Build Coastguard Worker } 1595*a65addddSAndroid Build Coastguard Worker 1596*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 1597*a65addddSAndroid Build Coastguard Worker return x * factor; 1598*a65addddSAndroid Build Coastguard Worker } 1599*a65addddSAndroid Build Coastguard Worker }; 1600*a65addddSAndroid Build Coastguard Worker 1601*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1602*a65addddSAndroid Build Coastguard Worker 1603*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot> getScalerComponent() { 1604*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1605*a65addddSAndroid Build Coastguard Worker .bind<ScalerAnnot, ScalerImplAnnot>() 1606*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerImplPtrAnnot(fruit::Assisted<double>)>( 1607*a65addddSAndroid Build Coastguard Worker [](double) { 1608*a65addddSAndroid Build Coastguard Worker return std::unique_ptr<ScalerImpl>(nullptr); 1609*a65addddSAndroid Build Coastguard Worker }); 1610*a65addddSAndroid Build Coastguard Worker } 1611*a65addddSAndroid Build Coastguard Worker 1612*a65addddSAndroid Build Coastguard Worker int main() { 1613*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent); 1614*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 1615*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 1616*a65addddSAndroid Build Coastguard Worker Assert(scaler.get() == nullptr); 1617*a65addddSAndroid Build Coastguard Worker } 1618*a65addddSAndroid Build Coastguard Worker ''' 1619*a65addddSAndroid Build Coastguard Worker expect_success( 1620*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1621*a65addddSAndroid Build Coastguard Worker source, 1622*a65addddSAndroid Build Coastguard Worker locals()) 1623*a65addddSAndroid Build Coastguard Worker 1624*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1625*a65addddSAndroid Build Coastguard Worker ('Scaler', 1626*a65addddSAndroid Build Coastguard Worker 'std::function<Scaler(double)>'), 1627*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Scaler>', 1628*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<Scaler(double)>>'), 1629*a65addddSAndroid Build Coastguard Worker ]) 1630*a65addddSAndroid Build Coastguard Worker def test_register_factory_for_unique_pointer_returning_value(self, ScalerAnnot, ScalerFactoryAnnot): 1631*a65addddSAndroid Build Coastguard Worker source = ''' 1632*a65addddSAndroid Build Coastguard Worker struct Scaler { 1633*a65addddSAndroid Build Coastguard Worker private: 1634*a65addddSAndroid Build Coastguard Worker double factor; 1635*a65addddSAndroid Build Coastguard Worker 1636*a65addddSAndroid Build Coastguard Worker public: 1637*a65addddSAndroid Build Coastguard Worker Scaler(double factor) 1638*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1639*a65addddSAndroid Build Coastguard Worker } 1640*a65addddSAndroid Build Coastguard Worker 1641*a65addddSAndroid Build Coastguard Worker double scale(double x) { 1642*a65addddSAndroid Build Coastguard Worker return x * factor; 1643*a65addddSAndroid Build Coastguard Worker } 1644*a65addddSAndroid Build Coastguard Worker }; 1645*a65addddSAndroid Build Coastguard Worker 1646*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<Scaler(double)>; 1647*a65addddSAndroid Build Coastguard Worker 1648*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactoryAnnot> getScalerComponent() { 1649*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1650*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerAnnot(fruit::Assisted<double>)>( 1651*a65addddSAndroid Build Coastguard Worker [](double factor) { 1652*a65addddSAndroid Build Coastguard Worker return Scaler(factor); 1653*a65addddSAndroid Build Coastguard Worker }); 1654*a65addddSAndroid Build Coastguard Worker } 1655*a65addddSAndroid Build Coastguard Worker 1656*a65addddSAndroid Build Coastguard Worker int main() { 1657*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent); 1658*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>(); 1659*a65addddSAndroid Build Coastguard Worker Scaler scaler = scalerFactory(12.1); 1660*a65addddSAndroid Build Coastguard Worker std::cout << scaler.scale(3) << std::endl; 1661*a65addddSAndroid Build Coastguard Worker } 1662*a65addddSAndroid Build Coastguard Worker ''' 1663*a65addddSAndroid Build Coastguard Worker expect_success( 1664*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1665*a65addddSAndroid Build Coastguard Worker source, 1666*a65addddSAndroid Build Coastguard Worker locals()) 1667*a65addddSAndroid Build Coastguard Worker 1668*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1669*a65addddSAndroid Build Coastguard Worker 'ScalerImpl', 1670*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, ScalerImpl>', 1671*a65addddSAndroid Build Coastguard Worker ]) 1672*a65addddSAndroid Build Coastguard Worker def test_register_factory_inconsistent_signature(self, ScalerImplAnnot): 1673*a65addddSAndroid Build Coastguard Worker source = ''' 1674*a65addddSAndroid Build Coastguard Worker struct Scaler { 1675*a65addddSAndroid Build Coastguard Worker virtual double scale(double x) = 0; 1676*a65addddSAndroid Build Coastguard Worker }; 1677*a65addddSAndroid Build Coastguard Worker 1678*a65addddSAndroid Build Coastguard Worker struct ScalerImpl : public Scaler { 1679*a65addddSAndroid Build Coastguard Worker private: 1680*a65addddSAndroid Build Coastguard Worker double factor; 1681*a65addddSAndroid Build Coastguard Worker 1682*a65addddSAndroid Build Coastguard Worker public: 1683*a65addddSAndroid Build Coastguard Worker ScalerImpl(double factor) 1684*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1685*a65addddSAndroid Build Coastguard Worker } 1686*a65addddSAndroid Build Coastguard Worker 1687*a65addddSAndroid Build Coastguard Worker double scale(double x) override { 1688*a65addddSAndroid Build Coastguard Worker return x * factor; 1689*a65addddSAndroid Build Coastguard Worker } 1690*a65addddSAndroid Build Coastguard Worker }; 1691*a65addddSAndroid Build Coastguard Worker 1692*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>; 1693*a65addddSAndroid Build Coastguard Worker 1694*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 1695*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1696*a65addddSAndroid Build Coastguard Worker .bind<Scaler, ScalerImplAnnot>() 1697*a65addddSAndroid Build Coastguard Worker .registerFactory<ScalerImplAnnot(fruit::Assisted<double>)>([](float factor) { return ScalerImpl(factor); }); 1698*a65addddSAndroid Build Coastguard Worker } 1699*a65addddSAndroid Build Coastguard Worker 1700*a65addddSAndroid Build Coastguard Worker int main() { 1701*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactory> injector(getScalerComponent); 1702*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 1703*a65addddSAndroid Build Coastguard Worker std::unique_ptr<Scaler> scaler = scalerFactory(12.1); 1704*a65addddSAndroid Build Coastguard Worker std::cout << scaler->scale(3) << std::endl; 1705*a65addddSAndroid Build Coastguard Worker } 1706*a65addddSAndroid Build Coastguard Worker ''' 1707*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1708*a65addddSAndroid Build Coastguard Worker r'FunctorSignatureDoesNotMatchError<ScalerImpl\(double\),ScalerImpl\(float\)>', 1709*a65addddSAndroid Build Coastguard Worker r'Unexpected functor signature', 1710*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1711*a65addddSAndroid Build Coastguard Worker source, 1712*a65addddSAndroid Build Coastguard Worker locals()) 1713*a65addddSAndroid Build Coastguard Worker 1714*a65addddSAndroid Build Coastguard Worker def test_register_factory_inconsistent_signature_returning_value(self): 1715*a65addddSAndroid Build Coastguard Worker source = ''' 1716*a65addddSAndroid Build Coastguard Worker struct Scaler { 1717*a65addddSAndroid Build Coastguard Worker private: 1718*a65addddSAndroid Build Coastguard Worker double factor; 1719*a65addddSAndroid Build Coastguard Worker 1720*a65addddSAndroid Build Coastguard Worker public: 1721*a65addddSAndroid Build Coastguard Worker Scaler(double factor) 1722*a65addddSAndroid Build Coastguard Worker : factor(factor) { 1723*a65addddSAndroid Build Coastguard Worker } 1724*a65addddSAndroid Build Coastguard Worker 1725*a65addddSAndroid Build Coastguard Worker double scale(double x) { 1726*a65addddSAndroid Build Coastguard Worker return x * factor; 1727*a65addddSAndroid Build Coastguard Worker } 1728*a65addddSAndroid Build Coastguard Worker }; 1729*a65addddSAndroid Build Coastguard Worker 1730*a65addddSAndroid Build Coastguard Worker using ScalerFactory = std::function<Scaler(double)>; 1731*a65addddSAndroid Build Coastguard Worker 1732*a65addddSAndroid Build Coastguard Worker fruit::Component<ScalerFactory> getScalerComponent() { 1733*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1734*a65addddSAndroid Build Coastguard Worker .registerFactory<Scaler(fruit::Assisted<double>)>([](float factor) { return Scaler(factor); }); 1735*a65addddSAndroid Build Coastguard Worker } 1736*a65addddSAndroid Build Coastguard Worker 1737*a65addddSAndroid Build Coastguard Worker int main() { 1738*a65addddSAndroid Build Coastguard Worker fruit::Injector<ScalerFactory> injector(getScalerComponent); 1739*a65addddSAndroid Build Coastguard Worker ScalerFactory scalerFactory(injector); 1740*a65addddSAndroid Build Coastguard Worker Scaler scaler = scalerFactory(12.1); 1741*a65addddSAndroid Build Coastguard Worker std::cout << scaler.scale(3) << std::endl; 1742*a65addddSAndroid Build Coastguard Worker } 1743*a65addddSAndroid Build Coastguard Worker ''' 1744*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1745*a65addddSAndroid Build Coastguard Worker r'FunctorSignatureDoesNotMatchError<Scaler\(double\),Scaler\(float\)>', 1746*a65addddSAndroid Build Coastguard Worker r'Unexpected functor signature', 1747*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1748*a65addddSAndroid Build Coastguard Worker source) 1749*a65addddSAndroid Build Coastguard Worker 1750*a65addddSAndroid Build Coastguard Worker def test_register_factory_nonmovable_ok(self): 1751*a65addddSAndroid Build Coastguard Worker source = ''' 1752*a65addddSAndroid Build Coastguard Worker struct C { 1753*a65addddSAndroid Build Coastguard Worker INJECT(C()) = default; 1754*a65addddSAndroid Build Coastguard Worker 1755*a65addddSAndroid Build Coastguard Worker C(const C&) = delete; 1756*a65addddSAndroid Build Coastguard Worker C(C&&) = delete; 1757*a65addddSAndroid Build Coastguard Worker C& operator=(const C&) = delete; 1758*a65addddSAndroid Build Coastguard Worker C& operator=(C&&) = delete; 1759*a65addddSAndroid Build Coastguard Worker }; 1760*a65addddSAndroid Build Coastguard Worker 1761*a65addddSAndroid Build Coastguard Worker using CFactory = std::function<std::unique_ptr<C>()>; 1762*a65addddSAndroid Build Coastguard Worker 1763*a65addddSAndroid Build Coastguard Worker fruit::Component<CFactory> getCFactory() { 1764*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 1765*a65addddSAndroid Build Coastguard Worker } 1766*a65addddSAndroid Build Coastguard Worker 1767*a65addddSAndroid Build Coastguard Worker int main() { 1768*a65addddSAndroid Build Coastguard Worker fruit::Injector<CFactory> injector(getCFactory); 1769*a65addddSAndroid Build Coastguard Worker CFactory cFactory(injector); 1770*a65addddSAndroid Build Coastguard Worker std::unique_ptr<C> c = cFactory(); 1771*a65addddSAndroid Build Coastguard Worker (void)c; 1772*a65addddSAndroid Build Coastguard Worker } 1773*a65addddSAndroid Build Coastguard Worker ''' 1774*a65addddSAndroid Build Coastguard Worker expect_success( 1775*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1776*a65addddSAndroid Build Coastguard Worker source) 1777*a65addddSAndroid Build Coastguard Worker 1778*a65addddSAndroid Build Coastguard Worker # TODO: this might not be the best error message, maybe we should ignore the constructor entirely in the message, 1779*a65addddSAndroid Build Coastguard Worker # or mention that there are other ways to satisfy that dependency. 1780*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1781*a65addddSAndroid Build Coastguard Worker ('X', 1782*a65addddSAndroid Build Coastguard Worker 'std::function<X(int)>'), 1783*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 1784*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<X(int)>>'), 1785*a65addddSAndroid Build Coastguard Worker ]) 1786*a65addddSAndroid Build Coastguard Worker def test_register_factory_not_existing_constructor1(self, XAnnot, XFactoryAnnot): 1787*a65addddSAndroid Build Coastguard Worker source = ''' 1788*a65addddSAndroid Build Coastguard Worker struct X { 1789*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 1790*a65addddSAndroid Build Coastguard Worker }; 1791*a65addddSAndroid Build Coastguard Worker 1792*a65addddSAndroid Build Coastguard Worker fruit::Component<XFactoryAnnot> getComponent() { 1793*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 1794*a65addddSAndroid Build Coastguard Worker } 1795*a65addddSAndroid Build Coastguard Worker ''' 1796*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1797*a65addddSAndroid Build Coastguard Worker r'FunctorSignatureDoesNotMatchError<XAnnot\(int\),XAnnot\((void)?\)>', 1798*a65addddSAndroid Build Coastguard Worker r'Unexpected functor signature', 1799*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1800*a65addddSAndroid Build Coastguard Worker source, 1801*a65addddSAndroid Build Coastguard Worker locals()) 1802*a65addddSAndroid Build Coastguard Worker 1803*a65addddSAndroid Build Coastguard Worker # TODO: this might not be the best error message, maybe we should ignore the constructor entirely in the message, 1804*a65addddSAndroid Build Coastguard Worker # or mention that there are other ways to satisfy that dependency. 1805*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1806*a65addddSAndroid Build Coastguard Worker ('std::function<std::unique_ptr<X>(int)>', 1807*a65addddSAndroid Build Coastguard Worker r'std::unique_ptr<X(,std::default_delete<X>)?>\(int\)', 1808*a65addddSAndroid Build Coastguard Worker r'std::unique_ptr<X(,std::default_delete<X>)?>\((void)?\)'), 1809*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>(int)>>', 1810*a65addddSAndroid Build Coastguard Worker r'fruit::Annotated<Annotation1,std::unique_ptr<X(,std::default_delete<X>)?>>\(int\)', 1811*a65addddSAndroid Build Coastguard Worker r'fruit::Annotated<Annotation1,std::unique_ptr<X(,std::default_delete<X>)?>>\((void)?\)') 1812*a65addddSAndroid Build Coastguard Worker ]) 1813*a65addddSAndroid Build Coastguard Worker def test_register_factory_not_existing_constructor2(self, XIntFactoryAnnot, XIntFactoryAnnotRegex, XVoidFactoryAnnotRegex): 1814*a65addddSAndroid Build Coastguard Worker source = ''' 1815*a65addddSAndroid Build Coastguard Worker struct X { 1816*a65addddSAndroid Build Coastguard Worker using Inject = X(); 1817*a65addddSAndroid Build Coastguard Worker }; 1818*a65addddSAndroid Build Coastguard Worker 1819*a65addddSAndroid Build Coastguard Worker fruit::Component<XIntFactoryAnnot> getComponent() { 1820*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 1821*a65addddSAndroid Build Coastguard Worker } 1822*a65addddSAndroid Build Coastguard Worker ''' 1823*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1824*a65addddSAndroid Build Coastguard Worker 'FunctorSignatureDoesNotMatchError<XIntFactoryAnnotRegex,XVoidFactoryAnnotRegex>', 1825*a65addddSAndroid Build Coastguard Worker 'Unexpected functor signature', 1826*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1827*a65addddSAndroid Build Coastguard Worker source, 1828*a65addddSAndroid Build Coastguard Worker locals()) 1829*a65addddSAndroid Build Coastguard Worker 1830*a65addddSAndroid Build Coastguard Worker # TODO: this might not be the best error message, maybe we should ignore the constructor entirely in the message, 1831*a65addddSAndroid Build Coastguard Worker # or mention that there are other ways to satisfy that dependency. 1832*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1833*a65addddSAndroid Build Coastguard Worker ('X', 1834*a65addddSAndroid Build Coastguard Worker 'std::function<X(int)>'), 1835*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 1836*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<X(int)>>'), 1837*a65addddSAndroid Build Coastguard Worker ]) 1838*a65addddSAndroid Build Coastguard Worker def test_register_factory_not_existing_constructor2_returning_value(self, XAnnot, XFactoryAnnot): 1839*a65addddSAndroid Build Coastguard Worker source = ''' 1840*a65addddSAndroid Build Coastguard Worker struct X { 1841*a65addddSAndroid Build Coastguard Worker using Inject = X(); 1842*a65addddSAndroid Build Coastguard Worker }; 1843*a65addddSAndroid Build Coastguard Worker 1844*a65addddSAndroid Build Coastguard Worker fruit::Component<XFactoryAnnot> getComponent() { 1845*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 1846*a65addddSAndroid Build Coastguard Worker } 1847*a65addddSAndroid Build Coastguard Worker ''' 1848*a65addddSAndroid Build Coastguard Worker expect_compile_error( 1849*a65addddSAndroid Build Coastguard Worker r'FunctorSignatureDoesNotMatchError<XAnnot\(int\), XAnnot\((void)?\)>', 1850*a65addddSAndroid Build Coastguard Worker r'Unexpected functor signature', 1851*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1852*a65addddSAndroid Build Coastguard Worker source, 1853*a65addddSAndroid Build Coastguard Worker locals()) 1854*a65addddSAndroid Build Coastguard Worker 1855*a65addddSAndroid Build Coastguard Worker 1856*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1857*a65addddSAndroid Build Coastguard Worker 'std::function<X()>', 1858*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<X()>>', 1859*a65addddSAndroid Build Coastguard Worker ]) 1860*a65addddSAndroid Build Coastguard Worker def test_register_factory_success_factory_movable_only_implicit(self, XFactoryAnnot): 1861*a65addddSAndroid Build Coastguard Worker source = ''' 1862*a65addddSAndroid Build Coastguard Worker struct X { 1863*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 1864*a65addddSAndroid Build Coastguard Worker X(X&&) = default; 1865*a65addddSAndroid Build Coastguard Worker X(const X&) = delete; 1866*a65addddSAndroid Build Coastguard Worker }; 1867*a65addddSAndroid Build Coastguard Worker 1868*a65addddSAndroid Build Coastguard Worker fruit::Component<XFactoryAnnot> getComponent() { 1869*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 1870*a65addddSAndroid Build Coastguard Worker } 1871*a65addddSAndroid Build Coastguard Worker 1872*a65addddSAndroid Build Coastguard Worker int main() { 1873*a65addddSAndroid Build Coastguard Worker fruit::Injector<XFactoryAnnot> injector(getComponent); 1874*a65addddSAndroid Build Coastguard Worker injector.get<XFactoryAnnot>()(); 1875*a65addddSAndroid Build Coastguard Worker } 1876*a65addddSAndroid Build Coastguard Worker ''' 1877*a65addddSAndroid Build Coastguard Worker expect_success( 1878*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1879*a65addddSAndroid Build Coastguard Worker source, 1880*a65addddSAndroid Build Coastguard Worker locals()) 1881*a65addddSAndroid Build Coastguard Worker 1882*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1883*a65addddSAndroid Build Coastguard Worker ('X', 'X()', 'std::function<X()>'), 1884*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'X()', 'fruit::Annotated<Annotation1, std::function<X()>>'), 1885*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>', 'std::unique_ptr<X>(new X())', 'std::function<std::unique_ptr<X>()>'), 1886*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, std::unique_ptr<X>>', 'std::unique_ptr<X>(new X())', 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>'), 1887*a65addddSAndroid Build Coastguard Worker ]) 1888*a65addddSAndroid Build Coastguard Worker def test_register_factory_success_factory_movable_only_explicit(self, XPtrAnnot, ConstructX, XPtrFactoryAnnot): 1889*a65addddSAndroid Build Coastguard Worker source = ''' 1890*a65addddSAndroid Build Coastguard Worker struct X { 1891*a65addddSAndroid Build Coastguard Worker X() = default; 1892*a65addddSAndroid Build Coastguard Worker X(X&&) = default; 1893*a65addddSAndroid Build Coastguard Worker X(const X&) = delete; 1894*a65addddSAndroid Build Coastguard Worker }; 1895*a65addddSAndroid Build Coastguard Worker 1896*a65addddSAndroid Build Coastguard Worker fruit::Component<XPtrFactoryAnnot> getComponent() { 1897*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1898*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtrAnnot()>([](){return ConstructX;}); 1899*a65addddSAndroid Build Coastguard Worker } 1900*a65addddSAndroid Build Coastguard Worker 1901*a65addddSAndroid Build Coastguard Worker int main() { 1902*a65addddSAndroid Build Coastguard Worker fruit::Injector<XPtrFactoryAnnot> injector(getComponent); 1903*a65addddSAndroid Build Coastguard Worker injector.get<XPtrFactoryAnnot>()(); 1904*a65addddSAndroid Build Coastguard Worker } 1905*a65addddSAndroid Build Coastguard Worker ''' 1906*a65addddSAndroid Build Coastguard Worker expect_success( 1907*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1908*a65addddSAndroid Build Coastguard Worker source, 1909*a65addddSAndroid Build Coastguard Worker locals()) 1910*a65addddSAndroid Build Coastguard Worker 1911*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1912*a65addddSAndroid Build Coastguard Worker 'std::function<std::unique_ptr<X>()>', 1913*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>', 1914*a65addddSAndroid Build Coastguard Worker ]) 1915*a65addddSAndroid Build Coastguard Worker def test_register_factory_success_factory_not_movable_implicit(self, XPtrFactoryAnnot): 1916*a65addddSAndroid Build Coastguard Worker source = ''' 1917*a65addddSAndroid Build Coastguard Worker struct X { 1918*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 1919*a65addddSAndroid Build Coastguard Worker X(X&&) = delete; 1920*a65addddSAndroid Build Coastguard Worker X(const X&) = delete; 1921*a65addddSAndroid Build Coastguard Worker }; 1922*a65addddSAndroid Build Coastguard Worker 1923*a65addddSAndroid Build Coastguard Worker fruit::Component<XPtrFactoryAnnot> getComponent() { 1924*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 1925*a65addddSAndroid Build Coastguard Worker } 1926*a65addddSAndroid Build Coastguard Worker 1927*a65addddSAndroid Build Coastguard Worker int main() { 1928*a65addddSAndroid Build Coastguard Worker fruit::Injector<XPtrFactoryAnnot> injector(getComponent); 1929*a65addddSAndroid Build Coastguard Worker injector.get<XPtrFactoryAnnot>()(); 1930*a65addddSAndroid Build Coastguard Worker } 1931*a65addddSAndroid Build Coastguard Worker ''' 1932*a65addddSAndroid Build Coastguard Worker expect_success( 1933*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1934*a65addddSAndroid Build Coastguard Worker source, 1935*a65addddSAndroid Build Coastguard Worker locals()) 1936*a65addddSAndroid Build Coastguard Worker 1937*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 1938*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>', 'std::function<std::unique_ptr<X>()>'), 1939*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, std::unique_ptr<X>>', 'fruit::Annotated<Annotation1, std::function<std::unique_ptr<X>()>>'), 1940*a65addddSAndroid Build Coastguard Worker ]) 1941*a65addddSAndroid Build Coastguard Worker def test_register_factory_success_factory_not_movable_explicit_returning_pointer(self, XPtrAnnot, XPtrFactoryAnnot): 1942*a65addddSAndroid Build Coastguard Worker source = ''' 1943*a65addddSAndroid Build Coastguard Worker struct X { 1944*a65addddSAndroid Build Coastguard Worker X() = default; 1945*a65addddSAndroid Build Coastguard Worker X(X&&) = delete; 1946*a65addddSAndroid Build Coastguard Worker X(const X&) = delete; 1947*a65addddSAndroid Build Coastguard Worker }; 1948*a65addddSAndroid Build Coastguard Worker 1949*a65addddSAndroid Build Coastguard Worker fruit::Component<XPtrFactoryAnnot> getComponent() { 1950*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1951*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtrAnnot()>([](){return std::unique_ptr<X>(new X());}); 1952*a65addddSAndroid Build Coastguard Worker } 1953*a65addddSAndroid Build Coastguard Worker 1954*a65addddSAndroid Build Coastguard Worker int main() { 1955*a65addddSAndroid Build Coastguard Worker fruit::Injector<XPtrFactoryAnnot> injector(getComponent); 1956*a65addddSAndroid Build Coastguard Worker injector.get<XPtrFactoryAnnot>()(); 1957*a65addddSAndroid Build Coastguard Worker } 1958*a65addddSAndroid Build Coastguard Worker ''' 1959*a65addddSAndroid Build Coastguard Worker expect_success( 1960*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 1961*a65addddSAndroid Build Coastguard Worker source, 1962*a65addddSAndroid Build Coastguard Worker locals()) 1963*a65addddSAndroid Build Coastguard Worker 1964*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 1965*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 1966*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'), 1967*a65addddSAndroid Build Coastguard Worker ], [ 1968*a65addddSAndroid Build Coastguard Worker 'WithNoAnnotation', 1969*a65addddSAndroid Build Coastguard Worker 'WithAnnotation1', 1970*a65addddSAndroid Build Coastguard Worker ], [ 1971*a65addddSAndroid Build Coastguard Worker 'Y', 1972*a65addddSAndroid Build Coastguard Worker 'Y*', 1973*a65addddSAndroid Build Coastguard Worker 'const Y*', 1974*a65addddSAndroid Build Coastguard Worker 'Y&', 1975*a65addddSAndroid Build Coastguard Worker 'const Y&', 1976*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<Y>', 1977*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<Y>', 1978*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<const Y>', 1979*a65addddSAndroid Build Coastguard Worker ]) 1980*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_param_success(self, ConstructX, XPtr, WithAnnot, YVariant): 1981*a65addddSAndroid Build Coastguard Worker source = ''' 1982*a65addddSAndroid Build Coastguard Worker struct Y {}; 1983*a65addddSAndroid Build Coastguard Worker struct X {}; 1984*a65addddSAndroid Build Coastguard Worker 1985*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<Y>> getYComponent() { 1986*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1987*a65addddSAndroid Build Coastguard Worker .registerConstructor<WithAnnot<Y>()>(); 1988*a65addddSAndroid Build Coastguard Worker } 1989*a65addddSAndroid Build Coastguard Worker 1990*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<XPtr()>> getComponent() { 1991*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 1992*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 1993*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }); 1994*a65addddSAndroid Build Coastguard Worker } 1995*a65addddSAndroid Build Coastguard Worker 1996*a65addddSAndroid Build Coastguard Worker int main() { 1997*a65addddSAndroid Build Coastguard Worker fruit::Injector<std::function<XPtr()>> injector(getComponent); 1998*a65addddSAndroid Build Coastguard Worker XPtr x = injector.get<std::function<XPtr()>>()(); 1999*a65addddSAndroid Build Coastguard Worker (void) x; 2000*a65addddSAndroid Build Coastguard Worker } 2001*a65addddSAndroid Build Coastguard Worker ''' 2002*a65addddSAndroid Build Coastguard Worker expect_success( 2003*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2004*a65addddSAndroid Build Coastguard Worker source, 2005*a65addddSAndroid Build Coastguard Worker locals()) 2006*a65addddSAndroid Build Coastguard Worker 2007*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 2008*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 2009*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'), 2010*a65addddSAndroid Build Coastguard Worker ], [ 2011*a65addddSAndroid Build Coastguard Worker 'WithNoAnnotation', 2012*a65addddSAndroid Build Coastguard Worker 'WithAnnotation1', 2013*a65addddSAndroid Build Coastguard Worker ], [ 2014*a65addddSAndroid Build Coastguard Worker 'Y', 2015*a65addddSAndroid Build Coastguard Worker 'const Y*', 2016*a65addddSAndroid Build Coastguard Worker 'const Y&', 2017*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<const Y>', 2018*a65addddSAndroid Build Coastguard Worker ]) 2019*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_param_const_binding_success(self, ConstructX, XPtr, WithAnnot, YVariant): 2020*a65addddSAndroid Build Coastguard Worker source = ''' 2021*a65addddSAndroid Build Coastguard Worker struct Y {}; 2022*a65addddSAndroid Build Coastguard Worker struct X {}; 2023*a65addddSAndroid Build Coastguard Worker 2024*a65addddSAndroid Build Coastguard Worker const Y y{}; 2025*a65addddSAndroid Build Coastguard Worker 2026*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<const Y>> getYComponent() { 2027*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2028*a65addddSAndroid Build Coastguard Worker .bindInstance<WithAnnot<Y>, Y>(y); 2029*a65addddSAndroid Build Coastguard Worker } 2030*a65addddSAndroid Build Coastguard Worker 2031*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<XPtr()>> getComponent() { 2032*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2033*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 2034*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }); 2035*a65addddSAndroid Build Coastguard Worker } 2036*a65addddSAndroid Build Coastguard Worker 2037*a65addddSAndroid Build Coastguard Worker int main() { 2038*a65addddSAndroid Build Coastguard Worker fruit::Injector<std::function<XPtr()>> injector(getComponent); 2039*a65addddSAndroid Build Coastguard Worker XPtr x = injector.get<std::function<XPtr()>>()(); 2040*a65addddSAndroid Build Coastguard Worker (void) x; 2041*a65addddSAndroid Build Coastguard Worker } 2042*a65addddSAndroid Build Coastguard Worker ''' 2043*a65addddSAndroid Build Coastguard Worker expect_success( 2044*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2045*a65addddSAndroid Build Coastguard Worker source, 2046*a65addddSAndroid Build Coastguard Worker locals()) 2047*a65addddSAndroid Build Coastguard Worker 2048*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 2049*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 2050*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'), 2051*a65addddSAndroid Build Coastguard Worker ], [ 2052*a65addddSAndroid Build Coastguard Worker ('WithNoAnnotation', 'Y'), 2053*a65addddSAndroid Build Coastguard Worker ('WithAnnotation1', 'fruit::Annotated<Annotation1, Y>'), 2054*a65addddSAndroid Build Coastguard Worker ], [ 2055*a65addddSAndroid Build Coastguard Worker 'X', 2056*a65addddSAndroid Build Coastguard Worker 'std::unique_ptr<X>', 2057*a65addddSAndroid Build Coastguard Worker ], [ 2058*a65addddSAndroid Build Coastguard Worker 'Y*', 2059*a65addddSAndroid Build Coastguard Worker 'Y&', 2060*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<Y>', 2061*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<Y>', 2062*a65addddSAndroid Build Coastguard Worker ]) 2063*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_param_error_nonconst_param_required(self, ConstructX, XPtr, WithAnnot, YAnnotRegex, XFactoryResult, YVariant): 2064*a65addddSAndroid Build Coastguard Worker source = ''' 2065*a65addddSAndroid Build Coastguard Worker struct Y {}; 2066*a65addddSAndroid Build Coastguard Worker struct X {}; 2067*a65addddSAndroid Build Coastguard Worker 2068*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<const Y>> getYComponent(); 2069*a65addddSAndroid Build Coastguard Worker 2070*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<XFactoryResult()>> getComponent() { 2071*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2072*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 2073*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }); 2074*a65addddSAndroid Build Coastguard Worker } 2075*a65addddSAndroid Build Coastguard Worker ''' 2076*a65addddSAndroid Build Coastguard Worker expect_compile_error( 2077*a65addddSAndroid Build Coastguard Worker 'NonConstBindingRequiredButConstBindingProvidedError<YAnnotRegex>', 2078*a65addddSAndroid Build Coastguard Worker 'The type T was provided as constant, however one of the constructors/providers/factories in this component', 2079*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2080*a65addddSAndroid Build Coastguard Worker source, 2081*a65addddSAndroid Build Coastguard Worker locals()) 2082*a65addddSAndroid Build Coastguard Worker 2083*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 2084*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 2085*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'), 2086*a65addddSAndroid Build Coastguard Worker ], [ 2087*a65addddSAndroid Build Coastguard Worker 'X', 2088*a65addddSAndroid Build Coastguard Worker 'std::unique_ptr<X>', 2089*a65addddSAndroid Build Coastguard Worker ], [ 2090*a65addddSAndroid Build Coastguard Worker ('WithNoAnnotation', 'Y'), 2091*a65addddSAndroid Build Coastguard Worker ('WithAnnotation1', 'fruit::Annotated<Annotation1, Y>'), 2092*a65addddSAndroid Build Coastguard Worker ], [ 2093*a65addddSAndroid Build Coastguard Worker 'Y*', 2094*a65addddSAndroid Build Coastguard Worker 'Y&', 2095*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<Y>', 2096*a65addddSAndroid Build Coastguard Worker 'fruit::Provider<Y>', 2097*a65addddSAndroid Build Coastguard Worker ]) 2098*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_param_error_nonconst_param_required_install_after(self, ConstructX, XPtr, XFactoryResult, WithAnnot, YAnnotRegex, YVariant): 2099*a65addddSAndroid Build Coastguard Worker source = ''' 2100*a65addddSAndroid Build Coastguard Worker struct Y {}; 2101*a65addddSAndroid Build Coastguard Worker struct X {}; 2102*a65addddSAndroid Build Coastguard Worker 2103*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<const Y>> getYComponent(); 2104*a65addddSAndroid Build Coastguard Worker 2105*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<XFactoryResult()>> getComponent() { 2106*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2107*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtr(WithAnnot<YVariant>)>([](YVariant){ return ConstructX; }) 2108*a65addddSAndroid Build Coastguard Worker .install(getYComponent); 2109*a65addddSAndroid Build Coastguard Worker } 2110*a65addddSAndroid Build Coastguard Worker ''' 2111*a65addddSAndroid Build Coastguard Worker expect_compile_error( 2112*a65addddSAndroid Build Coastguard Worker 'NonConstBindingRequiredButConstBindingProvidedError<YAnnotRegex>', 2113*a65addddSAndroid Build Coastguard Worker 'The type T was provided as constant, however one of the constructors/providers/factories in this component', 2114*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2115*a65addddSAndroid Build Coastguard Worker source, 2116*a65addddSAndroid Build Coastguard Worker locals()) 2117*a65addddSAndroid Build Coastguard Worker 2118*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 2119*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 2120*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'), 2121*a65addddSAndroid Build Coastguard Worker ], [ 2122*a65addddSAndroid Build Coastguard Worker 'WithNoAnnotation', 2123*a65addddSAndroid Build Coastguard Worker 'WithAnnotation1', 2124*a65addddSAndroid Build Coastguard Worker ]) 2125*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_non_assignable_injected_param_success(self, ConstructX, XPtr, WithAnnot): 2126*a65addddSAndroid Build Coastguard Worker source = ''' 2127*a65addddSAndroid Build Coastguard Worker struct Y { 2128*a65addddSAndroid Build Coastguard Worker Y(const Y&) = delete; 2129*a65addddSAndroid Build Coastguard Worker Y& operator=(const Y&) = delete; 2130*a65addddSAndroid Build Coastguard Worker 2131*a65addddSAndroid Build Coastguard Worker Y() = default; 2132*a65addddSAndroid Build Coastguard Worker Y(Y&&) = default; 2133*a65addddSAndroid Build Coastguard Worker Y& operator=(Y&&) = default; 2134*a65addddSAndroid Build Coastguard Worker }; 2135*a65addddSAndroid Build Coastguard Worker struct X {}; 2136*a65addddSAndroid Build Coastguard Worker 2137*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<Y>> getYComponent() { 2138*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2139*a65addddSAndroid Build Coastguard Worker .registerConstructor<WithAnnot<Y>()>(); 2140*a65addddSAndroid Build Coastguard Worker } 2141*a65addddSAndroid Build Coastguard Worker 2142*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<XPtr()>> getComponent() { 2143*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2144*a65addddSAndroid Build Coastguard Worker .install(getYComponent) 2145*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtr(WithAnnot<Y&>)>([](Y&){ return ConstructX; }); 2146*a65addddSAndroid Build Coastguard Worker } 2147*a65addddSAndroid Build Coastguard Worker 2148*a65addddSAndroid Build Coastguard Worker int main() { 2149*a65addddSAndroid Build Coastguard Worker fruit::Injector<std::function<XPtr()>> injector(getComponent); 2150*a65addddSAndroid Build Coastguard Worker XPtr x = injector.get<std::function<XPtr()>>()(); 2151*a65addddSAndroid Build Coastguard Worker (void) x; 2152*a65addddSAndroid Build Coastguard Worker } 2153*a65addddSAndroid Build Coastguard Worker ''' 2154*a65addddSAndroid Build Coastguard Worker expect_success( 2155*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2156*a65addddSAndroid Build Coastguard Worker source, 2157*a65addddSAndroid Build Coastguard Worker locals()) 2158*a65addddSAndroid Build Coastguard Worker 2159*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 2160*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 2161*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'), 2162*a65addddSAndroid Build Coastguard Worker ]) 2163*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_non_assignable_assisted_param_success(self, ConstructX, XPtr): 2164*a65addddSAndroid Build Coastguard Worker source = ''' 2165*a65addddSAndroid Build Coastguard Worker struct Y { 2166*a65addddSAndroid Build Coastguard Worker Y(const Y&) = delete; 2167*a65addddSAndroid Build Coastguard Worker Y& operator=(const Y&) = delete; 2168*a65addddSAndroid Build Coastguard Worker 2169*a65addddSAndroid Build Coastguard Worker Y() = default; 2170*a65addddSAndroid Build Coastguard Worker Y(Y&&) = default; 2171*a65addddSAndroid Build Coastguard Worker Y& operator=(Y&&) = default; 2172*a65addddSAndroid Build Coastguard Worker }; 2173*a65addddSAndroid Build Coastguard Worker struct X {}; 2174*a65addddSAndroid Build Coastguard Worker 2175*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<XPtr(Y)>> getComponent() { 2176*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2177*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtr(fruit::Assisted<Y>)>([](Y){ return ConstructX; }); 2178*a65addddSAndroid Build Coastguard Worker } 2179*a65addddSAndroid Build Coastguard Worker 2180*a65addddSAndroid Build Coastguard Worker int main() { 2181*a65addddSAndroid Build Coastguard Worker fruit::Injector<std::function<XPtr(Y)>> injector(getComponent); 2182*a65addddSAndroid Build Coastguard Worker XPtr x = injector.get<std::function<XPtr(Y)>>()(Y()); 2183*a65addddSAndroid Build Coastguard Worker (void) x; 2184*a65addddSAndroid Build Coastguard Worker } 2185*a65addddSAndroid Build Coastguard Worker ''' 2186*a65addddSAndroid Build Coastguard Worker expect_success( 2187*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2188*a65addddSAndroid Build Coastguard Worker source, 2189*a65addddSAndroid Build Coastguard Worker locals()) 2190*a65addddSAndroid Build Coastguard Worker 2191*a65addddSAndroid Build Coastguard Worker def test_register_factory_requiring_nonconst_then_requiring_const_ok(self): 2192*a65addddSAndroid Build Coastguard Worker source = ''' 2193*a65addddSAndroid Build Coastguard Worker struct X {}; 2194*a65addddSAndroid Build Coastguard Worker struct Y {}; 2195*a65addddSAndroid Build Coastguard Worker struct Z {}; 2196*a65addddSAndroid Build Coastguard Worker 2197*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<Y()>, std::function<Z()>> getRootComponent() { 2198*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2199*a65addddSAndroid Build Coastguard Worker .registerFactory<Y(X&)>([](X&) { return Y();}) 2200*a65addddSAndroid Build Coastguard Worker .registerFactory<Z(const X&)>([](const X&) { return Z();}) 2201*a65addddSAndroid Build Coastguard Worker .registerConstructor<X()>(); 2202*a65addddSAndroid Build Coastguard Worker } 2203*a65addddSAndroid Build Coastguard Worker 2204*a65addddSAndroid Build Coastguard Worker int main() { 2205*a65addddSAndroid Build Coastguard Worker fruit::Injector<std::function<Y()>, std::function<Z()>> injector(getRootComponent); 2206*a65addddSAndroid Build Coastguard Worker std::function<Y()> yFactory = injector.get<std::function<Y()>>(); 2207*a65addddSAndroid Build Coastguard Worker yFactory(); 2208*a65addddSAndroid Build Coastguard Worker std::function<Z()> zFactory = injector.get<std::function<Z()>>(); 2209*a65addddSAndroid Build Coastguard Worker zFactory(); 2210*a65addddSAndroid Build Coastguard Worker } 2211*a65addddSAndroid Build Coastguard Worker ''' 2212*a65addddSAndroid Build Coastguard Worker expect_success( 2213*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2214*a65addddSAndroid Build Coastguard Worker source, 2215*a65addddSAndroid Build Coastguard Worker locals()) 2216*a65addddSAndroid Build Coastguard Worker 2217*a65addddSAndroid Build Coastguard Worker def test_register_factory_requiring_nonconst_then_requiring_const_declaring_const_requirement_error(self): 2218*a65addddSAndroid Build Coastguard Worker source = ''' 2219*a65addddSAndroid Build Coastguard Worker struct X {}; 2220*a65addddSAndroid Build Coastguard Worker struct Y {}; 2221*a65addddSAndroid Build Coastguard Worker struct Z {}; 2222*a65addddSAndroid Build Coastguard Worker 2223*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>, std::function<Y()>, std::function<Z()>> getRootComponent() { 2224*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2225*a65addddSAndroid Build Coastguard Worker .registerFactory<Y(X&)>([](X&) { return Y();}) 2226*a65addddSAndroid Build Coastguard Worker .registerFactory<Z(const X&)>([](const X&) { return Z();}); 2227*a65addddSAndroid Build Coastguard Worker } 2228*a65addddSAndroid Build Coastguard Worker ''' 2229*a65addddSAndroid Build Coastguard Worker expect_compile_error( 2230*a65addddSAndroid Build Coastguard Worker 'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>', 2231*a65addddSAndroid Build Coastguard Worker 'The type T was declared as a const Required type in the returned Component, however', 2232*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2233*a65addddSAndroid Build Coastguard Worker source, 2234*a65addddSAndroid Build Coastguard Worker locals()) 2235*a65addddSAndroid Build Coastguard Worker 2236*a65addddSAndroid Build Coastguard Worker def test_register_factory_requiring_const_then_requiring_nonconst_ok(self): 2237*a65addddSAndroid Build Coastguard Worker source = ''' 2238*a65addddSAndroid Build Coastguard Worker struct X {}; 2239*a65addddSAndroid Build Coastguard Worker struct Y {}; 2240*a65addddSAndroid Build Coastguard Worker struct Z {}; 2241*a65addddSAndroid Build Coastguard Worker 2242*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<Y()>, std::function<Z()>> getRootComponent() { 2243*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2244*a65addddSAndroid Build Coastguard Worker .registerFactory<Y(const X&)>([](const X&) { return Y();}) 2245*a65addddSAndroid Build Coastguard Worker .registerFactory<Z(X&)>([](X&) { return Z();}) 2246*a65addddSAndroid Build Coastguard Worker .registerConstructor<X()>(); 2247*a65addddSAndroid Build Coastguard Worker } 2248*a65addddSAndroid Build Coastguard Worker 2249*a65addddSAndroid Build Coastguard Worker int main() { 2250*a65addddSAndroid Build Coastguard Worker fruit::Injector<std::function<Y()>, std::function<Z()>> injector(getRootComponent); 2251*a65addddSAndroid Build Coastguard Worker std::function<Y()> yFactory = injector.get<std::function<Y()>>(); 2252*a65addddSAndroid Build Coastguard Worker yFactory(); 2253*a65addddSAndroid Build Coastguard Worker std::function<Z()> zFactory = injector.get<std::function<Z()>>(); 2254*a65addddSAndroid Build Coastguard Worker zFactory(); 2255*a65addddSAndroid Build Coastguard Worker } 2256*a65addddSAndroid Build Coastguard Worker ''' 2257*a65addddSAndroid Build Coastguard Worker expect_success( 2258*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2259*a65addddSAndroid Build Coastguard Worker source, 2260*a65addddSAndroid Build Coastguard Worker locals()) 2261*a65addddSAndroid Build Coastguard Worker 2262*a65addddSAndroid Build Coastguard Worker def test_register_factory_requiring_const_then_requiring_nonconst_declaring_const_requirement_error(self): 2263*a65addddSAndroid Build Coastguard Worker source = ''' 2264*a65addddSAndroid Build Coastguard Worker struct X {}; 2265*a65addddSAndroid Build Coastguard Worker struct Y {}; 2266*a65addddSAndroid Build Coastguard Worker struct Z {}; 2267*a65addddSAndroid Build Coastguard Worker 2268*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Required<const X>, std::function<Y()>, std::function<Z()>> getRootComponent() { 2269*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2270*a65addddSAndroid Build Coastguard Worker .registerFactory<Y(const X&)>([](const X&) { return Y();}) 2271*a65addddSAndroid Build Coastguard Worker .registerFactory<Z(X&)>([](X&) { return Z();}); 2272*a65addddSAndroid Build Coastguard Worker } 2273*a65addddSAndroid Build Coastguard Worker ''' 2274*a65addddSAndroid Build Coastguard Worker expect_compile_error( 2275*a65addddSAndroid Build Coastguard Worker 'ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<X>', 2276*a65addddSAndroid Build Coastguard Worker 'The type T was declared as a const Required type in the returned Component, however', 2277*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2278*a65addddSAndroid Build Coastguard Worker source, 2279*a65addddSAndroid Build Coastguard Worker locals()) 2280*a65addddSAndroid Build Coastguard Worker 2281*a65addddSAndroid Build Coastguard Worker def test_provider_get_error_type_unique_pointer_pointer_not_provided(self): 2282*a65addddSAndroid Build Coastguard Worker source = ''' 2283*a65addddSAndroid Build Coastguard Worker struct X {}; 2284*a65addddSAndroid Build Coastguard Worker 2285*a65addddSAndroid Build Coastguard Worker void f(fruit::Provider<X> provider) { 2286*a65addddSAndroid Build Coastguard Worker provider.get<std::unique_ptr<X>*>(); 2287*a65addddSAndroid Build Coastguard Worker } 2288*a65addddSAndroid Build Coastguard Worker ''' 2289*a65addddSAndroid Build Coastguard Worker expect_compile_error( 2290*a65addddSAndroid Build Coastguard Worker r'TypeNotProvidedError<std::unique_ptr<X(,std::default_delete<X>)?>\*>', 2291*a65addddSAndroid Build Coastguard Worker r'Trying to get an instance of T, but it is not provided by this Provider/Injector.', 2292*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2293*a65addddSAndroid Build Coastguard Worker source) 2294*a65addddSAndroid Build Coastguard Worker 2295*a65addddSAndroid Build Coastguard Worker @multiple_parameters([ 2296*a65addddSAndroid Build Coastguard Worker ('X()', 'X'), 2297*a65addddSAndroid Build Coastguard Worker ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'), 2298*a65addddSAndroid Build Coastguard Worker ], [ 2299*a65addddSAndroid Build Coastguard Worker 'X', 2300*a65addddSAndroid Build Coastguard Worker 'std::unique_ptr<X>', 2301*a65addddSAndroid Build Coastguard Worker ], [ 2302*a65addddSAndroid Build Coastguard Worker ('Y**', r'Y\*\*'), 2303*a65addddSAndroid Build Coastguard Worker ('std::shared_ptr<Y>*', r'std::shared_ptr<Y>\*'), 2304*a65addddSAndroid Build Coastguard Worker ('std::nullptr_t', r'(std::)?nullptr(_t)?'), 2305*a65addddSAndroid Build Coastguard Worker ('Y*&', r'Y\*&'), 2306*a65addddSAndroid Build Coastguard Worker ('Y(*)()', r'Y(\((__cdecl)?\*\))?\((void)?\)'), 2307*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Y**>', r'Y\*\*'), 2308*a65addddSAndroid Build Coastguard Worker ]) 2309*a65addddSAndroid Build Coastguard Worker def test_register_factory_with_param_error_type_not_injectable(self, 2310*a65addddSAndroid Build Coastguard Worker ConstructX, XPtr, XFactoryResult, YVariant, YVariantRegex): 2311*a65addddSAndroid Build Coastguard Worker source = ''' 2312*a65addddSAndroid Build Coastguard Worker struct Y {}; 2313*a65addddSAndroid Build Coastguard Worker struct X {}; 2314*a65addddSAndroid Build Coastguard Worker 2315*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 2316*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2317*a65addddSAndroid Build Coastguard Worker .registerFactory<XPtr(YVariant)>([](YVariant){ return ConstructX; }); 2318*a65addddSAndroid Build Coastguard Worker } 2319*a65addddSAndroid Build Coastguard Worker ''' 2320*a65addddSAndroid Build Coastguard Worker expect_compile_error( 2321*a65addddSAndroid Build Coastguard Worker 'NonInjectableTypeError<YVariantRegex>', 2322*a65addddSAndroid Build Coastguard Worker 'The type T is not injectable.', 2323*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2324*a65addddSAndroid Build Coastguard Worker source, 2325*a65addddSAndroid Build Coastguard Worker locals()) 2326*a65addddSAndroid Build Coastguard Worker 2327*a65addddSAndroid Build Coastguard Worker def test_register_factory_bind_nonconst_unique_ptr_factory_to_const_value_factory(self): 2328*a65addddSAndroid Build Coastguard Worker source = ''' 2329*a65addddSAndroid Build Coastguard Worker struct X { 2330*a65addddSAndroid Build Coastguard Worker INJECT(X()) = default; 2331*a65addddSAndroid Build Coastguard Worker }; 2332*a65addddSAndroid Build Coastguard Worker 2333*a65addddSAndroid Build Coastguard Worker fruit::Component<const std::function<X()>> getChildComponent() { 2334*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 2335*a65addddSAndroid Build Coastguard Worker } 2336*a65addddSAndroid Build Coastguard Worker 2337*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<std::unique_ptr<X>()>> getRootComponent() { 2338*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2339*a65addddSAndroid Build Coastguard Worker .install(getChildComponent); 2340*a65addddSAndroid Build Coastguard Worker } 2341*a65addddSAndroid Build Coastguard Worker 2342*a65addddSAndroid Build Coastguard Worker int main() { 2343*a65addddSAndroid Build Coastguard Worker fruit::Injector<std::function<std::unique_ptr<X>()>> injector(getRootComponent); 2344*a65addddSAndroid Build Coastguard Worker std::function<std::unique_ptr<X>()> xFactory(injector); 2345*a65addddSAndroid Build Coastguard Worker xFactory(); 2346*a65addddSAndroid Build Coastguard Worker } 2347*a65addddSAndroid Build Coastguard Worker ''' 2348*a65addddSAndroid Build Coastguard Worker expect_success( 2349*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2350*a65addddSAndroid Build Coastguard Worker source, 2351*a65addddSAndroid Build Coastguard Worker locals()) 2352*a65addddSAndroid Build Coastguard Worker 2353*a65addddSAndroid Build Coastguard Worker def test_register_factory_bind_const_interface_factory_to_nonconst_implementation_factory(self): 2354*a65addddSAndroid Build Coastguard Worker source = ''' 2355*a65addddSAndroid Build Coastguard Worker struct X { 2356*a65addddSAndroid Build Coastguard Worker virtual void foo() = 0; 2357*a65addddSAndroid Build Coastguard Worker virtual ~X() = default; 2358*a65addddSAndroid Build Coastguard Worker }; 2359*a65addddSAndroid Build Coastguard Worker 2360*a65addddSAndroid Build Coastguard Worker struct Y : public X { 2361*a65addddSAndroid Build Coastguard Worker INJECT(Y()) = default; 2362*a65addddSAndroid Build Coastguard Worker 2363*a65addddSAndroid Build Coastguard Worker void foo() override { 2364*a65addddSAndroid Build Coastguard Worker } 2365*a65addddSAndroid Build Coastguard Worker }; 2366*a65addddSAndroid Build Coastguard Worker 2367*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<std::unique_ptr<Y>()>> getChildComponent() { 2368*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 2369*a65addddSAndroid Build Coastguard Worker } 2370*a65addddSAndroid Build Coastguard Worker 2371*a65addddSAndroid Build Coastguard Worker fruit::Component<const std::function<std::unique_ptr<X>()>> getRootComponent() { 2372*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2373*a65addddSAndroid Build Coastguard Worker .install(getChildComponent) 2374*a65addddSAndroid Build Coastguard Worker .bind<X, Y>(); 2375*a65addddSAndroid Build Coastguard Worker } 2376*a65addddSAndroid Build Coastguard Worker 2377*a65addddSAndroid Build Coastguard Worker int main() { 2378*a65addddSAndroid Build Coastguard Worker fruit::Injector<const std::function<std::unique_ptr<X>()>> injector(getRootComponent); 2379*a65addddSAndroid Build Coastguard Worker std::function<std::unique_ptr<X>()> xFactory(injector); 2380*a65addddSAndroid Build Coastguard Worker xFactory(); 2381*a65addddSAndroid Build Coastguard Worker } 2382*a65addddSAndroid Build Coastguard Worker ''' 2383*a65addddSAndroid Build Coastguard Worker expect_success( 2384*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2385*a65addddSAndroid Build Coastguard Worker source, 2386*a65addddSAndroid Build Coastguard Worker locals()) 2387*a65addddSAndroid Build Coastguard Worker 2388*a65addddSAndroid Build Coastguard Worker def test_register_factory_bind_nonconst_interface_factory_to_const_implementation_factory(self): 2389*a65addddSAndroid Build Coastguard Worker source = ''' 2390*a65addddSAndroid Build Coastguard Worker struct X { 2391*a65addddSAndroid Build Coastguard Worker virtual void foo() = 0; 2392*a65addddSAndroid Build Coastguard Worker virtual ~X() = default; 2393*a65addddSAndroid Build Coastguard Worker }; 2394*a65addddSAndroid Build Coastguard Worker 2395*a65addddSAndroid Build Coastguard Worker struct Y : public X { 2396*a65addddSAndroid Build Coastguard Worker INJECT(Y()) = default; 2397*a65addddSAndroid Build Coastguard Worker 2398*a65addddSAndroid Build Coastguard Worker void foo() override { 2399*a65addddSAndroid Build Coastguard Worker } 2400*a65addddSAndroid Build Coastguard Worker }; 2401*a65addddSAndroid Build Coastguard Worker 2402*a65addddSAndroid Build Coastguard Worker fruit::Component<const std::function<std::unique_ptr<Y>()>> getChildComponent() { 2403*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 2404*a65addddSAndroid Build Coastguard Worker } 2405*a65addddSAndroid Build Coastguard Worker 2406*a65addddSAndroid Build Coastguard Worker fruit::Component<std::function<std::unique_ptr<X>()>> getRootComponent() { 2407*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2408*a65addddSAndroid Build Coastguard Worker .install(getChildComponent) 2409*a65addddSAndroid Build Coastguard Worker .bind<X, Y>(); 2410*a65addddSAndroid Build Coastguard Worker } 2411*a65addddSAndroid Build Coastguard Worker 2412*a65addddSAndroid Build Coastguard Worker int main() { 2413*a65addddSAndroid Build Coastguard Worker fruit::Injector<std::function<std::unique_ptr<X>()>> injector(getRootComponent); 2414*a65addddSAndroid Build Coastguard Worker std::function<std::unique_ptr<X>()> xFactory(injector); 2415*a65addddSAndroid Build Coastguard Worker xFactory(); 2416*a65addddSAndroid Build Coastguard Worker } 2417*a65addddSAndroid Build Coastguard Worker ''' 2418*a65addddSAndroid Build Coastguard Worker expect_success( 2419*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2420*a65addddSAndroid Build Coastguard Worker source, 2421*a65addddSAndroid Build Coastguard Worker locals()) 2422*a65addddSAndroid Build Coastguard Worker 2423*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 2424*a65addddSAndroid Build Coastguard Worker 'WithNoAnnotation', 2425*a65addddSAndroid Build Coastguard Worker 'WithAnnotation1', 2426*a65addddSAndroid Build Coastguard Worker ]) 2427*a65addddSAndroid Build Coastguard Worker def test_register_factory_abstract_class_ok(self, WithAnnot): 2428*a65addddSAndroid Build Coastguard Worker source = ''' 2429*a65addddSAndroid Build Coastguard Worker struct I { 2430*a65addddSAndroid Build Coastguard Worker virtual int foo() = 0; 2431*a65addddSAndroid Build Coastguard Worker virtual ~I() = default; 2432*a65addddSAndroid Build Coastguard Worker }; 2433*a65addddSAndroid Build Coastguard Worker 2434*a65addddSAndroid Build Coastguard Worker struct X : public I { 2435*a65addddSAndroid Build Coastguard Worker int foo() override { 2436*a65addddSAndroid Build Coastguard Worker return 5; 2437*a65addddSAndroid Build Coastguard Worker } 2438*a65addddSAndroid Build Coastguard Worker }; 2439*a65addddSAndroid Build Coastguard Worker 2440*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<std::function<std::unique_ptr<I>()>>> getComponent() { 2441*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2442*a65addddSAndroid Build Coastguard Worker .registerFactory<WithAnnot<std::unique_ptr<I>>()>([](){return std::unique_ptr<I>(static_cast<I*>(new X()));}); 2443*a65addddSAndroid Build Coastguard Worker } 2444*a65addddSAndroid Build Coastguard Worker 2445*a65addddSAndroid Build Coastguard Worker int main() { 2446*a65addddSAndroid Build Coastguard Worker fruit::Injector<WithAnnot<std::function<std::unique_ptr<I>()>>> injector(getComponent); 2447*a65addddSAndroid Build Coastguard Worker 2448*a65addddSAndroid Build Coastguard Worker Assert(injector.get<WithAnnot<std::function<std::unique_ptr<I>()>>>()()->foo() == 5); 2449*a65addddSAndroid Build Coastguard Worker } 2450*a65addddSAndroid Build Coastguard Worker ''' 2451*a65addddSAndroid Build Coastguard Worker expect_success( 2452*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2453*a65addddSAndroid Build Coastguard Worker source, 2454*a65addddSAndroid Build Coastguard Worker locals()) 2455*a65addddSAndroid Build Coastguard Worker 2456*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 2457*a65addddSAndroid Build Coastguard Worker 'WithNoAnnotation', 2458*a65addddSAndroid Build Coastguard Worker 'WithAnnotation1', 2459*a65addddSAndroid Build Coastguard Worker ]) 2460*a65addddSAndroid Build Coastguard Worker def test_register_factory_abstract_class_with_no_virtual_destructor_error(self, WithAnnot): 2461*a65addddSAndroid Build Coastguard Worker if re.search('MSVC', CXX_COMPILER_NAME): 2462*a65addddSAndroid Build Coastguard Worker # This is disabled in MSVC because it compiles cleanly with the latest MSVC. 2463*a65addddSAndroid Build Coastguard Worker # TODO: investigate why this doesn't fail to compile with MSVC and then re-enable it for MSVC too. 2464*a65addddSAndroid Build Coastguard Worker return 2465*a65addddSAndroid Build Coastguard Worker source = ''' 2466*a65addddSAndroid Build Coastguard Worker struct I { 2467*a65addddSAndroid Build Coastguard Worker virtual int foo() = 0; 2468*a65addddSAndroid Build Coastguard Worker }; 2469*a65addddSAndroid Build Coastguard Worker 2470*a65addddSAndroid Build Coastguard Worker struct X : public I { 2471*a65addddSAndroid Build Coastguard Worker int foo() override { 2472*a65addddSAndroid Build Coastguard Worker return 5; 2473*a65addddSAndroid Build Coastguard Worker } 2474*a65addddSAndroid Build Coastguard Worker }; 2475*a65addddSAndroid Build Coastguard Worker 2476*a65addddSAndroid Build Coastguard Worker fruit::Component<WithAnnot<std::function<std::unique_ptr<I>()>>> getComponent() { 2477*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 2478*a65addddSAndroid Build Coastguard Worker .registerFactory<WithAnnot<std::unique_ptr<I>>()>([](){return std::unique_ptr<I>(static_cast<I*>(new X()));}); 2479*a65addddSAndroid Build Coastguard Worker } 2480*a65addddSAndroid Build Coastguard Worker ''' 2481*a65addddSAndroid Build Coastguard Worker expect_compile_error( 2482*a65addddSAndroid Build Coastguard Worker r'RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorError<I>', 2483*a65addddSAndroid Build Coastguard Worker r'registerFactory\(\) was called with a lambda that returns a std::unique_ptr<T>, but T is an abstract class', 2484*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 2485*a65addddSAndroid Build Coastguard Worker source, 2486*a65addddSAndroid Build Coastguard Worker locals(), 2487*a65addddSAndroid Build Coastguard Worker ignore_warnings=True, 2488*a65addddSAndroid Build Coastguard Worker disable_error_line_number_check=True) 2489*a65addddSAndroid Build Coastguard Worker 2490*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__': 2491*a65addddSAndroid Build Coastguard Worker absltest.main() 2492