DbRegenerationPHPUnitEventSubscriber::endTest()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hgraca\DoctrineTestDbRegenerationBundle\EventSubscriber;
6
7
use Exception;
8
use Hgraca\DoctrineTestDbRegenerationBundle\Doctrine\SchemaManager;
9
use Hgraca\DoctrineTestDbRegenerationBundle\Doctrine\SchemaManagerInterface;
10
use PHPUnit\Framework\TestListener;
11
use PHPUnit\Framework\TestListenerDefaultImplementation;
12
13
if (
14
    class_exists('PHPUnit_Runner_Version')
15
    && version_compare(PHPUnit_Runner_Version::id(), '5', '>=')
16
    && version_compare(PHPUnit_Runner_Version::id(), '6', '<')
17
) {
18
    // PHPUnit 5
19
20
    /**
21
     * @codeCoverageIgnore We can never cover both of these classes, although we do cover the trait
22
     */
23
    class DbRegenerationPHPUnitEventSubscriber extends \PHPUnit_Framework_BaseTestListener
0 ignored issues
show
Bug introduced by
The type PHPUnit_Framework_BaseTestListener was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
    {
25
        use DbRegenerationPHPUnitEventSubscriberTrait;
26
27
        /**
28
         * @throws \Exception
29
         */
30
        public function startTest(\PHPUnit_Framework_Test $test): void
0 ignored issues
show
Bug introduced by
The type PHPUnit_Framework_Test was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
        {
32
            $this->onTestStart($test);
33
        }
34
35
        /**
36
         * @throws \Exception
37
         */
38
        public function endTest(\PHPUnit_Framework_Test $test, $time): void
39
        {
40
            $this->onEndTest($test);
41
        }
42
    }
43
} elseif (class_exists('\PHPUnit\Runner\Version') && version_compare(\PHPUnit\Runner\Version::id(), '7', '<')) {
44
    // PHPUnit 6+
45
46
    /**
47
     * @codeCoverageIgnore We can never cover both of these classes, although we do cover the trait
48
     */
49
    class DbRegenerationPHPUnitEventSubscriber implements TestListener
50
    {
51
        use TestListenerDefaultImplementation,
52
            DbRegenerationPHPUnitEventSubscriberTrait;
53
54
        /**
55
         * @throws \Exception
56
         */
57
        public function startTest(\PHPUnit\Framework\Test $test): void
58
        {
59
            $this->onTestStart($test);
60
        }
61
62
        /**
63
         * @throws \Exception
64
         */
65
        public function endTest(\PHPUnit\Framework\Test $test, $time): void
66
        {
67
            $this->onEndTest($test);
68
        }
69
    }
70
} elseif (class_exists('\PHPUnit\Runner\Version') && version_compare(\PHPUnit\Runner\Version::id(), '7', '>=')) {
71
    // PHPUnit 7+
72
73
    /**
74
     * @codeCoverageIgnore We can never cover both of these classes, although we do cover the trait
75
     */
76
    class DbRegenerationPHPUnitEventSubscriber implements TestListener
77
    {
78
        use TestListenerDefaultImplementation,
79
            DbRegenerationPHPUnitEventSubscriberTrait;
80
81
        /**
82
         * @throws \Exception
83
         */
84
        public function startTest(\PHPUnit\Framework\Test $test): void
85
        {
86
            $this->onTestStart($test);
87
        }
88
89
        /**
90
         * @throws \Exception
91
         */
92
        public function endTest(\PHPUnit\Framework\Test $test, float $time): void
93
        {
94
            $this->onEndTest($test);
95
        }
96
    }
97
} else {
98
    throw new Exception('DoctrineTestDbRegenerationBundle doesn\'t work with such an old version of PHPUnit.');
99
}
100
101
trait DbRegenerationPHPUnitEventSubscriberTrait
102
{
103
    /**
104
     * @var bool
105
     */
106
    private $hasCreatedTestDatabaseBackup = false;
107
108
    /**
109
     * @var bool
110
     */
111
    private $hasRestoredTestDatabase = false;
112
113
    /**
114
     * @var SchemaManagerInterface
115
     */
116
    private static $schemaManager;
117
118
    /**
119
     * @var bool
120
     */
121
    private $shouldRegenerateDbOnEveryTest;
122
123
    /**
124
     * @var bool
125
     */
126
    private $shouldRemoveDbAfterEveryTest;
127
128
    /**
129
     * @var int
130
     */
131
    private $shouldReuseExistingDbBkp;
132
133
    /**
134
     * @var array
135
     */
136
    private $executeMigrations;
137
138 16
    public function __construct(
139
        int $shouldRemoveDbAfterEveryTest = 1,
140
        int $shouldRegenerateDbOnEveryTest = 1,
141
        int $shouldReuseExistingDbBkp = 0,
142
        array $executeMigrations = [],
143
        SchemaManagerInterface $schemaManager = null
144
    ) {
145 16
        $this->shouldRemoveDbAfterEveryTest = (bool) $shouldRemoveDbAfterEveryTest;
146 16
        $this->shouldRegenerateDbOnEveryTest = (bool) $shouldRegenerateDbOnEveryTest;
147 16
        $this->shouldReuseExistingDbBkp = (bool) $shouldReuseExistingDbBkp;
0 ignored issues
show
Documentation Bug introduced by
The property $shouldReuseExistingDbBkp was declared of type integer, but (bool)$shouldReuseExistingDbBkp is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
148 16
        $this->executeMigrations = $executeMigrations;
149 16
        self::$schemaManager = $schemaManager;
150 16
    }
151
152
    /**
153
     * @throws \Exception
154
     */
155 8
    private function onTestStart($test): void
156
    {
157 8
        if (!$test instanceof DatabaseAwareTestInterface) {
158 4
            return;
159
        }
160
161 4
        if (!$this->hasCreatedTestDatabaseBackup()) {
162 4
            $this->createTestDatabaseBackup($this->shouldReuseExistingDbBkp);
0 ignored issues
show
Bug introduced by
$this->shouldReuseExistingDbBkp of type integer is incompatible with the type boolean expected by parameter $shouldReuseExistingDbBkp of Hgraca\DoctrineTestDbReg...ateTestDatabaseBackup(). ( Ignorable by Annotation )

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

162
            $this->createTestDatabaseBackup(/** @scrutinizer ignore-type */ $this->shouldReuseExistingDbBkp);
Loading history...
163
        }
164
165 4
        if (!$this->hasRestoredTestDatabase() || $this->shouldRegenerateDbOnEveryTest) {
166 4
            $this->restoreTestDatabase();
167
        }
168 4
    }
169
170
    /**
171
     * At the end of each test that used the DB,
172
     * we remove the dirty DB just in case we forget
173
     * to add the interface to another test and it
174
     * ends up using a dirty DB, yielding unreliable results.
175
     * Its safer but slower though, so we can turn it off if we want to.
176
     *
177
     * @throws \ErrorException
178
     */
179 8
    public function onEndTest($test): void
180
    {
181 8
        if (!$this->shouldRemoveDbAfterEveryTest || !$test instanceof DatabaseAwareTestInterface) {
182 4
            return;
183
        }
184
185 4
        if ($this->shouldRegenerateDbOnEveryTest) {
186 2
            $this->getSchemaManager()->removeTestDatabase();
187
        }
188 4
    }
189
190
    /**
191
     * @throws \ErrorException
192
     */
193 6
    public static function getSchemaManager(): SchemaManagerInterface
194
    {
195 6
        return self::$schemaManager ?? self::$schemaManager = SchemaManager::constructUsingTestContainer();
196
    }
197
198 4
    private function hasCreatedTestDatabaseBackup(): bool
199
    {
200 4
        return $this->hasCreatedTestDatabaseBackup;
201
    }
202
203 4
    private function createdTestDatabaseBackup(): void
204
    {
205 4
        $this->hasCreatedTestDatabaseBackup = true;
206 4
    }
207
208 4
    private function hasRestoredTestDatabase(): bool
209
    {
210 4
        return $this->hasRestoredTestDatabase;
211
    }
212
213 4
    private function restoredTestDatabase(): void
214
    {
215 4
        $this->hasRestoredTestDatabase = true;
216 4
    }
217
218
    /**
219
     * @throws \ErrorException
220
     */
221 4
    private function createTestDatabaseBackup(bool $shouldReuseExistingDbBkp = false): void
222
    {
223 4
        $this->switchOffDoctrineTestBundleStaticDriver();
224 4
        $this->getSchemaManager()->createTestDatabaseBackup($shouldReuseExistingDbBkp, $this->executeMigrations);
225 4
        $this->createdTestDatabaseBackup();
226 4
        $this->switchOnDoctrineTestBundleStaticDriver();
227 4
    }
228
229
    /**
230
     * @throws \ErrorException
231
     */
232 4
    private function restoreTestDatabase(): void
233
    {
234 4
        $this->getSchemaManager()->restoreTestDatabase();
235 4
        $this->restoredTestDatabase();
236 4
    }
237
238 4
    private function switchOffDoctrineTestBundleStaticDriver(): void
239
    {
240 4
        if (\class_exists('DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver')) {
241
            \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver::setKeepStaticConnections(false);
0 ignored issues
show
Bug introduced by
The type DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
242
        }
243 4
    }
244
245 4
    private function switchOnDoctrineTestBundleStaticDriver(): void
246
    {
247 4
        if (\class_exists('DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver')) {
248
            \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver::setKeepStaticConnections(true);
249
        }
250 4
    }
251
}
252