Passed
Pull Request — master (#18)
by ANTHONIUS
05:16
created

AbstractSession   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 242
Duplicated Lines 0 %

Test Coverage

Coverage 65.25%

Importance

Changes 0
Metric Value
eloc 92
dl 0
loc 242
ccs 92
cts 141
cp 0.6525
rs 10
c 0
b 0
f 0
wmc 27

19 Methods

Rating   Name   Duplication   Size   Complexity  
A getProcessor() 0 3 1
A reset() 0 6 1
A start() 0 24 3
A stop() 0 14 2
A setTestCase() 0 3 1
A getName() 0 3 1
A serialize() 0 5 1
A createContainer() 0 4 1
A save() 0 8 1
A toCache() 0 9 2
A fromCache() 0 4 2
A init() 0 7 1
A refresh() 0 11 2
A unserialize() 0 4 1
A addException() 0 7 2
A __construct() 0 9 1
A getExceptions() 0 3 1
A shutdown() 0 6 2
A hasExceptions() 0 3 1
1
<?php
2
3
/*
4
 * This file is part of the doyo/code-coverage project.
5
 *
6
 * (c) Anthonius Munthi <https://itstoni.com>
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\Bridge\CodeCoverage\Session;
15
16
use Doyo\Bridge\CodeCoverage\ContainerFactory;
17
use Doyo\Bridge\CodeCoverage\Exception\SessionException;
18
use Doyo\Bridge\CodeCoverage\ProcessorInterface;
19
use Doyo\Bridge\CodeCoverage\TestCase;
20
use Psr\Container\ContainerInterface;
21
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
22
23
abstract class AbstractSession implements SessionInterface, \Serializable
24
{
25
    const CACHE_KEY = 'session';
26
27
    /**
28
     * @var string
29
     */
30
    protected $name;
31
32
    /**
33
     * @var TestCase|null
34
     */
35
    protected $testCase;
36
37
    /**
38
     * @var FilesystemAdapter|null
39
     */
40
    protected $adapter;
41
42
    /**
43
     * @var ProcessorInterface
44
     */
45
    protected $processor;
46
47
    /**
48
     * @var array
49
     */
50
    protected $exceptions = [];
51
52
    /**
53
     * @var array
54
     */
55
    protected $config = [];
56
57
    /**
58
     * @var ContainerInterface|null
59
     */
60
    protected $container;
61
62
    /**
63
     * @var ProcessorInterface|null
64
     */
65
    protected $currentProcessor;
66
67
    protected $cachedProperties = [
68
        'name',
69
        'processor',
70
        'exceptions',
71
        'config',
72
        'testCase',
73
    ];
74
75
    private $started = false;
76
77
    /**
78
     * AbstractSession constructor.
79
     *
80
     * @param string $name
81
     * @param array  $config
82
     */
83 17
    public function __construct(string $name)
84
    {
85 17
        $dir           = sys_get_temp_dir().'/doyo/code-coverage/sessions';
86 17
        $this->adapter = new FilesystemAdapter($name, 0, $dir);
87 17
        $this->refresh();
88
89 17
        $this->name = $name;
90
91 17
        register_shutdown_function([$this, 'shutdown']);
92
    }
93
94 9
    public function init(array $config)
95
    {
96 9
        $this->config = $config;
97 9
        $this->createContainer($config);
98 9
        $this->processor = $this->container->get('factory')->createProcessor(true);
99 9
        $this->reset();
100 9
        $this->save();
101
    }
102
103 3
    public function serialize()
104
    {
105 3
        $data = $this->toCache();
106
107 3
        return serialize($data);
108
    }
109
110 2
    public function unserialize($serialized)
111
    {
112 2
        $cache = unserialize($serialized);
113 2
        $this->fromCache($cache);
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119 3
    public function getName(): string
120
    {
121 3
        return $this->name;
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127 4
    public function getProcessor()
128
    {
129 4
        return $this->processor;
130
    }
131
132 17
    public function refresh()
133
    {
134 17
        $adapter = $this->adapter;
135
136 17
        $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

136
        $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...
137
138 17
        if(!is_null($cached)){
139 13
            $this->fromCache($cached);
140
        }
141
142 17
        $this->createContainer($this->config);
143
    }
144
145 17
    private function createContainer($config)
146
    {
147 17
        $container       = (new ContainerFactory($config))->getContainer();
148 17
        $this->container = $container;
149
    }
150
151 11
    private function toCache()
152
    {
153 11
        $data = [];
154
155 11
        foreach ($this->cachedProperties as $property) {
156 11
            $data[$property] = $this->{$property};
157
        }
158
159 11
        return $data;
160
    }
161
162 13
    private function fromCache(array $cache)
163
    {
164 13
        foreach ($cache as $name => $value) {
165 13
            $this->{$name} = $value;
166
        }
167
    }
168
169 11
    public function save()
170
    {
171 11
        $adapter = $this->adapter;
172 11
        $item    = $adapter->getItem(static::CACHE_KEY);
173 11
        $data    = $this->toCache();
174
175 11
        $item->set($data);
176 11
        $adapter->save($item);
177
    }
178
179 9
    public function reset()
180
    {
181 9
        $this->testCase   = null;
182 9
        $this->exceptions = [];
183
184 9
        $this->processor->clear();
185
    }
186
187 4
    public function hasExceptions()
188
    {
189 4
        return \count($this->exceptions) > 0;
190
    }
191
192 2
    public function getExceptions()
193
    {
194 2
        return $this->exceptions;
195
    }
196
197 4
    public function addException(\Exception $exception)
198
    {
199 4
        $message = $exception->getMessage();
200 4
        $id      = md5($message);
201
202 4
        if (!isset($this->exceptions[$id])) {
203 4
            $this->exceptions[$id] = $exception;
204
        }
205
    }
206
207 5
    public function setTestCase(TestCase $testCase)
208
    {
209 5
        $this->testCase = $testCase;
210
    }
211
212
    /**
213
     * @throws SessionException If TestCase is null
214
     */
215 6
    public function start()
216
    {
217 6
        if (null === $this->testCase) {
218 2
            throw new SessionException('Can not start coverage with null TestCase');
219
        }
220
221
        try {
222 4
            $container = $this->container;
223 4
            $testCase  = $this->testCase;
224 4
            $processor = $container->get('factory')->createProcessor();
0 ignored issues
show
Bug introduced by
The method get() 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
            $processor = $container->/** @scrutinizer ignore-call */ get('factory')->createProcessor();

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 4
            $processor->start($testCase);
227
228 5
            $this->currentProcessor = $processor;
229 5
            $this->started = true;
230 1
        } catch (\Exception $exception) {
231 1
            $this->started = false;
232 1
            $message = sprintf(
233 1
                "Can not start coverage on session %s. Error message:\n%s",
234 1
                $this->getName(),
235 1
                $exception->getMessage()
236
            );
237 1
            $exception = new  SessionException($message);
238 1
            $this->addException($exception);
239
        }
240
    }
241
242 3
    public function stop()
243
    {
244
        try{
245 3
            $this->currentProcessor->stop();
0 ignored issues
show
Bug introduced by
The method stop() 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

245
            $this->currentProcessor->/** @scrutinizer ignore-call */ 
246
                                     stop();

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...
246 3
            $this->processor->merge($this->currentProcessor);
247 2
            $this->started = false;
248 1
        }catch (\Exception $exception){
249 1
            $message = sprintf(
250 1
                "Can not stop coverage on session <comment>%s</comment>. Error message:\n<error>%s</error>",
251 1
                $this->name,
252 1
                $exception->getMessage()
253
            );
254 1
            $e = new SessionException($message);
255 1
            $this->addException($e);
256
        }
257
    }
258
259 1
    public function shutdown()
260
    {
261 1
        if ($this->started) {
262 1
            $this->stop();
263
        }
264 1
        $this->save();
265
    }
266
}
267