Completed
Push — master ( 601d80...357a47 )
by Andreas
01:53 queued 10s
created

AbstractDoctrineExtensionTest   F

Complexity

Total Complexity 67

Size/Duplication

Total Lines 1104
Duplicated Lines 7.52 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
wmc 67
lcom 1
cbo 13
dl 83
loc 1104
rs 2.224
c 0
b 0
f 0

49 Methods

Rating   Name   Duplication   Size   Complexity  
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 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
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
    public function testDependencyInjectionImportsOverrideDefaults()
391
    {
392
        $container = $this->loadContainer('orm_imports');
393
394
        $cacheDefinition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
395
        $this->assertEquals(DoctrineProvider::class, $cacheDefinition->getClass());
396
397
        $configDefinition = $container->getDefinition('doctrine.orm.default_configuration');
398
        $this->assertDICDefinitionMethodCallOnce($configDefinition, 'setAutoGenerateProxyClasses', ['%doctrine.orm.auto_generate_proxy_classes%']);
399
    }
400
401
    public function testSingleEntityManagerMultipleMappingBundleDefinitions()
402
    {
403
        $container = $this->loadContainer('orm_single_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
404
405
        $definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
406
407
        $this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
408
            new Reference('doctrine.orm.default_annotation_metadata_driver'),
409
            'Fixtures\Bundles\AnnotationsBundle\Entity',
410
        ]);
411
412
        $this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
413
            new Reference('doctrine.orm.default_yml_metadata_driver'),
414
            'Fixtures\Bundles\YamlBundle\Entity',
415
        ]);
416
417
        $this->assertDICDefinitionMethodCallAt(2, $definition, 'addDriver', [
418
            new Reference('doctrine.orm.default_xml_metadata_driver'),
419
            'Fixtures\Bundles\XmlBundle',
420
        ]);
421
422
        $annDef = $container->getDefinition('doctrine.orm.default_annotation_metadata_driver');
423
        $this->assertDICConstructorArguments($annDef, [
424
            new Reference('doctrine.orm.metadata.annotation_reader'),
425
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity'],
426
        ]);
427
428
        $ymlDef = $container->getDefinition('doctrine.orm.default_yml_metadata_driver');
429
        $this->assertDICConstructorArguments($ymlDef, [
430
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'YamlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity'],
431
        ]);
432
433
        $xmlDef = $container->getDefinition('doctrine.orm.default_xml_metadata_driver');
434
        $this->assertDICConstructorArguments($xmlDef, [
435
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'XmlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\XmlBundle'],
436
        ]);
437
    }
438
439
    public function testMultipleEntityManagersMappingBundleDefinitions()
440
    {
441
        $container = $this->loadContainer('orm_multiple_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
442
443
        $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.');
444
        $this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');
445
446
        $def1 = $container->getDefinition('doctrine.orm.em1_metadata_driver');
447
        $def2 = $container->getDefinition('doctrine.orm.em2_metadata_driver');
448
449
        $this->assertDICDefinitionMethodCallAt(0, $def1, 'addDriver', [
450
            new Reference('doctrine.orm.em1_annotation_metadata_driver'),
451
            'Fixtures\Bundles\AnnotationsBundle\Entity',
452
        ]);
453
454
        $this->assertDICDefinitionMethodCallAt(0, $def2, 'addDriver', [
455
            new Reference('doctrine.orm.em2_yml_metadata_driver'),
456
            'Fixtures\Bundles\YamlBundle\Entity',
457
        ]);
458
459
        $this->assertDICDefinitionMethodCallAt(1, $def2, 'addDriver', [
460
            new Reference('doctrine.orm.em2_xml_metadata_driver'),
461
            'Fixtures\Bundles\XmlBundle',
462
        ]);
463
464
        $annDef = $container->getDefinition('doctrine.orm.em1_annotation_metadata_driver');
465
        $this->assertDICConstructorArguments($annDef, [
466
            new Reference('doctrine.orm.metadata.annotation_reader'),
467
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity'],
468
        ]);
469
470
        $ymlDef = $container->getDefinition('doctrine.orm.em2_yml_metadata_driver');
471
        $this->assertDICConstructorArguments($ymlDef, [
472
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'YamlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity'],
473
        ]);
474
475
        $xmlDef = $container->getDefinition('doctrine.orm.em2_xml_metadata_driver');
476
        $this->assertDICConstructorArguments($xmlDef, [
477
            [__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'XmlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\XmlBundle'],
478
        ]);
479
    }
480
481
    public function testSingleEntityManagerDefaultTableOptions()
482
    {
483
        $container = $this->loadContainer('orm_single_em_default_table_options', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle']);
484
485
        $param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
486
487
        $this->assertArrayHasKey('defaultTableOptions', $param);
488
489
        $defaults = $param['defaultTableOptions'];
490
491
        $this->assertArrayHasKey('charset', $defaults);
492
        $this->assertArrayHasKey('collate', $defaults);
493
        $this->assertArrayHasKey('engine', $defaults);
494
495
        $this->assertEquals('utf8mb4', $defaults['charset']);
496
        $this->assertEquals('utf8mb4_unicode_ci', $defaults['collate']);
497
        $this->assertEquals('InnoDB', $defaults['engine']);
498
    }
499
500
    public function testSetTypes()
501
    {
502
        $container = $this->loadContainer('dbal_types');
503
504
        $this->assertEquals(
505
            ['test' => ['class' => TestType::class, 'commented' => null]],
506
            $container->getParameter('doctrine.dbal.connection_factory.types')
507
        );
508
        $this->assertEquals('%doctrine.dbal.connection_factory.types%', $container->getDefinition('doctrine.dbal.connection_factory')->getArgument(0));
509
    }
510
511
    public function testSetCustomFunctions()
512
    {
513
        $container = $this->loadContainer('orm_functions');
514
515
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
516
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', ['test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction']);
517
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomNumericFunction', ['test_numeric', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction']);
518
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomDatetimeFunction', ['test_datetime', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction']);
519
    }
520
521 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...
522
    {
523
        $container = $this->loadContainer('orm_namingstrategy');
524
525
        $def1 = $container->getDefinition('doctrine.orm.em1_configuration');
526
        $def2 = $container->getDefinition('doctrine.orm.em2_configuration');
527
528
        $this->assertDICDefinitionMethodCallOnce($def1, 'setNamingStrategy', [0 => new Reference('doctrine.orm.naming_strategy.default')]);
529
        $this->assertDICDefinitionMethodCallOnce($def2, 'setNamingStrategy', [0 => new Reference('doctrine.orm.naming_strategy.underscore')]);
530
    }
531
532 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...
533
    {
534
        $container = $this->loadContainer('orm_quotestrategy');
535
536
        $def1 = $container->getDefinition('doctrine.orm.em1_configuration');
537
        $def2 = $container->getDefinition('doctrine.orm.em2_configuration');
538
539
        $this->assertDICDefinitionMethodCallOnce($def1, 'setQuoteStrategy', [0 => new Reference('doctrine.orm.quote_strategy.default')]);
540
        $this->assertDICDefinitionMethodCallOnce($def2, 'setQuoteStrategy', [0 => new Reference('doctrine.orm.quote_strategy.ansi')]);
541
    }
542
543
    public function testSecondLevelCache()
544
    {
545
        $container = $this->loadContainer('orm_second_level_cache');
546
547
        $this->assertTrue($container->has('doctrine.orm.default_configuration'));
548
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.cache_configuration'));
549
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region_cache_driver'));
550
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.regions_configuration'));
551
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.default_cache_factory'));
552
553
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger_chain'));
554
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger_statistics'));
555
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger.my_service_logger1'));
556
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.logger.my_service_logger2'));
557
558
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_entity_region'));
559
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_service_region'));
560
        $this->assertTrue($container->has('doctrine.orm.default_second_level_cache.region.my_query_region_filelock'));
561
562
        $slcFactoryDef       = $container->getDefinition('doctrine.orm.default_second_level_cache.default_cache_factory');
563
        $myEntityRegionDef   = $container->getDefinition('doctrine.orm.default_second_level_cache.region.my_entity_region');
564
        $loggerChainDef      = $container->getDefinition('doctrine.orm.default_second_level_cache.logger_chain');
565
        $loggerStatisticsDef = $container->getDefinition('doctrine.orm.default_second_level_cache.logger_statistics');
566
        $myQueryRegionDef    = $container->getDefinition('doctrine.orm.default_second_level_cache.region.my_query_region_filelock');
567
        $cacheDriverDef      = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_second_level_cache.region_cache_driver'));
568
        $configDef           = $container->getDefinition('doctrine.orm.default_configuration');
569
        $myEntityRegionArgs  = $myEntityRegionDef->getArguments();
570
        $myQueryRegionArgs   = $myQueryRegionDef->getArguments();
571
        $slcFactoryArgs      = $slcFactoryDef->getArguments();
572
573
        $this->assertDICDefinitionClass($slcFactoryDef, '%doctrine.orm.second_level_cache.default_cache_factory.class%');
574
        $this->assertDICDefinitionClass($myQueryRegionDef, '%doctrine.orm.second_level_cache.filelock_region.class%');
575
        $this->assertDICDefinitionClass($myEntityRegionDef, '%doctrine.orm.second_level_cache.default_region.class%');
576
        $this->assertDICDefinitionClass($loggerChainDef, '%doctrine.orm.second_level_cache.logger_chain.class%');
577
        $this->assertDICDefinitionClass($loggerStatisticsDef, '%doctrine.orm.second_level_cache.logger_statistics.class%');
578
        $this->assertDICDefinitionClass($cacheDriverDef, DoctrineProvider::class);
579
        $this->assertDICDefinitionMethodCallOnce($configDef, 'setSecondLevelCacheConfiguration');
580
        $this->assertDICDefinitionMethodCallCount($slcFactoryDef, 'setRegion', [], 3);
581
        $this->assertDICDefinitionMethodCallCount($loggerChainDef, 'setLogger', [], 3);
582
583
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $slcFactoryArgs[0]);
584
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $slcFactoryArgs[1]);
585
586
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $myEntityRegionArgs[1]);
587
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $myQueryRegionArgs[0]);
588
589
        $this->assertEquals('my_entity_region', $myEntityRegionArgs[0]);
590
        $this->assertEquals('doctrine.orm.default_second_level_cache.region.my_entity_region_driver', $myEntityRegionArgs[1]);
591
        $this->assertEquals(600, $myEntityRegionArgs[2]);
592
593
        $this->assertEquals('doctrine.orm.default_second_level_cache.region.my_query_region', $myQueryRegionArgs[0]);
594
        $this->assertContains('/doctrine/orm/slc/filelock', $myQueryRegionArgs[1]);
595
        $this->assertEquals(60, $myQueryRegionArgs[2]);
596
597
        $this->assertEquals('doctrine.orm.default_second_level_cache.regions_configuration', $slcFactoryArgs[0]);
598
        $this->assertEquals('doctrine.orm.default_second_level_cache.region_cache_driver', $slcFactoryArgs[1]);
599
    }
600
601
    public function testSingleEMSetCustomFunctions()
602
    {
603
        $container = $this->loadContainer('orm_single_em_dql_functions');
604
605
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
606
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', ['test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction']);
607
    }
608
609
    public function testAddCustomHydrationMode()
610
    {
611
        $container = $this->loadContainer('orm_hydration_mode');
612
613
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
614
        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomHydrationMode', ['test_hydrator', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator']);
615
    }
616
617
    public function testAddFilter()
618
    {
619
        $container = $this->loadContainer('orm_filters');
620
621
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
622
        $args       = [
623
            ['soft_delete', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter'],
624
            ['myFilter', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\TestFilter'],
625
        ];
626
        $this->assertDICDefinitionMethodCallCount($definition, 'addFilter', $args, 2);
627
628
        $definition = $container->getDefinition('doctrine.orm.default_manager_configurator');
629
        $this->assertDICConstructorArguments($definition, [['soft_delete', 'myFilter'], ['myFilter' => ['myParameter' => 'myValue', 'mySecondParameter' => 'mySecondValue']]]);
630
631
        // Let's create the instance to check the configurator work.
632
        /** @var EntityManager $entityManager */
633
        $entityManager = $container->get('doctrine.orm.entity_manager');
634
        $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...
635
    }
636
637
    public function testResolveTargetEntity()
638
    {
639
        $container = $this->loadContainer('orm_resolve_target_entity');
640
641
        $definition = $container->getDefinition('doctrine.orm.listeners.resolve_target_entity');
642
        $this->assertDICDefinitionMethodCallOnce($definition, 'addResolveTargetEntity', ['Symfony\Component\Security\Core\User\UserInterface', 'MyUserClass', []]);
643
644
        $this->assertEquals(['doctrine.event_subscriber' => [[]]], $definition->getTags());
645
    }
646
647
    public function testAttachEntityListeners()
648
    {
649
        $container = $this->loadContainer('orm_attach_entity_listener');
650
651
        $definition  = $container->getDefinition('doctrine.orm.default_listeners.attach_entity_listeners');
652
        $methodCalls = $definition->getMethodCalls();
653
654
        $this->assertDICDefinitionMethodCallCount($definition, 'addEntityListener', [], 6);
655
        $this->assertEquals(['doctrine.event_listener' => [ ['event' => 'loadClassMetadata'] ] ], $definition->getTags());
656
657
        $this->assertEquals($methodCalls[0], [
658
            'addEntityListener',
659
            [
660
                'ExternalBundles\Entities\FooEntity',
661
                'MyBundles\Listeners\FooEntityListener',
662
                'prePersist',
663
                null,
664
            ],
665
        ]);
666
667
        $this->assertEquals($methodCalls[1], [
668
            'addEntityListener',
669
            [
670
                'ExternalBundles\Entities\FooEntity',
671
                'MyBundles\Listeners\FooEntityListener',
672
                'postPersist',
673
                'postPersist',
674
            ],
675
        ]);
676
677
        $this->assertEquals($methodCalls[2], [
678
            'addEntityListener',
679
            [
680
                'ExternalBundles\Entities\FooEntity',
681
                'MyBundles\Listeners\FooEntityListener',
682
                'postLoad',
683
                'postLoadHandler',
684
            ],
685
        ]);
686
687
        $this->assertEquals($methodCalls[3], [
688
            'addEntityListener',
689
            [
690
                'ExternalBundles\Entities\BarEntity',
691
                'MyBundles\Listeners\BarEntityListener',
692
                'prePersist',
693
                'prePersist',
694
            ],
695
        ]);
696
697
        $this->assertEquals($methodCalls[4], [
698
            'addEntityListener',
699
            [
700
                'ExternalBundles\Entities\BarEntity',
701
                'MyBundles\Listeners\BarEntityListener',
702
                'prePersist',
703
                'prePersistHandler',
704
            ],
705
        ]);
706
707
        $this->assertEquals($methodCalls[5], [
708
            'addEntityListener',
709
            [
710
                'ExternalBundles\Entities\BarEntity',
711
                'MyBundles\Listeners\LogDeleteEntityListener',
712
                'postDelete',
713
                'postDelete',
714
            ],
715
        ]);
716
    }
717
718
    public function testDbalAutoCommit()
719
    {
720
        $container = $this->loadContainer('dbal_auto_commit');
721
722
        $definition = $container->getDefinition('doctrine.dbal.default_connection.configuration');
723
        $this->assertDICDefinitionMethodCallOnce($definition, 'setAutoCommit', [false]);
724
    }
725
726
    public function testDbalOracleConnectstring()
727
    {
728
        $container = $this->loadContainer('dbal_oracle_connectstring');
729
730
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
731
        $this->assertSame('scott@sales-server:1521/sales.us.example.com', $config['connectstring']);
732
    }
733
734
    public function testDbalOracleInstancename()
735
    {
736
        $container = $this->loadContainer('dbal_oracle_instancename');
737
738
        $config = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);
739
        $this->assertSame('mySuperInstance', $config['instancename']);
740
    }
741
742
    public function testDbalSchemaFilter()
743
    {
744
        if (method_exists(Configuration::class, 'setSchemaAssetsFilter')) {
745
            $this->markTestSkipped('Test only applies to doctrine/dbal 2.8 or lower');
746
        }
747
748
        $container = $this->loadContainer('dbal_schema_filter');
749
750
        $definition = $container->getDefinition('doctrine.dbal.connection1_connection.configuration');
751
        $this->assertDICDefinitionMethodCallOnce($definition, 'setFilterSchemaAssetsExpression', ['~^(?!t_)~']);
752
    }
753
754
    public function testDbalSchemaFilterNewConfig()
755
    {
756
        if (! method_exists(Configuration::class, 'setSchemaAssetsFilter')) {
757
            $this->markTestSkipped('Test requires doctrine/dbal 2.9 or higher');
758
        }
759
760
        $container = $this->getContainer([]);
761
        $loader    = new DoctrineExtension();
762
        $container->registerExtension($loader);
763
        $container->addCompilerPass(new DbalSchemaFilterPass());
764
765
        // ignore table1 table on "default" connection
766
        $container->register('dummy_filter1', DummySchemaAssetsFilter::class)
767
            ->setArguments(['table1'])
768
            ->addTag('doctrine.dbal.schema_filter');
769
770
        // ignore table2 table on "connection2" connection
771
        $container->register('dummy_filter2', DummySchemaAssetsFilter::class)
772
            ->setArguments(['table2'])
773
            ->addTag('doctrine.dbal.schema_filter', ['connection' => 'connection2']);
774
775
        $this->loadFromFile($container, 'dbal_schema_filter');
776
777
        $assetNames               = ['table1', 'table2', 'table3', 't_ignored'];
778
        $expectedConnectionAssets = [
779
            // ignores table1 + schema_filter applies
780
            'connection1' => ['table2', 'table3'],
781
            // ignores table2, no schema_filter applies
782
            'connection2' => ['table1', 'table3', 't_ignored'],
783
            // connection3 has no ignores, handled separately
784
        ];
785
786
        $this->compileContainer($container);
787
788
        $getConfiguration = static function (string $connectionName) use ($container) : Configuration {
789
            return $container->get(sprintf('doctrine.dbal.%s_connection', $connectionName))->getConfiguration();
790
        };
791
792
        foreach ($expectedConnectionAssets as $connectionName => $expectedTables) {
793
            $connConfig = $getConfiguration($connectionName);
794
            $this->assertSame($expectedTables, array_values(array_filter($assetNames, $connConfig->getSchemaAssetsFilter())), sprintf('Filtering for connection "%s"', $connectionName));
795
        }
796
797
        $this->assertNull($connConfig = $getConfiguration('connection3')->getSchemaAssetsFilter());
798
    }
799
800
    public function testEntityListenerResolver()
801
    {
802
        $container = $this->loadContainer('orm_entity_listener_resolver', ['YamlBundle'], new EntityListenerPass());
803
804
        $definition = $container->getDefinition('doctrine.orm.em1_configuration');
805
        $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityListenerResolver', [new Reference('doctrine.orm.em1_entity_listener_resolver')]);
806
807
        $definition = $container->getDefinition('doctrine.orm.em2_configuration');
808
        $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityListenerResolver', [new Reference('doctrine.orm.em2_entity_listener_resolver')]);
809
810
        $listener = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
811
        $this->assertDICDefinitionMethodCallOnce($listener, 'registerService', ['EntityListener', 'entity_listener1']);
812
813
        $listener = $container->getDefinition('entity_listener_resolver');
814
        $this->assertDICDefinitionMethodCallOnce($listener, 'register', [new Reference('entity_listener2')]);
815
    }
816
817
    public function testAttachEntityListenerTag()
818
    {
819
        $container = $this->getContainer([]);
820
        $loader    = new DoctrineExtension();
821
        $container->registerExtension($loader);
822
        $container->addCompilerPass(new EntityListenerPass());
823
824
        $this->loadFromFile($container, 'orm_attach_entity_listener_tag');
825
826
        $this->compileContainer($container);
827
828
        $listener = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
829
        $this->assertDICDefinitionMethodCallCount($listener, 'registerService', [
830
            ['EntityListener1', 'entity_listener1'],
831
            ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'],
832
            ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'],
833
            ['ParentEntityListener', 'children_entity_listener'],
834
        ], 4);
835
836
        $listener = $container->getDefinition('doctrine.orm.em2_entity_listener_resolver');
837
        $this->assertDICDefinitionMethodCallOnce($listener, 'registerService', ['EntityListener2', 'entity_listener2']);
838
839
        $attachListener = $container->getDefinition('doctrine.orm.em1_listeners.attach_entity_listeners');
840
        $this->assertDICDefinitionMethodCallAt(0, $attachListener, 'addEntityListener', ['My/Entity1', 'EntityListener1', 'postLoad']);
841
        $this->assertDICDefinitionMethodCallAt(1, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'loadClassMetadata', '__invoke']);
842
        $this->assertDICDefinitionMethodCallAt(2, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'postPersist']);
843
        $this->assertDICDefinitionMethodCallAt(3, $attachListener, 'addEntityListener', ['My/Entity3', 'ParentEntityListener', 'postLoad']);
844
845
        $attachListener = $container->getDefinition('doctrine.orm.em2_listeners.attach_entity_listeners');
846
        $this->assertDICDefinitionMethodCallOnce($attachListener, 'addEntityListener', ['My/Entity2', 'EntityListener2', 'preFlush', 'preFlushHandler']);
847
    }
848
849
    public function testAttachEntityListenersTwoConnections()
850
    {
851
        $container = $this->getContainer(['YamlBundle']);
852
        $loader    = new DoctrineExtension();
853
        $container->registerExtension($loader);
854
        $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass('doctrine.connections', 'doctrine.dbal.%s_connection.event_manager', 'doctrine'));
855
856
        $this->loadFromFile($container, 'orm_attach_entity_listeners_two_connections');
857
858
        $this->compileContainer($container);
859
860
        $defaultEventManager = $container->getDefinition('doctrine.dbal.default_connection.event_manager');
861
        $this->assertDICDefinitionNoMethodCall($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]);
862
        $this->assertDICDefinitionMethodCallOnce($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]);
863
864
        $foobarEventManager = $container->getDefinition('doctrine.dbal.foobar_connection.event_manager');
865
        $this->assertDICDefinitionNoMethodCall($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]);
866
        $this->assertDICDefinitionMethodCallOnce($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]);
867
    }
868
869
    public function testAttachLazyEntityListener()
870
    {
871
        $container = $this->getContainer([]);
872
        $loader    = new DoctrineExtension();
873
        $container->registerExtension($loader);
874
        $container->addCompilerPass(new EntityListenerPass());
875
876
        $this->loadFromFile($container, 'orm_attach_lazy_entity_listener');
877
878
        $this->compileContainer($container);
879
880
        $resolver1 = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver');
881
        $this->assertDICDefinitionMethodCallAt(0, $resolver1, 'registerService', ['EntityListener1', 'entity_listener1']);
882
        $this->assertDICDefinitionMethodCallAt(1, $resolver1, 'register', [new Reference('entity_listener3')]);
883
        $this->assertDICDefinitionMethodCallAt(2, $resolver1, 'registerService', ['EntityListener4', 'entity_listener4']);
884
885
        $serviceLocatorReference = $resolver1->getArgument(0);
886
        $this->assertInstanceOf(Reference::class, $serviceLocatorReference);
887
        $serviceLocatorDefinition = $container->getDefinition((string) $serviceLocatorReference);
888
        $this->assertSame(ServiceLocator::class, $serviceLocatorDefinition->getClass());
889
        $serviceLocatorMap = $serviceLocatorDefinition->getArgument(0);
890
        $this->assertSame(['entity_listener1', 'entity_listener4'], array_keys($serviceLocatorMap));
891
892
        $resolver2 = $container->findDefinition('custom_entity_listener_resolver');
893
        $this->assertDICDefinitionMethodCallOnce($resolver2, 'registerService', ['EntityListener2', 'entity_listener2']);
894
    }
895
896
    public function testAttachLazyEntityListenerForCustomResolver()
897
    {
898
        $container = $this->getContainer([]);
899
        $loader    = new DoctrineExtension();
900
        $container->registerExtension($loader);
901
        $container->addCompilerPass(new EntityListenerPass());
902
903
        $this->loadFromFile($container, 'orm_entity_listener_custom_resolver');
904
905
        $this->compileContainer($container);
906
907
        $resolver = $container->getDefinition('custom_entity_listener_resolver');
908
        $this->assertTrue($resolver->isPublic());
909
        $this->assertEmpty($resolver->getArguments(), 'We must not change the arguments for custom services.');
910
        $this->assertDICDefinitionMethodCallOnce($resolver, 'registerService', ['EntityListener', 'entity_listener']);
911
        $this->assertTrue($container->getDefinition('entity_listener')->isPublic());
912
    }
913
914
    /**
915
     * @expectedException \InvalidArgumentException
916
     * @expectedExceptionMessage EntityListenerServiceResolver
917
     */
918 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...
919
    {
920
        $container = $this->getContainer([]);
921
        $loader    = new DoctrineExtension();
922
        $container->registerExtension($loader);
923
        $container->addCompilerPass(new EntityListenerPass());
924
925
        $this->loadFromFile($container, 'orm_entity_listener_lazy_resolver_without_interface');
926
927
        $this->compileContainer($container);
928
    }
929
930
    public function testPrivateLazyEntityListener()
931
    {
932
        $container = $this->getContainer([]);
933
        $loader    = new DoctrineExtension();
934
        $container->registerExtension($loader);
935
        $container->addCompilerPass(new EntityListenerPass());
936
937
        $this->loadFromFile($container, 'orm_entity_listener_lazy_private');
938
939
        $this->compileContainer($container);
940
941
        $this->assertTrue($container->getDefinition('doctrine.orm.em1_entity_listener_resolver')->isPublic());
942
    }
943
944
    /**
945
     * @expectedException \InvalidArgumentException
946
     * @expectedExceptionMessageRegExp /The service ".*" must not be abstract as this entity listener is lazy-loaded/
947
     */
948 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...
949
    {
950
        $container = $this->getContainer([]);
951
        $loader    = new DoctrineExtension();
952
        $container->registerExtension($loader);
953
        $container->addCompilerPass(new EntityListenerPass());
954
955
        $this->loadFromFile($container, 'orm_entity_listener_lazy_abstract');
956
957
        $this->compileContainer($container);
958
    }
959
960
    public function testRepositoryFactory()
961
    {
962
        $container = $this->loadContainer('orm_repository_factory');
963
964
        $definition = $container->getDefinition('doctrine.orm.default_configuration');
965
        $this->assertDICDefinitionMethodCallOnce($definition, 'setRepositoryFactory', ['repository_factory']);
966
    }
967
968
    private function loadContainer($fixture, array $bundles = ['YamlBundle'], CompilerPassInterface $compilerPass = null)
969
    {
970
        $container = $this->getContainer($bundles);
971
        $container->registerExtension(new DoctrineExtension());
972
973
        $this->loadFromFile($container, $fixture);
974
975
        if ($compilerPass !== null) {
976
            $container->addCompilerPass($compilerPass);
977
        }
978
979
        $this->compileContainer($container);
980
981
        return $container;
982
    }
983
984
    private function getContainer(array $bundles)
985
    {
986
        $map = [];
987
        foreach ($bundles as $bundle) {
988
            require_once __DIR__ . '/Fixtures/Bundles/' . $bundle . '/' . $bundle . '.php';
989
990
            $map[$bundle] = 'Fixtures\\Bundles\\' . $bundle . '\\' . $bundle;
991
        }
992
993
        $container = new ContainerBuilder(new ParameterBag([
994
            'kernel.name' => 'app',
995
            'kernel.debug' => false,
996
            'kernel.bundles' => $map,
997
            'kernel.cache_dir' => sys_get_temp_dir(),
998
            'kernel.environment' => 'test',
999
            'kernel.root_dir' => __DIR__ . '/../../', // src dir
1000
            'kernel.project_dir' => __DIR__ . '/../../', // src dir
1001
            'kernel.bundles_metadata' => [],
1002
            'container.build_id' => uniqid(),
1003
        ]));
1004
1005
        // Register dummy cache services so we don't have to load the FrameworkExtension
1006
        $container->setDefinition('cache.system', (new Definition(ArrayAdapter::class))->setPublic(true));
1007
        $container->setDefinition('cache.app', (new Definition(ArrayAdapter::class))->setPublic(true));
1008
1009
        return $container;
1010
    }
1011
1012
    /**
1013
     * Assertion on the Class of a DIC Service Definition.
1014
     *
1015
     * @param string $expectedClass
1016
     */
1017
    private function assertDICDefinitionClass(Definition $definition, $expectedClass)
1018
    {
1019
        $this->assertEquals($expectedClass, $definition->getClass(), 'Expected Class of the DIC Container Service Definition is wrong.');
1020
    }
1021
1022
    private function assertDICConstructorArguments(Definition $definition, $args)
1023
    {
1024
        $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass() . "' don't match.");
1025
    }
1026
1027 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...
1028
    {
1029
        $calls = $definition->getMethodCalls();
1030
        if (! isset($calls[$pos][0])) {
1031
            $this->fail(sprintf('Method call at position %s not found!', $pos));
1032
1033
            return;
1034
        }
1035
1036
        $this->assertEquals($methodName, $calls[$pos][0], "Method '" . $methodName . "' is expected to be called at position " . $pos . '.');
1037
1038
        if ($params === null) {
1039
            return;
1040
        }
1041
1042
        $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1043
    }
1044
1045
    /**
1046
     * Assertion for the DI Container, check if the given definition contains a method call with the given parameters.
1047
     *
1048
     * @param string $methodName
1049
     * @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...
1050
     */
1051 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...
1052
    {
1053
        $calls  = $definition->getMethodCalls();
1054
        $called = false;
1055
        foreach ($calls as $call) {
1056
            if ($call[0] !== $methodName) {
1057
                continue;
1058
            }
1059
1060
            if ($called) {
1061
                $this->fail("Method '" . $methodName . "' is expected to be called only once, a second call was registered though.");
1062
            } else {
1063
                $called = true;
1064
                if ($params !== null) {
1065
                    $this->assertEquals($params, $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1066
                }
1067
            }
1068
        }
1069
        if ($called) {
1070
            return;
1071
        }
1072
1073
        $this->fail("Method '" . $methodName . "' is expected to be called once, definition does not contain a call though.");
1074
    }
1075
1076
    private function assertDICDefinitionMethodCallCount(Definition $definition, $methodName, array $params = [], $nbCalls = 1)
1077
    {
1078
        $calls  = $definition->getMethodCalls();
1079
        $called = 0;
1080
        foreach ($calls as $call) {
1081
            if ($call[0] !== $methodName) {
1082
                continue;
1083
            }
1084
1085
            if ($called > $nbCalls) {
1086
                break;
1087
            }
1088
1089
            if (isset($params[$called])) {
1090
                $this->assertEquals($params[$called], $call[1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters.");
1091
            }
1092
            $called++;
1093
        }
1094
1095
        $this->assertEquals($nbCalls, $called, sprintf('The method "%s" should be called %d times', $methodName, $nbCalls));
1096
    }
1097
1098
    /**
1099
     * Assertion for the DI Container, check if the given definition does not contain a method call with the given parameters.
1100
     *
1101
     * @param string $methodName
1102
     * @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...
1103
     */
1104
    private function assertDICDefinitionNoMethodCall(Definition $definition, $methodName, array $params = null)
1105
    {
1106
        $calls = $definition->getMethodCalls();
1107
        foreach ($calls as $call) {
1108
            if ($call[0] !== $methodName) {
1109
                continue;
1110
            }
1111
1112
            if ($params !== null) {
1113
                $this->assertNotEquals($params, $call[1], "Method '" . $methodName . "' is not expected to be called with the given parameters.");
1114
            } else {
1115
                $this->fail("Method '" . $methodName . "' is not expected to be called");
1116
            }
1117
        }
1118
    }
1119
1120
    private function compileContainer(ContainerBuilder $container)
1121
    {
1122
        $container->getCompilerPassConfig()->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
1123
        $container->getCompilerPassConfig()->setRemovingPasses([]);
1124
        $container->compile();
1125
    }
1126
}
1127
1128
class DummySchemaAssetsFilter
1129
{
1130
    /** @var string */
1131
    private $tableToIgnore;
1132
1133
    public function __construct(string $tableToIgnore)
1134
    {
1135
        $this->tableToIgnore = $tableToIgnore;
1136
    }
1137
1138
    public function __invoke($assetName) : bool
1139
    {
1140
        if ($assetName instanceof AbstractAsset) {
1141
            $assetName = $assetName->getName();
1142
        }
1143
1144
        return $assetName !== $this->tableToIgnore;
1145
    }
1146
}
1147