| Total Complexity | 42 |
| Total Lines | 1035 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like InjectorTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use InjectorTest, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 43 | class InjectorTest extends SapphireTest |
||
| 44 | { |
||
| 45 | |||
| 46 | protected $nestingLevel = 0; |
||
| 47 | |||
| 48 | protected function setUp() |
||
| 49 | { |
||
| 50 | parent::setUp(); |
||
| 51 | |||
| 52 | $this->nestingLevel = 0; |
||
| 53 | } |
||
| 54 | |||
| 55 | protected function tearDown() |
||
| 56 | { |
||
| 57 | |||
| 58 | while ($this->nestingLevel > 0) { |
||
| 59 | $this->nestingLevel--; |
||
| 60 | Config::unnest(); |
||
| 61 | } |
||
| 62 | |||
| 63 | parent::tearDown(); |
||
| 64 | } |
||
| 65 | |||
| 66 | public function testCorrectlyInitialised() |
||
| 72 | ); |
||
| 73 | } |
||
| 74 | |||
| 75 | public function testBasicInjector() |
||
| 76 | { |
||
| 77 | $injector = new Injector(); |
||
| 78 | $injector->setAutoScanProperties(true); |
||
| 79 | $config = array( |
||
| 80 | 'SampleService' => array( |
||
| 81 | 'src' => TEST_SERVICES . '/SampleService.php', |
||
| 82 | 'class' => SampleService::class, |
||
| 83 | ) |
||
| 84 | ); |
||
| 85 | |||
| 86 | $injector->load($config); |
||
| 87 | |||
| 88 | |||
| 89 | $this->assertFalse($injector->has('UnknownService')); |
||
| 90 | $this->assertNull($injector->getServiceName('UnknownService')); |
||
| 91 | |||
| 92 | $this->assertTrue($injector->has('SampleService')); |
||
| 93 | $this->assertEquals( |
||
| 94 | 'SampleService', |
||
| 95 | $injector->getServiceName('SampleService') |
||
| 96 | ); |
||
| 97 | |||
| 98 | $myObject = new TestObject(); |
||
| 99 | $injector->inject($myObject); |
||
| 100 | |||
| 101 | $this->assertInstanceOf( |
||
| 102 | SampleService::class, |
||
| 103 | $myObject->sampleService |
||
| 104 | ); |
||
| 105 | } |
||
| 106 | |||
| 107 | public function testEmptyFactory() |
||
| 108 | { |
||
| 109 | $this->expectException(InjectorNotFoundException::class); |
||
| 110 | $injector = new Injector(); |
||
| 111 | $services = array( |
||
| 112 | 'SomeClass' => array( |
||
| 113 | 'class' => AnotherService::class, |
||
| 114 | 'factory' => EmptyFactory::class, |
||
| 115 | ) |
||
| 116 | ); |
||
| 117 | |||
| 118 | $injector->load($services); |
||
| 119 | $injector->create('SomeClass'); |
||
| 120 | } |
||
| 121 | |||
| 122 | public function testConfiguredInjector() |
||
| 154 | } |
||
| 155 | |||
| 156 | public function testIdToNameMap() |
||
| 157 | { |
||
| 158 | $injector = new Injector(); |
||
| 159 | $services = array( |
||
| 160 | 'FirstId' => AnotherService::class, |
||
| 161 | 'SecondId' => SampleService::class, |
||
| 162 | ); |
||
| 163 | |||
| 164 | $injector->load($services); |
||
| 165 | |||
| 166 | $this->assertTrue($injector->has('FirstId')); |
||
| 167 | $this->assertEquals($injector->getServiceName('FirstId'), 'FirstId'); |
||
| 168 | |||
| 169 | $this->assertTrue($injector->has('SecondId')); |
||
| 170 | $this->assertEquals($injector->getServiceName('SecondId'), 'SecondId'); |
||
| 171 | |||
| 172 | $this->assertTrue($injector->get('FirstId') instanceof AnotherService); |
||
| 173 | $this->assertTrue($injector->get('SecondId') instanceof SampleService); |
||
| 174 | } |
||
| 175 | |||
| 176 | public function testReplaceService() |
||
| 177 | { |
||
| 178 | $injector = new Injector(); |
||
| 179 | $injector->setAutoScanProperties(true); |
||
| 180 | |||
| 181 | $config = array( |
||
| 182 | 'SampleService' => array( |
||
| 183 | 'src' => TEST_SERVICES . '/SampleService.php', |
||
| 184 | 'class' => SampleService::class, |
||
| 185 | ) |
||
| 186 | ); |
||
| 187 | |||
| 188 | // load |
||
| 189 | $injector->load($config); |
||
| 190 | |||
| 191 | // inject |
||
| 192 | $myObject = new TestObject(); |
||
| 193 | $injector->inject($myObject); |
||
| 194 | |||
| 195 | $this->assertInstanceOf( |
||
| 196 | SampleService::class, |
||
| 197 | $myObject->sampleService |
||
| 198 | ); |
||
| 199 | |||
| 200 | // also tests that ID can be the key in the array |
||
| 201 | $config = array( |
||
| 202 | 'SampleService' => array( |
||
| 203 | 'src' => TEST_SERVICES . '/AnotherService.php', |
||
| 204 | 'class' => AnotherService::class, |
||
| 205 | ) |
||
| 206 | ); |
||
| 207 | // , 'id' => SampleService::class)); |
||
|
|
|||
| 208 | // load |
||
| 209 | $injector->load($config); |
||
| 210 | |||
| 211 | $injector->inject($myObject); |
||
| 212 | $this->assertInstanceOf( |
||
| 213 | AnotherService::class, |
||
| 214 | $myObject->sampleService |
||
| 215 | ); |
||
| 216 | } |
||
| 217 | |||
| 218 | public function testUpdateSpec() |
||
| 219 | { |
||
| 220 | $injector = new Injector(); |
||
| 221 | $services = array( |
||
| 222 | AnotherService::class => array( |
||
| 223 | 'src' => TEST_SERVICES . '/AnotherService.php', |
||
| 224 | 'properties' => array( |
||
| 225 | 'filters' => array( |
||
| 226 | 'One', |
||
| 227 | 'Two', |
||
| 228 | ) |
||
| 229 | ), |
||
| 230 | ) |
||
| 231 | ); |
||
| 232 | |||
| 233 | $injector->load($services); |
||
| 234 | |||
| 235 | $injector->updateSpec(AnotherService::class, 'filters', 'Three'); |
||
| 236 | $another = $injector->get(AnotherService::class); |
||
| 237 | |||
| 238 | $this->assertEquals(3, count($another->filters)); |
||
| 239 | $this->assertEquals('Three', $another->filters[2]); |
||
| 240 | } |
||
| 241 | |||
| 242 | public function testConstantUsage() |
||
| 243 | { |
||
| 244 | $injector = new Injector(); |
||
| 245 | $services = array( |
||
| 246 | AnotherService::class => array( |
||
| 247 | 'properties' => array( |
||
| 248 | 'filters' => array( |
||
| 249 | '`BASE_PATH`', |
||
| 250 | '`TEMP_PATH`', |
||
| 251 | '`NOT_DEFINED`', |
||
| 252 | 'THIRDPARTY_DIR' // Not back-tick escaped |
||
| 253 | ) |
||
| 254 | ), |
||
| 255 | ) |
||
| 256 | ); |
||
| 257 | |||
| 258 | $injector->load($services); |
||
| 259 | $another = $injector->get(AnotherService::class); |
||
| 260 | $this->assertEquals( |
||
| 261 | [ |
||
| 262 | BASE_PATH, |
||
| 263 | TEMP_PATH, |
||
| 264 | null, |
||
| 265 | 'THIRDPARTY_DIR', |
||
| 266 | ], |
||
| 267 | $another->filters |
||
| 268 | ); |
||
| 269 | } |
||
| 270 | |||
| 271 | public function testAutoSetInjector() |
||
| 301 | } |
||
| 302 | |||
| 303 | public function testSettingSpecificProperty() |
||
| 304 | { |
||
| 305 | $injector = new Injector(); |
||
| 306 | $config = array(AnotherService::class); |
||
| 307 | $injector->load($config); |
||
| 308 | $injector->setInjectMapping(TestObject::class, 'sampleService', AnotherService::class); |
||
| 309 | $testObject = $injector->get(TestObject::class); |
||
| 310 | |||
| 311 | $this->assertInstanceOf( |
||
| 312 | AnotherService::class, |
||
| 313 | $testObject->sampleService |
||
| 314 | ); |
||
| 315 | } |
||
| 316 | |||
| 317 | public function testSettingSpecificMethod() |
||
| 329 | ); |
||
| 330 | } |
||
| 331 | |||
| 332 | public function testInjectingScopedService() |
||
| 333 | { |
||
| 334 | $injector = new Injector(); |
||
| 335 | |||
| 336 | $config = array( |
||
| 337 | AnotherService::class, |
||
| 338 | 'SilverStripe\Core\Tests\Injector\AopProxyServiceTest\AnotherService.DottedChild' => SampleService::class, |
||
| 339 | ); |
||
| 340 | |||
| 341 | $injector->load($config); |
||
| 342 | |||
| 343 | $service = $injector->get('SilverStripe\Core\Tests\Injector\AopProxyServiceTest\AnotherService.DottedChild'); |
||
| 344 | $this->assertInstanceOf(SampleService::class, $service); |
||
| 345 | |||
| 346 | $service = $injector->get('SilverStripe\Core\Tests\Injector\AopProxyServiceTest\AnotherService.Subset'); |
||
| 347 | $this->assertInstanceOf(AnotherService::class, $service); |
||
| 348 | |||
| 349 | $injector->setInjectMapping( |
||
| 350 | TestObject::class, |
||
| 351 | 'sampleService', |
||
| 352 | 'SilverStripe\Core\Tests\Injector\AopProxyServiceTest\AnotherService.Geronimo' |
||
| 353 | ); |
||
| 354 | $testObject = $injector->create(TestObject::class); |
||
| 355 | $this->assertEquals(get_class($testObject->sampleService), AnotherService::class); |
||
| 356 | |||
| 357 | $injector->setInjectMapping( |
||
| 358 | TestObject::class, |
||
| 359 | 'sampleService', |
||
| 360 | 'SilverStripe\Core\Tests\Injector\AopProxyServiceTest\AnotherService.DottedChild.AnotherDown' |
||
| 361 | ); |
||
| 362 | $testObject = $injector->create(TestObject::class); |
||
| 363 | $this->assertEquals(get_class($testObject->sampleService), SampleService::class); |
||
| 364 | } |
||
| 365 | |||
| 366 | public function testInjectUsingConstructor() |
||
| 367 | { |
||
| 368 | $injector = new Injector(); |
||
| 369 | $config = array( |
||
| 370 | 'SampleService' => array( |
||
| 371 | 'src' => TEST_SERVICES . '/SampleService.php', |
||
| 372 | 'class' => SampleService::class, |
||
| 373 | 'constructor' => array( |
||
| 374 | 'val1', |
||
| 375 | 'val2', |
||
| 376 | ) |
||
| 377 | ) |
||
| 378 | ); |
||
| 379 | |||
| 380 | $injector->load($config); |
||
| 381 | $sample = $injector->get('SampleService'); |
||
| 382 | $this->assertEquals($sample->constructorVarOne, 'val1'); |
||
| 383 | $this->assertEquals($sample->constructorVarTwo, 'val2'); |
||
| 384 | |||
| 385 | $injector = new Injector(); |
||
| 386 | $config = array( |
||
| 387 | 'AnotherService' => AnotherService::class, |
||
| 388 | 'SampleService' => array( |
||
| 389 | 'src' => TEST_SERVICES . '/SampleService.php', |
||
| 390 | 'class' => SampleService::class, |
||
| 391 | 'constructor' => array( |
||
| 392 | 'val1', |
||
| 393 | '%$AnotherService', |
||
| 394 | ) |
||
| 395 | ) |
||
| 396 | ); |
||
| 397 | |||
| 398 | $injector->load($config); |
||
| 399 | $sample = $injector->get('SampleService'); |
||
| 400 | $this->assertEquals($sample->constructorVarOne, 'val1'); |
||
| 401 | $this->assertInstanceOf( |
||
| 402 | AnotherService::class, |
||
| 403 | $sample->constructorVarTwo |
||
| 404 | ); |
||
| 405 | |||
| 406 | $injector = new Injector(); |
||
| 407 | $config = array( |
||
| 408 | 'SampleService' => array( |
||
| 409 | 'src' => TEST_SERVICES . '/SampleService.php', |
||
| 410 | 'class' => SampleService::class, |
||
| 411 | 'constructor' => array( |
||
| 412 | 'val1', |
||
| 413 | 'val2', |
||
| 414 | ) |
||
| 415 | ) |
||
| 416 | ); |
||
| 417 | |||
| 418 | $injector->load($config); |
||
| 419 | $sample = $injector->get('SampleService'); |
||
| 420 | $this->assertEquals($sample->constructorVarOne, 'val1'); |
||
| 421 | $this->assertEquals($sample->constructorVarTwo, 'val2'); |
||
| 422 | |||
| 423 | // test constructors on prototype |
||
| 424 | $injector = new Injector(); |
||
| 425 | $config = array( |
||
| 426 | 'SampleService' => array( |
||
| 427 | 'type' => 'prototype', |
||
| 428 | 'src' => TEST_SERVICES . '/SampleService.php', |
||
| 429 | 'class' => SampleService::class, |
||
| 430 | 'constructor' => array( |
||
| 431 | 'val1', |
||
| 432 | 'val2', |
||
| 433 | ) |
||
| 434 | ) |
||
| 435 | ); |
||
| 436 | |||
| 437 | $injector->load($config); |
||
| 438 | $sample = $injector->get('SampleService'); |
||
| 439 | $this->assertEquals($sample->constructorVarOne, 'val1'); |
||
| 440 | $this->assertEquals($sample->constructorVarTwo, 'val2'); |
||
| 441 | |||
| 442 | $again = $injector->get('SampleService'); |
||
| 443 | $this->assertFalse($sample === $again); |
||
| 444 | |||
| 445 | $this->assertEquals($sample->constructorVarOne, 'val1'); |
||
| 446 | $this->assertEquals($sample->constructorVarTwo, 'val2'); |
||
| 447 | } |
||
| 448 | |||
| 449 | public function testInjectUsingSetter() |
||
| 450 | { |
||
| 451 | $injector = new Injector(); |
||
| 452 | $injector->setAutoScanProperties(true); |
||
| 453 | $config = array( |
||
| 454 | 'SampleService' => array( |
||
| 455 | 'src' => TEST_SERVICES . '/SampleService.php', |
||
| 456 | 'class' => SampleService::class, |
||
| 457 | ) |
||
| 458 | ); |
||
| 459 | |||
| 460 | $injector->load($config); |
||
| 461 | $this->assertTrue($injector->has('SampleService')); |
||
| 462 | $this->assertEquals('SampleService', $injector->getServiceName('SampleService')); |
||
| 463 | |||
| 464 | $myObject = new InjectorTest\OtherTestObject(); |
||
| 465 | $injector->inject($myObject); |
||
| 466 | |||
| 467 | $this->assertInstanceOf( |
||
| 468 | SampleService::class, |
||
| 469 | $myObject->s() |
||
| 470 | ); |
||
| 471 | |||
| 472 | // and again because it goes down a different code path when setting things |
||
| 473 | // based on the inject map |
||
| 474 | $myObject = new InjectorTest\OtherTestObject(); |
||
| 475 | $injector->inject($myObject); |
||
| 476 | |||
| 477 | $this->assertInstanceOf( |
||
| 478 | SampleService::class, |
||
| 479 | $myObject->s() |
||
| 480 | ); |
||
| 481 | } |
||
| 482 | |||
| 483 | // make sure we can just get any arbitrary object - it should be created for us |
||
| 484 | public function testInstantiateAnObjectViaGet() |
||
| 485 | { |
||
| 486 | $injector = new Injector(); |
||
| 487 | $injector->setAutoScanProperties(true); |
||
| 488 | $config = array( |
||
| 489 | 'SampleService' => array( |
||
| 490 | 'src' => TEST_SERVICES . '/SampleService.php', |
||
| 491 | 'class' => SampleService::class, |
||
| 492 | ) |
||
| 493 | ); |
||
| 494 | |||
| 495 | $injector->load($config); |
||
| 496 | $this->assertTrue($injector->has('SampleService')); |
||
| 497 | $this->assertEquals('SampleService', $injector->getServiceName('SampleService')); |
||
| 498 | |||
| 499 | $myObject = $injector->get(OtherTestObject::class); |
||
| 500 | $this->assertInstanceOf( |
||
| 501 | SampleService::class, |
||
| 502 | $myObject->s() |
||
| 503 | ); |
||
| 504 | |||
| 505 | // and again because it goes down a different code path when setting things |
||
| 506 | // based on the inject map |
||
| 507 | $myObject = $injector->get(OtherTestObject::class); |
||
| 508 | $this->assertInstanceOf(SampleService::class, $myObject->s()); |
||
| 509 | } |
||
| 510 | |||
| 511 | public function testCircularReference() |
||
| 512 | { |
||
| 513 | $services = array( |
||
| 514 | 'CircularOne' => CircularOne::class, |
||
| 515 | 'CircularTwo' => CircularTwo::class |
||
| 516 | ); |
||
| 517 | $injector = new Injector($services); |
||
| 518 | $injector->setAutoScanProperties(true); |
||
| 519 | |||
| 520 | $obj = $injector->get(NeedsBothCirculars::class); |
||
| 521 | |||
| 522 | $this->assertTrue($obj->circularOne instanceof InjectorTest\CircularOne); |
||
| 523 | $this->assertTrue($obj->circularTwo instanceof InjectorTest\CircularTwo); |
||
| 524 | } |
||
| 525 | |||
| 526 | public function testPrototypeObjects() |
||
| 527 | { |
||
| 528 | $services = array( |
||
| 529 | 'CircularOne' => CircularOne::class, |
||
| 530 | 'CircularTwo' => CircularTwo::class, |
||
| 531 | 'NeedsBothCirculars' => array( |
||
| 532 | 'class' => NeedsBothCirculars::class, |
||
| 533 | 'type' => 'prototype' |
||
| 534 | ) |
||
| 535 | ); |
||
| 536 | $injector = new Injector($services); |
||
| 537 | $injector->setAutoScanProperties(true); |
||
| 538 | $obj1 = $injector->get('NeedsBothCirculars'); |
||
| 539 | $obj2 = $injector->get('NeedsBothCirculars'); |
||
| 540 | |||
| 541 | // if this was the same object, then $obj1->var would now be two |
||
| 542 | $obj1->var = 'one'; |
||
| 543 | $obj2->var = 'two'; |
||
| 544 | |||
| 545 | $this->assertTrue($obj1->circularOne instanceof InjectorTest\CircularOne); |
||
| 546 | $this->assertTrue($obj1->circularTwo instanceof InjectorTest\CircularTwo); |
||
| 547 | |||
| 548 | $this->assertEquals($obj1->circularOne, $obj2->circularOne); |
||
| 549 | $this->assertNotEquals($obj1, $obj2); |
||
| 550 | } |
||
| 551 | |||
| 552 | public function testSimpleInstantiation() |
||
| 553 | { |
||
| 554 | $services = array( |
||
| 555 | 'CircularOne' => CircularOne::class, |
||
| 556 | 'CircularTwo' => CircularTwo::class |
||
| 557 | ); |
||
| 558 | $injector = new Injector($services); |
||
| 559 | |||
| 560 | // similar to the above, but explicitly instantiating this object here |
||
| 561 | $obj1 = $injector->create(NeedsBothCirculars::class); |
||
| 562 | $obj2 = $injector->create(NeedsBothCirculars::class); |
||
| 563 | |||
| 564 | // if this was the same object, then $obj1->var would now be two |
||
| 565 | $obj1->var = 'one'; |
||
| 566 | $obj2->var = 'two'; |
||
| 567 | |||
| 568 | $this->assertEquals($obj1->circularOne, $obj2->circularOne); |
||
| 569 | $this->assertNotEquals($obj1, $obj2); |
||
| 570 | } |
||
| 571 | |||
| 572 | public function testCreateWithConstructor() |
||
| 573 | { |
||
| 574 | $injector = new Injector(); |
||
| 575 | $obj = $injector->create(CircularTwo::class, 'param'); |
||
| 576 | $this->assertEquals($obj->otherVar, 'param'); |
||
| 577 | } |
||
| 578 | |||
| 579 | public function testSimpleSingleton() |
||
| 580 | { |
||
| 581 | $injector = new Injector(); |
||
| 582 | |||
| 583 | $one = $injector->create(CircularOne::class); |
||
| 584 | $two = $injector->create(CircularOne::class); |
||
| 585 | |||
| 586 | $this->assertFalse($one === $two); |
||
| 587 | |||
| 588 | $one = $injector->get(CircularTwo::class); |
||
| 589 | $two = $injector->get(CircularTwo::class); |
||
| 590 | |||
| 591 | $this->assertTrue($one === $two); |
||
| 592 | } |
||
| 593 | |||
| 594 | public function testOverridePriority() |
||
| 595 | { |
||
| 596 | $injector = new Injector(); |
||
| 597 | $injector->setAutoScanProperties(true); |
||
| 598 | $config = array( |
||
| 599 | 'SampleService' => array( |
||
| 600 | 'src' => TEST_SERVICES . '/SampleService.php', |
||
| 601 | 'class' => SampleService::class, |
||
| 602 | 'priority' => 10, |
||
| 603 | ) |
||
| 604 | ); |
||
| 605 | |||
| 606 | // load |
||
| 607 | $injector->load($config); |
||
| 608 | |||
| 609 | // inject |
||
| 610 | $myObject = new InjectorTest\TestObject(); |
||
| 611 | $injector->inject($myObject); |
||
| 612 | |||
| 613 | $this->assertInstanceOf(SampleService::class, $myObject->sampleService); |
||
| 614 | |||
| 615 | $config = array( |
||
| 616 | array( |
||
| 617 | 'src' => TEST_SERVICES . '/AnotherService.php', |
||
| 618 | 'class' => AnotherService::class, |
||
| 619 | 'id' => 'SampleService', |
||
| 620 | 'priority' => 1, |
||
| 621 | ) |
||
| 622 | ); |
||
| 623 | // load |
||
| 624 | $injector->load($config); |
||
| 625 | |||
| 626 | $injector->inject($myObject); |
||
| 627 | $this->assertInstanceOf( |
||
| 628 | SampleService::class, |
||
| 629 | $myObject->sampleService |
||
| 630 | ); |
||
| 631 | } |
||
| 632 | |||
| 633 | /** |
||
| 634 | * Specific test method to illustrate various ways of setting a requirements backend |
||
| 635 | */ |
||
| 636 | public function testRequirementsSettingOptions() |
||
| 637 | { |
||
| 638 | $injector = new Injector(); |
||
| 639 | $config = array( |
||
| 640 | OriginalRequirementsBackend::class, |
||
| 641 | NewRequirementsBackend::class, |
||
| 642 | DummyRequirements::class => array( |
||
| 643 | 'constructor' => array( |
||
| 644 | '%$' . OriginalRequirementsBackend::class |
||
| 645 | ) |
||
| 646 | ) |
||
| 647 | ); |
||
| 648 | |||
| 649 | $injector->load($config); |
||
| 650 | |||
| 651 | $requirements = $injector->get(DummyRequirements::class); |
||
| 652 | $this->assertInstanceOf( |
||
| 653 | OriginalRequirementsBackend::class, |
||
| 654 | $requirements->backend |
||
| 655 | ); |
||
| 656 | |||
| 657 | // just overriding the definition here |
||
| 658 | $injector->load( |
||
| 659 | array( |
||
| 660 | DummyRequirements::class => array( |
||
| 661 | 'constructor' => array( |
||
| 662 | '%$' . NewRequirementsBackend::class |
||
| 663 | ) |
||
| 664 | ) |
||
| 665 | ) |
||
| 666 | ); |
||
| 667 | |||
| 668 | // requirements should have been reinstantiated with the new bean setting |
||
| 669 | $requirements = $injector->get(DummyRequirements::class); |
||
| 670 | $this->assertInstanceOf( |
||
| 671 | NewRequirementsBackend::class, |
||
| 672 | $requirements->backend |
||
| 673 | ); |
||
| 674 | } |
||
| 675 | |||
| 676 | /** |
||
| 677 | * disabled for now |
||
| 678 | */ |
||
| 679 | public function testStaticInjections() |
||
| 680 | { |
||
| 681 | $injector = new Injector(); |
||
| 682 | $config = array( |
||
| 683 | NewRequirementsBackend::class, |
||
| 684 | ); |
||
| 685 | |||
| 686 | $injector->load($config); |
||
| 687 | |||
| 688 | $si = $injector->get(TestStaticInjections::class); |
||
| 689 | $this->assertInstanceOf( |
||
| 690 | NewRequirementsBackend::class, |
||
| 691 | $si->backend |
||
| 692 | ); |
||
| 693 | } |
||
| 694 | |||
| 695 | public function testSetterInjections() |
||
| 696 | { |
||
| 697 | $injector = new Injector(); |
||
| 698 | $config = array( |
||
| 699 | NewRequirementsBackend::class, |
||
| 700 | ); |
||
| 701 | |||
| 702 | $injector->load($config); |
||
| 703 | |||
| 704 | $si = $injector->get(TestSetterInjections::class); |
||
| 705 | $this->assertInstanceOf( |
||
| 706 | NewRequirementsBackend::class, |
||
| 707 | $si->getBackend() |
||
| 708 | ); |
||
| 709 | } |
||
| 710 | |||
| 711 | public function testCustomObjectCreator() |
||
| 712 | { |
||
| 713 | $injector = new Injector(); |
||
| 714 | $injector->setObjectCreator(new InjectorTest\SSObjectCreator($injector)); |
||
| 715 | $config = array( |
||
| 716 | OriginalRequirementsBackend::class, |
||
| 717 | DummyRequirements::class => array( |
||
| 718 | 'class' => DummyRequirements::class . '(\'%$' . OriginalRequirementsBackend::class . '\')' |
||
| 719 | ) |
||
| 720 | ); |
||
| 721 | $injector->load($config); |
||
| 722 | |||
| 723 | $requirements = $injector->get(DummyRequirements::class); |
||
| 724 | $this->assertEquals(OriginalRequirementsBackend::class, get_class($requirements->backend)); |
||
| 725 | } |
||
| 726 | |||
| 727 | public function testInheritedConfig() |
||
| 728 | { |
||
| 729 | |||
| 730 | // Test that child class does not automatically inherit config |
||
| 731 | $injector = new Injector(array('locator' => SilverStripeServiceConfigurationLocator::class)); |
||
| 732 | Config::modify()->merge( |
||
| 733 | Injector::class, |
||
| 734 | MyParentClass::class, |
||
| 735 | [ |
||
| 736 | 'properties' => ['one' => 'the one'], |
||
| 737 | 'class' => MyParentClass::class, |
||
| 738 | ] |
||
| 739 | ); |
||
| 740 | $obj = $injector->get(MyParentClass::class); |
||
| 741 | $this->assertInstanceOf(MyParentClass::class, $obj); |
||
| 742 | $this->assertEquals($obj->one, 'the one'); |
||
| 743 | |||
| 744 | // Class isn't inherited and parent properties are ignored |
||
| 745 | $obj = $injector->get(MyChildClass::class); |
||
| 746 | $this->assertInstanceOf(MyChildClass::class, $obj); |
||
| 747 | $this->assertNotEquals($obj->one, 'the one'); |
||
| 748 | |||
| 749 | // Set child class as alias |
||
| 750 | $injector = new Injector( |
||
| 751 | array( |
||
| 752 | 'locator' => SilverStripeServiceConfigurationLocator::class |
||
| 753 | ) |
||
| 754 | ); |
||
| 755 | Config::modify()->merge( |
||
| 756 | Injector::class, |
||
| 757 | MyChildClass::class, |
||
| 758 | '%$' . MyParentClass::class |
||
| 759 | ); |
||
| 760 | |||
| 761 | // Class isn't inherited and parent properties are ignored |
||
| 762 | $obj = $injector->get(MyChildClass::class); |
||
| 763 | $this->assertInstanceOf(MyParentClass::class, $obj); |
||
| 764 | $this->assertEquals($obj->one, 'the one'); |
||
| 765 | } |
||
| 766 | |||
| 767 | public function testSameNamedSingeltonPrototype() |
||
| 768 | { |
||
| 769 | $injector = new Injector(); |
||
| 770 | |||
| 771 | // get a singleton object |
||
| 772 | $object = $injector->get(NeedsBothCirculars::class); |
||
| 773 | $object->var = 'One'; |
||
| 774 | |||
| 775 | $again = $injector->get(NeedsBothCirculars::class); |
||
| 776 | $this->assertEquals($again->var, 'One'); |
||
| 777 | |||
| 778 | // create a NEW instance object |
||
| 779 | $new = $injector->create(NeedsBothCirculars::class); |
||
| 780 | $this->assertNull($new->var); |
||
| 781 | |||
| 782 | // this will trigger a problem below |
||
| 783 | $new->var = 'Two'; |
||
| 784 | |||
| 785 | $again = $injector->get(NeedsBothCirculars::class); |
||
| 786 | $this->assertEquals($again->var, 'One'); |
||
| 787 | } |
||
| 788 | |||
| 789 | public function testConvertServicePropertyOnCreate() |
||
| 790 | { |
||
| 791 | // make sure convert service property is not called on direct calls to create, only on configured |
||
| 792 | // declarations to avoid un-needed function calls |
||
| 793 | $injector = new Injector(); |
||
| 794 | $item = $injector->create(ConstructableObject::class, '%$' . TestObject::class); |
||
| 795 | $this->assertEquals('%$' . TestObject::class, $item->property); |
||
| 796 | |||
| 797 | // do it again but have test object configured as a constructor dependency |
||
| 798 | $injector = new Injector(); |
||
| 799 | $config = array( |
||
| 800 | ConstructableObject::class => array( |
||
| 801 | 'constructor' => array( |
||
| 802 | '%$' . TestObject::class |
||
| 803 | ) |
||
| 804 | ) |
||
| 805 | ); |
||
| 806 | |||
| 807 | $injector->load($config); |
||
| 808 | $item = $injector->get(ConstructableObject::class); |
||
| 809 | $this->assertTrue($item->property instanceof InjectorTest\TestObject); |
||
| 810 | |||
| 811 | // and with a configured object defining TestObject to be something else! |
||
| 812 | $injector = new Injector(array('locator' => InjectorTest\InjectorTestConfigLocator::class)); |
||
| 813 | $config = array( |
||
| 814 | ConstructableObject::class => array( |
||
| 815 | 'constructor' => array( |
||
| 816 | '%$' . TestObject::class |
||
| 817 | ) |
||
| 818 | ), |
||
| 819 | ); |
||
| 820 | |||
| 821 | $injector->load($config); |
||
| 822 | $item = $injector->get(ConstructableObject::class); |
||
| 823 | $this->assertTrue($item->property instanceof InjectorTest\ConstructableObject); |
||
| 824 | |||
| 825 | $this->assertInstanceOf(OtherTestObject::class, $item->property->property); |
||
| 826 | } |
||
| 827 | |||
| 828 | public function testNamedServices() |
||
| 829 | { |
||
| 830 | $injector = new Injector(); |
||
| 831 | $service = new TestObject(); |
||
| 832 | $service->setSomething('injected'); |
||
| 833 | |||
| 834 | // Test registering with non-class name |
||
| 835 | $injector->registerService($service, 'NamedService'); |
||
| 836 | $this->assertTrue($injector->has('NamedService')); |
||
| 837 | $this->assertEquals($service, $injector->get('NamedService')); |
||
| 838 | |||
| 839 | // Unregister service by name |
||
| 840 | $injector->unregisterNamedObject('NamedService'); |
||
| 841 | $this->assertFalse($injector->has('NamedService')); |
||
| 842 | |||
| 843 | // Test registered with class name |
||
| 844 | $injector->registerService($service); |
||
| 845 | $this->assertTrue($injector->has(TestObject::class)); |
||
| 846 | $this->assertEquals($service, $injector->get(TestObject::class)); |
||
| 847 | |||
| 848 | // Unregister service by class |
||
| 849 | $injector->unregisterNamedObject(TestObject::class); |
||
| 850 | $this->assertFalse($injector->has(TestObject::class)); |
||
| 851 | } |
||
| 852 | |||
| 853 | public function testCreateConfiggedObjectWithCustomConstructorArgs() |
||
| 854 | { |
||
| 855 | // need to make sure that even if the config defines some constructor params, |
||
| 856 | // that we take our passed in constructor args instead |
||
| 857 | $injector = new Injector(array('locator' => InjectorTest\InjectorTestConfigLocator::class)); |
||
| 858 | |||
| 859 | $item = $injector->create('ConfigConstructor', 'othervalue'); |
||
| 860 | $this->assertEquals($item->property, 'othervalue'); |
||
| 861 | } |
||
| 862 | |||
| 863 | /** |
||
| 864 | * Tests creating a service with a custom factory. |
||
| 865 | */ |
||
| 866 | public function testCustomFactory() |
||
| 890 | } |
||
| 891 | |||
| 892 | public function testMethods() |
||
| 893 | { |
||
| 894 | // do it again but have test object configured as a constructor dependency |
||
| 895 | $injector = new Injector(); |
||
| 896 | $config = array( |
||
| 897 | 'A' => array( |
||
| 898 | 'class' => TestObject::class, |
||
| 899 | ), |
||
| 900 | 'B' => array( |
||
| 901 | 'class' => TestObject::class, |
||
| 902 | ), |
||
| 903 | 'TestService' => array( |
||
| 904 | 'class' => TestObject::class, |
||
| 905 | 'calls' => array( |
||
| 906 | array('myMethod', array('%$A')), |
||
| 907 | array('myMethod', array('%$B')), |
||
| 908 | array('noArgMethod') |
||
| 909 | ) |
||
| 910 | ) |
||
| 911 | ); |
||
| 912 | |||
| 913 | $injector->load($config); |
||
| 914 | $item = $injector->get('TestService'); |
||
| 915 | $this->assertTrue($item instanceof InjectorTest\TestObject); |
||
| 916 | $this->assertEquals( |
||
| 917 | array($injector->get('A'), $injector->get('B'), 'noArgMethod called'), |
||
| 918 | $item->methodCalls |
||
| 919 | ); |
||
| 920 | } |
||
| 921 | |||
| 922 | /** |
||
| 923 | * @expectedException InvalidArgumentException |
||
| 924 | */ |
||
| 925 | public function testNonExistentMethods() |
||
| 926 | { |
||
| 927 | $injector = new Injector(); |
||
| 928 | $config = array( |
||
| 929 | 'TestService' => array( |
||
| 930 | 'class' => TestObject::class, |
||
| 931 | 'calls' => array( |
||
| 932 | array('thisDoesntExist') |
||
| 933 | ) |
||
| 934 | ) |
||
| 935 | ); |
||
| 936 | |||
| 937 | $injector->load($config); |
||
| 938 | $item = $injector->get('TestService'); |
||
| 939 | } |
||
| 940 | |||
| 941 | /** |
||
| 942 | * @expectedException InvalidArgumentException |
||
| 943 | */ |
||
| 944 | public function testProtectedMethods() |
||
| 945 | { |
||
| 946 | $injector = new Injector(); |
||
| 947 | $config = array( |
||
| 948 | 'TestService' => array( |
||
| 949 | 'class' => TestObject::class, |
||
| 950 | 'calls' => array( |
||
| 951 | array('protectedMethod') |
||
| 952 | ) |
||
| 953 | ) |
||
| 954 | ); |
||
| 955 | |||
| 956 | $injector->load($config); |
||
| 957 | $item = $injector->get('TestService'); |
||
| 958 | } |
||
| 959 | |||
| 960 | /** |
||
| 961 | * @expectedException InvalidArgumentException |
||
| 962 | */ |
||
| 963 | public function testTooManyArrayValues() |
||
| 964 | { |
||
| 965 | $injector = new Injector(); |
||
| 966 | $config = array( |
||
| 967 | 'TestService' => array( |
||
| 968 | 'class' => TestObject::class, |
||
| 969 | 'calls' => array( |
||
| 970 | array('method', array('args'), 'what is this?') |
||
| 971 | ) |
||
| 972 | ) |
||
| 973 | ); |
||
| 974 | |||
| 975 | $injector->load($config); |
||
| 976 | $item = $injector->get('TestService'); |
||
| 977 | } |
||
| 978 | |||
| 979 | /** |
||
| 980 | * @expectedException \SilverStripe\Core\Injector\InjectorNotFoundException |
||
| 981 | */ |
||
| 982 | public function testGetThrowsOnNotFound() |
||
| 983 | { |
||
| 984 | $injector = new Injector(); |
||
| 985 | $injector->get('UnknownService'); |
||
| 986 | } |
||
| 987 | |||
| 988 | public function testGetTrimsWhitespaceFromNames() |
||
| 989 | { |
||
| 990 | $injector = new Injector; |
||
| 991 | |||
| 992 | $this->assertInstanceOf(MyChildClass::class, $injector->get(' ' . MyChildClass::class . ' ')); |
||
| 993 | } |
||
| 994 | |||
| 995 | /** |
||
| 996 | * Test nesting of injector |
||
| 997 | */ |
||
| 998 | public function testNest() |
||
| 1058 | } |
||
| 1059 | |||
| 1060 | /** |
||
| 1061 | * Tests that overloaded extensions work, see {@link Extensible::getExtensionInstance()} |
||
| 1062 | */ |
||
| 1063 | public function testExtendedExtensions() |
||
| 1064 | { |
||
| 1078 | } |
||
| 1079 | } |
||
| 1080 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.