Passed
Pull Request — develop (#8)
by ANTHONIUS
04:34
created

Session::getTestCase()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the doyo/behat-coverage-extension project.
5
 *
6
 * (c) Anthonius Munthi <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Doyo\Behat\Coverage\Bridge\CodeCoverage\Session;
15
16
use Doyo\Behat\Coverage\Bridge\CodeCoverage\Processor;
17
use Doyo\Behat\Coverage\Bridge\CodeCoverage\TestCase;
18
use Doyo\Behat\Coverage\Bridge\Exception\CacheException;
19
use SebastianBergmann\CodeCoverage\Filter;
20
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
21
22
abstract class Session implements \Serializable, SessionInterface
23
{
24
    const CACHE_KEY = 'session';
25
26
    /**
27
     * @var string|null
28
     */
29
    protected $name;
30
31
    /**
32
     * @var TestCase
33
     */
34
    protected $testCase;
35
36
    /**
37
     * @var FilesystemAdapter|null
38
     */
39
    protected $adapter;
40
41
    /**
42
     * @var array
43
     */
44
    protected $data = [];
45
46
    /**
47
     * @var array
48
     */
49
    protected $filterOptions = [];
50
51
    /**
52
     * @var Processor
53
     */
54
    protected $processor;
55
56
    /**
57
     * @var array
58
     */
59
    protected $codeCoverageOptions = [];
60
61
    /**
62
     * @var \Exception[]
63
     */
64
    protected $exceptions = [];
65
66
    /**
67
     * @var bool
68
     */
69
    protected $hasStarted = false;
70
71 25
    public function __construct($sessionName)
72
    {
73 25
        $dir               = sys_get_temp_dir().'/doyo/behat-coverage-extension';
74 25
        $adapter           = new FilesystemAdapter($sessionName, 0, $dir);
75 25
        $this->adapter     = $adapter;
76 25
        $this->name = $sessionName;
77
78 25
        $this->refresh();
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84 23
    public function reset()
85
    {
86 23
        $this->testCase   = null;
87 23
        $this->data       = [];
88 23
        $this->processor  = null;
89 23
        $this->exceptions = [];
90
91 23
        $this->save();
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97 25
    public function serialize()
98
    {
99
        $data = [
100 25
            $this->testCase,
101 25
            $this->data,
102 25
            $this->codeCoverageOptions,
103 25
            $this->filterOptions,
104 25
            $this->exceptions,
105
        ];
106
107 25
        return serialize($data);
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113 23
    public function unserialize($serialized)
114
    {
115
        list(
116 23
            $this->testCase,
117 23
            $this->data,
118 23
            $this->codeCoverageOptions,
119 23
            $this->filterOptions,
120 23
            $this->exceptions
121 23
        ) = unserialize($serialized);
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127 25
    public function refresh()
128
    {
129 25
        $adapter = $this->adapter;
130 25
        $cached  = $adapter->getItem(static::CACHE_KEY)->get();
0 ignored issues
show
Bug introduced by
The method getItem() does not exist on null. ( Ignorable by Annotation )

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

130
        $cached  = $adapter->/** @scrutinizer ignore-call */ getItem(static::CACHE_KEY)->get();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
131
132 25
        if ($cached instanceof self) {
133 22
            $this->testCase                   = $cached->getTestCase();
134 22
            $this->data                       = $cached->getData() ?: [];
135 22
            $this->exceptions                 = $cached->getExceptions();
136 22
            $this->filterOptions              = $cached->getFilterOptions();
137 22
            $this->codeCoverageOptions        = $cached->getCodeCoverageOptions();
138
        }
139
    }
140
141
    /**
142
     * @return string|null
143
     */
144 7
    public function getName()
145
    {
146 7
        return $this->name;
147
    }
148
149
    /**
150
     * @return TestCase
151
     */
152 23
    public function getTestCase()
153
    {
154 23
        return $this->testCase;
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160 19
    public function setTestCase(TestCase $testCase = null)
161
    {
162 19
        $this->testCase = $testCase;
163
164 19
        return $this;
165
    }
166
167
    /**
168
     * @return FilesystemAdapter|null
169
     */
170 1
    public function getAdapter(): FilesystemAdapter
171
    {
172 1
        return $this->adapter;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->adapter could return the type null which is incompatible with the type-hinted return Symfony\Component\Cache\Adapter\FilesystemAdapter. Consider adding an additional type-check to rule them out.
Loading history...
173
    }
174
175
    /**
176
     * @param FilesystemAdapter|null $adapter
177
     *
178
     * @return Cache
0 ignored issues
show
Bug introduced by
The type Doyo\Behat\Coverage\Brid...eCoverage\Session\Cache 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...
179
     */
180 1
    public function setAdapter(FilesystemAdapter $adapter): self
181
    {
182 1
        $this->adapter = $adapter;
183
184 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Doyo\Behat\Coverage\Brid...overage\Session\Session which is incompatible with the documented return type Doyo\Behat\Coverage\Brid...eCoverage\Session\Cache.
Loading history...
185
    }
186
187
    /**
188
     * {@inheritdoc}
189
     */
190 22
    public function getData()
191
    {
192 22
        return $this->data;
193
    }
194
195
    /**
196
     * @param array $data
197
     *
198
     * @return Cache
199
     */
200 4
    public function setData(array $data)
201
    {
202 4
        $this->data = $data;
203
    }
204
205
    /**
206
     * @return array
207
     */
208 22
    public function getCodeCoverageOptions(): array
209
    {
210 22
        return $this->codeCoverageOptions;
211
    }
212
213
    /**
214
     * {@inheritdoc}
215
     */
216 10
    public function setCodeCoverageOptions(array $codeCoverageOptions): self
217
    {
218 10
        $this->codeCoverageOptions = $codeCoverageOptions;
219
220 10
        return $this;
221
    }
222
223
    /**
224
     * @param Processor $processor
225
     *
226
     * @return Cache
227
     */
228 15
    public function setProcessor(Processor $processor = null)
229
    {
230 15
        $this->processor = $processor;
231
232 15
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Doyo\Behat\Coverage\Brid...overage\Session\Session which is incompatible with the documented return type Doyo\Behat\Coverage\Brid...eCoverage\Session\Cache.
Loading history...
233
    }
234
235 1
    public function getProcessor()
236
    {
237 1
        return $this->processor;
238
    }
239
240 22
    public function getFilterOptions(): array
241
    {
242 22
        return $this->filterOptions;
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248 10
    public function setFilterOptions(array $filterOptions)
249
    {
250 10
        $this->filterOptions = $filterOptions;
251
252 10
        return $this;
253
    }
254
255
    /**
256
     * {@inheritdoc}
257
     */
258 7
    public function hasExceptions()
259
    {
260 7
        return \count($this->exceptions) > 0;
261
    }
262
263
    /**
264
     * {@inheritdoc}
265
     */
266 22
    public function getExceptions()
267
    {
268 22
        return $this->exceptions;
269
    }
270
271
    /**
272
     * {@inheritdoc}
273
     */
274 9
    final public function start($driver = null)
275
    {
276 5
        if (null === $this->testCase) {
277 1
            return;
278
        }
279
        try {
280 4
            $processor = $this->processor;
281 4
            if (null === $processor) {
282 1
                $processor = $this->createCodeCoverage($driver);
283
            }
284 4
            $processor->start($this->testCase);
285 9
            $this->hasStarted = true;
286 1
        } catch (\Exception $e) {
287 1
            $message = sprintf(
288 1
                "Can not start code coverage in namespace: %s :\n%s",
289 1
                $this->name,
290 1
                $e->getMessage()
291
            );
292 1
            $this->exceptions[] = $message;
293
        }
294
    }
295
296
    /**
297
     * {@inheritdoc}
298
     */
299 25
    public function save()
300
    {
301 25
        $adapter = $this->adapter;
302 25
        $item    = $adapter->getItem(static::CACHE_KEY);
303
304 25
        $item->set($this);
305 25
        $adapter->save($item);
306
    }
307
308
    /**
309
     * @return Filter
310
     */
311 1
    protected function createCodeCoverageFilter()
312
    {
313 1
        $config = $this->filterOptions;
314 1
        $filter = new Filter();
315 1
        foreach ($config as $method => $value) {
316 1
            $method = 'set'.ucfirst($method);
317 1
            \call_user_func_array([$filter, $method], [$value]);
318
        }
319
320 1
        return $filter;
321
    }
322
323 8
    public function shutdown()
324
    {
325 8
        if ($this->hasStarted) {
326
            try {
327 8
                $this->stop();
328 2
            } catch (\Exception $e) {
329 2
                $this->exceptions[] = new CacheException($e->getMessage());
330
            }
331
        }
332
333 3
        $this->processor    = null;
334 3
        $this->hasStarted   = false;
335 3
        $this->save();
336
    }
337
338
    /**
339
     * @param mixed|null $driver
340
     *
341
     * @return Processor
342
     */
343 1
    protected function createCodeCoverage($driver = null)
344
    {
345 1
        $coverage = $this->processor;
346 1
        $filter   = $this->createCodeCoverageFilter();
347 1
        $options  = $this->codeCoverageOptions;
348
349 1
        if (null === $coverage) {
350 1
            $coverage        = new Processor($driver, $filter);
351 1
            $this->processor = $coverage;
352
        }
353
354 1
        foreach ($options as $method => $option) {
355 1
            $method = 'set'.ucfirst($method);
356 1
            \call_user_func_array([$coverage, $method], [$option]);
357
        }
358
359 1
        return $coverage;
360
    }
361
}
362