Passed
Pull Request — develop (#5)
by ANTHONIUS
04:29
created

Cache::getCodeCoverageOptions()   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;
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 $coverage = [];
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 19
    public function __construct($namespace)
65
    {
66 19
        $dir             = sys_get_temp_dir().'/doyo/behat-coverage-extension';
67 19
        $adapter         = new FilesystemAdapter($namespace, 0, $dir);
68 19
        $this->adapter   = $adapter;
69 19
        $this->namespace = $namespace;
70
71 19
        $this->readCache();
72
    }
73
74 12
    public function reset()
75
    {
76 12
        $this->coverageId = null;
77 12
        $this->coverage   = [];
78 12
        $this->exceptions = [];
79
80 12
        $this->save();
81
    }
82
83 19
    public function serialize()
84
    {
85
        $data = [
86 19
            $this->coverageId,
87 19
            $this->coverage,
88
        ];
89
90 19
        return serialize($data);
91
    }
92
93 17
    public function unserialize($serialized)
94
    {
95 17
        list($this->coverageId, $this->coverage) = unserialize($serialized);
96
    }
97
98
    /**
99
     * @return string|null
100
     */
101 1
    public function getNamespace()
102
    {
103 1
        return $this->namespace;
104
    }
105
106
    /**
107
     * @return string|null
108
     */
109 17
    public function getCoverageId()
110
    {
111 17
        return $this->coverageId;
112
    }
113
114
    /**
115
     * @param string|null $coverageId
116
     *
117
     * @return Cache
118
     */
119 4
    public function setCoverageId(string $coverageId): self
120
    {
121 4
        $this->coverageId = $coverageId;
122
123 4
        return $this;
124
    }
125
126
    /**
127
     * @return FilesystemAdapter|null
128
     */
129 1
    public function getAdapter(): FilesystemAdapter
130
    {
131 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...
132
    }
133
134
    /**
135
     * @param FilesystemAdapter|null $adapter
136
     *
137
     * @return Cache
138
     */
139 1
    public function setAdapter(FilesystemAdapter $adapter): self
140
    {
141 1
        $this->adapter = $adapter;
142
143 1
        return $this;
144
    }
145
146
    /**
147
     * @return array
148
     */
149 17
    public function getCoverage(): array
150
    {
151 17
        return $this->coverage;
152
    }
153
154
    /**
155
     * @param array $coverage
156
     *
157
     * @return Cache
158
     */
159 2
    public function setCoverage(array $coverage): self
160
    {
161 2
        $this->coverage = $coverage;
162
163 2
        return $this;
164
    }
165
166
    /**
167
     * @return array
168
     */
169 1
    public function getCodeCoverageOptions(): array
170
    {
171 1
        return $this->codeCoverageOptions;
172
    }
173
174
    /**
175
     * @param array $codeCoverageOptions
176
     *
177
     * @return Cache
178
     */
179 9
    public function setCodeCoverageOptions(array $codeCoverageOptions): self
180
    {
181 9
        $this->codeCoverageOptions = $codeCoverageOptions;
182
183 9
        return $this;
184
    }
185
186 1
    public function getFilter(): array
187
    {
188 1
        return $this->filter;
189
    }
190
191
    /**
192
     * @param Filter|array $filter
193
     *
194
     * @return $this
195
     */
196 10
    public function setFilter($filter)
197
    {
198 10
        if ($filter instanceof Filter) {
199 8
            $whitelistedFiles              = $filter->getWhitelistedFiles();
200 8
            $filter                        = [];
201 8
            $filter['addFilesToWhitelist'] = $whitelistedFiles;
202
        }
203
204 10
        $this->filter = $filter;
205
206 10
        return $this;
207
    }
208
209 19
    public function save()
210
    {
211 19
        $adapter = $this->adapter;
212 19
        $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

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