Completed
Pull Request — master (#3610)
by Sergei
03:27 queued 10s
created

ConnectionTest   B

Complexity

Total Complexity 41

Size/Duplication

Total Lines 839
Duplicated Lines 27.53 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 41
lcom 1
cbo 11
dl 231
loc 839
rs 8.881
c 0
b 0
f 0

41 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 4 1
A getExecuteUpdateMockConnection() 0 17 1
A testIsConnected() 0 4 1
A testNoTransactionActiveByDefault() 0 4 1
A testCommitWithNoActiveTransactionThrowsException() 0 5 1
A testRollbackWithNoActiveTransactionThrowsException() 0 5 1
A testSetRollbackOnlyNoActiveTransactionThrowsException() 0 5 1
A testIsRollbackOnlyNoActiveTransactionThrowsException() 0 5 1
A testGetConfiguration() 0 6 1
A testGetDriver() 0 4 1
A testGetEventManager() 0 4 1
A testConnectDispatchEvent() 0 17 1
A testEventManagerPassedToPlatform() 0 19 1
A testDriverExceptionIsWrapped() 0 12 1
A getQueryMethods() 0 10 1
A testEchoSQLLogger() 0 6 1
A testDebugSQLStack() 0 6 1
A testIsAutoCommit() 0 4 1
A testSetAutoCommit() 0 5 1
A testConnectStartsTransactionInNoAutoCommitMode() 18 18 1
A testCommitStartsTransactionInNoAutoCommitMode() 16 16 1
A resultProvider() 0 4 1
A testRollBackStartsTransactionInNoAutoCommitMode() 16 16 1
A testSwitchingAutoCommitModeCommitsAllCurrentTransactions() 0 23 1
A testEmptyInsert() 0 10 1
A testUpdateWithDifferentColumnsInDataAndIdentifiers() 0 40 1
A testUpdateWithSameColumnInDataAndIdentifiers() 39 39 1
A testUpdateWithIsNull() 38 38 1
A testDeleteWithIsNull() 0 24 1
A testFetchAssoc() 35 35 1
A testFetchArray() 35 35 1
A testFetchColumn() 0 36 1
A testFetchAll() 34 34 1
A testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException() 0 9 1
A testCallConnectOnce() 0 13 1
A testPlatformDetectionIsTriggerOnlyOnceOnRetrievingPlatform() 0 32 1
A testConnectionParamsArePassedToTheQueryCacheProfileInExecuteCacheQuery() 0 37 1
A testShouldNotPassPlatformInParamsToTheQueryCacheProfileInExecuteCacheQuery() 0 35 1
A testThrowsExceptionWhenInValidPlatformSpecified() 0 12 1
A testRethrowsOriginalExceptionOnDeterminingPlatformWhenConnectingToNonExistentDatabase() 0 21 1
A testExecuteCacheQueryStripsPlatformFromConnectionParamsBeforeGeneratingCacheKeys() 0 47 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
declare(strict_types=1);
4
5
namespace Doctrine\Tests\DBAL;
6
7
use Doctrine\Common\Cache\Cache;
8
use Doctrine\Common\EventManager;
9
use Doctrine\DBAL\Cache\ArrayStatement;
10
use Doctrine\DBAL\Cache\QueryCacheProfile;
11
use Doctrine\DBAL\Configuration;
12
use Doctrine\DBAL\Connection;
13
use Doctrine\DBAL\ConnectionException;
14
use Doctrine\DBAL\DBALException;
15
use Doctrine\DBAL\Driver;
16
use Doctrine\DBAL\Driver\Connection as DriverConnection;
17
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
18
use Doctrine\DBAL\Driver\Statement;
19
use Doctrine\DBAL\DriverManager;
20
use Doctrine\DBAL\Events;
21
use Doctrine\DBAL\Exception\InvalidArgumentException;
22
use Doctrine\DBAL\FetchMode;
23
use Doctrine\DBAL\Logging\DebugStack;
24
use Doctrine\DBAL\Logging\EchoSQLLogger;
25
use Doctrine\DBAL\ParameterType;
26
use Doctrine\DBAL\Platforms\AbstractPlatform;
27
use Doctrine\DBAL\VersionAwarePlatformDriver;
28
use Doctrine\Tests\DbalTestCase;
29
use Exception;
30
use PHPUnit\Framework\MockObject\MockObject;
31
use stdClass;
32
33
/**
34
 * @requires extension pdo_mysql
35
 */
36
class ConnectionTest extends DbalTestCase
37
{
38
    /** @var Connection */
39
    private $connection;
40
41
    /** @var array<string, mixed> */
42
    protected $params = [
43
        'driver' => 'pdo_mysql',
44
        'host' => 'localhost',
45
        'user' => 'root',
46
        'password' => 'password',
47
        'port' => 1234,
48
    ];
49
50
    protected function setUp() : void
51
    {
52
        $this->connection = DriverManager::getConnection($this->params);
53
    }
54
55
    /**
56
     * @return Connection|MockObject
57
     */
58
    private function getExecuteUpdateMockConnection()
59
    {
60
        $driverMock = $this->createMock(Driver::class);
61
62
        $driverMock->expects($this->any())
63
            ->method('connect')
64
            ->will($this->returnValue(
65
                $this->createMock(DriverConnection::class)
66
            ));
67
68
        $platform = $this->getMockForAbstractClass(AbstractPlatform::class);
69
70
        return $this->getMockBuilder(Connection::class)
71
            ->onlyMethods(['executeUpdate'])
72
            ->setConstructorArgs([['platform' => $platform], $driverMock])
73
            ->getMock();
74
    }
75
76
    public function testIsConnected() : void
77
    {
78
        self::assertFalse($this->connection->isConnected());
79
    }
80
81
    public function testNoTransactionActiveByDefault() : void
82
    {
83
        self::assertFalse($this->connection->isTransactionActive());
84
    }
85
86
    public function testCommitWithNoActiveTransactionThrowsException() : void
87
    {
88
        $this->expectException(ConnectionException::class);
89
        $this->connection->commit();
90
    }
91
92
    public function testRollbackWithNoActiveTransactionThrowsException() : void
93
    {
94
        $this->expectException(ConnectionException::class);
95
        $this->connection->rollBack();
96
    }
97
98
    public function testSetRollbackOnlyNoActiveTransactionThrowsException() : void
99
    {
100
        $this->expectException(ConnectionException::class);
101
        $this->connection->setRollbackOnly();
102
    }
103
104
    public function testIsRollbackOnlyNoActiveTransactionThrowsException() : void
105
    {
106
        $this->expectException(ConnectionException::class);
107
        $this->connection->isRollbackOnly();
108
    }
109
110
    public function testGetConfiguration() : void
111
    {
112
        $config = $this->connection->getConfiguration();
113
114
        self::assertInstanceOf(Configuration::class, $config);
115
    }
116
117
    public function testGetDriver() : void
118
    {
119
        self::assertInstanceOf(\Doctrine\DBAL\Driver\PDOMySql\Driver::class, $this->connection->getDriver());
120
    }
121
122
    public function testGetEventManager() : void
123
    {
124
        self::assertInstanceOf(EventManager::class, $this->connection->getEventManager());
125
    }
126
127
    public function testConnectDispatchEvent() : void
128
    {
129
        $listenerMock = $this->getMockBuilder($this->getMockClass('ConnectDispatchEventListener'))
130
            ->addMethods(['postConnect'])
131
            ->getMock();
132
        $listenerMock->expects($this->once())->method('postConnect');
133
134
        $eventManager = new EventManager();
135
        $eventManager->addEventListener([Events::postConnect], $listenerMock);
136
137
        $driverMock = $this->createMock(Driver::class);
138
        $driverMock->expects($this->at(0))
139
                   ->method('connect');
140
141
        $conn = new Connection([], $driverMock, new Configuration(), $eventManager);
0 ignored issues
show
Documentation introduced by
$driverMock is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\DBAL\Driver>.

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...
142
        $conn->connect();
143
    }
144
145
    public function testEventManagerPassedToPlatform() : void
146
    {
147
        $eventManager = new EventManager();
148
149
        /** @var AbstractPlatform|MockObject $driver */
150
        $platform = $this->createMock(AbstractPlatform::class);
151
        $platform->expects($this->once())
152
            ->method('setEventManager')
153
            ->with($eventManager);
154
155
        /** @var Driver|MockObject $driver */
156
        $driver = $this->createMock(Driver::class);
157
        $driver->expects($this->any())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit\Framework\MockObject\MockObject, but not in Doctrine\DBAL\Driver.

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...
158
            ->method('getDatabasePlatform')
159
            ->willReturn($platform);
160
161
        $connection = new Connection($this->params, $driver, null, $eventManager);
0 ignored issues
show
Bug introduced by
It seems like $driver defined by $this->createMock(\Doctrine\DBAL\Driver::class) on line 156 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...
162
        $connection->getDatabasePlatform();
163
    }
164
165
    /**
166
     * @requires extension pdo_sqlite
167
     * @dataProvider getQueryMethods
168
     */
169
    public function testDriverExceptionIsWrapped(string $method) : void
170
    {
171
        $this->expectException(DBALException::class);
172
        $this->expectExceptionMessage("An exception occurred while executing \"MUUHAAAAHAAAA\":\n\nSQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\"");
173
174
        $connection = DriverManager::getConnection([
175
            'driver' => 'pdo_sqlite',
176
            'memory' => true,
177
        ]);
178
179
        $connection->$method('MUUHAAAAHAAAA');
180
    }
181
182
    /**
183
     * @return array<int, array<int, mixed>>
0 ignored issues
show
Documentation introduced by
The doc-type array<int, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
184
     */
185
    public static function getQueryMethods() : iterable
186
    {
187
        return [
188
            ['exec'],
189
            ['query'],
190
            ['executeQuery'],
191
            ['executeUpdate'],
192
            ['prepare'],
193
        ];
194
    }
195
196
    /**
197
     * Pretty dumb test, however we want to check that the EchoSQLLogger correctly implements the interface.
198
     *
199
     * @group DBAL-11
200
     */
201
    public function testEchoSQLLogger() : void
202
    {
203
        $logger = new EchoSQLLogger();
204
        $this->connection->getConfiguration()->setSQLLogger($logger);
205
        self::assertSame($logger, $this->connection->getConfiguration()->getSQLLogger());
206
    }
207
208
    /**
209
     * Pretty dumb test, however we want to check that the DebugStack correctly implements the interface.
210
     *
211
     * @group DBAL-11
212
     */
213
    public function testDebugSQLStack() : void
214
    {
215
        $logger = new DebugStack();
216
        $this->connection->getConfiguration()->setSQLLogger($logger);
217
        self::assertSame($logger, $this->connection->getConfiguration()->getSQLLogger());
218
    }
219
220
    /**
221
     * @group DBAL-81
222
     */
223
    public function testIsAutoCommit() : void
224
    {
225
        self::assertTrue($this->connection->isAutoCommit());
226
    }
227
228
    /**
229
     * @group DBAL-81
230
     */
231
    public function testSetAutoCommit() : void
232
    {
233
        $this->connection->setAutoCommit(false);
234
        self::assertFalse($this->connection->isAutoCommit());
235
    }
236
237
    /**
238
     * @group DBAL-81
239
     */
240 View Code Duplication
    public function testConnectStartsTransactionInNoAutoCommitMode() : void
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...
241
    {
242
        $driverMock = $this->createMock(Driver::class);
243
        $driverMock->expects($this->any())
244
            ->method('connect')
245
            ->will($this->returnValue(
246
                $this->createMock(DriverConnection::class)
247
            ));
248
        $conn = new Connection([], $driverMock);
0 ignored issues
show
Documentation introduced by
$driverMock is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\DBAL\Driver>.

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...
249
250
        $conn->setAutoCommit(false);
251
252
        self::assertFalse($conn->isTransactionActive());
253
254
        $conn->connect();
255
256
        self::assertTrue($conn->isTransactionActive());
257
    }
258
259
    /**
260
     * @group DBAL-81
261
     */
262 View Code Duplication
    public function testCommitStartsTransactionInNoAutoCommitMode() : void
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...
263
    {
264
        $driverMock = $this->createMock(Driver::class);
265
        $driverMock->expects($this->any())
266
            ->method('connect')
267
            ->will($this->returnValue(
268
                $this->createMock(DriverConnection::class)
269
            ));
270
        $conn = new Connection([], $driverMock);
0 ignored issues
show
Documentation introduced by
$driverMock is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\DBAL\Driver>.

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...
271
272
        $conn->setAutoCommit(false);
273
        $conn->connect();
274
        $conn->commit();
275
276
        self::assertTrue($conn->isTransactionActive());
277
    }
278
279
    /**
280
     * @return bool[][]
281
     */
282
    public function resultProvider() : array
283
    {
284
        return [[true], [false]];
285
    }
286
287
    /**
288
     * @group DBAL-81
289
     */
290 View Code Duplication
    public function testRollBackStartsTransactionInNoAutoCommitMode() : void
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...
291
    {
292
        $driverMock = $this->createMock(Driver::class);
293
        $driverMock->expects($this->any())
294
            ->method('connect')
295
            ->will($this->returnValue(
296
                $this->createMock(DriverConnection::class)
297
            ));
298
        $conn = new Connection([], $driverMock);
0 ignored issues
show
Documentation introduced by
$driverMock is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\DBAL\Driver>.

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...
299
300
        $conn->setAutoCommit(false);
301
        $conn->connect();
302
        $conn->rollBack();
303
304
        self::assertTrue($conn->isTransactionActive());
305
    }
306
307
    /**
308
     * @group DBAL-81
309
     */
310
    public function testSwitchingAutoCommitModeCommitsAllCurrentTransactions() : void
311
    {
312
        $driverMock = $this->createMock(Driver::class);
313
        $driverMock->expects($this->any())
314
            ->method('connect')
315
            ->will($this->returnValue(
316
                $this->createMock(DriverConnection::class)
317
            ));
318
        $conn = new Connection([], $driverMock);
0 ignored issues
show
Documentation introduced by
$driverMock is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\DBAL\Driver>.

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...
319
320
        $conn->connect();
321
        $conn->beginTransaction();
322
        $conn->beginTransaction();
323
        $conn->setAutoCommit(false);
324
325
        self::assertSame(1, $conn->getTransactionNestingLevel());
326
327
        $conn->beginTransaction();
328
        $conn->beginTransaction();
329
        $conn->setAutoCommit(true);
330
331
        self::assertFalse($conn->isTransactionActive());
332
    }
333
334
    public function testEmptyInsert() : void
335
    {
336
        $conn = $this->getExecuteUpdateMockConnection();
337
338
        $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...
339
            ->method('executeUpdate')
340
            ->with('INSERT INTO footable () VALUES ()');
341
342
        $conn->insert('footable', []);
0 ignored issues
show
Bug introduced by
The method insert 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...
343
    }
344
345
    /**
346
     * @group DBAL-2511
347
     */
348
    public function testUpdateWithDifferentColumnsInDataAndIdentifiers() : void
349
    {
350
        $conn = $this->getExecuteUpdateMockConnection();
351
352
        $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...
353
            ->method('executeUpdate')
354
            ->with(
355
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND name = ?',
356
                [
357
                    'some text',
358
                    true,
359
                    1,
360
                    'foo',
361
                ],
362
                [
363
                    'string',
364
                    'boolean',
365
                    'integer',
366
                    'string',
367
                ]
368
            );
369
370
        $conn->update(
0 ignored issues
show
Bug introduced by
The method update 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...
371
            'TestTable',
372
            [
373
                'text' => 'some text',
374
                'is_edited' => true,
375
            ],
376
            [
377
                'id' => 1,
378
                'name' => 'foo',
379
            ],
380
            [
381
                'text' => 'string',
382
                'is_edited' => 'boolean',
383
                'id' => 'integer',
384
                'name' => 'string',
385
            ]
386
        );
387
    }
388
389
    /**
390
     * @group DBAL-2511
391
     */
392 View Code Duplication
    public function testUpdateWithSameColumnInDataAndIdentifiers() : void
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...
393
    {
394
        $conn = $this->getExecuteUpdateMockConnection();
395
396
        $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...
397
            ->method('executeUpdate')
398
            ->with(
399
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND is_edited = ?',
400
                [
401
                    'some text',
402
                    true,
403
                    1,
404
                    false,
405
                ],
406
                [
407
                    'string',
408
                    'boolean',
409
                    'integer',
410
                    'boolean',
411
                ]
412
            );
413
414
        $conn->update(
0 ignored issues
show
Bug introduced by
The method update 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...
415
            'TestTable',
416
            [
417
                'text' => 'some text',
418
                'is_edited' => true,
419
            ],
420
            [
421
                'id' => 1,
422
                'is_edited' => false,
423
            ],
424
            [
425
                'text' => 'string',
426
                'is_edited' => 'boolean',
427
                'id' => 'integer',
428
            ]
429
        );
430
    }
431
432
    /**
433
     * @group DBAL-2688
434
     */
435 View Code Duplication
    public function testUpdateWithIsNull() : void
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...
436
    {
437
        $conn = $this->getExecuteUpdateMockConnection();
438
439
        $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...
440
            ->method('executeUpdate')
441
            ->with(
442
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id IS NULL AND name = ?',
443
                [
444
                    'some text',
445
                    null,
446
                    'foo',
447
                ],
448
                [
449
                    'string',
450
                    'boolean',
451
                    'string',
452
                ]
453
            );
454
455
        $conn->update(
0 ignored issues
show
Bug introduced by
The method update 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...
456
            'TestTable',
457
            [
458
                'text' => 'some text',
459
                'is_edited' => null,
460
            ],
461
            [
462
                'id' => null,
463
                'name' => 'foo',
464
            ],
465
            [
466
                'text' => 'string',
467
                'is_edited' => 'boolean',
468
                'id' => 'integer',
469
                'name' => 'string',
470
            ]
471
        );
472
    }
473
474
    /**
475
     * @group DBAL-2688
476
     */
477
    public function testDeleteWithIsNull() : void
478
    {
479
        $conn = $this->getExecuteUpdateMockConnection();
480
481
        $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...
482
            ->method('executeUpdate')
483
            ->with(
484
                'DELETE FROM TestTable WHERE id IS NULL AND name = ?',
485
                ['foo'],
486
                ['string']
487
            );
488
489
        $conn->delete(
0 ignored issues
show
Bug introduced by
The method delete 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...
490
            'TestTable',
491
            [
492
                'id' => null,
493
                'name' => 'foo',
494
            ],
495
            [
496
                'id' => 'integer',
497
                'name' => 'string',
498
            ]
499
        );
500
    }
501
502 View Code Duplication
    public function testFetchAssoc() : void
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...
503
    {
504
        $statement = 'SELECT * FROM foo WHERE bar = ?';
505
        $params    = [666];
506
        $types     = [ParameterType::INTEGER];
507
        $result    = [];
508
509
        $driverMock = $this->createMock(Driver::class);
510
511
        $driverMock->expects($this->any())
512
            ->method('connect')
513
            ->will($this->returnValue(
514
                $this->createMock(DriverConnection::class)
515
            ));
516
517
        $driverStatementMock = $this->createMock(Statement::class);
518
519
        $driverStatementMock->expects($this->once())
520
            ->method('fetch')
521
            ->with(FetchMode::ASSOCIATIVE)
522
            ->will($this->returnValue($result));
523
524
        /** @var Connection|MockObject $conn */
525
        $conn = $this->getMockBuilder(Connection::class)
526
            ->onlyMethods(['executeQuery'])
527
            ->setConstructorArgs([[], $driverMock])
528
            ->getMock();
529
530
        $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...
531
            ->method('executeQuery')
532
            ->with($statement, $params, $types)
533
            ->will($this->returnValue($driverStatementMock));
534
535
        self::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...
536
    }
537
538 View Code Duplication
    public function testFetchArray() : void
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...
539
    {
540
        $statement = 'SELECT * FROM foo WHERE bar = ?';
541
        $params    = [666];
542
        $types     = [ParameterType::INTEGER];
543
        $result    = [];
544
545
        $driverMock = $this->createMock(Driver::class);
546
547
        $driverMock->expects($this->any())
548
            ->method('connect')
549
            ->will($this->returnValue(
550
                $this->createMock(DriverConnection::class)
551
            ));
552
553
        $driverStatementMock = $this->createMock(Statement::class);
554
555
        $driverStatementMock->expects($this->once())
556
            ->method('fetch')
557
            ->with(FetchMode::NUMERIC)
558
            ->will($this->returnValue($result));
559
560
        /** @var Connection|MockObject $conn */
561
        $conn = $this->getMockBuilder(Connection::class)
562
            ->onlyMethods(['executeQuery'])
563
            ->setConstructorArgs([[], $driverMock])
564
            ->getMock();
565
566
        $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...
567
            ->method('executeQuery')
568
            ->with($statement, $params, $types)
569
            ->will($this->returnValue($driverStatementMock));
570
571
        self::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...
572
    }
573
574
    public function testFetchColumn() : void
575
    {
576
        $statement = 'SELECT * FROM foo WHERE bar = ?';
577
        $params    = [666];
578
        $types     = [ParameterType::INTEGER];
579
        $column    = 0;
580
        $result    = [];
581
582
        $driverMock = $this->createMock(Driver::class);
583
584
        $driverMock->expects($this->any())
585
            ->method('connect')
586
            ->will($this->returnValue(
587
                $this->createMock(DriverConnection::class)
588
            ));
589
590
        $driverStatementMock = $this->createMock(Statement::class);
591
592
        $driverStatementMock->expects($this->once())
593
            ->method('fetchColumn')
594
            ->with($column)
595
            ->will($this->returnValue($result));
596
597
        /** @var Connection|MockObject $conn */
598
        $conn = $this->getMockBuilder(Connection::class)
599
            ->onlyMethods(['executeQuery'])
600
            ->setConstructorArgs([[], $driverMock])
601
            ->getMock();
602
603
        $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...
604
            ->method('executeQuery')
605
            ->with($statement, $params, $types)
606
            ->will($this->returnValue($driverStatementMock));
607
608
        self::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...
609
    }
610
611 View Code Duplication
    public function testFetchAll() : void
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...
612
    {
613
        $statement = 'SELECT * FROM foo WHERE bar = ?';
614
        $params    = [666];
615
        $types     = [ParameterType::INTEGER];
616
        $result    = [];
617
618
        $driverMock = $this->createMock(Driver::class);
619
620
        $driverMock->expects($this->any())
621
            ->method('connect')
622
            ->will($this->returnValue(
623
                $this->createMock(DriverConnection::class)
624
            ));
625
626
        $driverStatementMock = $this->createMock(Statement::class);
627
628
        $driverStatementMock->expects($this->once())
629
            ->method('fetchAll')
630
            ->will($this->returnValue($result));
631
632
        /** @var Connection|MockObject $conn */
633
        $conn = $this->getMockBuilder(Connection::class)
634
            ->onlyMethods(['executeQuery'])
635
            ->setConstructorArgs([[], $driverMock])
636
            ->getMock();
637
638
        $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...
639
            ->method('executeQuery')
640
            ->with($statement, $params, $types)
641
            ->will($this->returnValue($driverStatementMock));
642
643
        self::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...
644
    }
645
646
    public function testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException() : void
647
    {
648
        /** @var Driver $driver */
649
        $driver = $this->createMock(Driver::class);
650
        $conn   = new Connection([], $driver);
651
652
        $this->expectException(InvalidArgumentException::class);
653
        $conn->delete('kittens', []);
654
    }
655
656
    public function testCallConnectOnce() : void
657
    {
658
        /** @var Driver|MockObject $driver */
659
        $driver = $this->createMock(Driver::class);
660
        $driver->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\Driver.

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...
661
            ->method('connect');
662
663
        $platform = $this->createMock(AbstractPlatform::class);
664
665
        $conn = new Connection(['platform' => $platform], $driver);
0 ignored issues
show
Bug introduced by
It seems like $driver defined by $this->createMock(\Doctrine\DBAL\Driver::class) on line 659 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...
666
        $conn->connect();
667
        $conn->connect();
668
    }
669
670
    /**
671
     * @group DBAL-1127
672
     */
673
    public function testPlatformDetectionIsTriggerOnlyOnceOnRetrievingPlatform() : void
674
    {
675
        /** @var VersionAwarePlatformDriver|MockObject $driverMock */
676
        $driverMock = $this->createMock(VersionAwarePlatformDriver::class);
677
678
        /** @var DriverConnection|ServerInfoAwareConnection|MockObject $driverConnectionMock */
679
        $driverConnectionMock = $this->createMock(ServerInfoAwareConnection::class);
680
681
        /** @var AbstractPlatform|MockObject $platformMock */
682
        $platformMock = $this->getMockForAbstractClass(AbstractPlatform::class);
683
684
        $connection = new Connection([], $driverMock);
0 ignored issues
show
Bug introduced by
It seems like $driverMock defined by $this->createMock(\Doctr...ePlatformDriver::class) on line 676 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...
685
686
        $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\DBAL\VersionAwarePlatformDriver.

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...
687
            ->method('connect')
688
            ->will($this->returnValue($driverConnectionMock));
689
690
        $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\DBAL\Driver\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...
691
            ->method('requiresQueryForServerVersion')
692
            ->will($this->returnValue(false));
693
694
        $driverConnectionMock->expects($this->once())
695
            ->method('getServerVersion')
696
            ->will($this->returnValue('6.6.6'));
697
698
        $driverMock->expects($this->once())
699
            ->method('createDatabasePlatformForVersion')
700
            ->with('6.6.6')
701
            ->will($this->returnValue($platformMock));
702
703
        self::assertSame($platformMock, $connection->getDatabasePlatform());
704
    }
705
706
    public function testConnectionParamsArePassedToTheQueryCacheProfileInExecuteCacheQuery() : void
707
    {
708
        $resultCacheDriverMock = $this->createMock(Cache::class);
709
710
        $resultCacheDriverMock
711
            ->expects($this->atLeastOnce())
712
            ->method('fetch')
713
            ->with('cacheKey')
714
            ->will($this->returnValue(['realKey' => []]));
715
716
        $query  = 'SELECT * FROM foo WHERE bar = ?';
717
        $params = [666];
718
        $types  = [ParameterType::INTEGER];
719
720
        /** @var QueryCacheProfile|MockObject $queryCacheProfileMock */
721
        $queryCacheProfileMock = $this->createMock(QueryCacheProfile::class);
722
723
        $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...
724
            ->expects($this->any())
725
            ->method('getResultCacheDriver')
726
            ->will($this->returnValue($resultCacheDriverMock));
727
728
        // This is our main expectation
729
        $queryCacheProfileMock
730
            ->expects($this->once())
731
            ->method('generateCacheKeys')
732
            ->with($query, $params, $types, $this->params)
733
            ->will($this->returnValue(['cacheKey', 'realKey']));
734
735
        /** @var Driver $driver */
736
        $driver = $this->createMock(Driver::class);
737
738
        self::assertInstanceOf(
739
            ArrayStatement::class,
740
            (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 721 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...
741
        );
742
    }
743
744
    /**
745
     * @group #2821
746
     */
747
    public function testShouldNotPassPlatformInParamsToTheQueryCacheProfileInExecuteCacheQuery() : void
748
    {
749
        $resultCacheDriverMock = $this->createMock(Cache::class);
750
751
        $resultCacheDriverMock
752
            ->expects($this->atLeastOnce())
753
            ->method('fetch')
754
            ->with('cacheKey')
755
            ->will($this->returnValue(['realKey' => []]));
756
757
        /** @var QueryCacheProfile|MockObject $queryCacheProfileMock */
758
        $queryCacheProfileMock = $this->createMock(QueryCacheProfile::class);
759
760
        $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...
761
            ->expects($this->any())
762
            ->method('getResultCacheDriver')
763
            ->will($this->returnValue($resultCacheDriverMock));
764
765
        $query = 'SELECT 1';
766
767
        $connectionParams = $this->params;
768
769
        $queryCacheProfileMock
770
            ->expects($this->once())
771
            ->method('generateCacheKeys')
772
            ->with($query, [], [], $connectionParams)
773
            ->will($this->returnValue(['cacheKey', 'realKey']));
774
775
        $connectionParams['platform'] = $this->createMock(AbstractPlatform::class);
776
777
        /** @var Driver $driver */
778
        $driver = $this->createMock(Driver::class);
779
780
        (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 758 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...
781
    }
782
783
    /**
784
     * @group #2821
785
     */
786
    public function testThrowsExceptionWhenInValidPlatformSpecified() : void
787
    {
788
        $connectionParams             = $this->params;
789
        $connectionParams['platform'] = new stdClass();
790
791
        /** @var Driver $driver */
792
        $driver = $this->createMock(Driver::class);
793
794
        $this->expectException(DBALException::class);
795
796
        new Connection($connectionParams, $driver);
797
    }
798
799
    /**
800
     * @group DBAL-990
801
     */
802
    public function testRethrowsOriginalExceptionOnDeterminingPlatformWhenConnectingToNonExistentDatabase() : void
803
    {
804
        /** @var VersionAwarePlatformDriver|MockObject $driverMock */
805
        $driverMock = $this->createMock(VersionAwarePlatformDriver::class);
806
807
        $connection        = new Connection(['dbname' => 'foo'], $driverMock);
0 ignored issues
show
Bug introduced by
It seems like $driverMock defined by $this->createMock(\Doctr...ePlatformDriver::class) on line 805 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...
808
        $originalException = new Exception('Original exception');
809
        $fallbackException = new Exception('Fallback exception');
810
811
        $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\DBAL\VersionAwarePlatformDriver.

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...
812
            ->method('connect')
813
            ->willThrowException($originalException);
814
815
        $driverMock->expects($this->at(1))
816
            ->method('connect')
817
            ->willThrowException($fallbackException);
818
819
        $this->expectExceptionMessage($originalException->getMessage());
820
821
        $connection->getDatabasePlatform();
822
    }
823
824
    /**
825
     * @group #3194
826
     */
827
    public function testExecuteCacheQueryStripsPlatformFromConnectionParamsBeforeGeneratingCacheKeys() : void
828
    {
829
        /** @var Driver|MockObject $driver */
830
        $driver = $this->createMock(Driver::class);
831
832
        /** @var AbstractPlatform|MockObject $platform */
833
        $platform = $this->createMock(AbstractPlatform::class);
834
835
        /** @var QueryCacheProfile|MockObject $queryCacheProfile */
836
        $queryCacheProfile = $this->createMock(QueryCacheProfile::class);
837
838
        /** @var Cache|MockObject $resultCacheDriver */
839
        $resultCacheDriver = $this->createMock(Cache::class);
840
841
        $queryCacheProfile
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...
842
            ->expects($this->any())
843
            ->method('getResultCacheDriver')
844
            ->will($this->returnValue($resultCacheDriver));
845
846
        $resultCacheDriver
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit\Framework\MockObject\MockObject, but not in Doctrine\Common\Cache\Cache.

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...
847
            ->expects($this->atLeastOnce())
848
            ->method('fetch')
849
            ->with('cacheKey')
850
            ->will($this->returnValue(['realKey' => []]));
851
852
        $query = 'SELECT 1';
853
854
        $params = [
855
            'dbname' => 'foo',
856
            'platform' => $platform,
857
        ];
858
859
        $paramsWithoutPlatform = $params;
860
        unset($paramsWithoutPlatform['platform']);
861
862
        $queryCacheProfile
863
            ->expects($this->once())
864
            ->method('generateCacheKeys')
865
            ->with($query, [], [], $paramsWithoutPlatform)
866
            ->will($this->returnValue(['cacheKey', 'realKey']));
867
868
        $connection = new Connection($params, $driver);
0 ignored issues
show
Bug introduced by
It seems like $driver defined by $this->createMock(\Doctrine\DBAL\Driver::class) on line 830 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...
869
870
        self::assertSame($params, $connection->getParams());
871
872
        $connection->executeCacheQuery($query, [], [], $queryCacheProfile);
0 ignored issues
show
Bug introduced by
It seems like $queryCacheProfile defined by $this->createMock(\Doctr...eryCacheProfile::class) on line 836 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...
873
    }
874
}
875