buildContainerWithDependencies()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the CrossContainerExtension package.
7
 *
8
 * (c) Kamil Kokot <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace tests\FriendsOfBehat\CrossContainer\Extension;
15
16
use FriendsOfBehat\CrossContainerExtension\ContainerBasedContainerAccessor;
17
use FriendsOfBehat\CrossContainerExtension\CrossContainerProcessor;
18
use PHPUnit\Framework\Assert;
19
use PHPUnit\Framework\TestCase;
20
use Symfony\Component\DependencyInjection\ContainerBuilder;
21
use Symfony\Component\DependencyInjection\Definition;
22
use Symfony\Component\DependencyInjection\Reference;
23
24
final class CrossContainerProcessorTest extends TestCase
25
{
26
    /**
27
     * @test
28
     */
29 View Code Duplication
    public function it_resolves_cross_container_references_in_service_argument(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
30
    {
31
        $externalContainer = new ContainerBuilder();
32
        $externalContainer->setDefinition('array_object', (new Definition(\ArrayObject::class, [['foo' => 'bar']]))->setPublic(true));
33
34
        $baseContainer = new ContainerBuilder();
35
        $baseContainer->setDefinition('array_object', (new Definition(\ArrayObject::class, [
36
            new Reference('__external__.array_object'),
37
        ]))->setPublic(true));
38
39
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
40
41
        Assert::assertInstanceOf(\ArrayObject::class, $baseContainer->get('array_object'));
42
        Assert::assertSame(['foo' => 'bar'], $baseContainer->get('array_object')->getArrayCopy());
43
    }
44
45
    /**
46
     * @test
47
     */
48 View Code Duplication
    public function it_resolves_cross_container_references_in_service_argument_array(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
49
    {
50
        $externalContainer = new ContainerBuilder();
51
        $externalContainer->setDefinition('std_class', (new Definition(\stdClass::class))->setPublic(true));
52
53
        $baseContainer = new ContainerBuilder();
54
        $baseContainer->setDefinition('array_object', (new Definition(\ArrayObject::class, [
55
            ['std' => ['class' => new Reference('__external__.std_class')]],
56
        ]))->setPublic(true));
57
58
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
59
60
        Assert::assertInstanceOf(\ArrayObject::class, $baseContainer->get('array_object'));
61
        Assert::assertInstanceOf(\stdClass::class, $baseContainer->get('array_object')['std']['class']);
62
    }
63
64
    /**
65
     * @test
66
     */
67
    public function it_resolves_cross_container_references_in_service_argument_anonymous_definition(): void
68
    {
69
        $externalContainer = new ContainerBuilder();
70
        $externalContainer->setDefinition('std_class', (new Definition(\stdClass::class))->setPublic(true));
71
72
        $baseContainer = new ContainerBuilder();
73
        $baseContainer->setDefinition('array_object', (new Definition(\ArrayObject::class, [
74
            new Definition(\ArrayObject::class, [
75
                ['std_class' => new Reference('__external__.std_class')],
76
            ]),
77
        ]))->setPublic(true));
78
79
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
80
81
        Assert::assertInstanceOf(\ArrayObject::class, $baseContainer->get('array_object'));
82
        Assert::assertInstanceOf(\stdClass::class, $baseContainer->get('array_object')->getArrayCopy()['std_class']);
83
    }
84
85
    /**
86
     * @test
87
     */
88
    public function it_resolves_cross_container_references_in_service_factory(): void
89
    {
90
        $externalContainer = new ContainerBuilder();
91
        $externalContainer->setDefinition('array_object_factory', (new Definition(\ArrayObject::class, [['old' => 'old']]))->setPublic(true));
92
93
        $baseContainer = new ContainerBuilder();
94
        $baseContainer->setDefinition(
95
            'array_object',
96
            (new Definition(\ArrayObject::class, [['new' => 'new']]))
97
                ->setFactory([new Reference('__external__.array_object_factory'), 'exchangeArray'])
98
                ->setPublic(true)
99
        );
100
101
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
102
103
        Assert::assertSame(['old' => 'old'], $baseContainer->get('array_object'));
104
    }
105
106
    /**
107
     * @test
108
     */
109
    public function it_resolves_cross_container_parameters_inline_in_parameter(): void
110
    {
111
        $externalContainer = new ContainerBuilder();
112
        $externalContainer->setParameter('parameter', '42');
113
114
        $baseContainer = new ContainerBuilder();
115
        $baseContainer->setParameter('parameter', '%__external__.parameter%');
116
117
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
118
119
        Assert::assertSame('42', $baseContainer->getParameter('parameter'));
120
    }
121
122
    /**
123
     * @test
124
     */
125 View Code Duplication
    public function it_resolves_cross_container_parameters_depending_on_another_parameters(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
    {
127
        $externalContainer = new ContainerBuilder();
128
        $externalContainer->setParameter('parameter', '%nested_parameter%');
129
        $externalContainer->setParameter('nested_parameter', '42');
130
131
        $baseContainer = new ContainerBuilder();
132
        $baseContainer->setParameter('parameter', '%__external__.parameter%');
133
134
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
135
136
        Assert::assertSame('42', $baseContainer->getParameter('parameter'));
137
    }
138
139
    /**
140
     * @test
141
     */
142
    public function it_resolves_cross_container_parameters_in_service_definition_array(): void
143
    {
144
        $externalContainer = new ContainerBuilder();
145
        $externalContainer->setParameter('parameter', '42');
146
147
        $baseContainer = new ContainerBuilder();
148
        $baseContainer->setDefinition(
149
            'array_object',
150
            (new Definition(\ArrayObject::class, [['parameter' => '%__external__.parameter%']]))
151
                ->setPublic(true)
152
        );
153
154
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
155
156
        Assert::assertSame(['parameter' => '42'], $baseContainer->get('array_object')->getArrayCopy());
157
    }
158
159
    /**
160
     * @test
161
     */
162
    public function it_resolves_cross_container_escaped_parameters(): void
163
    {
164
        $externalContainer = new ContainerBuilder();
165
        $externalContainer->setParameter('parameter', '%%s?%%s');
166
167
        $baseContainer = new ContainerBuilder();
168
        $baseContainer->setParameter('parameter', '%__external__.parameter%');
169
170
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
171
172
        Assert::assertSame('%s?%s', $baseContainer->getParameter('parameter'));
173
    }
174
175
    /**
176
     * @test
177
     */
178 View Code Duplication
    public function it_resolves_cross_container_escaped_parameters_symfony_kernel(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
    {
180
        $externalContainer = new ContainerBuilder();
181
        $externalContainer->setParameter('parameter', 'testParam1-%%s-%%s');
182
        $externalContainer->compile();
183
184
        $baseContainer = new ContainerBuilder();
185
        $baseContainer->setParameter('parameter', '%__external__.parameter%');
186
187
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
188
189
        Assert::assertSame('testParam1-%s-%s', $baseContainer->getParameter('parameter'));
190
    }
191
192
    /**
193
     * @test
194
     */
195 View Code Duplication
    public function it_resolves_cross_container_references_in_method_calls(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
196
    {
197
        $externalContainer = new ContainerBuilder();
198
        $externalContainer->setDefinition('array_object', (new Definition(\ArrayObject::class, [['foo' => 'bar']]))->setPublic(true));
199
200
        $baseContainer = new ContainerBuilder();
201
        $baseContainer->setDefinition(
202
            'array_object',
203
            (new Definition(\ArrayObject::class, [[]]))
204
                ->addMethodCall('exchangeArray', [new Reference('__external__.array_object')])
205
                ->setPublic(true)
206
        );
207
208
        $this->buildContainerWithDependencies($baseContainer, ['external' => $externalContainer]);
209
210
        Assert::assertInstanceOf(\ArrayObject::class, $baseContainer->get('array_object'));
211
        Assert::assertSame(['foo' => 'bar'], $baseContainer->get('array_object')->getArrayCopy());
212
    }
213
214
    /**
215
     * @param ContainerBuilder $baseContainer
216
     * @param ContainerBuilder[] $externalContainers
217
     */
218
    private function buildContainerWithDependencies(ContainerBuilder $baseContainer, array $externalContainers): void
219
    {
220
        $accessors = [];
221
        foreach ($externalContainers as $containerIdentifier => $container) {
222
            $accessors[$containerIdentifier] = new ContainerBasedContainerAccessor($container);
223
        }
224
225
        $crossContainerReferencesResolver = new CrossContainerProcessor($accessors);
226
        $crossContainerReferencesResolver->process($baseContainer);
227
228
        $baseContainer->compile();
229
    }
230
}
231