Passed
Push — master ( 4425a9...7a5165 )
by Doug
09:36
created

Extension::initCodeCoverage()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 54
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 7.0336

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 7
eloc 33
c 3
b 0
f 0
nc 24
nop 5
dl 0
loc 54
ccs 31
cts 34
cp 0.9118
crap 7.0336
rs 8.4586

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Behat Code Coverage
4
 */
5
declare(strict_types=1);
6
7
namespace DVDoug\Behat\CodeCoverage;
8
9
use function array_walk;
10
use Behat\Testwork\Cli\ServiceContainer\CliExtension;
11
use Behat\Testwork\ServiceContainer\Extension as ExtensionInterface;
12
use Behat\Testwork\ServiceContainer\ExtensionManager;
13
use DVDoug\Behat\CodeCoverage\Subscriber\EventSubscriber;
14
use ReflectionClass;
15
use SebastianBergmann\CodeCoverage\CodeCoverage;
16
use SebastianBergmann\CodeCoverage\Driver\Driver;
17
use SebastianBergmann\CodeCoverage\Driver\Selector;
18
use SebastianBergmann\CodeCoverage\Driver\Xdebug2NotEnabledException;
19
use SebastianBergmann\CodeCoverage\Driver\Xdebug3NotEnabledException;
20
use SebastianBergmann\CodeCoverage\Filter;
21
use SebastianBergmann\CodeCoverage\NoCodeCoverageDriverAvailableException;
22
use SebastianBergmann\CodeCoverage\NoCodeCoverageDriverWithPathCoverageSupportAvailableException;
23
use function sprintf;
24
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
25
use Symfony\Component\Config\FileLocator;
26
use Symfony\Component\Console\Input\InputInterface;
27
use Symfony\Component\Console\Output\OutputInterface;
28
use Symfony\Component\DependencyInjection\ContainerBuilder;
29
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
30
use Symfony\Component\DependencyInjection\Reference;
31
use function sys_get_temp_dir;
32
33
class Extension implements ExtensionInterface
34
{
35
    /**
36
     * {@inheritdoc}
37
     */
38 4
    public function initialize(ExtensionManager $extensionManager): void
39
    {
40 4
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45 4
    public function load(ContainerBuilder $container, array $config): void
46
    {
47 4
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/Resources/config'));
48
49 4
        $servicesFile = 'services.xml';
50 4
        $loader->load($servicesFile);
51
52 4
        $container->setParameter('behat.code_coverage.config.filter', $config['filter']);
53 4
        $container->setParameter('behat.code_coverage.config.branchAndPathCoverage', $config['branchAndPathCoverage']);
54 4
        $container->setParameter('behat.code_coverage.config.reports', $config['reports'] ?? []);
55 4
        $container->setParameter('behat.code_coverage.config.cache', $config['cache']);
56 4
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61 8
    public function configure(ArrayNodeDefinition $builder): void
62
    {
63
        $builder
64 8
            ->children()
65 8
                ->scalarNode('cache')
66 8
                    ->defaultValue(sys_get_temp_dir() . '/behat-code-coverage-cache')
67 8
                ->end()
68 8
                ->booleanNode('branchAndPathCoverage')
0 ignored issues
show
Bug introduced by
The method booleanNode() does not exist on Symfony\Component\Config...der\NodeParentInterface. It seems like you code against a sub-type of Symfony\Component\Config...der\NodeParentInterface such as Symfony\Component\Config...ion\Builder\NodeBuilder. ( Ignorable by Annotation )

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

68
                ->/** @scrutinizer ignore-call */ booleanNode('branchAndPathCoverage')
Loading history...
69 8
                  ->defaultNull() // use null to mean auto
70 8
                ->end()
71 8
                ->arrayNode('filter')
72 8
                    ->addDefaultsIfNotSet()
73 8
                    ->children()
74 8
                        ->scalarNode('includeUncoveredFiles')
75 8
                            ->defaultTrue()
76 8
                        ->end()
77 8
                        ->scalarNode('processUncoveredFiles')
78 8
                            ->defaultFalse()
79 8
                            ->setDeprecated('dvdoug/behat-code-coverage', '5.3', 'the processUncoveredFiles setting is deprecated, it has been removed from php-code-coverage v10')
80 8
                        ->end()
81 8
                        ->arrayNode('include')
82 8
                            ->addDefaultsIfNotSet()
83 8
                            ->children()
84 8
                                ->arrayNode('directories')
85 8
                                   ->useAttributeAsKey('name')
86 8
                                   ->normalizeKeys(false)
87 8
                                   ->prototype('array')
88 8
                                       ->children()
89 8
                                           ->scalarNode('prefix')->defaultValue('')->end()
90 8
                                           ->scalarNode('suffix')->defaultValue('.php')->end()
91 8
                                       ->end()
92 8
                                   ->end()
93 8
                                ->end()
94 8
                                ->arrayNode('files')
95 8
                                   ->prototype('scalar')->end()
96 8
                                ->end()
97 8
                            ->end()
98 8
                        ->end()
99 8
                        ->arrayNode('exclude')
100 8
                            ->addDefaultsIfNotSet()
101 8
                            ->children()
102 8
                                ->arrayNode('directories')
103 8
                                   ->useAttributeAsKey('name')
104 8
                                   ->normalizeKeys(false)
105 8
                                   ->prototype('array')
106 8
                                       ->children()
107 8
                                           ->scalarNode('prefix')->defaultValue('')->end()
108 8
                                           ->scalarNode('suffix')->defaultValue('.php')->end()
109 8
                                       ->end()
110 8
                                   ->end()
111 8
                                ->end()
112 8
                                ->arrayNode('files')
113 8
                                   ->prototype('scalar')->end()
114 8
                                ->end()
115 8
                            ->end()
116 8
                        ->end()
117 8
                    ->end()
118 8
                ->end()
119 8
                ->arrayNode('reports')
120 8
                    ->children()
121 8
                        ->arrayNode('cobertura')
122 8
                            ->children()
123 8
                                ->scalarNode('name')->defaultNull()->end()
124 8
                                ->scalarNode('target')->isRequired()->cannotBeEmpty()->end()
125 8
                            ->end()
126 8
                        ->end()
127 8
                        ->arrayNode('clover')
128 8
                            ->children()
129 8
                                ->scalarNode('name')->defaultNull()->end()
130 8
                                ->scalarNode('target')->isRequired()->cannotBeEmpty()->end()
131 8
                            ->end()
132 8
                        ->end()
133 8
                        ->arrayNode('crap4j')
134 8
                            ->children()
135 8
                                ->scalarNode('name')->defaultNull()->end()
136 8
                                ->scalarNode('target')->isRequired()->cannotBeEmpty()->end()
137 8
                            ->end()
138 8
                        ->end()
139 8
                        ->arrayNode('html')
140 8
                            ->children()
141 8
                                ->scalarNode('target')->isRequired()->cannotBeEmpty()->end()
142 8
                                ->scalarNode('lowUpperBound')->defaultValue(50)->end()
143 8
                                ->scalarNode('highLowerBound')->defaultValue(90)->end()
144 8
                            ->end()
145 8
                        ->end()
146 8
                        ->arrayNode('php')
147 8
                            ->children()
148 8
                                ->scalarNode('target')->isRequired()->cannotBeEmpty()->end()
149 8
                            ->end()
150 8
                        ->end()
151 8
                        ->arrayNode('text')
152 8
                            ->children()
153 8
                                ->booleanNode('showColors')->defaultValue(false)->end()
154 8
                                ->scalarNode('lowUpperBound')->defaultValue(50)->end()
155 8
                                ->scalarNode('highLowerBound')->defaultValue(90)->end()
156 8
                                ->booleanNode('showOnlySummary')->defaultValue(false)->end()
157 8
                                ->booleanNode('showUncoveredFiles')->defaultValue(false)->end()
158 8
                            ->end()
159 8
                        ->end()
160 8
                        ->arrayNode('xml')
161 8
                            ->children()
162 8
                                ->scalarNode('target')->isRequired()->cannotBeEmpty()->end()
163 8
                            ->end()
164 8
                        ->end()
165 8
                    ->end()
166 8
                ->end()
167 8
            ->end()
168 8
        ->end();
169 8
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174 8
    public function getConfigKey()
175
    {
176 8
        return 'code_coverage';
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     */
182 16
    public function process(ContainerBuilder $container): void
183
    {
184
        /** @var InputInterface $input */
185 16
        $input = $container->get(CliExtension::INPUT_ID);
186
187
        /** @var OutputInterface $output */
188 16
        $output = $container->get(CliExtension::OUTPUT_ID);
189
190 16
        $filterConfig = $container->getParameter('behat.code_coverage.config.filter');
191 16
        $branchPathConfig = $container->getParameter('behat.code_coverage.config.branchAndPathCoverage');
192 16
        $cacheDir = $container->getParameter('behat.code_coverage.config.cache');
193
194 16
        $canCollectCodeCoverage = true;
195
        try {
196 16
            $this->initCodeCoverage(new Filter(), $filterConfig, null, $cacheDir, $output);
0 ignored issues
show
Bug introduced by
It seems like $filterConfig can also be of type boolean and double and integer and null and string; however, parameter $filterConfig of DVDoug\Behat\CodeCoverag...ion::initCodeCoverage() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

196
            $this->initCodeCoverage(new Filter(), /** @scrutinizer ignore-type */ $filterConfig, null, $cacheDir, $output);
Loading history...
197
198 12
            $codeCoverageDefinition = $container->getDefinition(CodeCoverage::class);
199 12
            $filterDefinition = $container->getDefinition(Filter::class);
200 12
            $codeCoverageDefinition->setFactory([new Reference(self::class), 'initCodeCoverage']);
201 12
            $codeCoverageDefinition->setArguments([$filterDefinition, $filterConfig, $branchPathConfig, $cacheDir, $output]);
202 4
        } catch (NoCodeCoverageDriverAvailableException|Xdebug2NotEnabledException|Xdebug3NotEnabledException $e) {
203 4
            $output->writeln("<comment>No code coverage driver is available. {$e->getMessage()}</comment>");
204 4
            $canCollectCodeCoverage = false;
205
        }
206
207 16
        if (!$canCollectCodeCoverage || $input->hasParameterOption('--no-coverage')) {
208 8
            $container->getDefinition(EventSubscriber::class)->setArgument('$coverage', null);
209
        }
210 16
    }
211
212 12
    public function initCodeCoverage(Filter $filter, array $filterConfig, ?bool $branchPathConfig, string $cacheDir, OutputInterface $output): CodeCoverage
213
    {
214
        // set up filter
215 12
        array_walk($filterConfig['include']['directories'], static function (array $dir, string $path, Filter $filter): void {
216 12
            $filter->includeDirectory($path, $dir['suffix'], $dir['prefix']);
217 12
        }, $filter);
218
219 12
        array_walk($filterConfig['include']['files'], static function (string $file, string $key, Filter $filter): void {
220 12
            $filter->includeFile($file);
221 12
        }, $filter);
222
223 12
        array_walk($filterConfig['exclude']['directories'], static function (array $dir, string $path, Filter $filter): void {
224 12
            $filter->excludeDirectory($path, $dir['suffix'], $dir['prefix']);
225 12
        }, $filter);
226
227 12
        array_walk($filterConfig['exclude']['files'], static function (string $file, string $key, Filter $filter): void {
228 12
            $filter->excludeFile($file);
229 12
        }, $filter);
230
231
        // see if we can get a driver
232 12
        $selector = new Selector();
233 12
        $driver = $selector->forLineCoverage($filter);
234 12
        if ($branchPathConfig !== false) {
235
            try {
236 12
                $driver = $selector->forLineAndPathCoverage($filter);
237 9
            } catch (NoCodeCoverageDriverWithPathCoverageSupportAvailableException $e) {
238
                // fallback driver is already set
239 9
                if ($branchPathConfig === true) { //only warn if explicitly enabled
0 ignored issues
show
introduced by
The condition $branchPathConfig === true is always true.
Loading history...
240 3
                    $output->writeln(sprintf('<info>%s does not support collecting branch and path data</info>', $driver->nameAndVersion()));
241
                }
242
            }
243
        }
244
245
        // and init coverage
246 12
        $codeCoverage = new CodeCoverage($driver, $filter);
247 12
        $codeCoverage->cacheStaticAnalysis($cacheDir);
248
249 12
        if ($filterConfig['includeUncoveredFiles']) {
250 4
            $codeCoverage->includeUncoveredFiles();
251
        } else {
252 8
            $codeCoverage->excludeUncoveredFiles();
253
        }
254
255 12
        $codeCoverageReflection = new ReflectionClass($codeCoverage);
256
257 12
        if ($codeCoverageReflection->hasMethod('processUncoveredFiles')) {
258 12
            if ($filterConfig['processUncoveredFiles']) {
259 4
                $codeCoverage->processUncoveredFiles();
260
            } else {
261 8
                $codeCoverage->doNotProcessUncoveredFiles();
262
            }
263
        }
264
265 12
        return $codeCoverage;
266
    }
267
}
268