123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622 |
- <?php
- namespace Illuminate\Tests\Container;
- use Illuminate\Config\Repository;
- use Illuminate\Container\Container;
- use PHPUnit\Framework\TestCase;
- class ContextualBindingTest extends TestCase
- {
- public function testContainerCanInjectDifferentImplementationsDependingOnContext()
- {
- $container = new Container;
- $container->bind(IContainerContextContractStub::class, ContainerContextImplementationStub::class);
- $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStub::class);
- $container->when(ContainerTestContextInjectTwo::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);
- $one = $container->make(ContainerTestContextInjectOne::class);
- $two = $container->make(ContainerTestContextInjectTwo::class);
- $this->assertInstanceOf(ContainerContextImplementationStub::class, $one->impl);
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $two->impl);
- /*
- * Test With Closures
- */
- $container = new Container;
- $container->bind(IContainerContextContractStub::class, ContainerContextImplementationStub::class);
- $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStub::class);
- $container->when(ContainerTestContextInjectTwo::class)->needs(IContainerContextContractStub::class)->give(function ($container) {
- return $container->make(ContainerContextImplementationStubTwo::class);
- });
- $one = $container->make(ContainerTestContextInjectOne::class);
- $two = $container->make(ContainerTestContextInjectTwo::class);
- $this->assertInstanceOf(ContainerContextImplementationStub::class, $one->impl);
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $two->impl);
- }
- public function testContextualBindingWorksForExistingInstancedBindings()
- {
- $container = new Container;
- $container->instance(IContainerContextContractStub::class, new ContainerImplementationStub);
- $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $container->make(ContainerTestContextInjectOne::class)->impl);
- }
- public function testContextualBindingWorksForNewlyInstancedBindings()
- {
- $container = new Container;
- $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);
- $container->instance(IContainerContextContractStub::class, new ContainerImplementationStub);
- $this->assertInstanceOf(
- ContainerContextImplementationStubTwo::class,
- $container->make(ContainerTestContextInjectOne::class)->impl
- );
- }
- public function testContextualBindingWorksOnExistingAliasedInstances()
- {
- $container = new Container;
- $container->instance('stub', new ContainerImplementationStub);
- $container->alias('stub', IContainerContextContractStub::class);
- $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);
- $this->assertInstanceOf(
- ContainerContextImplementationStubTwo::class,
- $container->make(ContainerTestContextInjectOne::class)->impl
- );
- }
- public function testContextualBindingWorksOnNewAliasedInstances()
- {
- $container = new Container;
- $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);
- $container->instance('stub', new ContainerImplementationStub);
- $container->alias('stub', IContainerContextContractStub::class);
- $this->assertInstanceOf(
- ContainerContextImplementationStubTwo::class,
- $container->make(ContainerTestContextInjectOne::class)->impl
- );
- }
- public function testContextualBindingWorksOnNewAliasedBindings()
- {
- $container = new Container;
- $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);
- $container->bind('stub', ContainerContextImplementationStub::class);
- $container->alias('stub', IContainerContextContractStub::class);
- $this->assertInstanceOf(
- ContainerContextImplementationStubTwo::class,
- $container->make(ContainerTestContextInjectOne::class)->impl
- );
- }
- public function testContextualBindingWorksForMultipleClasses()
- {
- $container = new Container;
- $container->bind(IContainerContextContractStub::class, ContainerContextImplementationStub::class);
- $container->when([ContainerTestContextInjectTwo::class, ContainerTestContextInjectThree::class])->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);
- $this->assertInstanceOf(
- ContainerContextImplementationStub::class,
- $container->make(ContainerTestContextInjectOne::class)->impl
- );
- $this->assertInstanceOf(
- ContainerContextImplementationStubTwo::class,
- $container->make(ContainerTestContextInjectTwo::class)->impl
- );
- $this->assertInstanceOf(
- ContainerContextImplementationStubTwo::class,
- $container->make(ContainerTestContextInjectThree::class)->impl
- );
- }
- public function testContextualBindingDoesntOverrideNonContextualResolution()
- {
- $container = new Container;
- $container->instance('stub', new ContainerContextImplementationStub);
- $container->alias('stub', IContainerContextContractStub::class);
- $container->when(ContainerTestContextInjectTwo::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);
- $this->assertInstanceOf(
- ContainerContextImplementationStubTwo::class,
- $container->make(ContainerTestContextInjectTwo::class)->impl
- );
- $this->assertInstanceOf(
- ContainerContextImplementationStub::class,
- $container->make(ContainerTestContextInjectOne::class)->impl
- );
- }
- public function testContextuallyBoundInstancesAreNotUnnecessarilyRecreated()
- {
- ContainerTestContextInjectInstantiations::$instantiations = 0;
- $container = new Container;
- $container->instance(IContainerContextContractStub::class, new ContainerImplementationStub);
- $container->instance(ContainerTestContextInjectInstantiations::class, new ContainerTestContextInjectInstantiations);
- $this->assertEquals(1, ContainerTestContextInjectInstantiations::$instantiations);
- $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerTestContextInjectInstantiations::class);
- $container->make(ContainerTestContextInjectOne::class);
- $container->make(ContainerTestContextInjectOne::class);
- $container->make(ContainerTestContextInjectOne::class);
- $container->make(ContainerTestContextInjectOne::class);
- $this->assertEquals(1, ContainerTestContextInjectInstantiations::$instantiations);
- }
- public function testContainerCanInjectSimpleVariable()
- {
- $container = new Container;
- $container->when(ContainerInjectVariableStub::class)->needs('$something')->give(100);
- $instance = $container->make(ContainerInjectVariableStub::class);
- $this->assertEquals(100, $instance->something);
- $container = new Container;
- $container->when(ContainerInjectVariableStub::class)->needs('$something')->give(function ($container) {
- return $container->make(ContainerConcreteStub::class);
- });
- $instance = $container->make(ContainerInjectVariableStub::class);
- $this->assertInstanceOf(ContainerConcreteStub::class, $instance->something);
- }
- public function testContextualBindingWorksWithAliasedTargets()
- {
- $container = new Container;
- $container->bind(IContainerContextContractStub::class, ContainerContextImplementationStub::class);
- $container->alias(IContainerContextContractStub::class, 'interface-stub');
- $container->alias(ContainerContextImplementationStub::class, 'stub-1');
- $container->when(ContainerTestContextInjectOne::class)->needs('interface-stub')->give('stub-1');
- $container->when(ContainerTestContextInjectTwo::class)->needs('interface-stub')->give(ContainerContextImplementationStubTwo::class);
- $one = $container->make(ContainerTestContextInjectOne::class);
- $two = $container->make(ContainerTestContextInjectTwo::class);
- $this->assertInstanceOf(ContainerContextImplementationStub::class, $one->impl);
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $two->impl);
- }
- public function testContextualBindingWorksForNestedOptionalDependencies()
- {
- $container = new Container;
- $container->when(ContainerTestContextInjectTwoInstances::class)->needs(ContainerTestContextInjectTwo::class)->give(function () {
- return new ContainerTestContextInjectTwo(new ContainerContextImplementationStubTwo);
- });
- $resolvedInstance = $container->make(ContainerTestContextInjectTwoInstances::class);
- $this->assertInstanceOf(
- ContainerTestContextWithOptionalInnerDependency::class,
- $resolvedInstance->implOne
- );
- $this->assertNull($resolvedInstance->implOne->inner);
- $this->assertInstanceOf(
- ContainerTestContextInjectTwo::class,
- $resolvedInstance->implTwo
- );
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->implTwo->impl);
- }
- public function testContextualBindingWorksForVariadicDependencies()
- {
- $container = new Container;
- $container->when(ContainerTestContextInjectVariadic::class)->needs(IContainerContextContractStub::class)->give(function ($c) {
- return [
- $c->make(ContainerContextImplementationStub::class),
- $c->make(ContainerContextImplementationStubTwo::class),
- ];
- });
- $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);
- $this->assertCount(2, $resolvedInstance->stubs);
- $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);
- }
- public function testContextualBindingWorksForVariadicDependenciesWithNothingBound()
- {
- $container = new Container;
- $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);
- $this->assertCount(0, $resolvedInstance->stubs);
- }
- public function testContextualBindingWorksForVariadicAfterNonVariadicDependencies()
- {
- $container = new Container;
- $container->when(ContainerTestContextInjectVariadicAfterNonVariadic::class)->needs(IContainerContextContractStub::class)->give(function ($c) {
- return [
- $c->make(ContainerContextImplementationStub::class),
- $c->make(ContainerContextImplementationStubTwo::class),
- ];
- });
- $resolvedInstance = $container->make(ContainerTestContextInjectVariadicAfterNonVariadic::class);
- $this->assertCount(2, $resolvedInstance->stubs);
- $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);
- }
- public function testContextualBindingWorksForVariadicAfterNonVariadicDependenciesWithNothingBound()
- {
- $container = new Container;
- $resolvedInstance = $container->make(ContainerTestContextInjectVariadicAfterNonVariadic::class);
- $this->assertCount(0, $resolvedInstance->stubs);
- }
- public function testContextualBindingWorksForVariadicDependenciesWithoutFactory()
- {
- $container = new Container;
- $container->when(ContainerTestContextInjectVariadic::class)->needs(IContainerContextContractStub::class)->give([
- ContainerContextImplementationStub::class,
- ContainerContextImplementationStubTwo::class,
- ]);
- $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);
- $this->assertCount(2, $resolvedInstance->stubs);
- $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);
- }
- public function testContextualBindingGivesTagsForArrayWithNoTagsDefined()
- {
- $container = new Container;
- $container->when(ContainerTestContextInjectArray::class)->needs('$stubs')->giveTagged('stub');
- $resolvedInstance = $container->make(ContainerTestContextInjectArray::class);
- $this->assertCount(0, $resolvedInstance->stubs);
- }
- public function testContextualBindingGivesTagsForVariadicWithNoTagsDefined()
- {
- $container = new Container;
- $container->when(ContainerTestContextInjectVariadic::class)->needs(IContainerContextContractStub::class)->giveTagged('stub');
- $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);
- $this->assertCount(0, $resolvedInstance->stubs);
- }
- public function testContextualBindingGivesTagsForArray()
- {
- $container = new Container;
- $container->tag([
- ContainerContextImplementationStub::class,
- ContainerContextImplementationStubTwo::class,
- ], ['stub']);
- $container->when(ContainerTestContextInjectArray::class)->needs('$stubs')->giveTagged('stub');
- $resolvedInstance = $container->make(ContainerTestContextInjectArray::class);
- $this->assertCount(2, $resolvedInstance->stubs);
- $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);
- }
- public function testContextualBindingGivesTagsForVariadic()
- {
- $container = new Container;
- $container->tag([
- ContainerContextImplementationStub::class,
- ContainerContextImplementationStubTwo::class,
- ], ['stub']);
- $container->when(ContainerTestContextInjectVariadic::class)->needs(IContainerContextContractStub::class)->giveTagged('stub');
- $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);
- $this->assertCount(2, $resolvedInstance->stubs);
- $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);
- $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);
- }
- public function testContextualBindingGivesValuesFromConfigOptionalValueNull()
- {
- $container = new Container;
- $container->singleton('config', function () {
- return new Repository([
- 'test' => [
- 'username' => 'laravel',
- 'password' => 'hunter42',
- ],
- ]);
- });
- $container
- ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
- ->needs('$username')
- ->giveConfig('test.username');
- $container
- ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
- ->needs('$password')
- ->giveConfig('test.password');
- $resolvedInstance = $container->make(ContainerTestContextInjectFromConfigIndividualValues::class);
- $this->assertSame('laravel', $resolvedInstance->username);
- $this->assertSame('hunter42', $resolvedInstance->password);
- $this->assertNull($resolvedInstance->alias);
- }
- public function testContextualBindingGivesValuesFromConfigOptionalValueSet()
- {
- $container = new Container;
- $container->singleton('config', function () {
- return new Repository([
- 'test' => [
- 'username' => 'laravel',
- 'password' => 'hunter42',
- 'alias' => 'lumen',
- ],
- ]);
- });
- $container
- ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
- ->needs('$username')
- ->giveConfig('test.username');
- $container
- ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
- ->needs('$password')
- ->giveConfig('test.password');
- $container
- ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
- ->needs('$alias')
- ->giveConfig('test.alias');
- $resolvedInstance = $container->make(ContainerTestContextInjectFromConfigIndividualValues::class);
- $this->assertSame('laravel', $resolvedInstance->username);
- $this->assertSame('hunter42', $resolvedInstance->password);
- $this->assertSame('lumen', $resolvedInstance->alias);
- }
- public function testContextualBindingGivesValuesFromConfigWithDefault()
- {
- $container = new Container;
- $container->singleton('config', function () {
- return new Repository([
- 'test' => [
- 'password' => 'hunter42',
- ],
- ]);
- });
- $container
- ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
- ->needs('$username')
- ->giveConfig('test.username', 'DEFAULT_USERNAME');
- $container
- ->when(ContainerTestContextInjectFromConfigIndividualValues::class)
- ->needs('$password')
- ->giveConfig('test.password');
- $resolvedInstance = $container->make(ContainerTestContextInjectFromConfigIndividualValues::class);
- $this->assertSame('DEFAULT_USERNAME', $resolvedInstance->username);
- $this->assertSame('hunter42', $resolvedInstance->password);
- $this->assertNull($resolvedInstance->alias);
- }
- public function testContextualBindingGivesValuesFromConfigArray()
- {
- $container = new Container;
- $container->singleton('config', function () {
- return new Repository([
- 'test' => [
- 'username' => 'laravel',
- 'password' => 'hunter42',
- 'alias' => 'lumen',
- ],
- ]);
- });
- $container
- ->when(ContainerTestContextInjectFromConfigArray::class)
- ->needs('$settings')
- ->giveConfig('test');
- $resolvedInstance = $container->make(ContainerTestContextInjectFromConfigArray::class);
- $this->assertSame('laravel', $resolvedInstance->settings['username']);
- $this->assertSame('hunter42', $resolvedInstance->settings['password']);
- $this->assertSame('lumen', $resolvedInstance->settings['alias']);
- }
- }
- interface IContainerContextContractStub
- {
- //
- }
- class ContainerContextNonContractStub
- {
- //
- }
- class ContainerContextImplementationStub implements IContainerContextContractStub
- {
- //
- }
- class ContainerContextImplementationStubTwo implements IContainerContextContractStub
- {
- //
- }
- class ContainerTestContextInjectInstantiations implements IContainerContextContractStub
- {
- public static $instantiations;
- public function __construct()
- {
- static::$instantiations++;
- }
- }
- class ContainerTestContextInjectOne
- {
- public $impl;
- public function __construct(IContainerContextContractStub $impl)
- {
- $this->impl = $impl;
- }
- }
- class ContainerTestContextInjectTwo
- {
- public $impl;
- public function __construct(IContainerContextContractStub $impl)
- {
- $this->impl = $impl;
- }
- }
- class ContainerTestContextInjectThree
- {
- public $impl;
- public function __construct(IContainerContextContractStub $impl)
- {
- $this->impl = $impl;
- }
- }
- class ContainerTestContextInjectTwoInstances
- {
- public $implOne;
- public $implTwo;
- public function __construct(ContainerTestContextWithOptionalInnerDependency $implOne, ContainerTestContextInjectTwo $implTwo)
- {
- $this->implOne = $implOne;
- $this->implTwo = $implTwo;
- }
- }
- class ContainerTestContextWithOptionalInnerDependency
- {
- public $inner;
- public function __construct(ContainerTestContextInjectOne $inner = null)
- {
- $this->inner = $inner;
- }
- }
- class ContainerTestContextInjectArray
- {
- public $stubs;
- public function __construct(array $stubs)
- {
- $this->stubs = $stubs;
- }
- }
- class ContainerTestContextInjectVariadic
- {
- public $stubs;
- public function __construct(IContainerContextContractStub ...$stubs)
- {
- $this->stubs = $stubs;
- }
- }
- class ContainerTestContextInjectVariadicAfterNonVariadic
- {
- public $other;
- public $stubs;
- public function __construct(ContainerContextNonContractStub $other, IContainerContextContractStub ...$stubs)
- {
- $this->other = $other;
- $this->stubs = $stubs;
- }
- }
- class ContainerTestContextInjectFromConfigIndividualValues
- {
- public $username;
- public $password;
- public $alias = null;
- public function __construct($username, $password, $alias = null)
- {
- $this->username = $username;
- $this->password = $password;
- $this->alias = $alias;
- }
- }
- class ContainerTestContextInjectFromConfigArray
- {
- public $settings;
- public function __construct($settings)
- {
- $this->settings = $settings;
- }
- }
|