Total Complexity | 40 |
Total Lines | 328 |
Duplicated Lines | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
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.
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 |
||
19 | class ConnectionTest extends DbalFunctionalTestCase |
||
20 | { |
||
21 | protected function setUp() |
||
22 | { |
||
23 | $this->resetSharedConn(); |
||
24 | parent::setUp(); |
||
25 | } |
||
26 | |||
27 | protected function tearDown() |
||
31 | } |
||
32 | |||
33 | public function testGetWrappedConnection() |
||
34 | { |
||
35 | self::assertInstanceOf(DriverConnection::class, $this->connection->getWrappedConnection()); |
||
36 | } |
||
37 | |||
38 | public function testCommitWithRollbackOnlyThrowsException() |
||
45 | } |
||
46 | |||
47 | public function testTransactionNestingBehavior() |
||
48 | { |
||
49 | try { |
||
50 | $this->connection->beginTransaction(); |
||
51 | self::assertEquals(1, $this->connection->getTransactionNestingLevel()); |
||
52 | |||
53 | try { |
||
54 | $this->connection->beginTransaction(); |
||
55 | self::assertEquals(2, $this->connection->getTransactionNestingLevel()); |
||
56 | throw new Exception(); |
||
57 | $this->connection->commit(); // never reached |
||
|
|||
58 | } catch (Throwable $e) { |
||
59 | $this->connection->rollBack(); |
||
60 | self::assertEquals(1, $this->connection->getTransactionNestingLevel()); |
||
61 | //no rethrow |
||
62 | } |
||
63 | self::assertTrue($this->connection->isRollbackOnly()); |
||
64 | |||
65 | $this->connection->commit(); // should throw exception |
||
66 | $this->fail('Transaction commit after failed nested transaction should fail.'); |
||
67 | } catch (ConnectionException $e) { |
||
68 | self::assertEquals(1, $this->connection->getTransactionNestingLevel()); |
||
69 | $this->connection->rollBack(); |
||
70 | self::assertEquals(0, $this->connection->getTransactionNestingLevel()); |
||
71 | } |
||
72 | |||
73 | $this->connection->beginTransaction(); |
||
74 | $this->connection->close(); |
||
75 | $this->connection->beginTransaction(); |
||
76 | self::assertEquals(1, $this->connection->getTransactionNestingLevel()); |
||
77 | } |
||
78 | |||
79 | public function testTransactionNestingLevelIsResetOnReconnect() : void |
||
80 | { |
||
81 | if ($this->connection->getDatabasePlatform()->getName() === 'sqlite') { |
||
82 | $params = $this->connection->getParams(); |
||
83 | $params['memory'] = false; |
||
84 | $params['path'] = '/tmp/test_nesting.sqlite'; |
||
85 | |||
86 | $connection = DriverManager::getConnection( |
||
87 | $params, |
||
88 | $this->connection->getConfiguration(), |
||
89 | $this->connection->getEventManager() |
||
90 | ); |
||
91 | } else { |
||
92 | $connection = $this->connection; |
||
93 | } |
||
94 | |||
95 | $connection->executeQuery('CREATE TABLE test_nesting(test int not null)'); |
||
96 | |||
97 | $this->connection->beginTransaction(); |
||
98 | $this->connection->beginTransaction(); |
||
99 | $connection->close(); // connection closed in runtime (for example if lost or another application logic) |
||
100 | |||
101 | $connection->beginTransaction(); |
||
102 | $connection->executeQuery('insert into test_nesting values (33)'); |
||
103 | $connection->rollback(); |
||
104 | |||
105 | self::assertEquals(0, $connection->fetchColumn('select count(*) from test_nesting')); |
||
106 | } |
||
107 | |||
108 | public function testTransactionNestingBehaviorWithSavepoints() |
||
109 | { |
||
110 | if (! $this->connection->getDatabasePlatform()->supportsSavepoints()) { |
||
111 | $this->markTestSkipped('This test requires the platform to support savepoints.'); |
||
112 | } |
||
113 | |||
114 | $this->connection->setNestTransactionsWithSavepoints(true); |
||
115 | try { |
||
116 | $this->connection->beginTransaction(); |
||
117 | self::assertEquals(1, $this->connection->getTransactionNestingLevel()); |
||
118 | |||
119 | try { |
||
120 | $this->connection->beginTransaction(); |
||
121 | self::assertEquals(2, $this->connection->getTransactionNestingLevel()); |
||
122 | $this->connection->beginTransaction(); |
||
123 | self::assertEquals(3, $this->connection->getTransactionNestingLevel()); |
||
124 | $this->connection->commit(); |
||
125 | self::assertEquals(2, $this->connection->getTransactionNestingLevel()); |
||
126 | throw new Exception(); |
||
127 | $this->connection->commit(); // never reached |
||
128 | } catch (Throwable $e) { |
||
129 | $this->connection->rollBack(); |
||
130 | self::assertEquals(1, $this->connection->getTransactionNestingLevel()); |
||
131 | //no rethrow |
||
132 | } |
||
133 | self::assertFalse($this->connection->isRollbackOnly()); |
||
134 | try { |
||
135 | $this->connection->setNestTransactionsWithSavepoints(false); |
||
136 | $this->fail('Should not be able to disable savepoints in usage for nested transactions inside an open transaction.'); |
||
137 | } catch (ConnectionException $e) { |
||
138 | self::assertTrue($this->connection->getNestTransactionsWithSavepoints()); |
||
139 | } |
||
140 | $this->connection->commit(); // should not throw exception |
||
141 | } catch (ConnectionException $e) { |
||
142 | $this->fail('Transaction commit after failed nested transaction should not fail when using savepoints.'); |
||
143 | $this->connection->rollBack(); |
||
144 | } |
||
145 | } |
||
146 | |||
147 | public function testTransactionNestingBehaviorCantBeChangedInActiveTransaction() |
||
148 | { |
||
149 | if (! $this->connection->getDatabasePlatform()->supportsSavepoints()) { |
||
150 | $this->markTestSkipped('This test requires the platform to support savepoints.'); |
||
151 | } |
||
152 | |||
153 | $this->connection->beginTransaction(); |
||
154 | $this->expectException(ConnectionException::class); |
||
155 | $this->connection->setNestTransactionsWithSavepoints(true); |
||
156 | } |
||
157 | |||
158 | public function testSetNestedTransactionsThroughSavepointsNotSupportedThrowsException() |
||
159 | { |
||
160 | if ($this->connection->getDatabasePlatform()->supportsSavepoints()) { |
||
161 | $this->markTestSkipped('This test requires the platform not to support savepoints.'); |
||
162 | } |
||
163 | |||
164 | $this->expectException(ConnectionException::class); |
||
165 | $this->expectExceptionMessage('Savepoints are not supported by this driver.'); |
||
166 | |||
167 | $this->connection->setNestTransactionsWithSavepoints(true); |
||
168 | } |
||
169 | |||
170 | public function testCreateSavepointsNotSupportedThrowsException() |
||
171 | { |
||
172 | if ($this->connection->getDatabasePlatform()->supportsSavepoints()) { |
||
173 | $this->markTestSkipped('This test requires the platform not to support savepoints.'); |
||
174 | } |
||
175 | |||
176 | $this->expectException(ConnectionException::class); |
||
177 | $this->expectExceptionMessage('Savepoints are not supported by this driver.'); |
||
178 | |||
179 | $this->connection->createSavepoint('foo'); |
||
180 | } |
||
181 | |||
182 | public function testReleaseSavepointsNotSupportedThrowsException() |
||
183 | { |
||
184 | if ($this->connection->getDatabasePlatform()->supportsSavepoints()) { |
||
185 | $this->markTestSkipped('This test requires the platform not to support savepoints.'); |
||
186 | } |
||
187 | |||
188 | $this->expectException(ConnectionException::class); |
||
189 | $this->expectExceptionMessage('Savepoints are not supported by this driver.'); |
||
190 | |||
191 | $this->connection->releaseSavepoint('foo'); |
||
192 | } |
||
193 | |||
194 | public function testRollbackSavepointsNotSupportedThrowsException() |
||
195 | { |
||
196 | if ($this->connection->getDatabasePlatform()->supportsSavepoints()) { |
||
197 | $this->markTestSkipped('This test requires the platform not to support savepoints.'); |
||
198 | } |
||
199 | |||
200 | $this->expectException(ConnectionException::class); |
||
201 | $this->expectExceptionMessage('Savepoints are not supported by this driver.'); |
||
202 | |||
203 | $this->connection->rollbackSavepoint('foo'); |
||
204 | } |
||
205 | |||
206 | public function testTransactionBehaviorWithRollback() |
||
207 | { |
||
208 | try { |
||
209 | $this->connection->beginTransaction(); |
||
210 | self::assertEquals(1, $this->connection->getTransactionNestingLevel()); |
||
211 | |||
212 | throw new Exception(); |
||
213 | |||
214 | $this->connection->commit(); // never reached |
||
215 | } catch (Throwable $e) { |
||
216 | self::assertEquals(1, $this->connection->getTransactionNestingLevel()); |
||
217 | $this->connection->rollBack(); |
||
218 | self::assertEquals(0, $this->connection->getTransactionNestingLevel()); |
||
219 | } |
||
220 | } |
||
221 | |||
222 | public function testTransactionBehaviour() |
||
223 | { |
||
224 | try { |
||
225 | $this->connection->beginTransaction(); |
||
226 | self::assertEquals(1, $this->connection->getTransactionNestingLevel()); |
||
227 | $this->connection->commit(); |
||
228 | } catch (Throwable $e) { |
||
229 | $this->connection->rollBack(); |
||
230 | self::assertEquals(0, $this->connection->getTransactionNestingLevel()); |
||
231 | } |
||
232 | |||
233 | self::assertEquals(0, $this->connection->getTransactionNestingLevel()); |
||
234 | } |
||
235 | |||
236 | public function testTransactionalWithException() |
||
237 | { |
||
238 | try { |
||
239 | $this->connection->transactional(static function ($conn) { |
||
240 | /** @var Connection $conn */ |
||
241 | $conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL()); |
||
242 | throw new RuntimeException('Ooops!'); |
||
243 | }); |
||
244 | $this->fail('Expected exception'); |
||
245 | } catch (RuntimeException $expected) { |
||
246 | self::assertEquals(0, $this->connection->getTransactionNestingLevel()); |
||
247 | } |
||
248 | } |
||
249 | |||
250 | public function testTransactionalWithThrowable() |
||
251 | { |
||
252 | try { |
||
253 | $this->connection->transactional(static function ($conn) { |
||
254 | /** @var Connection $conn */ |
||
255 | $conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL()); |
||
256 | throw new Error('Ooops!'); |
||
257 | }); |
||
258 | $this->fail('Expected exception'); |
||
259 | } catch (Error $expected) { |
||
260 | self::assertEquals(0, $this->connection->getTransactionNestingLevel()); |
||
261 | } |
||
262 | } |
||
263 | |||
264 | public function testTransactional() |
||
265 | { |
||
266 | $res = $this->connection->transactional(static function ($conn) { |
||
267 | /** @var Connection $conn */ |
||
268 | $conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL()); |
||
269 | }); |
||
270 | |||
271 | self::assertNull($res); |
||
272 | } |
||
273 | |||
274 | public function testTransactionalReturnValue() |
||
275 | { |
||
276 | $res = $this->connection->transactional(static function () { |
||
277 | return 42; |
||
278 | }); |
||
279 | |||
280 | self::assertEquals(42, $res); |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * Tests that the quote function accepts DBAL and PDO types. |
||
285 | */ |
||
286 | public function testQuote() |
||
287 | { |
||
288 | self::assertEquals( |
||
289 | $this->connection->quote('foo', Type::STRING), |
||
290 | $this->connection->quote('foo', ParameterType::STRING) |
||
291 | ); |
||
292 | } |
||
293 | |||
294 | public function testPingDoesTriggersConnect() |
||
295 | { |
||
296 | self::assertTrue($this->connection->ping()); |
||
297 | self::assertTrue($this->connection->isConnected()); |
||
298 | } |
||
299 | |||
300 | /** |
||
301 | * @group DBAL-1025 |
||
302 | */ |
||
303 | public function testConnectWithoutExplicitDatabaseName() |
||
321 | } |
||
322 | |||
323 | /** |
||
324 | * @group DBAL-990 |
||
325 | */ |
||
326 | public function testDeterminesDatabasePlatformWhenConnectingToNonExistentDatabase() |
||
327 | { |
||
328 | if (in_array($this->connection->getDatabasePlatform()->getName(), ['oracle', 'db2'], true)) { |
||
329 | $this->markTestSkipped('Platform does not support connecting without database name.'); |
||
330 | } |
||
331 | |||
332 | $params = $this->connection->getParams(); |
||
333 | |||
334 | $params['dbname'] = 'foo_bar'; |
||
347 | } |
||
348 | } |
||
349 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.