Completed
Pull Request — master (#972)
by
unknown
01:58
created

testEventSubscriberAutoConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 9.536
c 0
b 0
f 0
cc 1
nc 1
nop 0
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\EventSubscriber;
8
use Doctrine\Common\Persistence\ManagerRegistry;
9
use Doctrine\Common\Persistence\ObjectManager;
10
use Doctrine\Common\Proxy\AbstractProxyFactory;
11
use Doctrine\DBAL\Connection;
12
use Doctrine\DBAL\Driver\Connection as DriverConnection;
13
use Doctrine\ORM\EntityManagerInterface;
14
use PHPUnit\Framework\TestCase;
15
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Definition;
18
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
19
use Symfony\Component\DependencyInjection\Reference;
20
use Symfony\Component\Messenger\MessageBusInterface;
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
        $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...
150
            'YamlBundle',
151
            'XmlBundle',
152
        ]);
153
154
        $extension->load(
155
            [
156
                [
157
                    'dbal' => [
158
                        'default_connection' => 'cn1',
159
                        'connections' => [
160
                            'cn1' => [],
161
                            'cn2' => [],
162
                        ],
163
                    ],
164
                    'orm' => ['entity_managers' => $entityManagers],
165
                ],
166
            ],
167
            $container
168
        );
169
170
        $configEm1 = $container->getDefinition('doctrine.orm.em1_configuration');
171
        $configEm2 = $container->getDefinition('doctrine.orm.em2_configuration');
172
173
        $this->assertContains(
174
            [
175
                'setEntityNamespaces',
176
                [
177
                    ['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'],
178
                ],
179
            ],
180
            $configEm1->getMethodCalls()
181
        );
182
183
        $this->assertContains(
184
            [
185
                'setEntityNamespaces',
186
                [
187
                    ['XmlBundle' => 'Fixtures\Bundles\XmlBundle\Entity'],
188
                ],
189
            ],
190
            $configEm2->getMethodCalls()
191
        );
192
    }
193
194
    public function testDbalLoad()
195
    {
196
        $container = $this->getContainer();
197
        $extension = new DoctrineExtension();
198
199
        $extension->load([
200
            ['dbal' => ['connections' => ['default' => ['password' => 'foo']]]],
201
            [],
202
            ['dbal' => ['default_connection' => 'foo']],
203
            [],
204
        ], $container);
205
206
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
207
208
        $this->assertEquals('foo', $config['password']);
209
        $this->assertEquals('root', $config['user']);
210
    }
211
212
    public function testDbalWrapperClass()
213
    {
214
        $container = $this->getContainer();
215
        $extension = new DoctrineExtension();
216
217
        $extension->load(
218
            [
219
                [
220
                    'dbal' => [
221
                        'connections' => [
222
                            'default' => ['password' => 'foo', 'wrapper_class' => TestWrapperClass::class],
223
                            'second' => ['password' => 'boo'],
224
                        ],
225
                    ],
226
                ],
227
                [],
228
                ['dbal' => ['default_connection' => 'foo']],
229
                [],
230
            ],
231
            $container
232
        );
233
234
        $this->assertEquals(TestWrapperClass::class, $container->getDefinition('doctrine.dbal.default_connection')->getClass());
235
        $this->assertNull($container->getDefinition('doctrine.dbal.second_connection')->getClass());
236
    }
237
238
    public function testDependencyInjectionConfigurationDefaults()
239
    {
240
        $container = $this->getContainer();
241
        $extension = new DoctrineExtension();
242
        $config    = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
243
244
        $extension->load([$config], $container);
245
246
        $this->assertFalse($container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
247
        $this->assertEquals('Doctrine\ORM\Configuration', $container->getParameter('doctrine.orm.configuration.class'));
248
        $this->assertEquals('Doctrine\ORM\EntityManager', $container->getParameter('doctrine.orm.entity_manager.class'));
249
        $this->assertEquals('Proxies', $container->getParameter('doctrine.orm.proxy_namespace'));
250
        $this->assertEquals('Doctrine\Common\Cache\ArrayCache', $container->getParameter('doctrine.orm.cache.array.class'));
251
        $this->assertEquals('Doctrine\Common\Cache\ApcCache', $container->getParameter('doctrine.orm.cache.apc.class'));
252
        $this->assertEquals('Doctrine\Common\Cache\MemcacheCache', $container->getParameter('doctrine.orm.cache.memcache.class'));
253
        $this->assertEquals('localhost', $container->getParameter('doctrine.orm.cache.memcache_host'));
254
        $this->assertEquals('11211', $container->getParameter('doctrine.orm.cache.memcache_port'));
255
        $this->assertEquals('Memcache', $container->getParameter('doctrine.orm.cache.memcache_instance.class'));
256
        $this->assertEquals('Doctrine\Common\Cache\XcacheCache', $container->getParameter('doctrine.orm.cache.xcache.class'));
257
        $this->assertEquals('Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain', $container->getParameter('doctrine.orm.metadata.driver_chain.class'));
258
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\AnnotationDriver', $container->getParameter('doctrine.orm.metadata.annotation.class'));
259
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver', $container->getParameter('doctrine.orm.metadata.xml.class'));
260
        $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver', $container->getParameter('doctrine.orm.metadata.yml.class'));
261
262
        // second-level cache
263
        $this->assertEquals('Doctrine\ORM\Cache\DefaultCacheFactory', $container->getParameter('doctrine.orm.second_level_cache.default_cache_factory.class'));
264
        $this->assertEquals('Doctrine\ORM\Cache\Region\DefaultRegion', $container->getParameter('doctrine.orm.second_level_cache.default_region.class'));
265
        $this->assertEquals('Doctrine\ORM\Cache\Region\FileLockRegion', $container->getParameter('doctrine.orm.second_level_cache.filelock_region.class'));
266
        $this->assertEquals('Doctrine\ORM\Cache\Logging\CacheLoggerChain', $container->getParameter('doctrine.orm.second_level_cache.logger_chain.class'));
267
        $this->assertEquals('Doctrine\ORM\Cache\Logging\StatisticsCacheLogger', $container->getParameter('doctrine.orm.second_level_cache.logger_statistics.class'));
268
        $this->assertEquals('Doctrine\ORM\Cache\CacheConfiguration', $container->getParameter('doctrine.orm.second_level_cache.cache_configuration.class'));
269
        $this->assertEquals('Doctrine\ORM\Cache\RegionsConfiguration', $container->getParameter('doctrine.orm.second_level_cache.regions_configuration.class'));
270
271
        $config = BundleConfigurationBuilder::createBuilder()
272
            ->addBaseConnection()
273
            ->addEntityManager([
274
                'proxy_namespace' => 'MyProxies',
275
                'auto_generate_proxy_classes' => true,
276
                'default_entity_manager' => 'default',
277
                'entity_managers' => [
278
                    'default' => [
279
                        'mappings' => ['YamlBundle' => []],
280
                    ],
281
                ],
282
            ])
283
            ->build();
284
285
        $container = $this->getContainer();
286
        $extension->load([$config], $container);
287
        $this->compileContainer($container);
288
289
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
290
291
        $args = $definition->getArguments();
292
        $this->assertEquals('pdo_mysql', $args[0]['driver']);
293
        $this->assertEquals('localhost', $args[0]['host']);
294
        $this->assertEquals('root', $args[0]['user']);
295
        $this->assertEquals('doctrine.dbal.default_connection.configuration', (string) $args[1]);
296
        $this->assertEquals('doctrine.dbal.default_connection.event_manager', (string) $args[2]);
297
        $this->assertCount(0, $definition->getMethodCalls());
0 ignored issues
show
Documentation introduced by
$definition->getMethodCalls() is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

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...
298
299
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
300
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
301
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
302
303
        $this->assertEquals(['default' => 'doctrine.orm.default_entity_manager'], $container->getParameter('doctrine.entity_managers'), 'Set of the existing EntityManagers names is incorrect.');
304
        $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');
305
306
        $arguments = $definition->getArguments();
307
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
308
        $this->assertEquals('doctrine.dbal.default_connection', (string) $arguments[0]);
309
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
310
        $this->assertEquals('doctrine.orm.default_configuration', (string) $arguments[1]);
311
312
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
313
        $calls      = array_values($definition->getMethodCalls());
314
        $this->assertEquals(['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'], $calls[0][1][0]);
315
        $this->assertEquals('doctrine.orm.default_metadata_cache', (string) $calls[1][1][0]);
316
        $this->assertEquals('doctrine.orm.default_query_cache', (string) $calls[2][1][0]);
317
        $this->assertEquals('doctrine.orm.default_result_cache', (string) $calls[3][1][0]);
318
319
        $this->assertEquals('doctrine.orm.naming_strategy.default', (string) $calls[10][1][0]);
320
        $this->assertEquals('doctrine.orm.quote_strategy.default', (string) $calls[11][1][0]);
321
        $this->assertEquals('doctrine.orm.default_entity_listener_resolver', (string) $calls[12][1][0]);
322
323
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
324
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
325
326
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_query_cache'));
327
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
328
329
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_result_cache'));
330
        $this->assertEquals('%doctrine_cache.array.class%', $definition->getClass());
331
    }
332
333
    public function testUseSavePointsAddMethodCallToAddSavepointsToTheConnection()
334
    {
335
        $container = $this->getContainer();
336
        $extension = new DoctrineExtension();
337
338
        $extension->load([[
339
            'dbal' => [
340
                'connections' => [
341
                    'default' => ['password' => 'foo', 'use_savepoints' => true],
342
                ],
343
            ],
344
        ],
345
        ], $container);
346
347
        $calls = $container->getDefinition('doctrine.dbal.default_connection')->getMethodCalls();
348
        $this->assertCount(1, $calls);
0 ignored issues
show
Documentation introduced by
$calls is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

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...
349
        $this->assertEquals('setNestTransactionsWithSavepoints', $calls[0][0]);
350
        $this->assertTrue($calls[0][1][0]);
351
    }
352
353
    public function testAutoGenerateProxyClasses()
354
    {
355
        $container = $this->getContainer();
356
        $extension = new DoctrineExtension();
357
358
        $config = BundleConfigurationBuilder::createBuilder()
359
            ->addBaseConnection()
360
            ->addEntityManager([
361
                'proxy_namespace' => 'MyProxies',
362
                'auto_generate_proxy_classes' => 'eval',
363
                'default_entity_manager' => 'default',
364
                'entity_managers' => [
365
                    'default' => [
366
                        'mappings' => ['YamlBundle' => []],
367
                    ],
368
                ],
369
            ])
370
            ->build();
371
372
        $extension->load([$config], $container);
373
374
        $this->assertEquals(AbstractProxyFactory::AUTOGENERATE_EVAL, $container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
375
    }
376
377
    public function testSingleEntityManagerWithDefaultConfiguration()
378
    {
379
        $container = $this->getContainer();
380
        $extension = new DoctrineExtension();
381
382
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()->build();
383
384
        $extension->load([$configurationArray], $container);
385
        $this->compileContainer($container);
386
387
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
388
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
389
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
390
391
        $this->assertDICConstructorArguments($definition, [
392
            new Reference('doctrine.dbal.default_connection'),
393
            new Reference('doctrine.orm.default_configuration'),
394
        ]);
395
    }
396
397
    public function testSingleEntityManagerWithDefaultSecondLevelCacheConfiguration()
398
    {
399
        $container = $this->getContainer();
400
        $extension = new DoctrineExtension();
401
402
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
403
            ->addBaseSecondLevelCache()
404
            ->build();
405
406
        $extension->load([$configurationArray], $container);
407
        $this->compileContainer($container);
408
409
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
410
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
411
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
412
413
        $this->assertDICConstructorArguments($definition, [
414
            new Reference('doctrine.dbal.default_connection'),
415
            new Reference('doctrine.orm.default_configuration'),
416
        ]);
417
418
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
419
        $this->assertEquals('%doctrine.orm.second_level_cache.default_cache_factory.class%', $slcDefinition->getClass());
420
    }
421
422
    public function testSingleEntityManagerWithCustomSecondLevelCacheConfiguration()
423
    {
424
        $container = $this->getContainer();
425
        $extension = new DoctrineExtension();
426
427
        $configurationArray = BundleConfigurationBuilder::createBuilderWithBaseValues()
428
            ->addSecondLevelCache([
429
                'region_cache_driver' => ['type' => 'memcache'],
430
                'regions' => [
431
                    'hour_region' => ['lifetime' => 3600],
432
                ],
433
                'factory' => 'YamlBundle\Cache\MyCacheFactory',
434
            ])
435
            ->build();
436
437
        $extension->load([$configurationArray], $container);
438
        $this->compileContainer($container);
439
440
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
441
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
442
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
443
444
        $this->assertDICConstructorArguments($definition, [
445
            new Reference('doctrine.dbal.default_connection'),
446
            new Reference('doctrine.orm.default_configuration'),
447
        ]);
448
449
        $slcDefinition = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
450
        $this->assertEquals('YamlBundle\Cache\MyCacheFactory', $slcDefinition->getClass());
451
    }
452
453 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...
454
    {
455
        $container = $this->getContainer();
456
        $extension = new DoctrineExtension();
457
458
        $config        = BundleConfigurationBuilder::createBuilder()
459
             ->addBaseConnection()
460
             ->build();
461
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => []]]]];
462
        $extension->load([$config], $container);
463
464
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
465
        $this->assertDICDefinitionMethodCallOnce(
466
            $definition,
467
            'setEntityNamespaces',
468
            [['YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity']]
469
        );
470
    }
471
472 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...
473
    {
474
        $container = $this->getContainer();
475
        $extension = new DoctrineExtension();
476
477
        $config        = BundleConfigurationBuilder::createBuilder()
478
             ->addBaseConnection()
479
             ->build();
480
        $config['orm'] = ['default_entity_manager' => 'default', 'entity_managers' => ['default' => ['mappings' => ['YamlBundle' => ['alias' => 'yml']]]]];
481
        $extension->load([$config], $container);
482
483
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
484
        $this->assertDICDefinitionMethodCallOnce(
485
            $definition,
486
            'setEntityNamespaces',
487
            [['yml' => 'Fixtures\Bundles\YamlBundle\Entity']]
488
        );
489
    }
490
491
    public function testYamlBundleMappingDetection()
492
    {
493
        $container = $this->getContainer('YamlBundle');
494
        $extension = new DoctrineExtension();
495
496
        $config = BundleConfigurationBuilder::createBuilder()
497
            ->addBaseConnection()
498
            ->addBaseEntityManager()
499
            ->build();
500
        $extension->load([$config], $container);
501
502
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
503
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
504
            new Reference('doctrine.orm.default_yml_metadata_driver'),
505
            'Fixtures\Bundles\YamlBundle\Entity',
506
        ]);
507
    }
508
509 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...
510
    {
511
        $container = $this->getContainer('XmlBundle');
512
        $extension = new DoctrineExtension();
513
514
        $config = BundleConfigurationBuilder::createBuilder()
515
            ->addBaseConnection()
516
            ->addEntityManager([
517
                'default_entity_manager' => 'default',
518
                'entity_managers' => [
519
                    'default' => [
520
                        'mappings' => [
521
                            'XmlBundle' => [],
522
                        ],
523
                    ],
524
                ],
525
            ])
526
            ->build();
527
        $extension->load([$config], $container);
528
529
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
530
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
531
            new Reference('doctrine.orm.default_xml_metadata_driver'),
532
            'Fixtures\Bundles\XmlBundle\Entity',
533
        ]);
534
    }
535
536 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...
537
    {
538
        $container = $this->getContainer('AnnotationsBundle');
539
        $extension = new DoctrineExtension();
540
541
        $config = BundleConfigurationBuilder::createBuilder()
542
            ->addBaseConnection()
543
            ->addEntityManager([
544
                'default_entity_manager' => 'default',
545
                'entity_managers' => [
546
                    'default' => [
547
                        'mappings' => [
548
                            'AnnotationsBundle' => [],
549
                        ],
550
                    ],
551
                ],
552
            ])
553
            ->build();
554
        $extension->load([$config], $container);
555
556
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
557
        $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
558
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
559
            'Fixtures\Bundles\AnnotationsBundle\Entity',
560
        ]);
561
    }
562
563
    public function testOrmMergeConfigs()
564
    {
565
        $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...
566
        $extension = new DoctrineExtension();
567
568
        $config1 = BundleConfigurationBuilder::createBuilder()
569
            ->addBaseConnection()
570
            ->addEntityManager([
571
                'auto_generate_proxy_classes' => true,
572
                'default_entity_manager' => 'default',
573
                'entity_managers' => [
574
                    'default' => [
575
                        'mappings' => [
576
                            'AnnotationsBundle' => [],
577
                        ],
578
                    ],
579
                ],
580
            ])
581
            ->build();
582
        $config2 = BundleConfigurationBuilder::createBuilder()
583
            ->addBaseConnection()
584
            ->addEntityManager([
585
                'auto_generate_proxy_classes' => false,
586
                'default_entity_manager' => 'default',
587
                'entity_managers' => [
588
                    'default' => [
589
                        'mappings' => [
590
                            'XmlBundle' => [],
591
                        ],
592
                    ],
593
                ],
594
            ])
595
            ->build();
596
        $extension->load([$config1, $config2], $container);
597
598
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
599
        $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
600
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
601
            'Fixtures\Bundles\AnnotationsBundle\Entity',
602
        ]);
603
        $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
604
            new Reference('doctrine.orm.default_xml_metadata_driver'),
605
            'Fixtures\Bundles\XmlBundle\Entity',
606
        ]);
607
608
        $configDef = $container->getDefinition('doctrine.orm.default_configuration');
609
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setAutoGenerateProxyClasses');
610
611
        $calls = $configDef->getMethodCalls();
612
        foreach ($calls as $call) {
613
            if ($call[0] === 'setAutoGenerateProxyClasses') {
614
                $this->assertFalse($container->getParameterBag()->resolveValue($call[1][0]));
615
                break;
616
            }
617
        }
618
    }
619
620
    public function testAnnotationsBundleMappingDetectionWithVendorNamespace()
621
    {
622
        $container = $this->getContainer('AnnotationsBundle', 'Vendor');
623
        $extension = new DoctrineExtension();
624
625
        $config = BundleConfigurationBuilder::createBuilder()
626
            ->addBaseConnection()
627
            ->addEntityManager([
628
                'default_entity_manager' => 'default',
629
                'entity_managers' => [
630
                    'default' => [
631
                        'mappings' => [
632
                            'AnnotationsBundle' => [],
633
                        ],
634
                    ],
635
                ],
636
            ])
637
            ->build();
638
        $extension->load([$config], $container);
639
640
        $calls = $container->getDefinition('doctrine.orm.default_metadata_driver')->getMethodCalls();
641
        $this->assertEquals('doctrine.orm.default_annotation_metadata_driver', (string) $calls[0][1][0]);
642
        $this->assertEquals('Fixtures\Bundles\Vendor\AnnotationsBundle\Entity', $calls[0][1][1]);
643
    }
644
645
    public function testMessengerIntegration()
646
    {
647
        if (! interface_exists(MessageBusInterface::class)) {
648
            $this->markTestSkipped('Symfony Messenger component is not installed');
649
        }
650
651
        $container = $this->getContainer();
652
        $extension = new DoctrineExtension();
653
654
        $config = BundleConfigurationBuilder::createBuilder()
655
            ->addBaseConnection()
656
            ->addEntityManager([
657
                'default_entity_manager' => 'default',
658
                'entity_managers' => [
659
                    'default' => [],
660
                ],
661
            ])
662
            ->build();
663
        $extension->load([$config], $container);
664
665
        $this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_transaction'));
666
        $this->assertCount(1, $middlewarePrototype->getArguments());
0 ignored issues
show
Documentation introduced by
$middlewarePrototype->getArguments() is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

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...
667
        $this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_ping_connection'));
668
        $this->assertCount(1, $middlewarePrototype->getArguments());
0 ignored issues
show
Documentation introduced by
$middlewarePrototype->getArguments() is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

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...
669
        $this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_close_connection'));
670
        $this->assertCount(1, $middlewarePrototype->getArguments());
0 ignored issues
show
Documentation introduced by
$middlewarePrototype->getArguments() is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

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...
671
    }
672
673
    /**
674
     * @param array|string $cacheConfig
675
     *
676
     * @dataProvider cacheConfigurationProvider
677
     */
678
    public function testCacheConfiguration(string $expectedAliasName, string $expectedAliasTarget, string $cacheName, $cacheConfig) : void
679
    {
680
        $container = $this->getContainer();
681
        $extension = new DoctrineExtension();
682
683
        $config = BundleConfigurationBuilder::createBuilder()
684
            ->addBaseConnection()
685
            ->addEntityManager([$cacheName => $cacheConfig])
686
            ->build();
687
688
        $extension->load([$config], $container);
689
690
        $this->assertTrue($container->hasAlias($expectedAliasName));
691
        $alias = $container->getAlias($expectedAliasName);
692
        $this->assertEquals($expectedAliasTarget, (string) $alias);
693
    }
694
695
    public function testEventSubscriberAutoConfiguration()
696
    {
697
        $container = $this->getContainer();
698
        $extension = new DoctrineExtension();
699
700
        $container->register('foo', EventSubscriber::class)
701
            ->setAutoconfigured(true)
702
            ->setPublic(true);
703
704
        $config = BundleConfigurationBuilder::createBuilder()
705
            ->addBaseConnection()
706
            ->addEntityManager([
707
                'default_entity_manager' => 'default',
708
                'entity_managers' => ['default' => []],
709
            ])
710
            ->build();
711
712
        $extension->load([$config], $container);
713
        $container->compile();
714
715
        $definition = $container->findDefinition('foo');
716
717
        $this->assertTrue($definition->hasTag('doctrine.event_subscriber'), 'Definition should have tag "doctrine.event_subscriber".');
718
    }
719
720
    public static function cacheConfigurationProvider() : array
721
    {
722
        return [
723
            'metadata_cache_provider' => [
724
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
725
                'expectedAliasTarget' => 'doctrine_cache.providers.metadata_cache',
726
                'cacheName' => 'metadata_cache_driver',
727
                'cacheConfig' => ['cache_provider' => 'metadata_cache'],
728
            ],
729
            'query_cache_provider' => [
730
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
731
                'expectedAliasTarget' => 'doctrine_cache.providers.query_cache',
732
                'cacheName' => 'query_cache_driver',
733
                'cacheConfig' => ['cache_provider' => 'query_cache'],
734
            ],
735
            'result_cache_provider' => [
736
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
737
                'expectedAliasTarget' => 'doctrine_cache.providers.result_cache',
738
                'cacheName' => 'result_cache_driver',
739
                'cacheConfig' => ['cache_provider' => 'result_cache'],
740
            ],
741
742
            'metadata_cache_service' => [
743
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
744
                'expectedAliasTarget' => 'service_target_metadata',
745
                'cacheName' => 'metadata_cache_driver',
746
                'cacheConfig' => ['type' => 'service', 'id' => 'service_target_metadata'],
747
            ],
748
            'query_cache_service' => [
749
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
750
                'expectedAliasTarget' => 'service_target_query',
751
                'cacheName' => 'query_cache_driver',
752
                'cacheConfig' => ['type' => 'service', 'id' => 'service_target_query'],
753
            ],
754
            'result_cache_service' => [
755
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
756
                'expectedAliasTarget' => 'service_target_result',
757
                'cacheName' => 'result_cache_driver',
758
                'cacheConfig' => ['type' => 'service', 'id' => 'service_target_result'],
759
            ],
760
761
            'metadata_cache_array' => [
762
                'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
763
                'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_metadata_cache',
764
                'cacheName' => 'metadata_cache_driver',
765
                'cacheConfig' => 'array',
766
            ],
767
            'query_cache_array' => [
768
                'expectedAliasName' => 'doctrine.orm.default_query_cache',
769
                'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_query_cache',
770
                'cacheName' => 'query_cache_driver',
771
                'cacheConfig' => 'array',
772
            ],
773
            'result_cache_array' => [
774
                'expectedAliasName' => 'doctrine.orm.default_result_cache',
775
                'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_result_cache',
776
                'cacheName' => 'result_cache_driver',
777
                'cacheConfig' => 'array',
778
            ],
779
        ];
780
    }
781
782
    public function testShardManager()
783
    {
784
        $container = $this->getContainer();
785
        $extension = new DoctrineExtension();
786
787
        $config = BundleConfigurationBuilder::createBuilder()
788
             ->addConnection([
789
                 'connections' => [
790
                     'foo' => [
791
                         'shards' => [
792
                             'test' => ['id' => 1],
793
                         ],
794
                     ],
795
                     'bar' => [],
796
                 ],
797
             ])
798
            ->build();
799
800
        $extension->load([$config], $container);
801
802
        $this->assertTrue($container->hasDefinition('doctrine.dbal.foo_shard_manager'));
803
        $this->assertFalse($container->hasDefinition('doctrine.dbal.bar_shard_manager'));
804
    }
805
806
    private function getContainer($bundles = 'YamlBundle', $vendor = null)
807
    {
808
        $bundles = (array) $bundles;
809
810
        $map = [];
811
        foreach ($bundles as $bundle) {
812
            require_once __DIR__ . '/Fixtures/Bundles/' . ($vendor ? $vendor . '/' : '') . $bundle . '/' . $bundle . '.php';
813
814
            $map[$bundle] = 'Fixtures\\Bundles\\' . ($vendor ? $vendor . '\\' : '') . $bundle . '\\' . $bundle;
815
        }
816
817
        return new ContainerBuilder(new ParameterBag([
818
            'kernel.name' => 'app',
819
            'kernel.debug' => false,
820
            'kernel.bundles' => $map,
821
            'kernel.cache_dir' => sys_get_temp_dir(),
822
            'kernel.environment' => 'test',
823
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
824
        ]));
825
    }
826
827
    private function assertDICConstructorArguments(Definition $definition, array $args)
828
    {
829
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
830
    }
831
832 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...
833
    {
834
        $calls = $definition->getMethodCalls();
835
        if (! isset($calls[$pos][0])) {
836
            return;
837
        }
838
839
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
840
841
        if ($params === null) {
842
            return;
843
        }
844
845
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
846
    }
847
848
    /**
849
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
850
     *
851
     * @param string     $methodName
852
     * @param array|null $params
853
     */
854 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...
855
    {
856
        $calls  = $definition->getMethodCalls();
857
        $called = false;
858
        foreach ($calls as $call) {
859
            if ($call[0] !== $methodName) {
860
                continue;
861
            }
862
863
            if ($called) {
864
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
865
            } else {
866
                $called = true;
867
                if ($params !== null) {
868
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
869
                }
870
            }
871
        }
872
        if ($called) {
873
            return;
874
        }
875
876
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
877
    }
878
879
    private function compileContainer(ContainerBuilder $container)
880
    {
881
        $container->getCompilerPassConfig()->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
882
        $container->getCompilerPassConfig()->setRemovingPasses([]);
883
        $container->compile();
884
    }
885
}
886
887
class TestWrapperClass extends Connection
888
{
889
}
890