Passed
Branch add-rector-actions (5668b1)
by Wilmer
03:26
created

TestCase::loadFixture()   B

Complexity

Conditions 10
Paths 72

Size

Total Lines 43
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 10
eloc 33
nc 72
nop 1
dl 0
loc 43
rs 7.6666
c 4
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\ActiveRecord\Tests;
6
7
use PHPUnit\Framework\TestCase as AbstractTestCase;
8
use Psr\Container\ContainerInterface;
9
use Psr\EventDispatcher\EventDispatcherInterface;
10
use Psr\EventDispatcher\ListenerProviderInterface;
11
use Psr\Log\LoggerInterface;
12
use ReflectionClass;
13
use ReflectionException;
14
use ReflectionObject;
15
use Yiisoft\ActiveRecord\ActiveRecordFactory;
16
use Yiisoft\Cache\ArrayCache;
17
use Yiisoft\Cache\Cache;
18
use Yiisoft\Cache\CacheInterface;
19
use Yiisoft\Db\Connection\ConnectionInterface;
20
use Yiisoft\Db\Connection\Dsn;
21
use Yiisoft\Db\Mssql\PDODriver as MssqlPDODriver;
22
use Yiisoft\Db\Mysql\PDODriver as MysqlPDODriver;
23
use Yiisoft\Db\Oracle\PDODriver as OraclePDODriver;
24
use Yiisoft\Db\Pgsql\PDODriver as PgsqlPDODriver;
25
use Yiisoft\Db\Sqlite\PDODriver as SqlitePDODriver;
26
use Yiisoft\Db\Mssql\Dsn as MssqlDsn;
27
use Yiisoft\Db\Mssql\ConnectionPDO as ConnectionPDOMssql;
28
use Yiisoft\Db\Mysql\ConnectionPDO as ConnectionPDOMysql;
29
use Yiisoft\Db\Oracle\ConnectionPDO as ConnectionPDOOracle;
30
use Yiisoft\Db\Pgsql\ConnectionPDO as ConnectionPDOPgsql;
31
use Yiisoft\Db\Sqlite\ConnectionPDO as ConnectionPDOSqlite;
32
use Yiisoft\Definitions\Reference;
33
use Yiisoft\Di\Container;
34
use Yiisoft\Di\ContainerConfig;
35
use Yiisoft\EventDispatcher\Dispatcher\Dispatcher;
36
use Yiisoft\EventDispatcher\Provider\Provider;
37
use Yiisoft\Factory\Factory;
38
use Yiisoft\Log\Logger;
39
use Yiisoft\Profiler\Profiler;
40
use Yiisoft\Profiler\ProfilerInterface;
41
42
use function array_merge;
43
use function explode;
44
use function file_get_contents;
45
use function preg_replace;
46
use function str_replace;
47
use function trim;
48
49
class TestCase extends AbstractTestCase
50
{
51
    protected ContainerInterface $container;
52
    protected ConnectionPDOMssql $mssqlConnection;
53
    protected ConnectionPDOMysql $mysqlConnection;
54
    protected ConnectionPDOOracle $ociConnection;
55
    protected ConnectionPDOPgsql $pgsqlConnection;
56
    protected ConnectionPDOSqlite $sqliteConnection;
57
    protected ActiveRecordFactory $arFactory;
58
59
    protected function setUp(): void
60
    {
61
        parent::setUp();
62
63
        $this->configContainer();
64
    }
65
66
    protected function configContainer(): void
67
    {
68
        $config = ContainerConfig::create()
69
            ->withDefinitions($this->config());
70
        $this->container = new Container($config);
71
72
        $this->mssqlConnection = $this->container->get(ConnectionPDOMssql::class);
73
        $this->mysqlConnection = $this->container->get(ConnectionPDOMysql::class);
74
        $this->ociConnection = $this->container->get(ConnectionPDOOracle::class);
75
        $this->pgsqlConnection = $this->container->get(ConnectionPDOPgsql::class);
76
        $this->sqliteConnection = $this->container->get(ConnectionPDOSqlite::class);
77
        $this->arFactory = $this->container->get(ActiveRecordFactory::class);
78
    }
79
80
    protected function checkFixture(ConnectionInterface $db, string $tablename, bool $reset = false): void
81
    {
82
        if ($db->getSchema()->getTableSchema($tablename, true) === null || $reset) {
83
            $this->loadFixture($db);
84
            $db->getSchema()->refresh();
85
        }
86
    }
87
88
    /**
89
     * Gets an inaccessible object property.
90
     *
91
     * @param bool $revoke whether to make property inaccessible after getting.
92
     *
93
     * @return mixed
94
     */
95
    protected function getInaccessibleProperty(object $object, string $propertyName, bool $revoke = true)
96
    {
97
        $class = new ReflectionClass($object);
98
99
        while (!$class->hasProperty($propertyName)) {
100
            $class = $class->getParentClass();
101
        }
102
103
        $property = $class->getProperty($propertyName);
104
105
        $property->setAccessible(true);
106
107
        $result = $property->getValue($object);
108
109
        if ($revoke) {
110
            $property->setAccessible(false);
111
        }
112
113
        return $result;
114
    }
115
116
    /**
117
     * Invokes a inaccessible method.
118
     *
119
     * @param $object
120
     * @param $method
121
     * @param array $args
122
     * @param bool $revoke whether to make method inaccessible after execution
123
     *
124
     * @throws ReflectionException
125
     *
126
     * @return mixed
127
     */
128
    protected function invokeMethod($object, $method, $args = [], $revoke = true)
129
    {
130
        $reflection = new ReflectionObject($object);
131
132
        $method = $reflection->getMethod($method);
133
134
        $method->setAccessible(true);
135
136
        $result = $method->invokeArgs($object, $args);
137
138
        if ($revoke) {
139
            $method->setAccessible(false);
140
        }
141
142
        return $result;
143
    }
144
145
    protected function loadFixture(ConnectionInterface $db): void
146
    {
147
        $fixture = null;
148
        switch ($this->driverName) {
149
            case 'mssql':
150
                $fixture = $this->params()['yiisoft/db-mssql']['fixture'];
151
                break;
152
            case 'mysql':
153
                $fixture = $this->params()['yiisoft/db-mysql']['fixture'];
154
                break;
155
            case 'oci':
156
                $fixture = $this->params()['yiisoft/db-oracle']['fixture'];
157
                break;
158
            case 'pgsql':
159
                $fixture = $this->params()['yiisoft/db-pgsql']['fixture'];
160
                break;
161
            case 'sqlite':
162
                $fixture = $this->params()['yiisoft/db-sqlite']['fixture'];
163
                break;
164
        }
165
166
        if ($db->isActive()) {
167
            $db->close();
168
        }
169
170
        $db->open();
171
172
        if ($this->driverName === 'oci') {
173
            [$drops, $creates] = explode('/* STATEMENTS */', file_get_contents($fixture), 2);
0 ignored issues
show
Bug introduced by
It seems like $fixture can also be of type null; however, parameter $filename of file_get_contents() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

173
            [$drops, $creates] = explode('/* STATEMENTS */', file_get_contents(/** @scrutinizer ignore-type */ $fixture), 2);
Loading history...
174
            [$statements, $triggers, $data] = explode('/* TRIGGERS */', $creates, 3);
175
            $lines = array_merge(
176
                explode('--', $drops),
177
                explode(';', $statements),
178
                explode('/', $triggers),
179
                explode(';', $data)
180
            );
181
        } else {
182
            $lines = explode(';', file_get_contents($fixture));
183
        }
184
185
        foreach ($lines as $line) {
186
            if (trim($line) !== '') {
187
                $db->getPDO()->exec($line);
0 ignored issues
show
Bug introduced by
The method getPDO() does not exist on Yiisoft\Db\Connection\ConnectionInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Yiisoft\Db\Connection\Connection. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

187
                $db->/** @scrutinizer ignore-call */ 
188
                     getPDO()->exec($line);
Loading history...
188
            }
189
        }
190
    }
191
192
    /**
193
     * Adjust dbms specific escaping.
194
     *
195
     * @param $sql
196
     *
197
     * @return mixed
198
     */
199
    protected function replaceQuotes($sql)
200
    {
201
        return match ($this->driverName) {
202
            'mysql', 'sqlite' => str_replace(['[[', ']]'], '`', $sql),
203
            'oci' => str_replace(['[[', ']]'], '"', $sql),
204
            'pgsql' => str_replace(['\\[', '\\]'], ['[', ']'], preg_replace('/(\[\[)|((?<!(\[))]])/', '"', $sql)),
205
            'mssql' => str_replace(['[[', ']]'], ['[', ']'], $sql),
206
            default => $sql,
207
        };
208
    }
209
210
    private function config(): array
211
    {
212
        $params = $this->params();
213
214
        return [
215
            CacheInterface::class => [
216
                'class' => Cache::class,
217
                '__construct()' => [
218
                    Reference::to(ArrayCache::class),
219
                ],
220
            ],
221
222
            LoggerInterface::class => Logger::class,
223
224
            ProfilerInterface::class => Profiler::class,
225
226
            ListenerProviderInterface::class => Provider::class,
227
228
            EventDispatcherInterface::class => Dispatcher::class,
229
230
            ConnectionPDOMssql::class => [
231
                'class' => ConnectionPDOMssql::class,
232
                '__construct()' => [
233
                    'driver' => $params['yiisoft/db-mssql']['driver'],
234
                ],
235
            ],
236
237
            ConnectionPDOMysql::class => [
238
                'class' => ConnectionPDOMysql::class,
239
                '__construct()' => [
240
                    'driver' => $params['yiisoft/db-mysql']['driver'],
241
                ],
242
            ],
243
244
            ConnectionPDOPgsql::class => [
245
                'class' => ConnectionPDOPgsql::class,
246
                '__construct()' => [
247
                    'driver' => $params['yiisoft/db-pgsql']['driver'],
248
                ],
249
            ],
250
251
            ConnectionPDOOracle::class => [
252
                'class' => ConnectionPDOOracle::class,
253
                '__construct()' => [
254
                    'driver' => $params['yiisoft/db-oracle']['driver'],
255
                ],
256
            ],
257
258
            ConnectionPDOSqlite::class => [
259
                'class' => ConnectionPDOSqlite::class,
260
                '__construct()' => [
261
                    'driver' => $params['yiisoft/db-sqlite']['driver'],
262
                ],
263
            ],
264
265
            Factory::class => [
266
                'class' => Factory::class,
267
                '__construct()' => [
268
                    'definitions' => [ConnectionInterface::class => Reference::to(ConnectionPDOSqlite::class)],
269
                ],
270
            ],
271
        ];
272
    }
273
274
    private function params(): array
275
    {
276
        return [
277
            'yiisoft/db-mssql' => [
278
                'driver' => new MssqlPDODriver(
279
                    (new MssqlDsn('sqlsrv', '127.0.0.1', 'yiitest', '1433'))->asString(),
280
                    'SA',
281
                    'YourStrong!Passw0rd',
282
                ),
283
                'fixture' => __DIR__ . '/Data/mssql.sql',
284
            ],
285
            'yiisoft/db-mysql' => [
286
                'driver' => new MysqlPDODriver(
287
                    (new Dsn('mysql', '127.0.0.1', 'yiitest', '3306'))->asString(),
288
                    'root',
289
                    '',
290
                ),
291
                'fixture' => __DIR__ . '/Data/mysql.sql',
292
            ],
293
            'yiisoft/db-pgsql' => [
294
                'driver' => new PgsqlPDODriver(
295
                    (new Dsn('pgsql', '127.0.0.1', 'yiitest', '5432'))->asString(),
296
                    'root',
297
                    'root'
298
                ),
299
                'fixture' => __DIR__ . '/Data/pgsql.sql',
300
            ],
301
            'yiisoft/db-oracle' => [
302
                'driver' => new OraclePDODriver(
303
                    'oci:dbname=localhost/XE;charset=AL32UTF8;',
304
                    'system',
305
                    'oracle',
306
                ),
307
                'fixture' => __DIR__ . '/Data/oci.sql',
308
            ],
309
            'yiisoft/db-sqlite' => [
310
                'driver' => new SqlitePDODriver('sqlite:' . __DIR__ . '/Data/Runtime/yiitest.sq3'),
311
                'fixture' => __DIR__ . '/Data/sqlite.sql',
312
            ],
313
        ];
314
    }
315
}
316