Completed
Push — master ( b2754f...703fad )
by
unknown
14s queued 13s
created

DoctrineExtensionTest   C

Complexity

Total Complexity 52

Size/Duplication

Total Lines 790
Duplicated Lines 18.61 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 52
c 0
b 0
f 0
lcom 1
cbo 11
dl 147
loc 790
rs 6.6666

29 Methods

Rating   Name   Duplication   Size   Complexity  
B testAutowiringAlias() 0 24 2
A testPublicServicesAndAliases() 0 12 1
A testDbalGenerateDefaultConnectionConfiguration() 0 19 1
A testDbalOverrideDefaultConnection() 0 13 1
A testOrmRequiresDbal() 0 6 1
B getAutomappingConfigurations() 0 34 1
A testAutomapping() 0 52 2
A testDbalLoad() 0 17 1
B testDbalWrapperClass() 0 25 1
B testDependencyInjectionConfigurationDefaults() 6 103 4
A testUseSavePointsAddMethodCallToAddSavepointsToTheConnection() 0 19 1
A testAutoGenerateProxyClasses() 0 23 1
B testSingleEntityManagerWithDefaultConfiguration() 6 24 2
B testSingleEntityManagerWithDefaultSecondLevelCacheConfiguration() 6 32 3
B testSingleEntityManagerWithCustomSecondLevelCacheConfiguration() 6 38 3
A testBundleEntityAliases() 16 18 1
A testOverwriteEntityAliases() 16 18 1
A testYamlBundleMappingDetection() 0 17 1
B testXmlBundleMappingDetection() 26 26 1
B testAnnotationsBundleMappingDetection() 26 26 1
A testOrmMergeConfigs() 0 56 3
B testAnnotationsBundleMappingDetectionWithVendorNamespace() 0 24 1
B testCacheConfiguration() 0 28 1
A testShardManager() 0 23 1
A getContainer() 0 20 4
A assertDICConstructorArguments() 0 4 1
A assertDICDefinitionMethodCallAt() 15 15 3
B assertDICDefinitionMethodCallOnce() 24 24 6
A compileContainer() 0 6 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like DoctrineExtensionTest 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 DoctrineExtensionTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection;
4
5
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension;
6
use Doctrine\Bundle\DoctrineBundle\Tests\Builder\BundleConfigurationBuilder;
7
use Doctrine\Common\Persistence\ManagerRegistry;
8
use Doctrine\Common\Persistence\ObjectManager;
9
use Doctrine\Common\Proxy\AbstractProxyFactory;
10
use Doctrine\DBAL\Connection;
11
use Doctrine\DBAL\Driver\Connection as DriverConnection;
12
use Doctrine\ORM\EntityManagerInterface;
13
use Doctrine\ORM\Version;
14
use PHPUnit\Framework\TestCase;
15
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
16
use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass;
17
use Symfony\Component\DependencyInjection\ContainerBuilder;
18
use Symfony\Component\DependencyInjection\Definition;
19
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
20
use Symfony\Component\DependencyInjection\Reference;
21
22
class DoctrineExtensionTest extends TestCase
23
{
24
    public function testAutowiringAlias()
25
    {
26
        $container = $this->getContainer();
27
        $extension = new DoctrineExtension();
28
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
29
30
        $extension->load([$config], $container);
31
32
        $expectedAliases = [
33
            DriverConnection::class => 'database_connection',
34
            Connection::class => 'database_connection',
35
            ManagerRegistry::class => 'doctrine',
36
            ObjectManager::class => 'doctrine.orm.entity_manager',
37
            EntityManagerInterface::class => 'doctrine.orm.entity_manager',
38
        ];
39
40
        foreach ($expectedAliases as $id => $target) {
41
            $this->assertTrue($container->hasAlias($id), sprintf('The container should have a `%s` alias for autowiring support.', $id));
42
43
            $alias = $container->getAlias($id);
44
            $this->assertEquals($target, (string) $alias, sprintf('The autowiring for `%s` should use `%s`.', $id, $target));
45
            $this->assertFalse($alias->isPublic(), sprintf('The autowiring alias for `%s` should be private.', $id, $target));
46
        }
47
    }
48
49
    public function testPublicServicesAndAliases()
50
    {
51
        $container = $this->getContainer();
52
        $extension = new DoctrineExtension();
53
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
54
55
        $extension->load([$config], $container);
56
57
        $this->assertTrue($container->getDefinition('doctrine')->isPublic());
58
        $this->assertTrue($container->getAlias('doctrine.orm.entity_manager')->isPublic());
59
        $this->assertTrue($container->getAlias('database_connection')->isPublic());
60
    }
61
62
    public function testDbalGenerateDefaultConnectionConfiguration()
63
    {
64
        $container = $this->getContainer();
65
        $extension = new DoctrineExtension();
66
67
        $container->registerExtension($extension);
68
69
        $extension->load([['dbal' => []]], $container);
70
71
        // doctrine.dbal.default_connection
72
        $this->assertEquals('%doctrine.default_connection%', $container->getDefinition('doctrine')->getArgument(3));
73
        $this->assertEquals('default', $container->getParameter('doctrine.default_connection'));
74
        $this->assertEquals('root', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['user']);
75
        $this->assertNull($container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['password']);
76
        $this->assertEquals('localhost', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['host']);
77
        $this->assertNull($container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['port']);
78
        $this->assertEquals('pdo_mysql', $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['driver']);
79
        $this->assertEquals([], $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0)['driverOptions']);
80
    }
81
82
    public function testDbalOverrideDefaultConnection()
83
    {
84
        $container = $this->getContainer();
85
        $extension = new DoctrineExtension();
86
87
        $container->registerExtension($extension);
88
89
        $extension->load([[], ['dbal' => ['default_connection' => 'foo']], []], $container);
90
91
        // doctrine.dbal.default_connection
92
        $this->assertEquals('%doctrine.default_connection%', $container->getDefinition('doctrine')->getArgument(3), '->load() overrides existing configuration options');
93
        $this->assertEquals('foo', $container->getParameter('doctrine.default_connection'), '->load() overrides existing configuration options');
94
    }
95
96
    /**
97
     * @expectedException \LogicException
98
     * @expectedExceptionMessage Configuring the ORM layer requires to configure the DBAL layer as well.
99
     */
100
    public function testOrmRequiresDbal()
101
    {
102
        $extension = new DoctrineExtension();
103
104
        $extension->load([['orm' => ['auto_mapping' => true]]], $this->getContainer());
105
    }
106
107
    public function getAutomappingConfigurations()
108
    {
109
        return [
110
            [
111
                [
112
                    'em1' => [
113
                        'mappings' => ['YamlBundle' => null],
114
                    ],
115
                    'em2' => [
116
                        'mappings' => ['XmlBundle' => null],
117
                    ],
118
                ],
119
            ],
120
            [
121
                [
122
                    'em1' => ['auto_mapping' => true],
123
                    'em2' => [
124
                        'mappings' => ['XmlBundle' => null],
125
                    ],
126
                ],
127
            ],
128
            [
129
                [
130
                    'em1' => [
131
                        'auto_mapping' => true,
132
                        'mappings' => ['YamlBundle' => null],
133
                    ],
134
                    'em2' => [
135
                        'mappings' => ['XmlBundle' => null],
136
                    ],
137
                ],
138
            ],
139
        ];
140
    }
141
142
    /**
143
     * @dataProvider getAutomappingConfigurations
144
     */
145
    public function testAutomapping(array $entityManagers)
146
    {
147
        $extension = new DoctrineExtension();
148
149
        if (! method_exists($extension, 'fixManagersAutoMappings')) {
150
            $this->markTestSkipped('Auto mapping with multiple managers available with Symfony ~2.6');
151
        }
152
153
        $container = $this->getContainer([
0 ignored issues
show
Documentation introduced by
array('YamlBundle', 'XmlBundle') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
154
            'YamlBundle',
155
            'XmlBundle',
156
        ]);
157
158
        $extension->load(
159
            [
160
                [
161
                    'dbal' => [
162
                        'default_connection' => 'cn1',
163
                        'connections' => [
164
                            'cn1' => [],
165
                            'cn2' => [],
166
                        ],
167
                    ],
168
                    'orm' => ['entity_managers' => $entityManagers],
169
                ],
170
            ],
171
            $container
172
        );
173
174
        $configEm1 = $container->getDefinition('doctrine.orm.em1_configuration');
175
        $configEm2 = $container->getDefinition('doctrine.orm.em2_configuration');
176
177
        $this->assertContains(
178
            [
179
                'setEntityNamespaces',
180
                [
181
                    ['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'],
182
                ],
183
            ],
184
            $configEm1->getMethodCalls()
185
        );
186
187
        $this->assertContains(
188
            [
189
                'setEntityNamespaces',
190
                [
191
                    ['XmlBundle' => 'Fixtures\Bundles\XmlBundle\Entity'],
192
                ],
193
            ],
194
            $configEm2->getMethodCalls()
195
        );
196
    }
197
198
    public function testDbalLoad()
199
    {
200
        $container = $this->getContainer();
201
        $extension = new DoctrineExtension();
202
203
        $extension->load([
204
            ['dbal' => ['connections' => ['default' => ['password' => 'foo']]]],
205
            [],
206
            ['dbal' => ['default_connection' => 'foo']],
207
            [],
208
        ], $container);
209
210
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
211
212
        $this->assertEquals('foo', $config['password']);
213
        $this->assertEquals('root', $config['user']);
214
    }
215
216
    public function testDbalWrapperClass()
217
    {
218
        $container = $this->getContainer();
219
        $extension = new DoctrineExtension();
220
221
        $extension->load(
222
            [
223
                [
224
            'dbal' => [
225
            'connections' => [
226
                    'default' => ['password' => 'foo', 'wrapper_class' => TestWrapperClass::class],
227
                    'second' => ['password' => 'boo'],
228
                ],
229
            ],
230
                ],
231
                [],
232
                ['dbal' => ['default_connection' => 'foo']],
233
                [],
234
            ],
235
            $container
236
        );
237
238
        $this->assertEquals(TestWrapperClass::class, $container->getDefinition('doctrine.dbal.default_connection')->getClass());
239
        $this->assertNull($container->getDefinition('doctrine.dbal.second_connection')->getClass());
240
    }
241
242
    public function testDependencyInjectionConfigurationDefaults()
243
    {
244
        $container = $this->getContainer();
245
        $extension = new DoctrineExtension();
246
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
247
248
        $extension->load([$config], $container);
249
250
        $this->assertFalse($container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
251
        $this->assertEquals('Doctrine\ORM\Configuration', $container->getParameter('doctrine.orm.configuration.class'));
252
        $this->assertEquals('Doctrine\ORM\EntityManager', $container->getParameter('doctrine.orm.entity_manager.class'));
253
        $this->assertEquals('Proxies', $container->getParameter('doctrine.orm.proxy_namespace'));
254
        $this->assertEquals('Doctrine\Common\Cache\ArrayCache', $container->getParameter('doctrine.orm.cache.array.class'));
255
        $this->assertEquals('Doctrine\Common\Cache\ApcCache', $container->getParameter('doctrine.orm.cache.apc.class'));
256
        $this->assertEquals('Doctrine\Common\Cache\MemcacheCache', $container->getParameter('doctrine.orm.cache.memcache.class'));
257
        $this->assertEquals('localhost', $container->getParameter('doctrine.orm.cache.memcache_host'));
258
        $this->assertEquals('11211', $container->getParameter('doctrine.orm.cache.memcache_port'));
259
        $this->assertEquals('Memcache', $container->getParameter('doctrine.orm.cache.memcache_instance.class'));
260
        $this->assertEquals('Doctrine\Common\Cache\XcacheCache', $container->getParameter('doctrine.orm.cache.xcache.class'));
261
        $this->assertEquals('Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain', $container->getParameter('doctrine.orm.metadata.driver_chain.class'));
262
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\AnnotationDriver', $container->getParameter('doctrine.orm.metadata.annotation.class'));
263
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver', $container->getParameter('doctrine.orm.metadata.xml.class'));
264
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver', $container->getParameter('doctrine.orm.metadata.yml.class'));
265
266
        // second-level cache
267
        $this->assertEquals('Doctrine\ORM\Cache\DefaultCacheFactory', $container->getParameter('doctrine.orm.second_level_cache.default_cache_factory.class'));
268
        $this->assertEquals('Doctrine\ORM\Cache\Region\DefaultRegion', $container->getParameter('doctrine.orm.second_level_cache.default_region.class'));
269
        $this->assertEquals('Doctrine\ORM\Cache\Region\FileLockRegion', $container->getParameter('doctrine.orm.second_level_cache.filelock_region.class'));
270
        $this->assertEquals('Doctrine\ORM\Cache\Logging\CacheLoggerChain', $container->getParameter('doctrine.orm.second_level_cache.logger_chain.class'));
271
        $this->assertEquals('Doctrine\ORM\Cache\Logging\StatisticsCacheLogger', $container->getParameter('doctrine.orm.second_level_cache.logger_statistics.class'));
272
        $this->assertEquals('Doctrine\ORM\Cache\CacheConfiguration', $container->getParameter('doctrine.orm.second_level_cache.cache_configuration.class'));
273
        $this->assertEquals('Doctrine\ORM\Cache\RegionsConfiguration', $container->getParameter('doctrine.orm.second_level_cache.regions_configuration.class'));
274
275
        $config = BundleConfigurationBuilder::createBuilder()
276
            ->addBaseConnection()
277
            ->addEntityManager([
278
                'proxy_namespace' => 'MyProxies',
279
                'auto_generate_proxy_classes' => true,
280
                'default_entity_manager' => 'default',
281
                'entity_managers' => [
282
                    'default' => [
283
                        'mappings' => ['YamlBundle' => []],
284
                    ],
285
                ],
286
            ])
287
            ->build();
288
289
        $container = $this->getContainer();
290
        $extension->load([$config], $container);
291
        $this->compileContainer($container);
292
293
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
294
295
        $args = $definition->getArguments();
296
        $this->assertEquals('pdo_mysql', $args[0]['driver']);
297
        $this->assertEquals('localhost', $args[0]['host']);
298
        $this->assertEquals('root', $args[0]['user']);
299
        $this->assertEquals('doctrine.dbal.default_connection.configuration', (string) $args[1]);
300
        $this->assertEquals('doctrine.dbal.default_connection.event_manager', (string) $args[2]);
301
        $this->assertCount(0, $definition->getMethodCalls());
302
303
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
304
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
305 View Code Duplication
        if (method_exists($definition, 'getFactory')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
306
            $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
307
        } else {
308
            $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
0 ignored issues
show
Bug introduced by
The method getFactoryClass() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
309
            $this->assertEquals('create', $definition->getFactoryMethod());
0 ignored issues
show
Bug introduced by
The method getFactoryMethod() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
310
        }
311
312
        $this->assertEquals(['default' => 'doctrine.orm.default_entity_manager'], $container->getParameter('doctrine.entity_managers'), 'Set of the existing EntityManagers names is incorrect.');
313
        $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');
314
315
        $arguments = $definition->getArguments();
316
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
317
        $this->assertEquals('doctrine.dbal.default_connection', (string) $arguments[0]);
318
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
319
        $this->assertEquals('doctrine.orm.default_configuration', (string) $arguments[1]);
320
321
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
322
        $calls      = array_values($definition->getMethodCalls());
323
        $this->assertEquals(['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'], $calls[0][1][0]);
324
        $this->assertEquals('doctrine.orm.default_metadata_cache', (string) $calls[1][1][0]);
325
        $this->assertEquals('doctrine.orm.default_query_cache', (string) $calls[2][1][0]);
326
        $this->assertEquals('doctrine.orm.default_result_cache', (string) $calls[3][1][0]);
327
328
        if (version_compare(Version::VERSION, '2.3.0-DEV') >= 0) {
329
            $this->assertEquals('doctrine.orm.naming_strategy.default', (string) $calls[10][1][0]);
330
            $this->assertEquals('doctrine.orm.quote_strategy.default', (string) $calls[11][1][0]);
331
        }
332
        if (version_compare(Version::VERSION, '2.4.0-DEV') >= 0) {
333
            $this->assertEquals('doctrine.orm.default_entity_listener_resolver', (string) $calls[12][1][0]);
334
        }
335
336
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
337
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
338
339
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_query_cache'));
340
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
341
342
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_result_cache'));
343
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
344
    }
345
346
    public function testUseSavePointsAddMethodCallToAddSavepointsToTheConnection()
347
    {
348
        $container = $this->getContainer();
349
        $extension = new DoctrineExtension();
350
351
        $extension->load([[
352
        'dbal' => [
353
        'connections' => [
354
            'default' => ['password' => 'foo', 'use_savepoints' => true],
355
        ],
356
        ],
357
        ],
358
        ], $container);
359
360
        $calls = $container->getDefinition('doctrine.dbal.default_connection')->getMethodCalls();
361
        $this->assertCount(1, $calls);
362
        $this->assertEquals('setNestTransactionsWithSavepoints', $calls[0][0]);
363
        $this->assertTrue($calls[0][1][0]);
364
    }
365
366
    public function testAutoGenerateProxyClasses()
367
    {
368
        $container = $this->getContainer();
369
        $extension = new DoctrineExtension();
370
371
        $config = BundleConfigurationBuilder::createBuilder()
372
            ->addBaseConnection()
373
            ->addEntityManager([
374
                'proxy_namespace' => 'MyProxies',
375
                'auto_generate_proxy_classes' => 'eval',
376
                'default_entity_manager' => 'default',
377
                'entity_managers' => [
378
                    'default' => [
379
                        'mappings' => ['YamlBundle' => []],
380
                    ],
381
                ],
382
            ])
383
            ->build();
384
385
        $extension->load([$config], $container);
386
387
        $this->assertEquals(AbstractProxyFactory::AUTOGENERATE_EVAL, $container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
388
    }
389
390
    public function testSingleEntityManagerWithDefaultConfiguration()
391
    {
392
        $container = $this->getContainer();
393
        $extension = new DoctrineExtension();
394
395
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
396
397
        $extension->load([$configurationArray], $container);
398
        $this->compileContainer($container);
399
400
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
401
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
402 View Code Duplication
        if (method_exists($definition, 'getFactory')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
403
            $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
404
        } else {
405
            $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
0 ignored issues
show
Bug introduced by
The method getFactoryClass() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
406
            $this->assertEquals('create', $definition->getFactoryMethod());
0 ignored issues
show
Bug introduced by
The method getFactoryMethod() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
407
        }
408
409
        $this->assertDICConstructorArguments($definition, [
410
            new Reference('doctrine.dbal.default_connection'),
411
        new Reference('doctrine.orm.default_configuration'),
412
        ]);
413
    }
414
415
    public function testSingleEntityManagerWithDefaultSecondLevelCacheConfiguration()
416
    {
417
        if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) {
418
            $this->markTestSkipped(sprintf('Second Level cache not supported by this version of the ORM : %s', Version::VERSION));
419
        }
420
        $container = $this->getContainer();
421
        $extension = new DoctrineExtension();
422
423
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
424
            ->addBaseSecondLevelCache()
425
            ->build();
426
427
        $extension->load([$configurationArray], $container);
428
        $this->compileContainer($container);
429
430
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
431
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
432 View Code Duplication
        if (method_exists($definition, 'getFactory')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
433
            $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
434
        } else {
435
            $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
0 ignored issues
show
Bug introduced by
The method getFactoryClass() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
436
            $this->assertEquals('create', $definition->getFactoryMethod());
0 ignored issues
show
Bug introduced by
The method getFactoryMethod() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
437
        }
438
439
        $this->assertDICConstructorArguments($definition, [
440
            new Reference('doctrine.dbal.default_connection'),
441
        new Reference('doctrine.orm.default_configuration'),
442
        ]);
443
444
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
445
        $this->assertEquals('%doctrine.orm.second_level_cache.default_cache_factory.class%', $slcDefinition->getClass());
446
    }
447
448
    public function testSingleEntityManagerWithCustomSecondLevelCacheConfiguration()
449
    {
450
        if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) {
451
            $this->markTestSkipped(sprintf('Second Level cache not supported by this version of the ORM : %s', Version::VERSION));
452
        }
453
        $container = $this->getContainer();
454
        $extension = new DoctrineExtension();
455
456
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
457
            ->addSecondLevelCache([
458
                'region_cache_driver' => ['type' => 'memcache'],
459
                'regions' => [
460
                    'hour_region' => ['lifetime' => 3600],
461
                ],
462
                'factory' => 'YamlBundle\Cache\MyCacheFactory',
463
            ])
464
            ->build();
465
466
        $extension->load([$configurationArray], $container);
467
        $this->compileContainer($container);
468
469
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
470
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
471 View Code Duplication
        if (method_exists($definition, 'getFactory')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
472
            $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
473
        } else {
474
            $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
0 ignored issues
show
Bug introduced by
The method getFactoryClass() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
475
            $this->assertEquals('create', $definition->getFactoryMethod());
0 ignored issues
show
Bug introduced by
The method getFactoryMethod() does not exist on Symfony\Component\DependencyInjection\Definition. Did you maybe mean getFactory()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
476
        }
477
478
        $this->assertDICConstructorArguments($definition, [
479
            new Reference('doctrine.dbal.default_connection'),
480
        new Reference('doctrine.orm.default_configuration'),
481
        ]);
482
483
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
484
        $this->assertEquals('YamlBundle\Cache\MyCacheFactory', $slcDefinition->getClass());
485
    }
486
487 View Code Duplication
    public function testBundleEntityAliases()
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...
488
    {
489
        $container = $this->getContainer();
490
        $extension = new DoctrineExtension();
491
492
        $config        = BundleConfigurationBuilder::createBuilder()
493
             ->addBaseConnection()
494
             ->build();
495
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => []]]]];
496
        $extension->load([$config], $container);
497
498
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
499
        $this->assertDICDefinitionMethodCallOnce(
500
            $definition,
501
            'setEntityNamespaces',
502
            [['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity']]
503
        );
504
    }
505
506 View Code Duplication
    public function testOverwriteEntityAliases()
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...
507
    {
508
        $container = $this->getContainer();
509
        $extension = new DoctrineExtension();
510
511
        $config        = BundleConfigurationBuilder::createBuilder()
512
             ->addBaseConnection()
513
             ->build();
514
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => ['alias' => 'yml']]]]];
515
        $extension->load([$config], $container);
516
517
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
518
        $this->assertDICDefinitionMethodCallOnce(
519
            $definition,
520
            'setEntityNamespaces',
521
            [['yml' => 'Fixtures\Bundles\YamlBundle\Entity']]
522
        );
523
    }
524
525
    public function testYamlBundleMappingDetection()
526
    {
527
        $container = $this->getContainer('YamlBundle');
528
        $extension = new DoctrineExtension();
529
530
        $config = BundleConfigurationBuilder::createBuilder()
531
            ->addBaseConnection()
532
            ->addBaseEntityManager()
533
            ->build();
534
        $extension->load([$config], $container);
535
536
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
537
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
538
            new Reference('doctrine.orm.default_yml_metadata_driver'),
539
            'Fixtures\Bundles\YamlBundle\Entity',
540
        ]);
541
    }
542
543 View Code Duplication
    public function testXmlBundleMappingDetection()
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...
544
    {
545
        $container = $this->getContainer('XmlBundle');
546
        $extension = new DoctrineExtension();
547
548
        $config = BundleConfigurationBuilder::createBuilder()
549
            ->addBaseConnection()
550
            ->addEntityManager([
551
                'default_entity_manager' => 'default',
552
                'entity_managers' => [
553
                    'default' => [
554
                        'mappings' => [
555
                            'XmlBundle' => [],
556
                        ],
557
                    ],
558
                ],
559
            ])
560
            ->build();
561
        $extension->load([$config], $container);
562
563
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
564
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
565
            new Reference('doctrine.orm.default_xml_metadata_driver'),
566
            'Fixtures\Bundles\XmlBundle\Entity',
567
        ]);
568
    }
569
570 View Code Duplication
    public function testAnnotationsBundleMappingDetection()
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...
571
    {
572
        $container = $this->getContainer('AnnotationsBundle');
573
        $extension = new DoctrineExtension();
574
575
        $config = BundleConfigurationBuilder::createBuilder()
576
            ->addBaseConnection()
577
            ->addEntityManager([
578
                'default_entity_manager' => 'default',
579
                'entity_managers' => [
580
                    'default' => [
581
                        'mappings' => [
582
                            'AnnotationsBundle' => [],
583
                        ],
584
                    ],
585
                ],
586
            ])
587
            ->build();
588
        $extension->load([$config], $container);
589
590
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
591
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
592
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
593
            'Fixtures\Bundles\AnnotationsBundle\Entity',
594
        ]);
595
    }
596
597
    public function testOrmMergeConfigs()
598
    {
599
        $container = $this->getContainer(['XmlBundle', 'AnnotationsBundle']);
0 ignored issues
show
Documentation introduced by
array('XmlBundle', 'AnnotationsBundle') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
600
        $extension = new DoctrineExtension();
601
602
        $config1 = BundleConfigurationBuilder::createBuilder()
603
            ->addBaseConnection()
604
            ->addEntityManager([
605
                'auto_generate_proxy_classes' => true,
606
                'default_entity_manager' => 'default',
607
                'entity_managers' => [
608
                    'default' => [
609
                        'mappings' => [
610
                            'AnnotationsBundle' => [],
611
                        ],
612
                    ],
613
                ],
614
            ])
615
            ->build();
616
        $config2 = BundleConfigurationBuilder::createBuilder()
617
            ->addBaseConnection()
618
            ->addEntityManager([
619
                'auto_generate_proxy_classes' => false,
620
                'default_entity_manager' => 'default',
621
                'entity_managers' => [
622
                    'default' => [
623
                        'mappings' => [
624
                            'XmlBundle' => [],
625
                        ],
626
                    ],
627
                ],
628
            ])
629
            ->build();
630
        $extension->load([$config1, $config2], $container);
631
632
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
633
        $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
634
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
635
            'Fixtures\Bundles\AnnotationsBundle\Entity',
636
        ]);
637
        $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
638
            new Reference('doctrine.orm.default_xml_metadata_driver'),
639
            'Fixtures\Bundles\XmlBundle\Entity',
640
        ]);
641
642
        $configDef = $container->getDefinition('doctrine.orm.default_configuration');
643
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setAutoGenerateProxyClasses');
644
645
        $calls = $configDef->getMethodCalls();
646
        foreach ($calls as $call) {
647
            if ($call[0] === 'setAutoGenerateProxyClasses') {
648
                $this->assertFalse($container->getParameterBag()->resolveValue($call[1][0]));
649
                break;
650
            }
651
        }
652
    }
653
654
    public function testAnnotationsBundleMappingDetectionWithVendorNamespace()
655
    {
656
        $container = $this->getContainer('AnnotationsBundle', 'Vendor');
657
        $extension = new DoctrineExtension();
658
659
        $config = BundleConfigurationBuilder::createBuilder()
660
            ->addBaseConnection()
661
            ->addEntityManager([
662
                'default_entity_manager' => 'default',
663
                'entity_managers' => [
664
                    'default' => [
665
                        'mappings' => [
666
                            'AnnotationsBundle' => [],
667
                        ],
668
                    ],
669
                ],
670
            ])
671
            ->build();
672
        $extension->load([$config], $container);
673
674
        $calls = $container->getDefinition('doctrine.orm.default_metadata_driver')->getMethodCalls();
675
        $this->assertEquals('doctrine.orm.default_annotation_metadata_driver', (string) $calls[0][1][0]);
676
        $this->assertEquals('Fixtures\Bundles\Vendor\AnnotationsBundle\Entity', $calls[0][1][1]);
677
    }
678
679
    public function testCacheConfiguration()
680
    {
681
        $container = $this->getContainer();
682
        $extension = new DoctrineExtension();
683
684
        $config = BundleConfigurationBuilder::createBuilder()
685
             ->addBaseConnection()
686
             ->addEntityManager([
687
                 'metadata_cache_driver' => ['cache_provider' => 'metadata_cache'],
688
                 'query_cache_driver' => ['cache_provider' => 'query_cache'],
689
                 'result_cache_driver' => ['cache_provider' => 'result_cache'],
690
             ])
691
            ->build();
692
693
        $extension->load([$config], $container);
694
695
        $this->assertTrue($container->hasAlias('doctrine.orm.default_metadata_cache'));
696
        $alias = $container->getAlias('doctrine.orm.default_metadata_cache');
697
        $this->assertEquals('doctrine_cache.providers.metadata_cache', (string) $alias);
698
699
        $this->assertTrue($container->hasAlias('doctrine.orm.default_query_cache'));
700
        $alias = $container->getAlias('doctrine.orm.default_query_cache');
701
        $this->assertEquals('doctrine_cache.providers.query_cache', (string) $alias);
702
703
        $this->assertTrue($container->hasAlias('doctrine.orm.default_result_cache'));
704
        $alias = $container->getAlias('doctrine.orm.default_result_cache');
705
        $this->assertEquals('doctrine_cache.providers.result_cache', (string) $alias);
706
    }
707
708
    public function testShardManager()
709
    {
710
        $container = $this->getContainer();
711
        $extension = new DoctrineExtension();
712
713
        $config = BundleConfigurationBuilder::createBuilder()
714
             ->addConnection([
715
                 'connections' => [
716
                     'foo' => [
717
                         'shards' => [
718
                             'test' => ['id' => 1],
719
                         ],
720
                     ],
721
                     'bar' => [],
722
                 ],
723
             ])
724
            ->build();
725
726
        $extension->load([$config], $container);
727
728
        $this->assertTrue($container->hasDefinition('doctrine.dbal.foo_shard_manager'));
729
        $this->assertFalse($container->hasDefinition('doctrine.dbal.bar_shard_manager'));
730
    }
731
732
    private function getContainer($bundles = 'YamlBundle', $vendor = null)
733
    {
734
        $bundles = (array) $bundles;
735
736
        $map = [];
737
        foreach ($bundles as $bundle) {
738
            require_once __DIR__ . '/Fixtures/Bundles/' . ($vendor ? $vendor . '/' : '') . $bundle . '/' . $bundle . '.php';
739
740
            $map[$bundle] = 'Fixtures\\Bundles\\' . ($vendor ? $vendor . '\\' : '') . $bundle . '\\' . $bundle;
741
        }
742
743
        return new ContainerBuilder(new ParameterBag([
744
            'kernel.name' => 'app',
745
            'kernel.debug' => false,
746
            'kernel.bundles' => $map,
747
            'kernel.cache_dir' => sys_get_temp_dir(),
748
            'kernel.environment' => 'test',
749
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
750
        ]));
751
    }
752
753
    private function assertDICConstructorArguments(Definition $definition, array $args)
754
    {
755
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
756
    }
757
758 View Code Duplication
    private function assertDICDefinitionMethodCallAt($pos, Definition $definition, $methodName, array $params = null)
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...
759
    {
760
        $calls = $definition->getMethodCalls();
761
        if (! isset($calls[$pos][0])) {
762
            return;
763
        }
764
765
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
766
767
        if ($params === null) {
768
            return;
769
        }
770
771
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
772
    }
773
774
    /**
775
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
776
     *
777
     * @param string     $methodName
778
     * @param array|null $params
779
     */
780 View Code Duplication
    private function assertDICDefinitionMethodCallOnce(Definition $definition, $methodName, array $params = null)
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...
781
    {
782
        $calls  = $definition->getMethodCalls();
783
        $called = false;
784
        foreach ($calls as $call) {
785
            if ($call[0] !== $methodName) {
786
                continue;
787
            }
788
789
            if ($called) {
790
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
791
            } else {
792
                $called = true;
793
                if ($params !== null) {
794
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
795
                }
796
            }
797
        }
798
        if ($called) {
799
            return;
800
        }
801
802
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
803
    }
804
805
    private function compileContainer(ContainerBuilder $container)
806
    {
807
        $container->getCompilerPassConfig()->setOptimizationPasses([class_exists(ResolveChildDefinitionsPass::class) ? new ResolveChildDefinitionsPass() : new ResolveDefinitionTemplatesPass()]);
0 ignored issues
show
Documentation introduced by
array(class_exists(\Symf...initionTemplatesPass()) is of type array<integer,object<Sym...nitionTemplatesPass>"}>, but the function expects a array<integer,object<Sym...CompilerPassInterface>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
808
        $container->getCompilerPassConfig()->setRemovingPasses([]);
809
        $container->compile();
810
    }
811
}
812
813
class TestWrapperClass extends Connection
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
814
{
815
}
816