Completed
Push — master ( bdeeb7...fbc977 )
by Andreas
16s queued 10s
created

dataWellKnownSchemaFilterServices()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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