Completed
Push — develop ( dc7798...5a6da7 )
by ANTHONIUS
12s queued 10s
created

Extension::canCollectCodeCoverage()   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
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
4
namespace Doyo\PhpSpec\CodeCoverage;
5
6
use Doyo\Bridge\CodeCoverage\Driver\Dummy;
7
use Doyo\PhpSpec\CodeCoverage\Listener\CoverageListener;
8
use Doyo\Symfony\Bridge\EventDispatcher\EventDispatcher;
9
use PhpSpec\Extension as BaseExtension;
10
use PhpSpec\ServiceContainer;
11
use SebastianBergmann\CodeCoverage\Driver\PHPDBG;
12
use SebastianBergmann\CodeCoverage\Driver\Xdebug;
13
use SebastianBergmann\CodeCoverage\Filter;
14
use SebastianBergmann\CodeCoverage\Report\Html\Facade;
15
use SebastianBergmann\CodeCoverage\Report\PHP;
16
use SebastianBergmann\Environment\Runtime;
17
use Symfony\Component\Console\Input\InputOption;
18
use Doyo\Bridge\CodeCoverage\Processor;
19
20
class Extension implements BaseExtension
21
{
22 1
    public function load(ServiceContainer $container, array $params)
23
    {
24 1
        $this->addCoverageOptions($container);
25 1
        $this->loadCoverageListener($container, $params);
26
    }
27
28 2
    public function addCoverageOptions(ServiceContainer $container)
29
    {
30
        /* @var \PhpSpec\Console\Command\RunCommand $command */
31 2
        $command = $container->get('console.commands.run');
32 2
        $command->addOption(
33 2
            'coverage',
34 2
            null,
35 2
            InputOption::VALUE_NONE,
36 2
            'Run phpspec with code coverage'
37
        );
38
    }
39
40 3
    public function loadCoverageListener(ServiceContainer $container, array $params)
41
    {
42
        /* @var \Symfony\Component\Console\Input\InputInterface $input */
43 3
        $input = $container->get('console.input');
44
45
46 3
        if(false === $input->hasParameterOption(['--coverage'])){
47 1
            return;
48
        }
49
50 2
        $this->loadDriver($container, $params);
51 2
        $this->loadFilter($container, $params);
52 2
        $this->loadProcessor($container, $params);
53 2
        $this->loadReports($container, $params);
54 2
        $container->define('doyo.coverage.dispatcher', function($container){
0 ignored issues
show
Unused Code introduced by Anthonius Munthi
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

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

54
        $container->define('doyo.coverage.dispatcher', function(/** @scrutinizer ignore-unused */ $container){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
55 1
            $dispatcher = new EventDispatcher();
56
57 1
            return $dispatcher;
58 2
        });
59
60 2
        $container->define('doyo.coverage.listener',function($container){
61 1
            $dispatcher = $container->get('doyo.coverage.dispatcher');
62 1
            $consoleIO = $container->get('console.io');
63 1
            $processor = $container->get('doyo.coverage.processor');
64 1
            $canCollectCoverage = Extension::canCollectCodeCoverage();
65 1
            return new CoverageListener($dispatcher, $processor, $consoleIO, $canCollectCoverage);
66 2
        }, ['event_dispatcher.listeners']);
67
68 2
        $reports = $container->getByTag('doyo.coverage.reports');
69 2
        $dispatcher = $container->get('doyo.coverage.dispatcher');
70 2
        foreach($reports as $report){
71 2
            $dispatcher->addSubscriber($report);
72
        }
73
    }
74
75 2
    public static function getDriverClass()
76
    {
77 2
        static $runtime;
78 2
        if(!$runtime instanceof Runtime){
79 1
            $runtime = new Runtime();
80
        }
81
82 2
        $driverClass = Dummy::class;
83 2
        if($runtime->canCollectCodeCoverage()){
84 2
            if($runtime->isPHPDBG()){
85 2
                $driverClass = PHPDBG::class;
86
            }else{
87
                $driverClass = Xdebug::class;
88
            }
89
        }
90
91 2
        return $driverClass;
92
    }
93
94 2
    private function loadDriver(ServiceContainer $container, array $params)
95
    {
96 2
        $driverClass = static::getDriverClass();
97 2
        $container->define('doyo.coverage.driver', function() use ($params, $driverClass){
0 ignored issues
show
Unused Code introduced by Anthonius Munthi
The import $params is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
98 1
            return new $driverClass;
99 2
        });
100
    }
101
102
    private function loadFilter(ServiceContainer $container, array $params)
103
    {
104 2
        $container->define('doyo.coverage.filter', function() use ($params){
105 1
            $filters = $params['filters'] ?:[];
106 1
            $whitelist = isset($filters['whitelist']) ? $filters['whitelist']:[];
107 1
            $blacklist = isset($filters['blacklist']) ? $filters['blacklist']:[];
108 1
            $filter = new Filter();
109
110 1
            foreach($whitelist as $dir){
111 1
                $filter->addDirectoryToWhitelist($dir);
112
            }
113
114 1
            foreach($blacklist as $dir){
115 1
                $filter->removeDirectoryFromWhitelist($dir);
116
            }
117
118 1
            return $filter;
119 2
        });
120
    }
121
122
    private function loadProcessor(ServiceContainer $container, array $params)
123
    {
124 2
        $container->define('doyo.coverage.processor', function($container) use ($params){
0 ignored issues
show
Unused Code introduced by Anthonius Munthi
The import $params is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
125 1
            $driver = $container->get('doyo.coverage.driver');
126 1
            $filter = $container->get('doyo.coverage.filter');
127 1
            $processor = new Processor($driver, $filter);
128
129 1
            return $processor;
130 2
        });
131
    }
132
133 2
    private function loadReports(ServiceContainer $container, array $params)
134
    {
135
        $reports = [
136 2
            'html' => Facade::class,
137
            'php' => PHP::class
138
        ];
139
140 2
        $reportConfig = isset($params['reports']) ? $params['reports']:[];
141 2
        foreach($reports as $type => $class){
142 2
            $this->configureReport($container, $reportConfig, $type, $class);
143
        }
144
    }
145
146 2
    private function configureReport(ServiceContainer $container, array $reportConfig, $type, $class)
147
    {
148 2
        if(!isset($reportConfig[$type])){
149
            return;
150
        }
151
152 2
        $dirTypes = ['html'];
153 2
        $fsType = in_array($type, $dirTypes) ? 'dir':'file';
154 2
        $options = array();
155 2
        $test = $reportConfig[$type];
156
157 2
        if(is_string($test)){
158 2
            $options['target'] = $test;
159
        }else{
160
            $options = $reportConfig[$type];
161
        }
162
163 2
        $options['type'] = $fsType;
164 2
        $r = new \ReflectionClass($class);
165 2
        $constructorParams = [];
166
167 2
        if(!is_null($r->getConstructor())){
168 2
            foreach($r->getConstructor()->getParameters() as $parameter){
169 2
                $name = $parameter->getName();
170 2
                if($parameter->isDefaultValueAvailable()){
171 2
                    break;
172
                }
173
                $default = $parameter->getDefaultValue();
174
                $constructorParams[] = isset($options[$name]) ? $options[$name]:$default;
175
            }
176
        }
177
178 2
        $id = 'doyo.coverage.reports.'.$type;
179 2
        $container->define($id, function($container) use ($class, $constructorParams, $options){
0 ignored issues
show
Unused Code introduced by Anthonius Munthi
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

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

179
        $container->define($id, function(/** @scrutinizer ignore-unused */ $container) use ($class, $constructorParams, $options){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
180 1
            $r = new \ReflectionClass($class);
181 1
            $processor = $r->newInstanceArgs($constructorParams);
182 1
            $report = new Report($processor, $options);
183 1
            return $report;
184 2
        },['doyo.coverage.reports']);
185
    }
186
187 1
    public static function canCollectCodeCoverage()
188
    {
189 1
        return Extension::class !== Dummy::class;
190
    }
191
}