Completed
Push — master ( baba12...502b0f )
by Andreas
08:34
created

AbstractDoctrineExtensionTest   F

Complexity

Total Complexity 69

Size/Duplication

Total Lines 1148
Duplicated Lines 9.93 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
wmc 69
lcom 1
cbo 13
dl 114
loc 1148
rs 1.888
c 0
b 0
f 0

51 Methods

Rating   Name   Duplication   Size   Complexity  
A testEntityManagerRedisMetadataCacheDriverConfigurationWithDatabaseKey() 15 17 1
A testDependencyInjectionImportsOverrideDefaults() 0 10 1
A testSingleEntityManagerMultipleMappingBundleDefinitions() 0 37 1
A testMultipleEntityManagersMappingBundleDefinitions() 0 41 1
A testSingleEntityManagerDefaultTableOptions() 0 18 1
A testSetTypes() 0 10 1
A testSetCustomFunctions() 0 9 1
loadFromFile() 0 1 ?
B testDbalLoadFromXmlMultipleConnections() 0 66 1
A testDbalLoadFromXmlSingleConnections() 0 13 1
A testDbalLoadSingleMasterSlaveConnection() 0 33 1
A testDbalLoadPoolShardingConnection() 0 34 1
A testDbalLoadSavepointsForNestedTransactions() 0 15 1
A testLoadSimpleSingleConnection() 0 31 1
A testLoadSimpleSingleConnectionWithoutDbName() 0 34 1
A testLoadSingleConnection() 0 35 1
B testLoadMultipleConnections() 0 59 1
A testLoadLogging() 0 19 1
A testEntityManagerMetadataCacheDriverConfiguration() 0 10 1
A testEntityManagerMemcacheMetadataCacheDriverConfiguration() 16 19 1
A testSetNamingStrategy() 10 10 1
A testSetQuoteStrategy() 10 10 1
B testSecondLevelCache() 0 57 1
A testSingleEMSetCustomFunctions() 0 7 1
A testAddCustomHydrationMode() 0 7 1
A testAddFilter() 0 19 1
A testResolveTargetEntity() 0 9 1
B testAttachEntityListeners() 0 70 1
A testDbalAutoCommit() 0 7 1
A testDbalOracleConnectstring() 0 7 1
A testDbalOracleInstancename() 0 7 1
A testDbalSchemaFilter() 0 11 2
A testDbalSchemaFilterNewConfig() 0 45 3
A testEntityListenerResolver() 0 16 1
A testAttachEntityListenerTag() 0 31 1
A testAttachEntityListenersTwoConnections() 0 19 1
A testAttachLazyEntityListener() 0 26 1
A testAttachLazyEntityListenerForCustomResolver() 0 17 1
A testLazyEntityListenerResolverWithoutCorrectInterface() 11 11 1
A testPrivateLazyEntityListener() 0 13 1
A testAbstractLazyEntityListener() 11 11 1
A testRepositoryFactory() 0 7 1
A loadContainer() 0 15 2
A getContainer() 0 27 2
A assertDICDefinitionClass() 0 4 1
A assertDICConstructorArguments() 0 4 1
A assertDICDefinitionMethodCallAt() 17 17 3
B assertDICDefinitionMethodCallOnce() 24 24 6
A assertDICDefinitionMethodCallCount() 0 21 5
A assertDICDefinitionNoMethodCall() 0 15 4
A compileContainer() 0 6 1

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 AbstractDoctrineExtensionTest 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 AbstractDoctrineExtensionTest, 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\Compiler\DbalSchemaFilterPass;
6
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
7
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension;
8
use Doctrine\DBAL\Configuration;
9
use Doctrine\DBAL\Schema\AbstractAsset;
10
use Doctrine\ORM\EntityManager;
11
use PHPUnit\Framework\TestCase;
12
use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass;
13
use Symfony\Component\Cache\Adapter\ArrayAdapter;
14
use Symfony\Component\Cache\DoctrineProvider;
15
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
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
use Symfony\Component\DependencyInjection\ServiceLocator;
22
23
abstract class AbstractDoctrineExtensionTest extends TestCase
24
{
25
    abstract protected function loadFromFile(ContainerBuilder $container, $file);
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
26
27
    public function testDbalLoadFromXmlMultipleConnections()
28
    {
29
        $container = $this->loadContainer('dbal_service_multiple_connections');
30
31
        // doctrine.dbal.mysql_connection
32
        $config = $container->getDefinition('doctrine.dbal.mysql_connection')->getArgument(0);
33
34
        $this->assertEquals('mysql_s3cr3t', $config['password']);
35
        $this->assertEquals('mysql_user', $config['user']);
36
        $this->assertEquals('mysql_db', $config['dbname']);
37
        $this->assertEquals('/path/to/mysqld.sock', $config['unix_socket']);
38
39
        // doctrine.dbal.sqlite_connection
40
        $config = $container->getDefinition('doctrine.dbal.sqlite_connection')->getArgument(0);
41
        $this->assertSame('pdo_sqlite', $config['driver']);
42
        $this->assertSame('sqlite_db', $config['dbname']);
43
        $this->assertSame('sqlite_user', $config['user']);
44
        $this->assertSame('sqlite_s3cr3t', $config['password']);
45
        $this->assertSame('/tmp/db.sqlite', $config['path']);
46
        $this->assertTrue($config['memory']);
47
48
        // doctrine.dbal.oci8_connection
49
        $config = $container->getDefinition('doctrine.dbal.oci_connection')->getArgument(0);
50
        $this->assertSame('oci8', $config['driver']);
51
        $this->assertSame('oracle_db', $config['dbname']);
52
        $this->assertSame('oracle_user', $config['user']);
53
        $this->assertSame('oracle_s3cr3t', $config['password']);
54
        $this->assertSame('oracle_service', $config['servicename']);
55
        $this->assertTrue($config['service']);
56
        $this->assertTrue($config['pooled']);
57
        $this->assertSame('utf8', $config['charset']);
58
59
        // doctrine.dbal.ibmdb2_connection
60
        $config = $container->getDefinition('doctrine.dbal.ibmdb2_connection')->getArgument(0);
61
        $this->assertSame('ibm_db2', $config['driver']);
62
        $this->assertSame('ibmdb2_db', $config['dbname']);
63
        $this->assertSame('ibmdb2_user', $config['user']);
64
        $this->assertSame('ibmdb2_s3cr3t', $config['password']);
65
        $this->assertSame('TCPIP', $config['protocol']);
66
67
        // doctrine.dbal.pgsql_connection
68
        $config = $container->getDefinition('doctrine.dbal.pgsql_connection')->getArgument(0);
69
        $this->assertSame('pdo_pgsql', $config['driver']);
70
        $this->assertSame('pgsql_schema', $config['dbname']);
71
        $this->assertSame('pgsql_user', $config['user']);
72
        $this->assertSame('pgsql_s3cr3t', $config['password']);
73
        $this->assertSame('pgsql_db', $config['default_dbname']);
74
        $this->assertSame('require', $config['sslmode']);
75
        $this->assertSame('postgresql-ca.pem', $config['sslrootcert']);
76
        $this->assertSame('postgresql-cert.pem', $config['sslcert']);
77
        $this->assertSame('postgresql-key.pem', $config['sslkey']);
78
        $this->assertSame('postgresql.crl', $config['sslcrl']);
79
        $this->assertSame('utf8', $config['charset']);
80
81
        // doctrine.dbal.sqlanywhere_connection
82
        $config = $container->getDefinition('doctrine.dbal.sqlanywhere_connection')->getArgument(0);
83
        $this->assertSame('sqlanywhere', $config['driver']);
84
        $this->assertSame('localhost', $config['host']);
85
        $this->assertSame(2683, $config['port']);
86
        $this->assertSame('sqlanywhere_server', $config['server']);
87
        $this->assertSame('sqlanywhere_db', $config['dbname']);
88
        $this->assertSame('sqlanywhere_user', $config['user']);
89
        $this->assertSame('sqlanywhere_s3cr3t', $config['password']);
90
        $this->assertTrue($config['persistent']);
91
        $this->assertSame('utf8', $config['charset']);
92
    }
93
94
    public function testDbalLoadFromXmlSingleConnections()
95
    {
96
        $container = $this->loadContainer('dbal_service_single_connection');
97
98
        // doctrine.dbal.mysql_connection
99
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
100
101
        $this->assertEquals('mysql_s3cr3t', $config['password']);
102
        $this->assertEquals('mysql_user', $config['user']);
103
        $this->assertEquals('mysql_db', $config['dbname']);
104
        $this->assertEquals('/path/to/mysqld.sock', $config['unix_socket']);
105
        $this->assertEquals('5.6.20', $config['serverVersion']);
106
    }
107
108
    public function testDbalLoadSingleMasterSlaveConnection()
109
    {
110
        $container = $this->loadContainer('dbal_service_single_master_slave_connection');
111
112
        // doctrine.dbal.mysql_connection
113
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
114
115
        $this->assertEquals('Doctrine\\DBAL\\Connections\\MasterSlaveConnection', $param['wrapperClass']);
116
        $this->assertTrue($param['keepSlave']);
117
        $this->assertEquals(
118
            [
119
                'user' => 'mysql_user',
120
                'password' => 'mysql_s3cr3t',
121
                'port' => null,
122
                'dbname' => 'mysql_db',
123
                'host' => 'localhost',
124
                'unix_socket' => '/path/to/mysqld.sock',
125
            ],
126
            $param['master']
127
        );
128
        $this->assertEquals(
129
            [
130
                'user' => 'slave_user',
131
                'password' => 'slave_s3cr3t',
132
                'port' => null,
133
                'dbname' => 'slave_db',
134
                'host' => 'localhost',
135
                'unix_socket' => '/path/to/mysqld_slave.sock',
136
            ],
137
            $param['slaves']['slave1']
138
        );
139
        $this->assertEquals(['engine' => 'InnoDB'], $param['defaultTableOptions']);
140
    }
141
142
    public function testDbalLoadPoolShardingConnection()
143
    {
144
        $container = $this->loadContainer('dbal_service_pool_sharding_connection');
145
146
        // doctrine.dbal.mysql_connection
147
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
148
149
        $this->assertEquals('Doctrine\\DBAL\\Sharding\\PoolingShardConnection', $param['wrapperClass']);
150
        $this->assertEquals(new Reference('foo.shard_choser'), $param['shardChoser']);
151
        $this->assertEquals(
152
            [
153
                'user' => 'mysql_user',
154
                'password' => 'mysql_s3cr3t',
155
                'port' => null,
156
                'dbname' => 'mysql_db',
157
                'host' => 'localhost',
158
                'unix_socket' => '/path/to/mysqld.sock',
159
            ],
160
            $param['global']
161
        );
162
        $this->assertEquals(
163
            [
164
                'user' => 'shard_user',
165
                'password' => 'shard_s3cr3t',
166
                'port' => null,
167
                'dbname' => 'shard_db',
168
                'host' => 'localhost',
169
                'unix_socket' => '/path/to/mysqld_shard.sock',
170
                'id' => 1,
171
            ],
172
            $param['shards'][0]
173
        );
174
        $this->assertEquals(['engine' => 'InnoDB'], $param['defaultTableOptions']);
175
    }
176
177
    public function testDbalLoadSavepointsForNestedTransactions()
178
    {
179
        $container = $this->loadContainer('dbal_savepoints');
180
181
        $calls = $container->getDefinition('doctrine.dbal.savepoints_connection')->getMethodCalls();
182
        $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...
183
        $this->assertEquals('setNestTransactionsWithSavepoints', $calls[0][0]);
184
        $this->assertTrue($calls[0][1][0]);
185
186
        $calls = $container->getDefinition('doctrine.dbal.nosavepoints_connection')->getMethodCalls();
187
        $this->assertCount(0, $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...
188
189
        $calls = $container->getDefinition('doctrine.dbal.notset_connection')->getMethodCalls();
190
        $this->assertCount(0, $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...
191
    }
192
193
    public function testLoadSimpleSingleConnection()
194
    {
195
        $container = $this->loadContainer('orm_service_simple_single_entity_manager');
196
197
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
198
199
        $this->assertDICConstructorArguments($definition, [
200
            [
201
                'dbname' => 'db',
202
                'host' => 'localhost',
203
                'port' => null,
204
                'user' => 'root',
205
                'password' => null,
206
                'driver' => 'pdo_mysql',
207
                'driverOptions' => [],
208
                'defaultTableOptions' => [],
209
            ],
210
            new Reference('doctrine.dbal.default_connection.configuration'),
211
            new Reference('doctrine.dbal.default_connection.event_manager'),
212
            [],
213
        ]);
214
215
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
216
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
217
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
218
219
        $this->assertDICConstructorArguments($definition, [
220
            new Reference('doctrine.dbal.default_connection'),
221
            new Reference('doctrine.orm.default_configuration'),
222
        ]);
223
    }
224
225
    /**
226
     * The PDO driver doesn't require a database name to be to set when connecting to a database server
227
     */
228
    public function testLoadSimpleSingleConnectionWithoutDbName()
229
    {
230
        $container = $this->loadContainer('orm_service_simple_single_entity_manager_without_dbname');
231
232
        /** @var Definition $definition */
233
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
234
235
        $this->assertDICConstructorArguments($definition, [
236
            [
237
                'host' => 'localhost',
238
                'port' => null,
239
                'user' => 'root',
240
                'password' => null,
241
                'driver' => 'pdo_mysql',
242
                'driverOptions' => [],
243
                'defaultTableOptions' => [],
244
            ],
245
            new Reference('doctrine.dbal.default_connection.configuration'),
246
            new Reference('doctrine.dbal.default_connection.event_manager'),
247
            [],
248
        ]);
249
250
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
251
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
252
        $factory = $definition->getFactory();
253
254
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $factory[0]);
255
        $this->assertEquals('create', $factory[1]);
256
257
        $this->assertDICConstructorArguments($definition, [
258
            new Reference('doctrine.dbal.default_connection'),
259
            new Reference('doctrine.orm.default_configuration'),
260
        ]);
261
    }
262
263
    public function testLoadSingleConnection()
264
    {
265
        $container = $this->loadContainer('orm_service_single_entity_manager');
266
267
        $definition = $container->getDefinition('doctrine.dbal.default_connection');
268
269
        $this->assertDICConstructorArguments($definition, [
270
            [
271
                'host' => 'localhost',
272
                'driver' => 'pdo_sqlite',
273
                'driverOptions' => [],
274
                'user' => 'sqlite_user',
275
                'port' => null,
276
                'password' => 'sqlite_s3cr3t',
277
                'dbname' => 'sqlite_db',
278
                'memory' => true,
279
                'defaultTableOptions' => [],
280
            ],
281
            new Reference('doctrine.dbal.default_connection.configuration'),
282
            new Reference('doctrine.dbal.default_connection.event_manager'),
283
            [],
284
        ]);
285
286
        $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
287
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
288
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
289
290
        $this->assertDICConstructorArguments($definition, [
291
            new Reference('doctrine.dbal.default_connection'),
292
            new Reference('doctrine.orm.default_configuration'),
293
        ]);
294
295
        $configDef = $container->getDefinition('doctrine.orm.default_configuration');
296
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setDefaultRepositoryClassName', ['Acme\Doctrine\Repository']);
297
    }
298
299
    public function testLoadMultipleConnections()
300
    {
301
        $container = $this->loadContainer('orm_service_multiple_entity_managers');
302
303
        $definition = $container->getDefinition('doctrine.dbal.conn1_connection');
304
305
        $args = $definition->getArguments();
306
        $this->assertEquals('pdo_sqlite', $args[0]['driver']);
307
        $this->assertEquals('localhost', $args[0]['host']);
308
        $this->assertEquals('sqlite_user', $args[0]['user']);
309
        $this->assertEquals('doctrine.dbal.conn1_connection.configuration', (string) $args[1]);
310
        $this->assertEquals('doctrine.dbal.conn1_connection.event_manager', (string) $args[2]);
311
312
        $this->assertEquals('doctrine.orm.em2_entity_manager', (string) $container->getAlias('doctrine.orm.entity_manager'));
313
314
        $definition = $container->getDefinition('doctrine.orm.em1_entity_manager');
315
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
316
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
317
318
        $arguments = $definition->getArguments();
319
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
320
        $this->assertEquals('doctrine.dbal.conn1_connection', (string) $arguments[0]);
321
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
322
        $this->assertEquals('doctrine.orm.em1_configuration', (string) $arguments[1]);
323
324
        $definition = $container->getDefinition('doctrine.dbal.conn2_connection');
325
326
        $args = $definition->getArguments();
327
        $this->assertEquals('pdo_sqlite', $args[0]['driver']);
328
        $this->assertEquals('localhost', $args[0]['host']);
329
        $this->assertEquals('sqlite_user', $args[0]['user']);
330
        $this->assertEquals('doctrine.dbal.conn2_connection.configuration', (string) $args[1]);
331
        $this->assertEquals('doctrine.dbal.conn2_connection.event_manager', (string) $args[2]);
332
333
        $definition = $container->getDefinition('doctrine.orm.em2_entity_manager');
334
        $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
335
        $this->assertEquals(['%doctrine.orm.entity_manager.class%', 'create'], $definition->getFactory());
336
337
        $arguments = $definition->getArguments();
338
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
339
        $this->assertEquals('doctrine.dbal.conn2_connection', (string) $arguments[0]);
340
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]);
341
        $this->assertEquals('doctrine.orm.em2_configuration', (string) $arguments[1]);
342
343
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_metadata_cache'));
344
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
345
346
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_query_cache'));
347
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
348
        $arguments = $definition->getArguments();
349
        $this->assertInstanceOf(Reference::class, $arguments[0]);
350
        $this->assertEquals('cache.app', (string) $arguments[0]);
351
352
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_result_cache'));
353
        $this->assertEquals(DoctrineProvider::class, $definition->getClass());
354
        $arguments = $definition->getArguments();
355
        $this->assertInstanceOf(Reference::class, $arguments[0]);
356
        $this->assertEquals('cache.app', (string) $arguments[0]);
357
    }
358
359
    public function testLoadLogging()
360
    {
361
        $container = $this->loadContainer('dbal_logging');
362
363
        $definition = $container->getDefinition('doctrine.dbal.log_connection.configuration');
364
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger')]);
365
366
        $definition = $container->getDefinition('doctrine.dbal.profile_connection.configuration');
367
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger.profiling.profile')]);
368
369
        $definition = $container->getDefinition('doctrine.dbal.profile_with_backtrace_connection.configuration');
370
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger.backtrace.profile_with_backtrace')]);
371
372
        $definition = $container->getDefinition('doctrine.dbal.backtrace_without_profile_connection.configuration');
373
        $this->assertDICDefinitionNoMethodCall($definition, 'setSQLLogger');
374
375
        $definition = $container->getDefinition('doctrine.dbal.both_connection.configuration');
376
        $this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', [new Reference('doctrine.dbal.logger.chain.both')]);
377
    }
378
379
    public function testEntityManagerMetadataCacheDriverConfiguration()
380
    {
381
        $container = $this->loadContainer('orm_service_multiple_entity_managers');
382
383
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_metadata_cache'));
384
        $this->assertDICDefinitionClass($definition, DoctrineProvider::class);
385
386
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em2_metadata_cache'));
387
        $this->assertDICDefinitionClass($definition, DoctrineProvider::class);
388
    }
389
390
    /**
391
     * @group legacy
392
     */
393 View Code Duplication
    public function testEntityManagerMemcacheMetadataCacheDriverConfiguration()
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...
394
    {
395
        $container = $this->loadContainer('orm_service_simple_single_entity_manager_memcache');
396
397
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
398
        $this->assertDICDefinitionClass($definition, '%doctrine_cache.memcache.class%');
399
        $this->assertDICDefinitionMethodCallOnce(
400
            $definition,
401
            'setMemcache',
402
            [new Reference('doctrine_cache.services.doctrine.orm.default_metadata_cache.connection')]
403
        );
404
405
        $definition = $container->getDefinition('doctrine_cache.services.doctrine.orm.default_metadata_cache.connection');
406
        $this->assertDICDefinitionClass($definition, '%doctrine_cache.memcache.connection.class%');
407
        $this->assertDICDefinitionMethodCallOnce($definition, 'addServer', [
408
            'localhost',
409
            '11211',
410
        ]);
411
    }
412
413
    /**
414
     * @group legacy
415
     */
416 View Code Duplication
    public function testEntityManagerRedisMetadataCacheDriverConfigurationWithDatabaseKey()
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...
417
    {
418
        $container = $this->loadContainer('orm_service_simple_single_entity_manager_redis');
419
420
        $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
421
        $this->assertDICDefinitionClass($definition, '%doctrine_cache.redis.class%');
422
        $this->assertDICDefinitionMethodCallOnce(
423
            $definition,
424
            'setRedis',
425
            [new Reference('doctrine_cache.services.doctrine.orm.default_metadata_cache_redis.connection')]
426
        );
427
428
        $definition = $container->getDefinition('doctrine_cache.services.doctrine.orm.default_metadata_cache_redis.connection');
429
        $this->assertDICDefinitionClass($definition, '%doctrine_cache.redis.connection.class%');
430
        $this->assertDICDefinitionMethodCallOnce($definition, 'connect', ['localhost', '6379']);
431
        $this->assertDICDefinitionMethodCallOnce($definition, 'select', [1]);
432
    }
433
434
    public function testDependencyInjectionImportsOverrideDefaults()
435
    {
436
        $container = $this->loadContainer('orm_imports');
437
438
        $cacheDefinition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
439
        $this->assertEquals(DoctrineProvider::class, $cacheDefinition->getClass());
440
441
        $configDefinition = $container->getDefinition('doctrine.orm.default_configuration');
442
        $this->assertDICDefinitionMethodCallOnce($configDefinition, 'setAutoGenerateProxyClasses', ['%doctrine.orm.auto_generate_proxy_classes%']);
443
    }
444
445
    public function testSingleEntityManagerMultipleMappingBundleDefinitions()
446
    {
447
        $container = $this->loadContainer('orm_single_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
448
449
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
450
451
        $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
452
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
453
            'Fixtures\Bundles\AnnotationsBundle\Entity',
454
        ]);
455
456
        $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
457
            new Reference('doctrine.orm.default_yml_metadata_driver'),
458
            'Fixtures\Bundles\YamlBundle\Entity',
459
        ]);
460
461
        $this->assertDICDefinitionMethodCallAt(2, $definition, 'addDriver', [
462
            new Reference('doctrine.orm.default_xml_metadata_driver'),
463
            'Fixtures\Bundles\XmlBundle',
464
        ]);
465
466
        $annDef = $container->getDefinition('doctrine.orm.default_annotation_metadata_driver');
467
        $this->assertDICConstructorArguments($annDef, [
468
            new Reference('doctrine.orm.metadata.annotation_reader'),
469
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity'],
470
        ]);
471
472
        $ymlDef = $container->getDefinition('doctrine.orm.default_yml_metadata_driver');
473
        $this->assertDICConstructorArguments($ymlDef, [
474
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'YamlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity'],
475
        ]);
476
477
        $xmlDef = $container->getDefinition('doctrine.orm.default_xml_metadata_driver');
478
        $this->assertDICConstructorArguments($xmlDef, [
479
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'XmlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\XmlBundle'],
480
        ]);
481
    }
482
483
    public function testMultipleEntityManagersMappingBundleDefinitions()
484
    {
485
        $container = $this->loadContainer('orm_multiple_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
486
487
        $this->assertEquals(['em1' => 'doctrine.orm.em1_entity_manager', 'em2' => 'doctrine.orm.em2_entity_manager'], $container->getParameter('doctrine.entity_managers'), 'Set of the existing EntityManagers names is incorrect.');
488
        $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');
489
490
        $def1 = $container->getDefinition('doctrine.orm.em1_metadata_driver');
491
        $def2 = $container->getDefinition('doctrine.orm.em2_metadata_driver');
492
493
        $this->assertDICDefinitionMethodCallAt(0, $def1, 'addDriver', [
494
            new Reference('doctrine.orm.em1_annotation_metadata_driver'),
495
            'Fixtures\Bundles\AnnotationsBundle\Entity',
496
        ]);
497
498
        $this->assertDICDefinitionMethodCallAt(0, $def2, 'addDriver', [
499
            new Reference('doctrine.orm.em2_yml_metadata_driver'),
500
            'Fixtures\Bundles\YamlBundle\Entity',
501
        ]);
502
503
        $this->assertDICDefinitionMethodCallAt(1, $def2, 'addDriver', [
504
            new Reference('doctrine.orm.em2_xml_metadata_driver'),
505
            'Fixtures\Bundles\XmlBundle',
506
        ]);
507
508
        $annDef = $container->getDefinition('doctrine.orm.em1_annotation_metadata_driver');
509
        $this->assertDICConstructorArguments($annDef, [
510
            new Reference('doctrine.orm.metadata.annotation_reader'),
511
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity'],
512
        ]);
513
514
        $ymlDef = $container->getDefinition('doctrine.orm.em2_yml_metadata_driver');
515
        $this->assertDICConstructorArguments($ymlDef, [
516
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'YamlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity'],
517
        ]);
518
519
        $xmlDef = $container->getDefinition('doctrine.orm.em2_xml_metadata_driver');
520
        $this->assertDICConstructorArguments($xmlDef, [
521
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'XmlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\XmlBundle'],
522
        ]);
523
    }
524
525
    public function testSingleEntityManagerDefaultTableOptions()
526
    {
527
        $container = $this->loadContainer('orm_single_em_default_table_options', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
528
529
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
530
531
        $this->assertArrayHasKey('defaultTableOptions', $param);
532
533
        $defaults = $param['defaultTableOptions'];
534
535
        $this->assertArrayHasKey('charset', $defaults);
536
        $this->assertArrayHasKey('collate', $defaults);
537
        $this->assertArrayHasKey('engine', $defaults);
538
539
        $this->assertEquals('utf8mb4', $defaults['charset']);
540
        $this->assertEquals('utf8mb4_unicode_ci', $defaults['collate']);
541
        $this->assertEquals('InnoDB', $defaults['engine']);
542
    }
543
544
    public function testSetTypes()
545
    {
546
        $container = $this->loadContainer('dbal_types');
547
548
        $this->assertEquals(
549
            ['test' => ['class' => TestType::class, 'commented' => null]],
550
            $container->getParameter('doctrine.dbal.connection_factory.types')
551
        );
552
        $this->assertEquals('%doctrine.dbal.connection_factory.types%', $container->getDefinition('doctrine.dbal.connection_factory')->getArgument(0));
553
    }
554
555
    public function testSetCustomFunctions()
556
    {
557
        $container = $this->loadContainer('orm_functions');
558
559
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
560
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', ['test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction']);
561
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomNumericFunction', ['test_numeric', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction']);
562
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomDatetimeFunction', ['test_datetime', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction']);
563
    }
564
565 View Code Duplication
    public function testSetNamingStrategy()
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...
566
    {
567
        $container = $this->loadContainer('orm_namingstrategy');
568
569
        $def1 = $container->getDefinition('doctrine.orm.em1_configuration');
570
        $def2 = $container->getDefinition('doctrine.orm.em2_configuration');
571
572
        $this->assertDICDefinitionMethodCallOnce($def1, 'setNamingStrategy', [0 => new Reference('doctrine.orm.naming_strategy.default')]);
573
        $this->assertDICDefinitionMethodCallOnce($def2, 'setNamingStrategy', [0 => new Reference('doctrine.orm.naming_strategy.underscore')]);
574
    }
575
576 View Code Duplication
    public function testSetQuoteStrategy()
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...
577
    {
578
        $container = $this->loadContainer('orm_quotestrategy');
579
580
        $def1 = $container->getDefinition('doctrine.orm.em1_configuration');
581
        $def2 = $container->getDefinition('doctrine.orm.em2_configuration');
582
583
        $this->assertDICDefinitionMethodCallOnce($def1, 'setQuoteStrategy', [0 => new Reference('doctrine.orm.quote_strategy.default')]);
584
        $this->assertDICDefinitionMethodCallOnce($def2, 'setQuoteStrategy', [0 => new Reference('doctrine.orm.quote_strategy.ansi')]);
585
    }
586
587
    public function testSecondLevelCache()
588
    {
589
        $container = $this->loadContainer('orm_second_level_cache');
590
591
        $this->assertTrue($container->has('doctrine.orm.default_configuration'));
592
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.cache_configuration'));
593
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region_cache_driver'));
594
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.regions_configuration'));
595
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.default_cache_factory'));
596
597
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger_chain'));
598
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger_statistics'));
599
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger.my_service_logger1'));
600
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger.my_service_logger2'));
601
602
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_entity_region'));
603
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_service_region'));
604
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_query_region_filelock'));
605
606
        $slcFactoryDef       = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
607
        $myEntityRegionDef   = $container->getDefinition('doctrine.orm.default_second_level_cache.region.my_entity_region');
608
        $loggerChainDef      = $container->getDefinition('doctrine.orm.default_second_level_cache.logger_chain');
609
        $loggerStatisticsDef = $container->getDefinition('doctrine.orm.default_second_level_cache.logger_statistics');
610
        $myQueryRegionDef    = $container->getDefinition('doctrine.orm.default_second_level_cache.region.my_query_region_filelock');
611
        $cacheDriverDef      = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_second_level_cache.region_cache_driver'));
612
        $configDef           = $container->getDefinition('doctrine.orm.default_configuration');
613
        $myEntityRegionArgs  = $myEntityRegionDef->getArguments();
614
        $myQueryRegionArgs   = $myQueryRegionDef->getArguments();
615
        $slcFactoryArgs      = $slcFactoryDef->getArguments();
616
617
        $this->assertDICDefinitionClass($slcFactoryDef, '%doctrine.orm.second_level_cache.default_cache_factory.class%');
618
        $this->assertDICDefinitionClass($myQueryRegionDef, '%doctrine.orm.second_level_cache.filelock_region.class%');
619
        $this->assertDICDefinitionClass($myEntityRegionDef, '%doctrine.orm.second_level_cache.default_region.class%');
620
        $this->assertDICDefinitionClass($loggerChainDef, '%doctrine.orm.second_level_cache.logger_chain.class%');
621
        $this->assertDICDefinitionClass($loggerStatisticsDef, '%doctrine.orm.second_level_cache.logger_statistics.class%');
622
        $this->assertDICDefinitionClass($cacheDriverDef, DoctrineProvider::class);
623
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setSecondLevelCacheConfiguration');
624
        $this->assertDICDefinitionMethodCallCount($slcFactoryDef, 'setRegion', [], 3);
625
        $this->assertDICDefinitionMethodCallCount($loggerChainDef, 'setLogger', [], 3);
626
627
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $slcFactoryArgs[0]);
628
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $slcFactoryArgs[1]);
629
630
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $myEntityRegionArgs[1]);
631
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $myQueryRegionArgs[0]);
632
633
        $this->assertEquals('my_entity_region', $myEntityRegionArgs[0]);
634
        $this->assertEquals('doctrine.orm.default_second_level_cache.region.my_entity_region_driver', $myEntityRegionArgs[1]);
635
        $this->assertEquals(600, $myEntityRegionArgs[2]);
636
637
        $this->assertEquals('doctrine.orm.default_second_level_cache.region.my_query_region', $myQueryRegionArgs[0]);
638
        $this->assertContains('/doctrine/orm/slc/filelock', $myQueryRegionArgs[1]);
639
        $this->assertEquals(60, $myQueryRegionArgs[2]);
640
641
        $this->assertEquals('doctrine.orm.default_second_level_cache.regions_configuration', $slcFactoryArgs[0]);
642
        $this->assertEquals('doctrine.orm.default_second_level_cache.region_cache_driver', $slcFactoryArgs[1]);
643
    }
644
645
    public function testSingleEMSetCustomFunctions()
646
    {
647
        $container = $this->loadContainer('orm_single_em_dql_functions');
648
649
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
650
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', ['test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction']);
651
    }
652
653
    public function testAddCustomHydrationMode()
654
    {
655
        $container = $this->loadContainer('orm_hydration_mode');
656
657
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
658
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomHydrationMode', ['test_hydrator', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator']);
659
    }
660
661
    public function testAddFilter()
662
    {
663
        $container = $this->loadContainer('orm_filters');
664
665
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
666
        $args       = [
667
            ['soft_delete', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter'],
668
            ['myFilter', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter'],
669
        ];
670
        $this->assertDICDefinitionMethodCallCount($definition, 'addFilter', $args, 2);
671
672
        $definition = $container->getDefinition('doctrine.orm.default_manager_configurator');
673
        $this->assertDICConstructorArguments($definition, [['soft_delete', 'myFilter'], ['myFilter' => ['myParameter' => 'myValue', 'mySecondParameter' => 'mySecondValue']]]);
674
675
        // Let's create the instance to check the configurator work.
676
        /** @var EntityManager $entityManager */
677
        $entityManager = $container->get('doctrine.orm.entity_manager');
678
        $this->assertCount(2, $entityManager->getFilters()->getEnabledFilters());
0 ignored issues
show
Documentation introduced by
$entityManager->getFilters()->getEnabledFilters() is of type array<integer,object<Doc...uery\Filter\SQLFilter>>, 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...
679
    }
680
681
    public function testResolveTargetEntity()
682
    {
683
        $container = $this->loadContainer('orm_resolve_target_entity');
684
685
        $definition = $container->getDefinition('doctrine.orm.listeners.resolve_target_entity');
686
        $this->assertDICDefinitionMethodCallOnce($definition, 'addResolveTargetEntity', ['Symfony\Component\Security\Core\User\UserInterface', 'MyUserClass', []]);
687
688
        $this->assertEquals(['doctrine.event_subscriber' => [[]]], $definition->getTags());
689
    }
690
691
    public function testAttachEntityListeners()
692
    {
693
        $container = $this->loadContainer('orm_attach_entity_listener');
694
695
        $definition  = $container->getDefinition('doctrine.orm.default_listeners.attach_entity_listeners');
696
        $methodCalls = $definition->getMethodCalls();
697
698
        $this->assertDICDefinitionMethodCallCount($definition, 'addEntityListener', [], 6);
699
        $this->assertEquals(['doctrine.event_listener' => [ ['event' => 'loadClassMetadata'] ] ], $definition->getTags());
700
701
        $this->assertEquals($methodCalls[0], [
702
            'addEntityListener',
703
            [
704
                'ExternalBundles\Entities\FooEntity',
705
                'MyBundles\Listeners\FooEntityListener',
706
                'prePersist',
707
                null,
708
            ],
709
        ]);
710
711
        $this->assertEquals($methodCalls[1], [
712
            'addEntityListener',
713
            [
714
                'ExternalBundles\Entities\FooEntity',
715
                'MyBundles\Listeners\FooEntityListener',
716
                'postPersist',
717
                'postPersist',
718
            ],
719
        ]);
720
721
        $this->assertEquals($methodCalls[2], [
722
            'addEntityListener',
723
            [
724
                'ExternalBundles\Entities\FooEntity',
725
                'MyBundles\Listeners\FooEntityListener',
726
                'postLoad',
727
                'postLoadHandler',
728
            ],
729
        ]);
730
731
        $this->assertEquals($methodCalls[3], [
732
            'addEntityListener',
733
            [
734
                'ExternalBundles\Entities\BarEntity',
735
                'MyBundles\Listeners\BarEntityListener',
736
                'prePersist',
737
                'prePersist',
738
            ],
739
        ]);
740
741
        $this->assertEquals($methodCalls[4], [
742
            'addEntityListener',
743
            [
744
                'ExternalBundles\Entities\BarEntity',
745
                'MyBundles\Listeners\BarEntityListener',
746
                'prePersist',
747
                'prePersistHandler',
748
            ],
749
        ]);
750
751
        $this->assertEquals($methodCalls[5], [
752
            'addEntityListener',
753
            [
754
                'ExternalBundles\Entities\BarEntity',
755
                'MyBundles\Listeners\LogDeleteEntityListener',
756
                'postDelete',
757
                'postDelete',
758
            ],
759
        ]);
760
    }
761
762
    public function testDbalAutoCommit()
763
    {
764
        $container = $this->loadContainer('dbal_auto_commit');
765
766
        $definition = $container->getDefinition('doctrine.dbal.default_connection.configuration');
767
        $this->assertDICDefinitionMethodCallOnce($definition, 'setAutoCommit', [false]);
768
    }
769
770
    public function testDbalOracleConnectstring()
771
    {
772
        $container = $this->loadContainer('dbal_oracle_connectstring');
773
774
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
775
        $this->assertSame('scott@sales-server:1521/sales.us.example.com', $config['connectstring']);
776
    }
777
778
    public function testDbalOracleInstancename()
779
    {
780
        $container = $this->loadContainer('dbal_oracle_instancename');
781
782
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
783
        $this->assertSame('mySuperInstance', $config['instancename']);
784
    }
785
786
    public function testDbalSchemaFilter()
787
    {
788
        if (method_exists(Configuration::class, 'setSchemaAssetsFilter')) {
789
            $this->markTestSkipped('Test only applies to doctrine/dbal 2.8 or lower');
790
        }
791
792
        $container = $this->loadContainer('dbal_schema_filter');
793
794
        $definition = $container->getDefinition('doctrine.dbal.connection1_connection.configuration');
795
        $this->assertDICDefinitionMethodCallOnce($definition, 'setFilterSchemaAssetsExpression', ['~^(?!t_)~']);
796
    }
797
798
    public function testDbalSchemaFilterNewConfig()
799
    {
800
        if (! method_exists(Configuration::class, 'setSchemaAssetsFilter')) {
801
            $this->markTestSkipped('Test requires doctrine/dbal 2.9 or higher');
802
        }
803
804
        $container = $this->getContainer([]);
805
        $loader    = new DoctrineExtension();
806
        $container->registerExtension($loader);
807
        $container->addCompilerPass(new DbalSchemaFilterPass());
808
809
        // ignore table1 table on "default" connection
810
        $container->register('dummy_filter1', DummySchemaAssetsFilter::class)
811
            ->setArguments(['table1'])
812
            ->addTag('doctrine.dbal.schema_filter');
813
814
        // ignore table2 table on "connection2" connection
815
        $container->register('dummy_filter2', DummySchemaAssetsFilter::class)
816
            ->setArguments(['table2'])
817
            ->addTag('doctrine.dbal.schema_filter', ['connection' => 'connection2']);
818
819
        $this->loadFromFile($container, 'dbal_schema_filter');
820
821
        $assetNames               = ['table1', 'table2', 'table3', 't_ignored'];
822
        $expectedConnectionAssets = [
823
            // ignores table1 + schema_filter applies
824
            'connection1' => ['table2', 'table3'],
825
            // ignores table2, no schema_filter applies
826
            'connection2' => ['table1', 'table3', 't_ignored'],
827
            // connection3 has no ignores, handled separately
828
        ];
829
830
        $this->compileContainer($container);
831
832
        $getConfiguration = static function (string $connectionName) use ($container) : Configuration {
833
            return $container->get(sprintf('doctrine.dbal.%s_connection', $connectionName))->getConfiguration();
834
        };
835
836
        foreach ($expectedConnectionAssets as $connectionName => $expectedTables) {
837
            $connConfig = $getConfiguration($connectionName);
838
            $this->assertSame($expectedTables, array_values(array_filter($assetNames, $connConfig->getSchemaAssetsFilter())), sprintf('Filtering for connection "%s"', $connectionName));
839
        }
840
841
        $this->assertNull($connConfig = $getConfiguration('connection3')->getSchemaAssetsFilter());
842
    }
843
844
    public function testEntityListenerResolver()
845
    {
846
        $container = $this->loadContainer('orm_entity_listener_resolver', ['YamlBundle'], new EntityListenerPass());
847
848
        $definition = $container->getDefinition('doctrine.orm.em1_configuration');
849
        $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityListenerResolver', [new Reference('doctrine.orm.em1_entity_listener_resolver')]);
850
851
        $definition = $container->getDefinition('doctrine.orm.em2_configuration');
852
        $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityListenerResolver', [new Reference('doctrine.orm.em2_entity_listener_resolver')]);
853
854
        $listener = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
855
        $this->assertDICDefinitionMethodCallOnce($listener, 'registerService', ['EntityListener', 'entity_listener1']);
856
857
        $listener = $container->getDefinition('entity_listener_resolver');
858
        $this->assertDICDefinitionMethodCallOnce($listener, 'register', [new Reference('entity_listener2')]);
859
    }
860
861
    public function testAttachEntityListenerTag()
862
    {
863
        $container = $this->getContainer([]);
864
        $loader    = new DoctrineExtension();
865
        $container->registerExtension($loader);
866
        $container->addCompilerPass(new EntityListenerPass());
867
868
        $this->loadFromFile($container, 'orm_attach_entity_listener_tag');
869
870
        $this->compileContainer($container);
871
872
        $listener = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
873
        $this->assertDICDefinitionMethodCallCount($listener, 'registerService', [
874
            ['EntityListener1', 'entity_listener1'],
875
            ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'],
876
            ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'],
877
            ['ParentEntityListener', 'children_entity_listener'],
878
        ], 4);
879
880
        $listener = $container->getDefinition('doctrine.orm.em2_entity_listener_resolver');
881
        $this->assertDICDefinitionMethodCallOnce($listener, 'registerService', ['EntityListener2', 'entity_listener2']);
882
883
        $attachListener = $container->getDefinition('doctrine.orm.em1_listeners.attach_entity_listeners');
884
        $this->assertDICDefinitionMethodCallAt(0, $attachListener, 'addEntityListener', ['My/Entity1', 'EntityListener1', 'postLoad']);
885
        $this->assertDICDefinitionMethodCallAt(1, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'loadClassMetadata', '__invoke']);
886
        $this->assertDICDefinitionMethodCallAt(2, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'postPersist']);
887
        $this->assertDICDefinitionMethodCallAt(3, $attachListener, 'addEntityListener', ['My/Entity3', 'ParentEntityListener', 'postLoad']);
888
889
        $attachListener = $container->getDefinition('doctrine.orm.em2_listeners.attach_entity_listeners');
890
        $this->assertDICDefinitionMethodCallOnce($attachListener, 'addEntityListener', ['My/Entity2', 'EntityListener2', 'preFlush', 'preFlushHandler']);
891
    }
892
893
    public function testAttachEntityListenersTwoConnections()
894
    {
895
        $container = $this->getContainer(['YamlBundle']);
896
        $loader    = new DoctrineExtension();
897
        $container->registerExtension($loader);
898
        $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass('doctrine.connections', 'doctrine.dbal.%s_connection.event_manager', 'doctrine'));
899
900
        $this->loadFromFile($container, 'orm_attach_entity_listeners_two_connections');
901
902
        $this->compileContainer($container);
903
904
        $defaultEventManager = $container->getDefinition('doctrine.dbal.default_connection.event_manager');
905
        $this->assertDICDefinitionNoMethodCall($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]);
906
        $this->assertDICDefinitionMethodCallOnce($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]);
907
908
        $foobarEventManager = $container->getDefinition('doctrine.dbal.foobar_connection.event_manager');
909
        $this->assertDICDefinitionNoMethodCall($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]);
910
        $this->assertDICDefinitionMethodCallOnce($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]);
911
    }
912
913
    public function testAttachLazyEntityListener()
914
    {
915
        $container = $this->getContainer([]);
916
        $loader    = new DoctrineExtension();
917
        $container->registerExtension($loader);
918
        $container->addCompilerPass(new EntityListenerPass());
919
920
        $this->loadFromFile($container, 'orm_attach_lazy_entity_listener');
921
922
        $this->compileContainer($container);
923
924
        $resolver1 = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
925
        $this->assertDICDefinitionMethodCallAt(0, $resolver1, 'registerService', ['EntityListener1', 'entity_listener1']);
926
        $this->assertDICDefinitionMethodCallAt(1, $resolver1, 'register', [new Reference('entity_listener3')]);
927
        $this->assertDICDefinitionMethodCallAt(2, $resolver1, 'registerService', ['EntityListener4', 'entity_listener4']);
928
929
        $serviceLocatorReference = $resolver1->getArgument(0);
930
        $this->assertInstanceOf(Reference::class, $serviceLocatorReference);
931
        $serviceLocatorDefinition = $container->getDefinition((string) $serviceLocatorReference);
932
        $this->assertSame(ServiceLocator::class, $serviceLocatorDefinition->getClass());
933
        $serviceLocatorMap = $serviceLocatorDefinition->getArgument(0);
934
        $this->assertSame(['entity_listener1', 'entity_listener4'], array_keys($serviceLocatorMap));
935
936
        $resolver2 = $container->findDefinition('custom_entity_listener_resolver');
937
        $this->assertDICDefinitionMethodCallOnce($resolver2, 'registerService', ['EntityListener2', 'entity_listener2']);
938
    }
939
940
    public function testAttachLazyEntityListenerForCustomResolver()
941
    {
942
        $container = $this->getContainer([]);
943
        $loader    = new DoctrineExtension();
944
        $container->registerExtension($loader);
945
        $container->addCompilerPass(new EntityListenerPass());
946
947
        $this->loadFromFile($container, 'orm_entity_listener_custom_resolver');
948
949
        $this->compileContainer($container);
950
951
        $resolver = $container->getDefinition('custom_entity_listener_resolver');
952
        $this->assertTrue($resolver->isPublic());
953
        $this->assertEmpty($resolver->getArguments(), 'We must not change the arguments for custom services.');
954
        $this->assertDICDefinitionMethodCallOnce($resolver, 'registerService', ['EntityListener', 'entity_listener']);
955
        $this->assertTrue($container->getDefinition('entity_listener')->isPublic());
956
    }
957
958
    /**
959
     * @expectedException \InvalidArgumentException
960
     * @expectedExceptionMessage EntityListenerServiceResolver
961
     */
962 View Code Duplication
    public function testLazyEntityListenerResolverWithoutCorrectInterface()
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...
963
    {
964
        $container = $this->getContainer([]);
965
        $loader    = new DoctrineExtension();
966
        $container->registerExtension($loader);
967
        $container->addCompilerPass(new EntityListenerPass());
968
969
        $this->loadFromFile($container, 'orm_entity_listener_lazy_resolver_without_interface');
970
971
        $this->compileContainer($container);
972
    }
973
974
    public function testPrivateLazyEntityListener()
975
    {
976
        $container = $this->getContainer([]);
977
        $loader    = new DoctrineExtension();
978
        $container->registerExtension($loader);
979
        $container->addCompilerPass(new EntityListenerPass());
980
981
        $this->loadFromFile($container, 'orm_entity_listener_lazy_private');
982
983
        $this->compileContainer($container);
984
985
        $this->assertTrue($container->getDefinition('doctrine.orm.em1_entity_listener_resolver')->isPublic());
986
    }
987
988
    /**
989
     * @expectedException \InvalidArgumentException
990
     * @expectedExceptionMessageRegExp /The service ".*" must not be abstract as this entity listener is lazy-loaded/
991
     */
992 View Code Duplication
    public function testAbstractLazyEntityListener()
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...
993
    {
994
        $container = $this->getContainer([]);
995
        $loader    = new DoctrineExtension();
996
        $container->registerExtension($loader);
997
        $container->addCompilerPass(new EntityListenerPass());
998
999
        $this->loadFromFile($container, 'orm_entity_listener_lazy_abstract');
1000
1001
        $this->compileContainer($container);
1002
    }
1003
1004
    public function testRepositoryFactory()
1005
    {
1006
        $container = $this->loadContainer('orm_repository_factory');
1007
1008
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
1009
        $this->assertDICDefinitionMethodCallOnce($definition, 'setRepositoryFactory', ['repository_factory']);
1010
    }
1011
1012
    private function loadContainer($fixture, array $bundles = ['YamlBundle'], CompilerPassInterface $compilerPass = null)
1013
    {
1014
        $container = $this->getContainer($bundles);
1015
        $container->registerExtension(new DoctrineExtension());
1016
1017
        $this->loadFromFile($container, $fixture);
1018
1019
        if ($compilerPass !== null) {
1020
            $container->addCompilerPass($compilerPass);
1021
        }
1022
1023
        $this->compileContainer($container);
1024
1025
        return $container;
1026
    }
1027
1028
    private function getContainer(array $bundles)
1029
    {
1030
        $map = [];
1031
        foreach ($bundles as $bundle) {
1032
            require_once __DIR__ . '/Fixtures/Bundles/' . $bundle . '/' . $bundle . '.php';
1033
1034
            $map[$bundle] = 'Fixtures\\Bundles\\' . $bundle . '\\' . $bundle;
1035
        }
1036
1037
        $container = new ContainerBuilder(new ParameterBag([
1038
            'kernel.name' => 'app',
1039
            'kernel.debug' => false,
1040
            'kernel.bundles' => $map,
1041
            'kernel.cache_dir' => sys_get_temp_dir(),
1042
            'kernel.environment' => 'test',
1043
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
1044
            'kernel.project_dir' => __DIR__ . '/../../', // src dir
1045
            'kernel.bundles_metadata' => [],
1046
            'container.build_id' => uniqid(),
1047
        ]));
1048
1049
        // Register dummy cache services so we don't have to load the FrameworkExtension
1050
        $container->setDefinition('cache.system', (new Definition(ArrayAdapter::class))->setPublic(true));
1051
        $container->setDefinition('cache.app', (new Definition(ArrayAdapter::class))->setPublic(true));
1052
1053
        return $container;
1054
    }
1055
1056
    /**
1057
     * Assertion on the Class of a DIC Service Definition.
1058
     *
1059
     * @param string $expectedClass
1060
     */
1061
    private function assertDICDefinitionClass(Definition $definition, $expectedClass)
1062
    {
1063
        $this->assertEquals($expectedClass, $definition->getClass(), 'Expected Class of the DIC Container Service Definition is wrong.');
1064
    }
1065
1066
    private function assertDICConstructorArguments(Definition $definition, $args)
1067
    {
1068
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
1069
    }
1070
1071 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...
1072
    {
1073
        $calls = $definition->getMethodCalls();
1074
        if (! isset($calls[$pos][0])) {
1075
            $this->fail(sprintf('Method call at position %s not found!', $pos));
1076
1077
            return;
1078
        }
1079
1080
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
1081
1082
        if ($params === null) {
1083
            return;
1084
        }
1085
1086
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1087
    }
1088
1089
    /**
1090
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
1091
     *
1092
     * @param string $methodName
1093
     * @param array  $params
0 ignored issues
show
Documentation introduced by
Should the type for parameter $params not be null|array?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1094
     */
1095 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...
1096
    {
1097
        $calls  = $definition->getMethodCalls();
1098
        $called = false;
1099
        foreach ($calls as $call) {
1100
            if ($call[0] !== $methodName) {
1101
                continue;
1102
            }
1103
1104
            if ($called) {
1105
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
1106
            } else {
1107
                $called = true;
1108
                if ($params !== null) {
1109
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1110
                }
1111
            }
1112
        }
1113
        if ($called) {
1114
            return;
1115
        }
1116
1117
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
1118
    }
1119
1120
    private function assertDICDefinitionMethodCallCount(Definition $definition, $methodName, array $params = [], $nbCalls = 1)
1121
    {
1122
        $calls  = $definition->getMethodCalls();
1123
        $called = 0;
1124
        foreach ($calls as $call) {
1125
            if ($call[0] !== $methodName) {
1126
                continue;
1127
            }
1128
1129
            if ($called > $nbCalls) {
1130
                break;
1131
            }
1132
1133
            if (isset($params[$called])) {
1134
                $this->assertEquals($params[$called], $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1135
            }
1136
            $called++;
1137
        }
1138
1139
        $this->assertEquals($nbCalls, $called, sprintf('The method "%s" should be called %d times', $methodName, $nbCalls));
1140
    }
1141
1142
    /**
1143
     * Assertion for the DI Container, check if the given definition does not contain a method call with the given parameters.
1144
     *
1145
     * @param string $methodName
1146
     * @param array  $params
0 ignored issues
show
Documentation introduced by
Should the type for parameter $params not be null|array?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1147
     */
1148
    private function assertDICDefinitionNoMethodCall(Definition $definition, $methodName, array $params = null)
1149
    {
1150
        $calls = $definition->getMethodCalls();
1151
        foreach ($calls as $call) {
1152
            if ($call[0] !== $methodName) {
1153
                continue;
1154
            }
1155
1156
            if ($params !== null) {
1157
                $this->assertNotEquals($params, $call[1], "Method '" . $methodName . "' is not expected to be called with the given parameters.");
1158
            } else {
1159
                $this->fail("Method '" . $methodName . "' is not expected to be called");
1160
            }
1161
        }
1162
    }
1163
1164
    private function compileContainer(ContainerBuilder $container)
1165
    {
1166
        $container->getCompilerPassConfig()->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
1167
        $container->getCompilerPassConfig()->setRemovingPasses([]);
1168
        $container->compile();
1169
    }
1170
}
1171
1172
class DummySchemaAssetsFilter
1173
{
1174
    /** @var string */
1175
    private $tableToIgnore;
1176
1177
    public function __construct(string $tableToIgnore)
1178
    {
1179
        $this->tableToIgnore = $tableToIgnore;
1180
    }
1181
1182
    public function __invoke($assetName) : bool
1183
    {
1184
        if ($assetName instanceof AbstractAsset) {
1185
            $assetName = $assetName->getName();
1186
        }
1187
1188
        return $assetName !== $this->tableToIgnore;
1189
    }
1190
}
1191