Passed
Pull Request — develop (#4)
by ANTHONIUS
04:07
created

Extension::load()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
rs 10
ccs 3
cts 3
cp 1
cc 1
nc 1
nop 2
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 3
        if(false === $input->hasParameterOption(['--coverage'])){
46 1
            return;
47
        }
48
49 2
        if(static::getDriverClass() === Dummy::class){
50
            /* @var \PhpSpec\Console\ConsoleIO $output */
51
            $output = $container->get('console.io');
52
            $output->writeln('<error>No code coverage driver available</error>');
53
            return;
54
        }
55
56 2
        $this->loadDriver($container, $params);
57 2
        $this->loadFilter($container, $params);
58 2
        $this->loadProcessor($container, $params);
59 2
        $this->loadReports($container, $params);
60 2
        $container->define('doyo.coverage.dispatcher', function($container){
0 ignored issues
show
Unused Code introduced by
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

60
        $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...
61 1
            $dispatcher = new EventDispatcher();
62
63 1
            return $dispatcher;
64 2
        });
65
66 2
        $container->define('doyo.coverage.listener',function($container){
67 1
            $dispatcher = $container->get('doyo.coverage.dispatcher');
68 1
            $consoleIO = $container->get('console.io');
69 1
            $processor = $container->get('doyo.coverage.processor');
70 1
            return new CoverageListener($dispatcher, $processor, $consoleIO);
71 2
        }, ['event_dispatcher.listeners']);
72
73 2
        $reports = $container->getByTag('doyo.coverage.reports');
74 2
        $dispatcher = $container->get('doyo.coverage.dispatcher');
75 2
        foreach($reports as $report){
76 2
            $dispatcher->addSubscriber($report);
77
        }
78
    }
79
80 2
    public static function getDriverClass()
81
    {
82 2
        static $runtime;
83 2
        if(!$runtime instanceof Runtime){
84 1
            $runtime = new Runtime();
85
        }
86
87 2
        $driverClass = Dummy::class;
88 2
        if($runtime->canCollectCodeCoverage()){
89 2
            if($runtime->isPHPDBG()){
90 2
                $driverClass = PHPDBG::class;
91
            }else{
92
                $driverClass = Xdebug::class;
93
            }
94
        }
95
96 2
        return $driverClass;
97
    }
98
99 2
    private function loadDriver(ServiceContainer $container, array $params)
100
    {
101 2
        $driverClass = static::getDriverClass();
102 2
        $container->define('doyo.coverage.driver', function() use ($params, $driverClass){
0 ignored issues
show
Unused Code introduced by
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...
103 1
            return new $driverClass;
104 2
        });
105
    }
106
107
    private function loadFilter(ServiceContainer $container, array $params)
108
    {
109 2
        $container->define('doyo.coverage.filter', function() use ($params){
110 1
            $filters = $params['filters'] ?:[];
111 1
            $whitelist = isset($filters['whitelist']) ? $filters['whitelist']:[];
112 1
            $blacklist = isset($filters['blacklist']) ? $filters['blacklist']:[];
113 1
            $filter = new Filter();
114
115 1
            foreach($whitelist as $dir){
116 1
                $filter->addDirectoryToWhitelist($dir);
117
            }
118
119 1
            foreach($blacklist as $dir){
120 1
                $filter->removeDirectoryFromWhitelist($dir);
121
            }
122
123 1
            return $filter;
124 2
        });
125
    }
126
127
    private function loadProcessor(ServiceContainer $container, array $params)
128
    {
129 2
        $container->define('doyo.coverage.processor', function($container) use ($params){
0 ignored issues
show
Unused Code introduced by
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...
130 1
            $driver = $container->get('doyo.coverage.driver');
131 1
            $filter = $container->get('doyo.coverage.filter');
132 1
            $processor = new Processor($driver, $filter);
133
134 1
            return $processor;
135 2
        });
136
    }
137
138 2
    private function loadReports(ServiceContainer $container, array $params)
139
    {
140
        $reports = [
141 2
            'html' => Facade::class,
142
            'php' => PHP::class
143
        ];
144
145 2
        $reportConfig = isset($params['reports']) ? $params['reports']:[];
146 2
        foreach($reports as $type => $class){
147 2
            $this->configureReport($container, $reportConfig, $type, $class);
148
        }
149
    }
150
151 2
    private function configureReport(ServiceContainer $container, array $reportConfig, $type, $class)
152
    {
153 2
        if(!isset($reportConfig[$type])){
154
            return;
155
        }
156
157 2
        $dirTypes = ['html'];
158 2
        $fsType = in_array($type, $dirTypes) ? 'dir':'file';
159 2
        $options = array();
160 2
        $test = $reportConfig[$type];
161
162 2
        if(is_string($test)){
163 2
            $options['target'] = $test;
164
        }else{
165
            $options = $reportConfig[$type];
166
        }
167
168 2
        $options['type'] = $fsType;
169 2
        $r = new \ReflectionClass($class);
170 2
        $constructorParams = [];
171
172 2
        if(!is_null($r->getConstructor())){
173 2
            foreach($r->getConstructor()->getParameters() as $parameter){
174 2
                $name = $parameter->getName();
175 2
                if($parameter->isDefaultValueAvailable()){
176 2
                    break;
177
                }
178
                $default = $parameter->getDefaultValue();
179
                $constructorParams[] = isset($options[$name]) ? $options[$name]:$default;
180
            }
181
        }
182
183 2
        $id = 'doyo.coverage.reports.'.$type;
184 2
        $container->define($id, function($container) use ($class, $constructorParams, $options){
0 ignored issues
show
Unused Code introduced by
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

184
        $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...
185 1
            $r = new \ReflectionClass($class);
186 1
            $processor = $r->newInstanceArgs($constructorParams);
187 1
            $report = new Report($processor, $options);
188 1
            return $report;
189 2
        },['doyo.coverage.reports']);
190
    }
191
}