Failed Conditions
Push — master ( 6fdfca...ce7560 )
by Marco
06:09 queued 01:06
created

ConnectionTest   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 843
Duplicated Lines 28.35 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 7
Bugs 0 Features 0
Metric Value
wmc 47
lcom 1
cbo 14
dl 239
loc 843
rs 8
c 7
b 0
f 0

47 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 4 1
A getExecuteUpdateMockConnection() 0 15 1
A testIsConnected() 0 4 1
A testNoTransactionActiveByDefault() 0 4 1
A testCommitWithNoActiveTransaction_ThrowsException() 0 5 1
A testRollbackWithNoActiveTransaction_ThrowsException() 0 5 1
A testSetRollbackOnlyNoActiveTransaction_ThrowsException() 0 5 1
A testIsRollbackOnlyNoActiveTransaction_ThrowsException() 0 5 1
A testGetConfiguration() 0 6 1
A testGetHost() 0 4 1
A testGetPort() 0 4 1
A testGetUsername() 0 4 1
A testGetPassword() 0 4 1
A testGetDriver() 0 4 1
A testGetEventManager() 0 4 1
A testConnectDispatchEvent() 0 18 1
A testEventManagerPassedToPlatform() 0 7 1
A testDriverExceptionIsWrapped() 0 11 1
A getQueryMethods() 0 10 1
A testEchoSQLLogger() 0 6 1
A testDebugSQLStack() 0 6 1
A testIsAutoCommit() 0 4 1
A testSetAutoCommit() 0 7 1
A testConnectStartsTransactionInNoAutoCommitMode() 16 16 1
A testCommitStartsTransactionInNoAutoCommitMode() 14 14 1
A testRollBackStartsTransactionInNoAutoCommitMode() 14 14 1
A testSwitchingAutoCommitModeCommitsAllCurrentTransactions() 0 21 1
A testEmptyInsert() 0 10 1
B testUpdateWithDifferentColumnsInDataAndIdentifiers() 0 40 1
B testUpdateWithSameColumnInDataAndIdentifiers() 39 39 1
B testUpdateWithIsNull() 38 38 1
B testDeleteWithIsNull() 0 28 1
B testFetchAssoc() 33 33 1
B testFetchArray() 33 33 1
B testFetchColumn() 0 34 1
A testConnectionIsClosedButNotUnset() 0 22 1
B testFetchAll() 32 32 1
A testConnectionDoesNotMaintainTwoReferencesToExternalPDO() 10 10 1
A testPassingExternalPDOMeansConnectionIsConnected() 10 10 1
A testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException() 0 15 1
A dataCallConnectOnce() 0 10 1
A testCallConnectOnce() 0 20 1
B testPlatformDetectionIsTriggerOnlyOnceOnRetrievingPlatform() 0 32 1
B testConnectionParamsArePassedToTheQueryCacheProfileInExecuteCacheQuery() 0 37 1
B testShouldNotPassPlatformInParamsToTheQueryCacheProfileInExecuteCacheQuery() 0 35 1
A testThrowsExceptionWhenInValidPlatformSpecified() 0 12 1
A testRethrowsOriginalExceptionOnDeterminingPlatformWhenConnectingToNonExistentDatabase() 0 21 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 ConnectionTest 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 ConnectionTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Doctrine\Tests\DBAL;
4
5
use Doctrine\Common\Cache\Cache;
6
use Doctrine\Common\EventManager;
7
use Doctrine\DBAL\Cache\QueryCacheProfile;
8
use Doctrine\DBAL\Configuration;
9
use Doctrine\DBAL\Connection;
10
use Doctrine\DBAL\DBALException;
11
use Doctrine\DBAL\Driver;
12
use Doctrine\DBAL\Events;
13
use Doctrine\DBAL\Platforms\AbstractPlatform;
14
use Doctrine\Tests\Mocks\DriverConnectionMock;
15
use Doctrine\Tests\Mocks\DriverMock;
16
use Doctrine\DBAL\Cache\ArrayStatement;
17
use Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock;
18
19
class ConnectionTest extends \Doctrine\Tests\DbalTestCase
20
{
21
    /**
22
     * @var \Doctrine\DBAL\Connection
23
     */
24
    protected $_conn = null;
25
26
    protected $params = array(
27
        'driver' => 'pdo_mysql',
28
        'host' => 'localhost',
29
        'user' => 'root',
30
        'password' => 'password',
31
        'port' => '1234'
32
    );
33
34
    protected function setUp()
35
    {
36
        $this->_conn = \Doctrine\DBAL\DriverManager::getConnection($this->params);
37
    }
38
39
    public function getExecuteUpdateMockConnection()
40
    {
41
        $driverMock = $this->createMock(\Doctrine\DBAL\Driver::class);
42
43
        $driverMock->expects($this->any())
44
            ->method('connect')
45
            ->will($this->returnValue(new DriverConnectionMock()));
46
47
        $conn = $this->getMockBuilder(Connection::class)
48
            ->setMethods(['executeUpdate'])
49
            ->setConstructorArgs([['platform' => new Mocks\MockPlatform()], $driverMock])
50
            ->getMock();
51
52
        return $conn;
53
    }
54
55
    public function testIsConnected()
56
    {
57
        $this->assertFalse($this->_conn->isConnected());
58
    }
59
60
    public function testNoTransactionActiveByDefault()
61
    {
62
        $this->assertFalse($this->_conn->isTransactionActive());
63
    }
64
65
    public function testCommitWithNoActiveTransaction_ThrowsException()
66
    {
67
        $this->setExpectedException('Doctrine\DBAL\ConnectionException');
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0; use expectException() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
68
        $this->_conn->commit();
69
    }
70
71
    public function testRollbackWithNoActiveTransaction_ThrowsException()
72
    {
73
        $this->setExpectedException('Doctrine\DBAL\ConnectionException');
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0; use expectException() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
74
        $this->_conn->rollBack();
75
    }
76
77
    public function testSetRollbackOnlyNoActiveTransaction_ThrowsException()
78
    {
79
        $this->setExpectedException('Doctrine\DBAL\ConnectionException');
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0; use expectException() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
80
        $this->_conn->setRollbackOnly();
81
    }
82
83
    public function testIsRollbackOnlyNoActiveTransaction_ThrowsException()
84
    {
85
        $this->setExpectedException('Doctrine\DBAL\ConnectionException');
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0; use expectException() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
86
        $this->_conn->isRollbackOnly();
87
    }
88
89
    public function testGetConfiguration()
90
    {
91
        $config = $this->_conn->getConfiguration();
92
93
        $this->assertInstanceOf('Doctrine\DBAL\Configuration', $config);
94
    }
95
96
    public function testGetHost()
97
    {
98
        $this->assertEquals('localhost', $this->_conn->getHost());
99
    }
100
101
    public function testGetPort()
102
    {
103
        $this->assertEquals('1234', $this->_conn->getPort());
104
    }
105
106
    public function testGetUsername()
107
    {
108
        $this->assertEquals('root', $this->_conn->getUsername());
109
    }
110
111
    public function testGetPassword()
112
    {
113
        $this->assertEquals('password', $this->_conn->getPassword());
114
    }
115
116
    public function testGetDriver()
117
    {
118
        $this->assertInstanceOf('Doctrine\DBAL\Driver\PDOMySql\Driver', $this->_conn->getDriver());
119
    }
120
121
    public function testGetEventManager()
122
    {
123
        $this->assertInstanceOf('Doctrine\Common\EventManager', $this->_conn->getEventManager());
124
    }
125
126
    public function testConnectDispatchEvent()
127
    {
128
        $listenerMock = $this->getMockBuilder('ConnectDispatchEventListener')
129
            ->setMethods(array('postConnect'))
130
            ->getMock();
131
        $listenerMock->expects($this->once())->method('postConnect');
132
133
        $eventManager = new EventManager();
134
        $eventManager->addEventListener(array(Events::postConnect), $listenerMock);
135
136
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
137
        $driverMock->expects(($this->at(0)))
138
                   ->method('connect');
139
        $platform = new Mocks\MockPlatform();
140
141
        $conn = new Connection(array('platform' => $platform), $driverMock, new Configuration(), $eventManager);
142
        $conn->connect();
143
    }
144
145
    public function testEventManagerPassedToPlatform()
146
    {
147
        $driverMock = new DriverMock();
148
        $connection = new Connection($this->params, $driverMock);
149
        $this->assertInstanceOf('Doctrine\Common\EventManager', $connection->getDatabasePlatform()->getEventManager());
150
        $this->assertSame($connection->getEventManager(), $connection->getDatabasePlatform()->getEventManager());
151
    }
152
153
    /**
154
     * @expectedException \Doctrine\DBAL\DBALException
155
     * @dataProvider getQueryMethods
156
     */
157
    public function testDriverExceptionIsWrapped($method)
158
    {
159
        $this->setExpectedException('Doctrine\DBAL\DBALException', "An exception occurred while executing 'MUUHAAAAHAAAA':\n\nSQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\"");
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0; use expectException() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
160
161
        $con = \Doctrine\DBAL\DriverManager::getConnection(array(
162
            'driver' => 'pdo_sqlite',
163
            'memory' => true,
164
        ));
165
166
        $con->$method('MUUHAAAAHAAAA');
167
    }
168
169
    public function getQueryMethods()
170
    {
171
        return array(
172
            array('exec'),
173
            array('query'),
174
            array('executeQuery'),
175
            array('executeUpdate'),
176
            array('prepare'),
177
        );
178
    }
179
180
    /**
181
     * Pretty dumb test, however we want to check that the EchoSQLLogger correctly implements the interface.
182
     *
183
     * @group DBAL-11
184
     */
185
    public function testEchoSQLLogger()
186
    {
187
        $logger = new \Doctrine\DBAL\Logging\EchoSQLLogger();
188
        $this->_conn->getConfiguration()->setSQLLogger($logger);
189
        $this->assertSame($logger, $this->_conn->getConfiguration()->getSQLLogger());
190
    }
191
192
    /**
193
     * Pretty dumb test, however we want to check that the DebugStack correctly implements the interface.
194
     *
195
     * @group DBAL-11
196
     */
197
    public function testDebugSQLStack()
198
    {
199
        $logger = new \Doctrine\DBAL\Logging\DebugStack();
200
        $this->_conn->getConfiguration()->setSQLLogger($logger);
201
        $this->assertSame($logger, $this->_conn->getConfiguration()->getSQLLogger());
202
    }
203
204
    /**
205
     * @group DBAL-81
206
     */
207
    public function testIsAutoCommit()
208
    {
209
        $this->assertTrue($this->_conn->isAutoCommit());
210
    }
211
212
    /**
213
     * @group DBAL-81
214
     */
215
    public function testSetAutoCommit()
216
    {
217
        $this->_conn->setAutoCommit(false);
218
        $this->assertFalse($this->_conn->isAutoCommit());
219
        $this->_conn->setAutoCommit(0);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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...
220
        $this->assertFalse($this->_conn->isAutoCommit());
221
    }
222
223
    /**
224
     * @group DBAL-81
225
     */
226 View Code Duplication
    public function testConnectStartsTransactionInNoAutoCommitMode()
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...
227
    {
228
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
229
        $driverMock->expects($this->any())
230
            ->method('connect')
231
            ->will($this->returnValue(new DriverConnectionMock()));
232
        $conn = new Connection(array('platform' => new Mocks\MockPlatform()), $driverMock);
233
234
        $conn->setAutoCommit(false);
235
236
        $this->assertFalse($conn->isTransactionActive());
237
238
        $conn->connect();
239
240
        $this->assertTrue($conn->isTransactionActive());
241
    }
242
243
    /**
244
     * @group DBAL-81
245
     */
246 View Code Duplication
    public function testCommitStartsTransactionInNoAutoCommitMode()
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...
247
    {
248
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
249
        $driverMock->expects($this->any())
250
            ->method('connect')
251
            ->will($this->returnValue(new DriverConnectionMock()));
252
        $conn = new Connection(array('platform' => new Mocks\MockPlatform()), $driverMock);
253
254
        $conn->setAutoCommit(false);
255
        $conn->connect();
256
        $conn->commit();
257
258
        $this->assertTrue($conn->isTransactionActive());
259
    }
260
261
    /**
262
     * @group DBAL-81
263
     */
264 View Code Duplication
    public function testRollBackStartsTransactionInNoAutoCommitMode()
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...
265
    {
266
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
267
        $driverMock->expects($this->any())
268
            ->method('connect')
269
            ->will($this->returnValue(new DriverConnectionMock()));
270
        $conn = new Connection(array('platform' => new Mocks\MockPlatform()), $driverMock);
271
272
        $conn->setAutoCommit(false);
273
        $conn->connect();
274
        $conn->rollBack();
275
276
        $this->assertTrue($conn->isTransactionActive());
277
    }
278
279
    /**
280
     * @group DBAL-81
281
     */
282
    public function testSwitchingAutoCommitModeCommitsAllCurrentTransactions()
283
    {
284
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
285
        $driverMock->expects($this->any())
286
            ->method('connect')
287
            ->will($this->returnValue(new DriverConnectionMock()));
288
        $conn = new Connection(array('platform' => new Mocks\MockPlatform()), $driverMock);
289
290
        $conn->connect();
291
        $conn->beginTransaction();
292
        $conn->beginTransaction();
293
        $conn->setAutoCommit(false);
294
295
        $this->assertSame(1, $conn->getTransactionNestingLevel());
296
297
        $conn->beginTransaction();
298
        $conn->beginTransaction();
299
        $conn->setAutoCommit(true);
300
301
        $this->assertFalse($conn->isTransactionActive());
302
    }
303
304
    public function testEmptyInsert()
305
    {
306
        $conn = $this->getExecuteUpdateMockConnection();
307
308
        $conn->expects($this->once())
309
            ->method('executeUpdate')
310
            ->with('INSERT INTO footable () VALUES ()');
311
312
        $conn->insert('footable', array());
313
    }
314
315
    /**
316
     * @group DBAL-2511
317
     */
318
    public function testUpdateWithDifferentColumnsInDataAndIdentifiers()
319
    {
320
        $conn = $this->getExecuteUpdateMockConnection();
321
322
        $conn->expects($this->once())
323
            ->method('executeUpdate')
324
            ->with(
325
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND name = ?',
326
                [
327
                    'some text',
328
                    true,
329
                    1,
330
                    'foo',
331
                ],
332
                [
333
                    'string',
334
                    'boolean',
335
                    'integer',
336
                    'string',
337
                ]
338
            );
339
340
        $conn->update(
341
            'TestTable',
342
            [
343
                'text' => 'some text',
344
                'is_edited' => true,
345
            ],
346
            [
347
                'id' => 1,
348
                'name' => 'foo',
349
            ],
350
            [
351
                'text' => 'string',
352
                'is_edited' => 'boolean',
353
                'id' => 'integer',
354
                'name' => 'string',
355
            ]
356
        );
357
    }
358
359
    /**
360
     * @group DBAL-2511
361
     */
362 View Code Duplication
    public function testUpdateWithSameColumnInDataAndIdentifiers()
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...
363
    {
364
        $conn = $this->getExecuteUpdateMockConnection();
365
366
        $conn->expects($this->once())
367
            ->method('executeUpdate')
368
            ->with(
369
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND is_edited = ?',
370
                [
371
                    'some text',
372
                    true,
373
                    1,
374
                    false,
375
                ],
376
                [
377
                    'string',
378
                    'boolean',
379
                    'integer',
380
                    'boolean',
381
                ]
382
            );
383
384
        $conn->update(
385
            'TestTable',
386
            [
387
                'text' => 'some text',
388
                'is_edited' => true,
389
            ],
390
            [
391
                'id' => 1,
392
                'is_edited' => false,
393
            ],
394
            [
395
                'text' => 'string',
396
                'is_edited' => 'boolean',
397
                'id' => 'integer',
398
            ]
399
        );
400
    }
401
402
    /**
403
     * @group DBAL-2688
404
     */
405 View Code Duplication
    public function testUpdateWithIsNull()
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...
406
    {
407
        $conn = $this->getExecuteUpdateMockConnection();
408
409
        $conn->expects($this->once())
410
            ->method('executeUpdate')
411
            ->with(
412
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id IS NULL AND name = ?',
413
                [
414
                    'some text',
415
                    null,
416
                    'foo',
417
                ],
418
                [
419
                    'string',
420
                    'boolean',
421
                    'string',
422
                ]
423
            );
424
425
        $conn->update(
426
            'TestTable',
427
            [
428
                'text' => 'some text',
429
                'is_edited' => null,
430
            ],
431
            [
432
                'id' => null,
433
                'name' => 'foo',
434
            ],
435
            [
436
                'text' => 'string',
437
                'is_edited' => 'boolean',
438
                'id' => 'integer',
439
                'name' => 'string',
440
            ]
441
        );
442
    }
443
444
    /**
445
     * @group DBAL-2688
446
     */
447
    public function testDeleteWithIsNull()
448
    {
449
        $conn = $this->getExecuteUpdateMockConnection();
450
451
        $conn->expects($this->once())
452
            ->method('executeUpdate')
453
            ->with(
454
                'DELETE FROM TestTable WHERE id IS NULL AND name = ?',
455
                [
456
                    'foo',
457
                ],
458
                [
459
                    'string',
460
                ]
461
            );
462
463
        $conn->delete(
464
            'TestTable',
465
            [
466
                'id' => null,
467
                'name' => 'foo',
468
            ],
469
            [
470
                'id' => 'integer',
471
                'name' => 'string',
472
            ]
473
        );
474
    }
475
476 View Code Duplication
    public function testFetchAssoc()
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...
477
    {
478
        $statement = 'SELECT * FROM foo WHERE bar = ?';
479
        $params    = array(666);
480
        $types     = array(\PDO::PARAM_INT);
481
        $result    = array();
482
483
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
484
485
        $driverMock->expects($this->any())
486
            ->method('connect')
487
            ->will($this->returnValue(new DriverConnectionMock()));
488
489
        $driverStatementMock = $this->createMock('Doctrine\Tests\Mocks\DriverStatementMock');
490
491
        $driverStatementMock->expects($this->once())
492
            ->method('fetch')
493
            ->with(\PDO::FETCH_ASSOC)
494
            ->will($this->returnValue($result));
495
496
        /** @var \PHPUnit_Framework_MockObject_MockObject|\Doctrine\DBAL\Connection $conn */
497
        $conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
498
            ->setMethods(array('executeQuery'))
499
            ->setConstructorArgs(array(array('platform' => new Mocks\MockPlatform()), $driverMock))
500
            ->getMock();
501
502
        $conn->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\DBAL\Connection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
503
            ->method('executeQuery')
504
            ->with($statement, $params, $types)
505
            ->will($this->returnValue($driverStatementMock));
506
507
        $this->assertSame($result, $conn->fetchAssoc($statement, $params, $types));
0 ignored issues
show
Bug introduced by
The method fetchAssoc does only exist in Doctrine\DBAL\Connection, but not in PHPUnit_Framework_MockObject_MockObject.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
508
    }
509
510 View Code Duplication
    public function testFetchArray()
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...
511
    {
512
        $statement = 'SELECT * FROM foo WHERE bar = ?';
513
        $params    = array(666);
514
        $types     = array(\PDO::PARAM_INT);
515
        $result    = array();
516
517
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
518
519
        $driverMock->expects($this->any())
520
            ->method('connect')
521
            ->will($this->returnValue(new DriverConnectionMock()));
522
523
        $driverStatementMock = $this->createMock('Doctrine\Tests\Mocks\DriverStatementMock');
524
525
        $driverStatementMock->expects($this->once())
526
            ->method('fetch')
527
            ->with(\PDO::FETCH_NUM)
528
            ->will($this->returnValue($result));
529
530
        /** @var \PHPUnit_Framework_MockObject_MockObject|\Doctrine\DBAL\Connection $conn */
531
        $conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
532
            ->setMethods(array('executeQuery'))
533
            ->setConstructorArgs(array(array('platform' => new Mocks\MockPlatform()), $driverMock))
534
            ->getMock();
535
536
        $conn->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\DBAL\Connection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
537
            ->method('executeQuery')
538
            ->with($statement, $params, $types)
539
            ->will($this->returnValue($driverStatementMock));
540
541
        $this->assertSame($result, $conn->fetchArray($statement, $params, $types));
0 ignored issues
show
Bug introduced by
The method fetchArray does only exist in Doctrine\DBAL\Connection, but not in PHPUnit_Framework_MockObject_MockObject.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
542
    }
543
544
    public function testFetchColumn()
545
    {
546
        $statement = 'SELECT * FROM foo WHERE bar = ?';
547
        $params    = array(666);
548
        $types     = array(\PDO::PARAM_INT);
549
        $column    = 0;
550
        $result    = array();
551
552
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
553
554
        $driverMock->expects($this->any())
555
            ->method('connect')
556
            ->will($this->returnValue(new DriverConnectionMock()));
557
558
        $driverStatementMock = $this->createMock('Doctrine\Tests\Mocks\DriverStatementMock');
559
560
        $driverStatementMock->expects($this->once())
561
            ->method('fetchColumn')
562
            ->with($column)
563
            ->will($this->returnValue($result));
564
565
        /** @var \PHPUnit_Framework_MockObject_MockObject|\Doctrine\DBAL\Connection $conn */
566
        $conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
567
            ->setMethods(array('executeQuery'))
568
            ->setConstructorArgs(array(array('platform' => new Mocks\MockPlatform()), $driverMock))
569
            ->getMock();
570
571
        $conn->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\DBAL\Connection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
572
            ->method('executeQuery')
573
            ->with($statement, $params, $types)
574
            ->will($this->returnValue($driverStatementMock));
575
576
        $this->assertSame($result, $conn->fetchColumn($statement, $params, $column, $types));
0 ignored issues
show
Bug introduced by
The method fetchColumn does only exist in Doctrine\DBAL\Connection, but not in PHPUnit_Framework_MockObject_MockObject.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
577
    }
578
579
    public function testConnectionIsClosedButNotUnset()
580
    {
581
        // mock Connection, and make connect() purposefully do nothing
582
        $connection = $this->getMockBuilder('Doctrine\DBAL\Connection')
583
            ->disableOriginalConstructor()
584
            ->setMethods(array('connect'))
585
            ->getMock();
586
587
        // artificially set the wrapped connection to non-null
588
        $reflection = new \ReflectionObject($connection);
589
        $connProperty = $reflection->getProperty('_conn');
590
        $connProperty->setAccessible(true);
591
        $connProperty->setValue($connection, new \stdClass);
592
593
        // close the connection (should nullify the wrapped connection)
594
        $connection->close();
595
596
        // the wrapped connection should be null
597
        // (and since connect() does nothing, this will not reconnect)
598
        // this will also fail if this _conn property was unset instead of set to null
599
        $this->assertNull($connection->getWrappedConnection());
600
    }
601
602 View Code Duplication
    public function testFetchAll()
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...
603
    {
604
        $statement = 'SELECT * FROM foo WHERE bar = ?';
605
        $params    = array(666);
606
        $types     = array(\PDO::PARAM_INT);
607
        $result    = array();
608
609
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
610
611
        $driverMock->expects($this->any())
612
            ->method('connect')
613
            ->will($this->returnValue(new DriverConnectionMock()));
614
615
        $driverStatementMock = $this->createMock('Doctrine\Tests\Mocks\DriverStatementMock');
616
617
        $driverStatementMock->expects($this->once())
618
            ->method('fetchAll')
619
            ->will($this->returnValue($result));
620
621
        /** @var \PHPUnit_Framework_MockObject_MockObject|\Doctrine\DBAL\Connection $conn */
622
        $conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
623
            ->setMethods(array('executeQuery'))
624
            ->setConstructorArgs(array(array('platform' => new Mocks\MockPlatform()), $driverMock))
625
            ->getMock();
626
627
        $conn->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\DBAL\Connection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
628
            ->method('executeQuery')
629
            ->with($statement, $params, $types)
630
            ->will($this->returnValue($driverStatementMock));
631
632
        $this->assertSame($result, $conn->fetchAll($statement, $params, $types));
0 ignored issues
show
Bug introduced by
The method fetchAll does only exist in Doctrine\DBAL\Connection, but not in PHPUnit_Framework_MockObject_MockObject.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
633
    }
634
635 View Code Duplication
    public function testConnectionDoesNotMaintainTwoReferencesToExternalPDO()
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...
636
    {
637
        $params['pdo'] = new \stdClass();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
638
639
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
640
641
        $conn = new Connection($params, $driverMock);
642
643
        $this->assertArrayNotHasKey('pdo', $conn->getParams(), "Connection is maintaining additional reference to the PDO connection");
644
    }
645
646 View Code Duplication
    public function testPassingExternalPDOMeansConnectionIsConnected()
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...
647
    {
648
        $params['pdo'] = new \stdClass();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
649
650
        $driverMock = $this->createMock('Doctrine\DBAL\Driver');
651
652
        $conn = new Connection($params, $driverMock);
653
654
        $this->assertTrue($conn->isConnected(), "Connection is not connected after passing external PDO");
655
    }
656
657
    public function testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException()
658
    {
659
        /* @var $driver \Doctrine\DBAL\Driver */
660
        $driver  = $this->createMock('Doctrine\DBAL\Driver');
661
        $pdoMock = $this->createMock('Doctrine\DBAL\Driver\Connection');
662
663
        // should never execute queries with invalid arguments
664
        $pdoMock->expects($this->never())->method('exec');
665
        $pdoMock->expects($this->never())->method('prepare');
666
667
        $conn = new Connection(array('pdo' => $pdoMock), $driver);
668
669
        $this->setExpectedException('Doctrine\DBAL\Exception\InvalidArgumentException');
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0; use expectException() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
670
        $conn->delete('kittens', array());
671
    }
672
673
    public function dataCallConnectOnce()
674
    {
675
        return array(
676
            array('delete', array('tbl', array('id' => 12345))),
677
            array('insert', array('tbl', array('data' => 'foo'))),
678
            array('update', array('tbl', array('data' => 'bar'), array('id' => 12345))),
679
            array('prepare', array('select * from dual')),
680
            array('executeUpdate', array('insert into tbl (id) values (?)'), array(123)),
681
        );
682
    }
683
684
    /**
685
     * @dataProvider dataCallConnectOnce
686
     */
687
    public function testCallConnectOnce($method, $params)
688
    {
689
        $driverMock   = $this->createMock('Doctrine\DBAL\Driver');
690
        $pdoMock      = $this->createMock('Doctrine\DBAL\Driver\Connection');
691
        $platformMock = new Mocks\MockPlatform();
692
        $stmtMock     = $this->createMock('Doctrine\DBAL\Driver\Statement');
693
694
        $pdoMock->expects($this->any())
695
            ->method('prepare')
696
            ->will($this->returnValue($stmtMock));
697
698
        $conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
699
            ->setConstructorArgs(array(array('pdo' => $pdoMock, 'platform' => $platformMock), $driverMock))
700
            ->setMethods(array('connect'))
701
            ->getMock();
702
703
        $conn->expects($this->once())->method('connect');
704
705
        call_user_func_array(array($conn, $method), $params);
706
    }
707
708
    /**
709
     * @group DBAL-1127
710
     */
711
    public function testPlatformDetectionIsTriggerOnlyOnceOnRetrievingPlatform()
712
    {
713
        /** @var \Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock|\PHPUnit_Framework_MockObject_MockObject $driverMock */
714
        $driverMock = $this->createMock('Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock');
715
716
        /** @var \Doctrine\Tests\Mocks\ServerInfoAwareConnectionMock|\PHPUnit_Framework_MockObject_MockObject $driverConnectionMock */
717
        $driverConnectionMock = $this->createMock('Doctrine\Tests\Mocks\ServerInfoAwareConnectionMock');
718
719
        /** @var \Doctrine\DBAL\Platforms\AbstractPlatform|\PHPUnit_Framework_MockObject_MockObject $platformMock */
720
        $platformMock = $this->getMockForAbstractClass('Doctrine\DBAL\Platforms\AbstractPlatform');
721
722
        $connection = new Connection(array(), $driverMock);
0 ignored issues
show
Bug introduced by
It seems like $driverMock defined by $this->createMock('Doctr...arePlatformDriverMock') on line 714 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, Doctrine\DBAL\Connection::__construct() does only seem to accept object<Doctrine\DBAL\Driver>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
723
724
        $driverMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\Tests\Mocks\Ver...AwarePlatformDriverMock.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
725
            ->method('connect')
726
            ->will($this->returnValue($driverConnectionMock));
727
728
        $driverConnectionMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\Tests\Mocks\ServerInfoAwareConnectionMock.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
729
            ->method('requiresQueryForServerVersion')
730
            ->will($this->returnValue(false));
731
732
        $driverConnectionMock->expects($this->once())
733
            ->method('getServerVersion')
734
            ->will($this->returnValue('6.6.6'));
735
736
        $driverMock->expects($this->once())
737
            ->method('createDatabasePlatformForVersion')
738
            ->with('6.6.6')
739
            ->will($this->returnValue($platformMock));
740
741
        $this->assertSame($platformMock, $connection->getDatabasePlatform());
742
    }
743
744
    public function testConnectionParamsArePassedToTheQueryCacheProfileInExecuteCacheQuery()
745
    {
746
        $resultCacheDriverMock = $this->createMock(Cache::class);
747
748
        $resultCacheDriverMock
749
            ->expects($this->atLeastOnce())
750
            ->method('fetch')
751
            ->with('cacheKey')
752
            ->will($this->returnValue(['realKey' => []]));
753
754
        $query  = 'SELECT * FROM foo WHERE bar = ?';
755
        $params = [666];
756
        $types  = [\PDO::PARAM_INT];
757
758
        /* @var $queryCacheProfileMock QueryCacheProfile|\PHPUnit_Framework_MockObject_MockObject */
759
        $queryCacheProfileMock = $this->createMock(QueryCacheProfile::class);
760
761
        $queryCacheProfileMock
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\DBAL\Cache\QueryCacheProfile.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
762
            ->expects($this->any())
763
            ->method('getResultCacheDriver')
764
            ->will($this->returnValue($resultCacheDriverMock));
765
766
        // This is our main expectation
767
        $queryCacheProfileMock
768
            ->expects($this->once())
769
            ->method('generateCacheKeys')
770
            ->with($query, $params, $types, $this->params)
771
            ->will($this->returnValue(['cacheKey', 'realKey']));
772
773
        /* @var $driver Driver */
774
        $driver = $this->createMock(Driver::class);
775
776
        $this->assertInstanceOf(
777
            ArrayStatement::class,
778
            (new Connection($this->params, $driver))->executeCacheQuery($query, $params, $types, $queryCacheProfileMock)
0 ignored issues
show
Bug introduced by
It seems like $queryCacheProfileMock defined by $this->createMock(\Doctr...eryCacheProfile::class) on line 759 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, Doctrine\DBAL\Connection::executeCacheQuery() does only seem to accept object<Doctrine\DBAL\Cache\QueryCacheProfile>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
779
        );
780
    }
781
782
    /**
783
     * @group DBAL-2821
784
     */
785
    public function testShouldNotPassPlatformInParamsToTheQueryCacheProfileInExecuteCacheQuery(): void
786
    {
787
        $resultCacheDriverMock = $this->createMock(Cache::class);
788
789
        $resultCacheDriverMock
790
            ->expects($this->atLeastOnce())
791
            ->method('fetch')
792
            ->with('cacheKey')
793
            ->will($this->returnValue(['realKey' => []]));
794
795
        /* @var $queryCacheProfileMock QueryCacheProfile|\PHPUnit_Framework_MockObject_MockObject */
796
        $queryCacheProfileMock = $this->createMock(QueryCacheProfile::class);
797
798
        $queryCacheProfileMock
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\DBAL\Cache\QueryCacheProfile.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
799
            ->expects($this->any())
800
            ->method('getResultCacheDriver')
801
            ->will($this->returnValue($resultCacheDriverMock));
802
803
        $query  = 'SELECT 1';
804
805
        $connectionParams = $this->params;
806
807
        $queryCacheProfileMock
808
            ->expects($this->once())
809
            ->method('generateCacheKeys')
810
            ->with($query, [], [], $connectionParams)
811
            ->will($this->returnValue(['cacheKey', 'realKey']));
812
813
        $connectionParams['platform'] = $this->createMock(AbstractPlatform::class);
814
815
        /* @var $driver Driver */
816
        $driver = $this->createMock(Driver::class);
817
818
        (new Connection($connectionParams, $driver))->executeCacheQuery($query, [], [], $queryCacheProfileMock);
0 ignored issues
show
Bug introduced by
It seems like $queryCacheProfileMock defined by $this->createMock(\Doctr...eryCacheProfile::class) on line 796 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, Doctrine\DBAL\Connection::executeCacheQuery() does only seem to accept object<Doctrine\DBAL\Cache\QueryCacheProfile>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
819
    }
820
821
    /**
822
     * @group DBAL-2821
823
     */
824
    public function testThrowsExceptionWhenInValidPlatformSpecified(): void
825
    {
826
        $connectionParams = $this->params;
827
        $connectionParams['platform'] = new \stdClass();
828
829
        /* @var $driver Driver */
830
        $driver = $this->createMock(Driver::class);
831
832
        $this->expectException(DBALException::class);
833
834
        new Connection($connectionParams, $driver);
835
    }
836
837
    /**
838
     * @group DBAL-990
839
     */
840
    public function testRethrowsOriginalExceptionOnDeterminingPlatformWhenConnectingToNonExistentDatabase()
841
    {
842
        /** @var \Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock|\PHPUnit_Framework_MockObject_MockObject $driverMock */
843
        $driverMock = $this->createMock(VersionAwarePlatformDriverMock::class);
844
845
        $connection = new Connection(array('dbname' => 'foo'), $driverMock);
0 ignored issues
show
Bug introduced by
It seems like $driverMock defined by $this->createMock(\Doctr...tformDriverMock::class) on line 843 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, Doctrine\DBAL\Connection::__construct() does only seem to accept object<Doctrine\DBAL\Driver>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
846
        $originalException = new \Exception('Original exception');
847
        $fallbackException = new \Exception('Fallback exception');
848
849
        $driverMock->expects($this->at(0))
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\Tests\Mocks\Ver...AwarePlatformDriverMock.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
850
            ->method('connect')
851
            ->willThrowException($originalException);
852
853
        $driverMock->expects($this->at(1))
854
            ->method('connect')
855
            ->willThrowException($fallbackException);
856
857
        $this->expectExceptionMessage($originalException->getMessage());
858
859
        $connection->getDatabasePlatform();
860
    }
861
}
862