Passed
Pull Request — develop (#6)
by ANTHONIUS
04:16
created

Cache   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 292
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 95
dl 0
loc 292
ccs 104
cts 104
cp 1
rs 9.92
c 0
b 0
f 0
wmc 31

22 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A reset() 0 7 1
A readCache() 0 8 2
A setFilter() 0 11 2
A setData() 0 5 1
A serialize() 0 10 1
A getCoverageId() 0 3 1
A unserialize() 0 8 1
A setCoverageId() 0 5 1
A setCodeCoverageOptions() 0 5 1
A getExceptions() 0 3 1
A getData() 0 3 1
A getFilter() 0 3 1
A setAdapter() 0 5 1
A createCodeCoverage() 0 19 4
A createFilter() 0 9 2
A getCodeCoverageOptions() 0 3 1
A save() 0 7 1
A getNamespace() 0 3 1
A getAdapter() 0 3 1
A shutdown() 0 13 2
A startCoverage() 0 14 3
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;
15
16
use SebastianBergmann\CodeCoverage\CodeCoverage;
17
use SebastianBergmann\CodeCoverage\Filter;
18
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
19
20
class Cache implements \Serializable
21
{
22
    const CACHE_KEY = 'subject';
23
24
    /**
25
     * @var string|null
26
     */
27
    private $namespace;
28
29
    /**
30
     * @var string|null
31
     */
32
    private $coverageId;
33
34
    /**
35
     * @var FilesystemAdapter|null
36
     */
37
    private $adapter;
38
39
    /**
40
     * @var array
41
     */
42
    private $data = [];
43
44
    /**
45
     * @var array
46
     */
47
    private $filter = [];
48
49
    /**
50
     * @var CodeCoverage
51
     */
52
    private $codeCoverage;
53
54
    /**
55
     * @var array
56
     */
57
    private $codeCoverageOptions = [];
58
59
    /**
60
     * @var \Exception[]
61
     */
62
    private $exceptions = [];
63
64 21
    public function __construct($namespace)
65
    {
66 21
        $dir             = sys_get_temp_dir().'/doyo/behat-coverage-extension';
67 21
        $adapter         = new FilesystemAdapter($namespace, 0, $dir);
68 21
        $this->adapter   = $adapter;
69 21
        $this->namespace = $namespace;
70
71 21
        $this->readCache();
72
    }
73
74 14
    public function reset()
75
    {
76 14
        $this->coverageId = null;
77 14
        $this->data   = [];
78 14
        $this->exceptions = [];
79
80 14
        $this->save();
81
    }
82
83 21
    public function serialize()
84
    {
85
        $data = [
86 21
            $this->coverageId,
87 21
            $this->data,
88 21
            $this->codeCoverageOptions,
89 21
            $this->filter
90
        ];
91
92 21
        return serialize($data);
93
    }
94
95 19
    public function unserialize($serialized)
96
    {
97
        list(
98 19
            $this->coverageId,
99 19
            $this->data,
100 19
            $this->codeCoverageOptions,
101 19
            $this->filter
102 19
        ) = unserialize($serialized);
103
    }
104
105
    /**
106
     * @return string|null
107
     */
108 1
    public function getNamespace()
109
    {
110 1
        return $this->namespace;
111
    }
112
113
    /**
114
     * @return string|null
115
     */
116 19
    public function getCoverageId()
117
    {
118 19
        return $this->coverageId;
119
    }
120
121
    /**
122
     * @param string|null $coverageId
123
     *
124
     * @return Cache
125
     */
126 6
    public function setCoverageId(string $coverageId): self
127
    {
128 6
        $this->coverageId = $coverageId;
129
130 6
        return $this;
131
    }
132
133
    /**
134
     * @return FilesystemAdapter|null
135
     */
136 1
    public function getAdapter(): FilesystemAdapter
137
    {
138 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...
139
    }
140
141
    /**
142
     * @param FilesystemAdapter|null $adapter
143
     *
144
     * @return Cache
145
     */
146 1
    public function setAdapter(FilesystemAdapter $adapter): self
147
    {
148 1
        $this->adapter = $adapter;
149
150 1
        return $this;
151
    }
152
153
    /**
154
     * @return array
155
     */
156 19
    public function getData(): array
157
    {
158 19
        return $this->data;
159
    }
160
161
    /**
162
     * @param array $data
163
     *
164
     * @return Cache
165
     */
166 2
    public function setData(array $data): self
167
    {
168 2
        $this->data = $data;
169
170 2
        return $this;
171
    }
172
173
    /**
174
     * @return array
175
     */
176 1
    public function getCodeCoverageOptions(): array
177
    {
178 1
        return $this->codeCoverageOptions;
179
    }
180
181
    /**
182
     * @param array $codeCoverageOptions
183
     *
184
     * @return Cache
185
     */
186 11
    public function setCodeCoverageOptions(array $codeCoverageOptions): self
187
    {
188 11
        $this->codeCoverageOptions = $codeCoverageOptions;
189
190 11
        return $this;
191
    }
192
193 1
    public function getFilter(): array
194
    {
195 1
        return $this->filter;
196
    }
197
198
    /**
199
     * @param Filter|array $filter
200
     *
201
     * @return $this
202
     */
203 11
    public function setFilter($filter)
204
    {
205 11
        if ($filter instanceof Filter) {
206 9
            $whitelistedFiles              = $filter->getWhitelistedFiles();
207 9
            $filter                        = [];
208 9
            $filter['addFilesToWhitelist'] = $whitelistedFiles;
209
        }
210
211 11
        $this->filter = $filter;
212
213 11
        return $this;
214
    }
215
216 1
    public function getExceptions()
217
    {
218 1
        return $this->exceptions;
219
    }
220
221 21
    public function save()
222
    {
223 21
        $adapter = $this->adapter;
224 21
        $item    = $adapter->getItem(static::CACHE_KEY);
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

224
        /** @scrutinizer ignore-call */ 
225
        $item    = $adapter->getItem(static::CACHE_KEY);

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...
225
226 21
        $item->set($this);
227 21
        $adapter->save($item);
228
    }
229
230 21
    public function readCache()
231
    {
232 21
        $adapter = $this->adapter;
233 21
        $cached  = $adapter->getItem(static::CACHE_KEY)->get();
234
235 21
        if ($cached instanceof self) {
236 19
            $this->coverageId = $cached->getCoverageId();
237 19
            $this->data   = $cached->getData();
238
        }
239
    }
240
241
    /**
242
     * @return Filter
243
     */
244 3
    public function createFilter()
245
    {
246 3
        $config = $this->filter;
247 3
        $filter = new Filter();
248 3
        foreach ($config as $method => $value) {
249 1
            \call_user_func_array([$filter, $method], [$value]);
250
        }
251
252 3
        return $filter;
253
    }
254
255 3
    public function startCoverage($driver = null)
256
    {
257 2
        if (null === $this->coverageId) {
258 1
            return;
259
        }
260
        try {
261 2
            $coverage = $this->createCodeCoverage($driver);
262 2
            $coverage->start($this->getCoverageId());
263 3
            register_shutdown_function([$this, 'shutdown']);
264 1
        } catch (\Exception $e) {
265 1
            $this->exceptions[] = sprintf(
266 1
                "Can not start coverage in namespace: %s :\n%s",
267 1
                $this->namespace,
268 1
                $e->getMessage()
269
            );
270
        }
271
    }
272
273 3
    public function shutdown()
274
    {
275 3
        $codeCoverage = $this->codeCoverage;
276
277 3
        if (null === $codeCoverage) {
278 1
            return;
279
        }
280
281 3
        $data = $codeCoverage->stop();
282 1
        $this->data = $data;
283 1
        $this->codeCoverage = null;
284
285 1
        $this->save();
286
    }
287
288
    /**
289
     * @param mixed|null $driver
290
     *
291
     * @return CodeCoverage
292
     */
293 2
    private function createCodeCoverage($driver = null)
294
    {
295 2
        $coverage = $this->codeCoverage;
296 2
        $filter   = $this->createFilter();
297 2
        $options  = $this->codeCoverageOptions;
298
299 2
        if(is_null($coverage)){
300 2
            $coverage = new CodeCoverage($driver, $filter);
301 2
            $this->codeCoverage = $coverage;
302
        }
303
304 2
        foreach ($options as $method => $option) {
305 1
            $method = 'set'.$method;
306 1
            if (method_exists($coverage, $method)) {
307 1
                \call_user_func_array([$coverage, $method], [$option]);
308
            }
309
        }
310
311 2
        return $coverage;
312
    }
313
}
314