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