8000 [DependencyInjection] Update dumpers and loaders, add unit tests · symfony/symfony@140f807 · GitHub
[go: up one dir, main page]

Skip to content

Commit 140f807

Browse files
committed
[DependencyInjection] Update dumpers and loaders, add unit tests
1 parent 1eb1f4d commit 140f807

22 files changed

+316
-13
lines changed

src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Compiler;
1313

14-
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1514
use Symfony\Component\DependencyInjection\ContainerBuilder;
1615
use Symfony\Component\DependencyInjection\Alias;
1716

@@ -29,26 +28,27 @@ public function process(ContainerBuilder $container)
2928
if (!$decorated = $definition->getDecoratedService()) {
3029
continue;
3130
}
31+
$definition->setDecoratedService(null);
3232

33-
list ($decorated, $renamedId) = $decorated;
33+
list ($inner, $renamedId) = $decorated;
3434
if (!$renamedId) {
3535
$renamedId = $id.'.inner';
3636
}
3737

3838
// we create a new alias/service for the service we are replacing
3939
// to be able to reference it in the new one
40-
if ($container->hasAlias($decorated)) {
41-
$alias = $container->getAlias($decorated);
40+
if ($container->hasAlias($inner)) {
41+
$alias = $container->getAlias($inner);
4242
$public = $alias->isPublic();
4343
$container->setAlias($renamedId, new Alias((string) $alias, false));
4444
} else {
45-
$definition = $container->getDefinition($decorated);
45+
$definition = $container->getDefinition($inner);
4646
$public = $definition->isPublic();
4747
$definition->setPublic(false);
4848
$container->setDefinition($renamedId, $definition);
4949
}
5050

51-
$container->setAlias($decorated, new Alias($id, $public));
51+
$container->setAlias($inner, new Alias($id, $public));
5252
}
5353
}
5454
}

src/Symfony/Component/DependencyInjection/Definition.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,32 @@ public function setFactoryMethod($factoryMethod)
104104
/**
105105
* Sets the service that this service is decorating.
106106
*
107-
* @param string $id The decorated service id
108-
* @param string $renamedId The new decorated service id
107+
* @param null|string $id The decorated service id, use null to remove decoration
108+
* @param null|string $renamedId The new decorated service id
109+
*
110+
* @return Definition The current instance
111+
*
112+
* @throws InvalidArgumentException In case the decorated service id and the new decorated service id are equals.
109113
*/
110114
public function setDecoratedService($id, $renamedId = null)
111115
{
112116
if ($renamedId && $id == $renamedId) {
113-
throw new \LogicException(sprintf('The decorated service parent name for "%s" must be different than the service name itself.', $id));
117+
throw new \InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
114118
}
115119

116-
$this->decoratedService = array($id, $renamedId);
120+
if (null === $id) {
121+
$this->decoratedService = null;
122+
} else {
123+
$this->decoratedService = array($id, $renamedId);
124+
}
125+
126+
return $this;
117127
}
118128

119129
/**
120130
* Gets the service that decorates this service.
121131
*
122-
* @return array An array composed of the decorated service id and the new id for it
132+
* @return null|array An array composed of the decorated service id and the new id for it, null if no service is decorated
123133
*/
124134
public function getDecoratedService()
125135
{

src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ private function addService($definition, $id, \DOMElement $parent)
138138
if ($definition->isLazy()) {
139139
$service->setAttribute('lazy', 'true');
140140
}
141+
if (null !== $decorated = $definition->getDecoratedService()) {
142+
list ($decorated, $renamedId) = $decorated;
143+
$service->setAttribute('decorates', $decorated);
144+
if (null !== $renamedId) {
145+
$service->setAttribute('decoration-inner-name', $renamedId);
146+
}
147+
}
141148

142149
foreach ($definition->getTags() as $name => $tags) {
143150
foreach ($tags as $attributes) {

src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ private function addService($id, $definition)
139139
$code .= sprintf(" scope: %s\n", $scope);
140140
}
141141

142+
if (null !== $decorated = $definition->getDecoratedService()) {
143+
list ($decorated, $renamedId) = $decorated;
144+
$code .= sprintf(" decorates: %s\n", $decorated);
145+
if (null !== $renamedId) {
146+
$code .= sprintf(" decoration-inner-name: %s\n", $renamedId);
147+
}
148+
}
149+
142150
if ($callable = $definition->getConfigurator()) {
143151
if (is_array($callable)) {
144152
if ($callable[0] instanceof Reference) {

src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ private function parseDefinition($id, $service, $file)
197197
$definition->addTag((string) $tag['name'], $parameters);
198198
}
199199

200+
if (isset($service['decorates'])) {
201+
$renameId = isset($service['decoration-inner-name']) ? (string) $service['decoration-inner-name'] : null;
202+
$definition->setDecoratedService((string) $service['decorates'], $renameId);
203+
}
204+
200205
$this->container->setDefinition($id, $definition);
201206
}
202207

src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ private function parseDefinition($id, $service, $file)
234234
}
235235
}
236236

237+
if (isset($service['decorates'])) {
238+
$renameId = isset($service['decoration-inner-name']) ? $service['decoration-inner-name'] : null;
239+
$definition->setDecoratedService($service['decorates'], $renameId);
240+
}
241+
237242
$this->container->setDefinition($id, $definition);
238243
}
239244

src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@
9494
<xsd:attribute name="factory-service" type="xsd:string" />
9595
<xsd:attribute name="alias" type="xsd:string" />
9696
<xsd:attribute name="parent" type="xsd:string" />
97+
<xsd:attribute name="decorates" type="xsd:string" />
98+
<xsd:attribute name="decoration-inner-name" type="xsd:string" />
9799
</xsd:complexType>
98100

99101
<xsd:complexType name="tag">
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
4+
5+
use Symfony\Component\DependencyInjection\Alias;
6+
use Symfony\Component\DependencyInjection\ContainerBuilder;
7+
use Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass;
8+
9+
class DecoratorServicePassTest extends \PHPUnit_Framework_TestCase
10+
{
11+
public function testProcessWithoutAlias()
12+
{
13+
$container = new ContainerBuilder();
14+
$fooDefinition = $container
15+
->register('foo')
16+
->setPublic(false)
17+
;
18+
$fooExtendedDefinition = $container
19+
->register('foo.extended')
20+
->setPublic(true)
21+
->setDecoratedService('foo')
22+
;
23+
$barDefinition = $container
24+
->register('bar')
25+
->setPublic(true)
26+
;
27+
$barExtendedDefinition = $container
28+
->register('bar.extended')
29+
->setPublic(true)
30+
->setDecoratedService('bar', 'bar.yoo')
31+
;
32+
33+
$this->process($container);
34+
35+
$this->assertEquals('foo.extended', $container->getAlias('foo'));
36+
$this->assertFalse($container->getAlias('foo')->isPublic());
37+
38+
$this->assertEquals('bar.extended', $container->getAlias('bar'));
39+
$this->assertTrue($container->getAlias('bar')->isPublic());
40+
41+
$this->assertSame($fooDefinition, $container->getDefinition('foo.extended.inner'));
42+
$this->assertFalse($container->getDefinition('foo.extended.inner')->isPublic());
43+
44+
$this->assertSame($barDefinition, $container->getDefinition('bar.yoo'));
45+
$this->assertFalse($container->getDefinition('bar.yoo')->isPublic());
46+
47+
$this->assertNull($fooExtendedDefinition->getDecoratedService());
48+
$this->assertNull($barExtendedDefinition->getDecoratedService());
49+
}
50+
51+
public function testProcessWithAlias()
52+
{
53+
$container = new ContainerBuilder();
54+
$container
55+
->register('foo')
56+
->setPublic(true)
57+
;
58+
$container->setAlias('foo.alias', new Alias('foo', false));
59+
$fooExtendedDefinition = $container
60+
->register('foo.extended')
61+
->setPublic(true)
62+
->setDecoratedService('foo.alias')
63+
;
64+
65+
$this->process($container);
66+
67+
$this->assertEquals('foo.extended', $container->getAlias('foo.alias'));
68+
$this->assertFalse($container->getAlias('foo.alias')->isPublic());
69+
70+
$this->assertEquals('foo', $container->getAlias('foo.extended.inner'));
71+
$this->assertFalse($container->getAlias('foo.extended.inner')->isPublic());
72+
73+
$this->assertNull($fooExtendedDefinition->getDecoratedService());
74+
}
75+
76+
protected function process(ContainerBuilder $container)
77+
{
78+
$repeatedPass = new DecoratorServicePass();
79+
$repeatedPass->process($container);
80+
}
81+
}

src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,26 @@ public function testSetGetClass()
6262
$this->assertEquals('foo', $def->getClass(), '->getClass() returns the class name');
6363
}
6464

65+
public function testSetGetDecoratedService()
66+
{
67+
$def = new Definition('stdClass');
68+
$this->assertNull($def->getDecoratedService());
69+
$def->setDecoratedService('foo', 'foo.renamed');
70+
$this->assertEquals(array('foo', 'foo.renamed'), $def->getDecoratedService());
71+
$def->setDecoratedService(null);
72+
$this->assertNull($def->getDecoratedService());
73+
74+
$def = new Definition('s 341A tdClass');
75+
$def->setDecoratedService('foo');
76+
$this->assertEquals(array('foo', null), $def->getDecoratedService());
77+
$def->setDecoratedService(null);
78+
$this->assertNull($def->getDecoratedService());
79+
80+
$def = new Definition('stdClass');
81+
$this->setExpectedException('InvalidArgumentException', 'The decorated service inner name for "foo" must be different than the service name itself.');
82+
$def->setDecoratedService('foo', 'foo');
83+
}
84+
6585
/**
6686
* @covers Symfony\Component\DependencyInjection\Definition::setArguments
6787
* @covers Symfony\Component\DependencyInjection\Definition::getArguments

src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public function testAddService()
6666

6767
public function testDumpAnonymousServices()
6868
{
69-
include self::$fixturesPath.'/containers/container11.php';
69+
$container = include self::$fixturesPath.'/containers/container11.php';
7070
$dumper = new XmlDumper($container);
7171
$this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?>
7272
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
@@ -87,7 +87,7 @@ public function testDumpAnonymousServices()
8787

8888
public function testDumpEntities()
8989
{
90-
include self::$fixturesPath.'/containers/container12.php';
90+
$container = include self::$fixturesPath.'/containers/container12.php';
9191
$dumper = new XmlDumper($container);
9292
$this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?>
9393
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
@@ -100,4 +100,35 @@ public function testDumpEntities()
100100
</container>
101101
", $dumper->dump());
102102
}
103+
104+
/**
105+
* @dataProvider provideDecoratedServicesData
106+
*/
107+
public function testDumpDecoratedServices($expectedXmlDump, $container)
108+
{
109+
$dumper = new XmlDumper($container);
110+
$this->assertEquals($expectedXmlDump, $dumper->dump());
111+
}
112+
113+
public function provideDecoratedServicesData()
114+
{
115+
$fixturesPath = realpath(__DIR__.'/../Fixtures/');
116+
117+
return array(
118+
array("<?xml version=\"1.0\" encoding=\"utf-8\"?>
119+
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
120+
<services>
121+
<service id=\"foo\" class=\"FooClass\Foo\" decorates=\"bar\" decoration-inner-name=\"bar.woozy\"/>
122+
</services>
123+
</container>
124+
", include $fixturesPath.'/containers/container15.php'),
125+
array("<?xml version=\"1.0\" encoding=\"utf-8\"?>
126+
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
127+
<services>
128+
<service id=\"foo\" class=\"FooClass\Foo\" decorates=\"bar\"/>
129+
</services>
130+
</container>
131+
", include $fixturesPath.'/containers/container16.php'),
132+
);
133+
}
103134
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\ContainerBuilder;
4+
5+
$container = new ContainerBuilder();
6+
$container
7+
->register('foo', 'FooClass\\Foo')
8+
->setDecoratedService('bar', 'bar.woozy')
9+
;
10+
11+
return $container;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\ContainerBuilder;
4+
5+
$container = new ContainerBuilder();
6+
$container
7+
->register('foo', 'FooClass\\Foo')
8+
->setDecoratedService('bar')
9+
;
10+
11+
return $container;

src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,16 @@
9292
->register('configured_service', 'stdClass')
9393
->setConfigurator(array(new Reference('configurator_service'), 'configureStdClass'))
9494
;
95+
$container
96+
->register('decorated', 'stdClass')
97+
;
98+
$container
99+
->register('decorator_service', 'stdClass')
100+
->setDecoratedService('decorated')
101+
;
102+
$container
103+
->register('decorator_service_with_name', 'stdClass')
104+
->setDecoratedService('decorated', 'decorated.pif-pouf')
105+
;
95106

96107
return $container;

src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ digraph sc {
1616
node_depends_on_request [label="depends_on_request\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
1717
node_configurator_service [label="configurator_service\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
1818
node_configured_service [label="configured_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
19+
node_decorated [label="decorated\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
20+
node_decorator_service [label="decorator_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
21+
node_decorator_service_with_name [label="decorator_service_with_name\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
1922
node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
2023
node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"];
2124
node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"];

0 commit comments

Comments
 (0)
0