Issues (3)

src/CodeCoverageExtension.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
 * This file is part of the friends-of-phpspec/phpspec-code-coverage package.
5
 *
6
 * @author ek9 <[email protected]>
7
 * @license MIT
8
 *
9
 * For the full copyright and license information, please see the LICENSE file
10
 * that was distributed with this source code.
11
 */
12
13
declare(strict_types=1);
14
15
namespace FriendsOfPhpSpec\PhpSpec\CodeCoverage;
16
17
use FriendsOfPhpSpec\PhpSpec\CodeCoverage\Exception\NoCoverageDriverAvailableException;
18
use FriendsOfPhpSpec\PhpSpec\CodeCoverage\Listener\CodeCoverageListener;
19
use PhpSpec\Console\ConsoleIO;
20
use PhpSpec\Extension;
21
use PhpSpec\ServiceContainer;
22
use RuntimeException;
23
use SebastianBergmann\CodeCoverage\CodeCoverage;
24
use SebastianBergmann\CodeCoverage\Driver\Selector;
25
use SebastianBergmann\CodeCoverage\Filter;
26
use SebastianBergmann\CodeCoverage\Report;
27
use SebastianBergmann\CodeCoverage\Report\Thresholds;
0 ignored issues
show
The type SebastianBergmann\CodeCoverage\Report\Thresholds was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use SebastianBergmann\CodeCoverage\Version;
29
use Symfony\Component\Console\Input\InputInterface;
30
use Symfony\Component\Console\Input\InputOption;
31
32
use function count;
33
use function is_array;
34
35
/**
36
 * Injects Code Coverage Event Subscriber into the EventDispatcher.
37
 * The Subscriber will add Code Coverage information before each example.
38
 *
39
 * @author Henrik Bjornskov
40
 */
41
class CodeCoverageExtension implements Extension
42
{
43
    /**
44
     * @param array<string, string> $params
45
     */
46 5
    public function load(ServiceContainer $container, array $params = []): void
47
    {
48 5
        foreach ($container->getByTag('console.commands') as $command) {
49
            $command->addOption('no-coverage', null, InputOption::VALUE_NONE, 'Skip code coverage generation');
50
        }
51
52 5
        $container->define('code_coverage.filter', static function () {
53
            return new Filter();
54 5
        });
55
56 5
        $container->define('code_coverage', static function (ServiceContainer $container) {
57
            /** @var Filter $filter */
58
            $filter = $container->get('code_coverage.filter');
59
60
            try {
61
                return new CodeCoverage((new Selector())->forLineCoverage($filter), $filter);
62
            } catch (RuntimeException $error) {
63
                throw new NoCoverageDriverAvailableException(
64
                    'There is no available coverage driver to be used.',
65
                    0,
66
                    $error
67
                );
68
            }
69 5
        });
70
71 5
        $container->define('code_coverage.options', static function (ServiceContainer $container) use ($params) {
72 5
            $options = !empty($params) ? $params : $container->getParam('code_coverage');
73
74 5
            if (!isset($options['format'])) {
75 3
                $options['format'] = ['html'];
76 2
            } elseif (!is_array($options['format'])) {
77 2
                $options['format'] = (array) $options['format'];
78
            }
79
80 5
            if (isset($options['output'])) {
81 1
                if (!is_array($options['output']) && 1 === count($options['format'])) {
82 1
                    $format = $options['format'][0];
83 1
                    $options['output'] = [$format => $options['output']];
84
                }
85
            }
86
87 5
            if (!isset($options['show_uncovered_files'])) {
88 5
                $options['show_uncovered_files'] = true;
89
            }
90
91 5
            if (!isset($options['lower_upper_bound'])) {
92 5
                $options['lower_upper_bound'] = 35;
93
            }
94
95 5
            if (!isset($options['high_lower_bound'])) {
96 5
                $options['high_lower_bound'] = 70;
97
            }
98
99 5
            if (!isset($options['show_only_summary'])) {
100 4
                $options['show_only_summary'] = false;
101
            }
102
103 5
            return $options;
104 5
        });
105
106 5
        $container->define('code_coverage.reports', static function (ServiceContainer $container) {
107
            /** @var array<string, mixed> $options */
108
            $options = $container->get('code_coverage.options');
109
110
            $reports = [];
111
112
            foreach ($options['format'] as $format) {
113
                switch ($format) {
114
                    case 'clover':
115
                        $reports['clover'] = new Report\Clover();
116
117
                        break;
118
                    case 'php':
119
                        $reports['php'] = new Report\PHP();
120
121
                        break;
122
                    case 'text':
123
                        $reports['text'] = version_compare(Version::id(), '10.0.0', '>=') && class_exists(Thresholds::class)
124
                            ? new Report\Text(
125
                                Thresholds::from($options['lower_upper_bound'], $options['high_lower_bound']),
126
                                $options['show_uncovered_files'],
127
                                $options['show_only_summary']
128
                            )
129
                            : new Report\Text(
130
                                $options['lower_upper_bound'],
131
                                $options['high_lower_bound'],
132
                                $options['show_uncovered_files'],
133
                                $options['show_only_summary']
134
                            );
135
136
                        break;
137
                    case 'xml':
138
                        $reports['xml'] = new Report\Xml\Facade(Version::id());
139
140
                        break;
141
                    case 'crap4j':
142
                        $reports['crap4j'] = new Report\Crap4j();
143
144
                        break;
145
                    case 'html':
146
                        $reports['html'] = new Report\Html\Facade();
147
148
                        break;
149
                    case 'cobertura':
150
                        $reports['cobertura'] = new Report\Cobertura();
151
152
                        break;
153
                }
154
            }
155
156
            $container->setParam('code_coverage', $options);
157
158
            return $reports;
159 5
        });
160
161 5
        $container->define('event_dispatcher.listeners.code_coverage', static function (ServiceContainer $container) {
162
            /** @var InputInterface $input */
163
            $input = $container->get('console.input');
164
            $skipCoverage = $input->hasOption('no-coverage') && $input->getOption('no-coverage');
165
166
            /** @var ConsoleIO $consoleIO */
167
            $consoleIO = $container->get('console.io');
168
169
            /** @var CodeCoverage $codeCoverage */
170
            $codeCoverage = $container->get('code_coverage');
171
172
            /** @var array<string, object> $codeCoverageReports */
173
            $codeCoverageReports = $container->get('code_coverage.reports');
174
175
            $listener = new CodeCoverageListener($consoleIO, $codeCoverage, $codeCoverageReports, $skipCoverage);
176
            $listener->setOptions($container->getParam('code_coverage', []));
177
178
            return $listener;
179 5
        }, ['event_dispatcher.listeners']);
180
    }
181
}
182