1 | <?php |
||
2 | |||
3 | namespace Doctrine\Tests\DBAL\Driver; |
||
4 | |||
5 | use Doctrine\DBAL\Connection; |
||
6 | use Doctrine\DBAL\Driver\DriverException; |
||
7 | use Doctrine\DBAL\Driver\ExceptionConverterDriver; |
||
8 | use Doctrine\DBAL\VersionAwarePlatformDriver; |
||
9 | use Doctrine\Tests\DbalTestCase; |
||
10 | use Throwable; |
||
11 | |||
12 | abstract class AbstractDriverTest extends DbalTestCase |
||
13 | { |
||
14 | const EXCEPTION_CONNECTION = 'Doctrine\DBAL\Exception\ConnectionException'; |
||
15 | const EXCEPTION_CONSTRAINT_VIOLATION = 'Doctrine\DBAL\Exception\ConstraintViolationException'; |
||
16 | const EXCEPTION_DATABASE_OBJECT_EXISTS = 'Doctrine\DBAL\Exception\DatabaseObjectExistsException'; |
||
17 | const EXCEPTION_DATABASE_OBJECT_NOT_FOUND = 'Doctrine\DBAL\Exception\DatabaseObjectNotFoundException'; |
||
18 | const EXCEPTION_DRIVER = 'Doctrine\DBAL\Exception\DriverException'; |
||
19 | const EXCEPTION_FOREIGN_KEY_CONSTRAINT_VIOLATION = 'Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException'; |
||
20 | const EXCEPTION_INVALID_FIELD_NAME = 'Doctrine\DBAL\Exception\InvalidFieldNameException'; |
||
21 | const EXCEPTION_NON_UNIQUE_FIELD_NAME = 'Doctrine\DBAL\Exception\NonUniqueFieldNameException'; |
||
22 | const EXCEPTION_NOT_NULL_CONSTRAINT_VIOLATION = 'Doctrine\DBAL\Exception\NotNullConstraintViolationException'; |
||
23 | const EXCEPTION_READ_ONLY = 'Doctrine\DBAL\Exception\ReadOnlyException'; |
||
24 | const EXCEPTION_SERVER = 'Doctrine\DBAL\Exception\ServerException'; |
||
25 | const EXCEPTION_SYNTAX_ERROR = 'Doctrine\DBAL\Exception\SyntaxErrorException'; |
||
26 | const EXCEPTION_TABLE_EXISTS = 'Doctrine\DBAL\Exception\TableExistsException'; |
||
27 | const EXCEPTION_TABLE_NOT_FOUND = 'Doctrine\DBAL\Exception\TableNotFoundException'; |
||
28 | const EXCEPTION_UNIQUE_CONSTRAINT_VIOLATION = 'Doctrine\DBAL\Exception\UniqueConstraintViolationException'; |
||
29 | const EXCEPTION_DEADLOCK = 'Doctrine\DBAL\Exception\DeadlockException'; |
||
30 | const EXCEPTION_LOCK_WAIT_TIMEOUT = 'Doctrine\DBAL\Exception\LockWaitTimeoutException'; |
||
31 | |||
32 | /** |
||
33 | * The driver mock under test. |
||
34 | * |
||
35 | * @var \Doctrine\DBAL\Driver |
||
36 | */ |
||
37 | protected $driver; |
||
38 | |||
39 | protected function setUp() |
||
40 | { |
||
41 | parent::setUp(); |
||
42 | |||
43 | $this->driver = $this->createDriver(); |
||
44 | } |
||
45 | |||
46 | public function testConvertsException() |
||
47 | { |
||
48 | if ( ! $this->driver instanceof ExceptionConverterDriver) { |
||
49 | $this->markTestSkipped('This test is only intended for exception converter drivers.'); |
||
50 | } |
||
51 | |||
52 | $data = $this->getExceptionConversions(); |
||
53 | |||
54 | if (empty($data)) { |
||
55 | $this->fail( |
||
56 | sprintf( |
||
57 | 'No test data found for test %s. You have to return test data from %s.', |
||
58 | get_class($this) . '::' . __FUNCTION__, |
||
59 | get_class($this) . '::getExceptionConversionData' |
||
60 | ) |
||
61 | ); |
||
62 | } |
||
63 | |||
64 | $driverException = new class extends \Exception implements DriverException |
||
65 | { |
||
66 | public function __construct() |
||
67 | { |
||
68 | parent::__construct('baz'); |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * {@inheritDoc} |
||
73 | */ |
||
74 | public function getErrorCode() |
||
75 | { |
||
76 | return 'foo'; |
||
77 | } |
||
78 | |||
79 | /** |
||
80 | * {@inheritDoc} |
||
81 | */ |
||
82 | public function getSQLState() |
||
83 | { |
||
84 | return 'bar'; |
||
85 | } |
||
86 | }; |
||
87 | |||
88 | $data[] = array($driverException, self::EXCEPTION_DRIVER); |
||
89 | |||
90 | $message = 'DBAL exception message'; |
||
91 | |||
92 | foreach ($data as $item) { |
||
93 | /** @var $driverException \Doctrine\DBAL\Driver\DriverException */ |
||
94 | list($driverException, $convertedExceptionClassName) = $item; |
||
95 | |||
96 | $convertedException = $this->driver->convertException($message, $driverException); |
||
97 | |||
98 | self::assertSame($convertedExceptionClassName, get_class($convertedException)); |
||
99 | |||
100 | self::assertSame($driverException->getErrorCode(), $convertedException->getErrorCode()); |
||
101 | self::assertSame($driverException->getSQLState(), $convertedException->getSQLState()); |
||
102 | self::assertSame($message, $convertedException->getMessage()); |
||
103 | } |
||
104 | } |
||
105 | |||
106 | public function testCreatesDatabasePlatformForVersion() |
||
107 | { |
||
108 | if ( ! $this->driver instanceof VersionAwarePlatformDriver) { |
||
109 | $this->markTestSkipped('This test is only intended for version aware platform drivers.'); |
||
110 | } |
||
111 | |||
112 | $data = $this->getDatabasePlatformsForVersions(); |
||
113 | |||
114 | if (empty($data)) { |
||
115 | $this->fail( |
||
116 | sprintf( |
||
117 | 'No test data found for test %s. You have to return test data from %s.', |
||
118 | get_class($this) . '::' . __FUNCTION__, |
||
119 | get_class($this) . '::getDatabasePlatformsForVersions' |
||
120 | ) |
||
121 | ); |
||
122 | } |
||
123 | |||
124 | foreach ($data as $item) { |
||
125 | self::assertSame($item[1], get_class($this->driver->createDatabasePlatformForVersion($item[0]))); |
||
126 | } |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * @expectedException \Doctrine\DBAL\DBALException |
||
131 | */ |
||
132 | public function testThrowsExceptionOnCreatingDatabasePlatformsForInvalidVersion() |
||
133 | { |
||
134 | if ( ! $this->driver instanceof VersionAwarePlatformDriver) { |
||
135 | $this->markTestSkipped('This test is only intended for version aware platform drivers.'); |
||
136 | } |
||
137 | |||
138 | $this->driver->createDatabasePlatformForVersion('foo'); |
||
139 | } |
||
140 | |||
141 | View Code Duplication | public function testReturnsDatabaseName() |
|
142 | { |
||
143 | $params = array( |
||
144 | 'user' => 'foo', |
||
145 | 'password' => 'bar', |
||
146 | 'dbname' => 'baz', |
||
147 | ); |
||
148 | |||
149 | $connection = $this->getConnectionMock(); |
||
150 | |||
151 | $connection->expects($this->once()) |
||
152 | ->method('getParams') |
||
153 | ->will($this->returnValue($params)); |
||
154 | |||
155 | self::assertSame($params['dbname'], $this->driver->getDatabase($connection)); |
||
156 | } |
||
157 | |||
158 | public function testReturnsDatabasePlatform() |
||
159 | { |
||
160 | self::assertEquals($this->createPlatform(), $this->driver->getDatabasePlatform()); |
||
161 | } |
||
162 | |||
163 | public function testReturnsSchemaManager() |
||
164 | { |
||
165 | $connection = $this->getConnectionMock(); |
||
166 | $schemaManager = $this->driver->getSchemaManager($connection); |
||
167 | |||
168 | self::assertEquals($this->createSchemaManager($connection), $schemaManager); |
||
169 | self::assertAttributeSame($connection, '_conn', $schemaManager); |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * Factory method for creating the driver instance under test. |
||
174 | * |
||
175 | * @return \Doctrine\DBAL\Driver |
||
176 | */ |
||
177 | abstract protected function createDriver(); |
||
178 | |||
179 | /** |
||
180 | * Factory method for creating the the platform instance return by the driver under test. |
||
181 | * |
||
182 | * The platform instance returned by this method must be the same as returned by |
||
183 | * the driver's getDatabasePlatform() method. |
||
184 | * |
||
185 | * @return \Doctrine\DBAL\Platforms\AbstractPlatform |
||
186 | */ |
||
187 | abstract protected function createPlatform(); |
||
188 | |||
189 | /** |
||
190 | * Factory method for creating the the schema manager instance return by the driver under test. |
||
191 | * |
||
192 | * The schema manager instance returned by this method must be the same as returned by |
||
193 | * the driver's getSchemaManager() method. |
||
194 | * |
||
195 | * @param Connection $connection The underlying connection to use. |
||
196 | * |
||
197 | * @return \Doctrine\DBAL\Schema\AbstractSchemaManager |
||
198 | */ |
||
199 | abstract protected function createSchemaManager(Connection $connection); |
||
200 | |||
201 | protected function getConnectionMock() |
||
202 | { |
||
203 | return $this->getMockBuilder('Doctrine\DBAL\Connection') |
||
204 | ->disableOriginalConstructor() |
||
205 | ->getMock(); |
||
206 | } |
||
207 | |||
208 | protected function getDatabasePlatformsForVersions() |
||
209 | { |
||
210 | return array(); |
||
211 | } |
||
212 | |||
213 | protected function getExceptionConversionData() |
||
214 | { |
||
215 | return array(); |
||
216 | } |
||
217 | |||
218 | private function getExceptionConversions() |
||
219 | { |
||
220 | $data = array(); |
||
221 | |||
222 | foreach ($this->getExceptionConversionData() as $convertedExceptionClassName => $errors) { |
||
223 | foreach ($errors as $error) { |
||
224 | View Code Duplication | $driverException = new class ($error[0], $error[1], $error[2]) |
|
0 ignored issues
–
show
|
|||
225 | extends \Exception |
||
226 | implements DriverException |
||
227 | { |
||
228 | /** |
||
229 | * @var mixed |
||
230 | */ |
||
231 | private $errorCode; |
||
232 | |||
233 | /** |
||
234 | * @var mixed |
||
235 | */ |
||
236 | private $sqlState; |
||
237 | |||
238 | public function __construct($errorCode, $sqlState, $message) |
||
239 | { |
||
240 | parent::__construct($message); |
||
241 | |||
242 | $this->errorCode = $errorCode; |
||
243 | $this->sqlState = $sqlState; |
||
244 | } |
||
245 | |||
246 | /** |
||
247 | * {@inheritDoc} |
||
248 | */ |
||
249 | public function getErrorCode() |
||
250 | { |
||
251 | return $this->errorCode; |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * {@inheritDoc} |
||
256 | */ |
||
257 | public function getSQLState() |
||
258 | { |
||
259 | return $this->sqlState; |
||
260 | } |
||
261 | }; |
||
262 | |||
263 | $data[] = array($driverException, $convertedExceptionClassName); |
||
264 | } |
||
265 | } |
||
266 | |||
267 | return $data; |
||
268 | } |
||
269 | } |
||
270 |
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.