Skip to content

Commit

Permalink
Cover decorator definitions for the compiled container
Browse files Browse the repository at this point in the history
  • Loading branch information
mnapoli committed Jun 3, 2017
1 parent 8656f27 commit ffa8041
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 20 deletions.
34 changes: 30 additions & 4 deletions src/DI/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
use DI\Compiler\ObjectCreationCompiler;
use DI\Definition\AliasDefinition;
use DI\Definition\ArrayDefinition;
use DI\Definition\DecoratorDefinition;
use DI\Definition\Definition;
use DI\Definition\EnvironmentVariableDefinition;
use DI\Definition\Exception\InvalidDefinition;
use DI\Definition\FactoryDefinition;
use DI\Definition\Helper\DefinitionHelper;
use DI\Definition\ObjectDefinition;
Expand Down Expand Up @@ -114,10 +116,7 @@ private function compileDefinition(string $entryName, Definition $definition) :
PHP;
break;
case $definition instanceof ArrayDefinition:
$values = $definition->getValues();
$values = array_map(function ($value) {
return ' ' . $this->compileValue($value) . ",\n";
}, $values);
$values = $this->compileArrayValues($definition);
$values = implode('', $values);
$code = "return [\n$values ];";
break;
Expand All @@ -126,6 +125,8 @@ private function compileDefinition(string $entryName, Definition $definition) :
$code = $compiler->compile($definition);
$code .= "\n return \$object;";
break;
case $definition instanceof DecoratorDefinition:
throw new InvalidDefinition('Decorators cannot be nested in another definition');
default:
throw new \Exception('Cannot compile definition of type ' . get_class($definition));
}
Expand Down Expand Up @@ -166,4 +167,29 @@ private function createCompilationDirectory(string $directory)
throw new InvalidArgumentException(sprintf('Compilation directory is not writable: %s.', $directory));
}
}

/**
* @return string[]
*/
private function compileArrayValues(ArrayDefinition $definition) : array
{
$values = $definition->getValues();
$keys = array_keys($values);

$values = array_map(function ($value, $key) use ($definition) {
try {
$compiledValue = $this->compileValue($value);
} catch (\Exception $e) {
throw new DependencyException(sprintf(
'Error while compiling %s[%s]. %s',
$definition->getName(),
$key,
$e->getMessage()
), 0, $e);
}
return ' ' . $compiledValue . ",\n";
}, $values, $keys);

return $values;
}
}
43 changes: 27 additions & 16 deletions tests/IntegrationTest/Definitions/DecoratorDefinitionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
namespace DI\Test\IntegrationTest\Definitions;

use DI\ContainerBuilder;
use DI\Test\IntegrationTest\BaseContainerTest;
use Psr\Container\ContainerInterface;

/**
* Test decorator definitions.
*/
class DecoratorDefinitionTest extends \PHPUnit_Framework_TestCase
class DecoratorDefinitionTest extends BaseContainerTest
{
public function test_decorate_value()
/**
* @dataProvider provideContainer
*/
public function test_decorate_value(ContainerBuilder $builder)
{
$builder = new ContainerBuilder();
$builder->addDefinitions([
'foo' => 'bar',
]);
Expand All @@ -26,9 +29,11 @@ public function test_decorate_value()
$this->assertEquals('barbaz', $container->get('foo'));
}

public function test_decorate_factory()
/**
* @dataProvider provideContainer
*/
public function test_decorate_factory(ContainerBuilder $builder)
{
$builder = new ContainerBuilder();
$builder->addDefinitions([
'foo' => function () {
return 'bar';
Expand All @@ -44,9 +49,11 @@ public function test_decorate_factory()
$this->assertEquals('barbaz', $container->get('foo'));
}

public function test_decorate_object()
/**
* @dataProvider provideContainer
*/
public function test_decorate_object(ContainerBuilder $builder)
{
$builder = new ContainerBuilder();
$builder->addDefinitions([
'foo' => \DI\create('stdClass'),
]);
Expand All @@ -63,9 +70,11 @@ public function test_decorate_object()
$this->assertEquals('bar', $object->foo);
}

public function test_decorator_gets_container()
/**
* @dataProvider provideContainer
*/
public function test_decorator_gets_container(ContainerBuilder $builder)
{
$builder = new ContainerBuilder();
$builder->addDefinitions([
'foo' => 'hello ',
'bar' => 'world',
Expand All @@ -80,9 +89,11 @@ public function test_decorator_gets_container()
$this->assertEquals('hello world', $container->get('foo'));
}

public function test_multiple_decorators()
/**
* @dataProvider provideContainer
*/
public function test_multiple_decorators(ContainerBuilder $builder)
{
$builder = new ContainerBuilder();
$builder->addDefinitions([
'foo' => 'bar',
]);
Expand All @@ -102,12 +113,12 @@ public function test_multiple_decorators()
}

/**
* @dataProvider provideContainer
* @expectedException \DI\Definition\Exception\InvalidDefinition
* @expectedExceptionMessage Entry "foo" decorates nothing: no previous definition with the same name was found
*/
public function test_decorate_must_have_previous_definition()
public function test_decorate_must_have_previous_definition(ContainerBuilder $builder)
{
$builder = new ContainerBuilder();
$builder->addDefinitions([
'foo' => \DI\decorate(function ($previous) {
return $previous;
Expand All @@ -118,12 +129,12 @@ public function test_decorate_must_have_previous_definition()
}

/**
* @dataProvider provideContainer
* @expectedException \DI\DependencyException
* @expectedExceptionMessage Error while resolving foo[0]. Decorators cannot be nested in another definition
* @expectedExceptionMessageRegExp /Error while (resolving|compiling) foo\[0\]. Decorators cannot be nested in another definition/
*/
public function test_decorator_in_array()
public function test_decorator_in_array(ContainerBuilder $builder)
{
$builder = new ContainerBuilder();
$builder->addDefinitions([
'foo' => [
\DI\decorate(function ($previous) {
Expand Down

0 comments on commit ffa8041

Please sign in to comment.