Passed
Push — master ( 587e15...5923a6 )
by Doug
04:20
created

Extension::setupFactory()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 5.667

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 15
ccs 3
cts 9
cp 0.3333
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 5.667
1
<?php
2
3
declare(strict_types=1);
4
/**
5
 * Code Coverage Extension for Behat.
6
 *
7
 * @copyright 2013 Anthon Pang
8
 *
9
 * @license BSD-2-Clause
10
 */
11
12
namespace DVDoug\Behat\CodeCoverage;
13
14
use Behat\Testwork\ServiceContainer\Extension as ExtensionInterface;
15
use Behat\Testwork\ServiceContainer\ExtensionManager;
16
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
17
use Symfony\Component\Config\FileLocator;
18
use Symfony\Component\DependencyInjection\ContainerBuilder;
19
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
20
use Symfony\Component\DependencyInjection\Reference;
21
22
/**
23
 * Code coverage extension.
24
 *
25
 * @author Anthon Pang <[email protected]>
26
 */
27
class Extension implements ExtensionInterface
28
{
29
    /**
30
     * @var string
31
     */
32
    private $configFolder;
33
34
    /**
35
     * Constructor.
36
     *
37
     * @param string $configFolder
38
     */
39 8
    public function __construct($configFolder = null)
40
    {
41 8
        $this->configFolder = $configFolder ?: __DIR__ . '/Resources/config';
42 4
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47
    public function initialize(ExtensionManager $extensionManager): void
48
    {
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54 4
    public function load(ContainerBuilder $container, array $config): void
55
    {
56 4
        $loader = new XmlFileLoader($container, new FileLocator($this->configFolder));
57
58 4
        $servicesFile = 'services.xml';
59 4
        $loader->load($servicesFile);
60
61 4
        if (!isset($config['auth']['user']) || !isset($config['auth']['password'])) {
62 2
            $config['auth'] = null;
63
        }
64
65 4
        if (!count($config['drivers'])) {
66 2
            $config['drivers'] = ['local'];
67
        }
68
69 4
        if (!count($config['report']['options'])) {
70 2
            $config['report']['options'] = [
71
                'target' => '/tmp',
72
            ];
73
        }
74
75 4
        if (!$container->hasParameter('mink.base_url')) {
76 4
            $container->setParameter('mink.base_url', null);
77
        }
78
79 4
        $container->setParameter('behat.code_coverage.config.auth', $config['auth']);
80 4
        $container->setParameter('behat.code_coverage.config.create', $config['create']);
81 4
        $container->setParameter('behat.code_coverage.config.read', $config['read']);
82 4
        $container->setParameter('behat.code_coverage.config.delete', $config['delete']);
83 4
        $container->setParameter('behat.code_coverage.config.drivers', $config['drivers']);
84 4
        $container->setParameter('behat.code_coverage.config.filter', $config['filter']);
85 4
        $container->setParameter('behat.code_coverage.config.report', $config['report'] ?? []);
86 4
        $container->setParameter('behat.code_coverage.config.reports', $config['reports'] ?? []);
87 2
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92 2
    public function configure(ArrayNodeDefinition $builder): void
93
    {
94
        $builder
95 2
            ->children()
96 2
                ->arrayNode('auth')
97 2
                    ->children()
98 2
                        ->scalarNode('user')->end()
99 2
                        ->scalarNode('password')->end()
0 ignored issues
show
Bug introduced by
The method scalarNode() 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

99
                        ->/** @scrutinizer ignore-call */ scalarNode('password')->end()
Loading history...
100 2
                    ->end()
101 2
                ->end()
102 2
                ->arrayNode('create')
103 2
                    ->addDefaultsIfNotSet()
104 2
                    ->children()
105 2
                        ->scalarNode('method')->defaultValue('POST')->end()
106 2
                        ->scalarNode('path')->defaultValue('/')->end()
107 2
                    ->end()
108 2
                ->end()
109 2
                ->arrayNode('read')
110 2
                    ->addDefaultsIfNotSet()
111 2
                    ->children()
112 2
                        ->scalarNode('method')->defaultValue('GET')->end()
113 2
                        ->scalarNode('path')->defaultValue('/')->end()
114 2
                    ->end()
115 2
                ->end()
116 2
                ->arrayNode('delete')
117 2
                    ->addDefaultsIfNotSet()
118 2
                    ->children()
119 2
                        ->scalarNode('method')->defaultValue('DELETE')->end()
120 2
                        ->scalarNode('path')->defaultValue('/')->end()
121 2
                    ->end()
122 2
                ->end()
123 2
                ->arrayNode('drivers')
124 2
                    ->prototype('scalar')->end()
125 2
                ->end()
126 2
                ->arrayNode('filter')
127 2
                    ->addDefaultsIfNotSet()
128 2
                    ->children()
129 2
                        ->scalarNode('forceCoversAnnotation')
130 2
                            ->defaultFalse()
131 2
                        ->end()
132 2
                        ->scalarNode('mapTestClassNameToCoveredClassName')
133 2
                            ->defaultFalse()
134 2
                        ->end()
135 2
                        ->arrayNode('whitelist')
136 2
                            ->addDefaultsIfNotSet()
137 2
                            ->children()
138 2
                                ->scalarNode('addUncoveredFilesFromWhitelist')
139 2
                                    ->defaultTrue()
140 2
                                ->end()
141 2
                                ->scalarNode('processUncoveredFilesFromWhitelist')
142 2
                                    ->defaultFalse()
143 2
                                ->end()
144 2
                                ->arrayNode('include')
145 2
                                    ->addDefaultsIfNotSet()
146 2
                                    ->children()
147 2
                                        ->arrayNode('directories')
148 2
                                           ->useAttributeAsKey('name')
149 2
                                           ->normalizeKeys(false)
150 2
                                           ->prototype('array')
151 2
                                               ->children()
152 2
                                                   ->scalarNode('prefix')->defaultValue('')->end()
153 2
                                                   ->scalarNode('suffix')->defaultValue('.php')->end()
154 2
                                               ->end()
155 2
                                           ->end()
156 2
                                        ->end()
157 2
                                        ->arrayNode('files')
158 2
                                           ->prototype('scalar')->end()
159 2
                                        ->end()
160 2
                                    ->end()
161 2
                                ->end()
162 2
                                ->arrayNode('exclude')
163 2
                                    ->addDefaultsIfNotSet()
164 2
                                    ->children()
165 2
                                        ->arrayNode('directories')
166 2
                                           ->useAttributeAsKey('name')
167 2
                                           ->normalizeKeys(false)
168 2
                                           ->prototype('array')
169 2
                                               ->children()
170 2
                                                   ->scalarNode('prefix')->defaultValue('')->end()
171 2
                                                   ->scalarNode('suffix')->defaultValue('.php')->end()
172 2
                                               ->end()
173 2
                                           ->end()
174 2
                                        ->end()
175 2
                                        ->arrayNode('files')
176 2
                                           ->prototype('scalar')->end()
177 2
                                        ->end()
178 2
                                    ->end()
179 2
                                ->end()
180 2
                            ->end()
181 2
                        ->end()
182 2
                    ->end()
183 2
                ->end()
184 2
                ->arrayNode('report')
185 2
                    ->setDeprecated('The "report" option is deprecated. Use "reports" instead.')
186 2
                    ->children()
187 2
                        ->scalarNode('format')->defaultValue('html')->end()
188 2
                        ->arrayNode('options')
189 2
                            ->useAttributeAsKey('name')
190 2
                            ->prototype('scalar')->end()
191 2
                        ->end()
192 2
                    ->end()
193 2
                ->end()
194 2
                ->arrayNode('reports')
195 2
                    ->children()
196 2
                        ->arrayNode('clover')
197 2
                            ->children()
198 2
                                ->scalarNode('name')->end()
199 2
                                ->scalarNode('target')->end()
200 2
                            ->end()
201 2
                        ->end()
202 2
                        ->arrayNode('crap4j')
203 2
                            ->children()
204 2
                                ->scalarNode('name')->end()
205 2
                                ->scalarNode('target')->end()
206 2
                            ->end()
207 2
                        ->end()
208 2
                        ->arrayNode('html')
209 2
                            ->children()
210 2
                                ->scalarNode('target')->end()
211 2
                                ->scalarNode('lowUpperBound')->end()
212 2
                                ->scalarNode('highLowerBound')->end()
213 2
                            ->end()
214 2
                        ->end()
215 2
                        ->arrayNode('php')
216 2
                            ->children()
217 2
                                ->scalarNode('target')->end()
218 2
                            ->end()
219 2
                        ->end()
220 2
                        ->arrayNode('text')
221 2
                            ->children()
222 2
                                ->booleanNode('showColors')->end()
223 2
                                ->scalarNode('lowUpperBound')->end()
224 2
                                ->scalarNode('highLowerBound')->end()
225 2
                                ->booleanNode('showOnlySummary')->end()
226 2
                                ->booleanNode('showUncoveredFiles')->end()
227 2
                            ->end()
228 2
                        ->end()
229 2
                        ->arrayNode('xml')
230 2
                            ->children()
231 2
                                ->scalarNode('target')->end()
232 2
                            ->end()
233 2
                        ->end()
234 2
                    ->end()
235 2
                ->end()
236 2
            ->end()
237 2
        ->end();
238 1
    }
239
240
    /**
241
     * {@inheritdoc}
242
     */
243
    public function getConfigKey()
244
    {
245
        return 'code_coverage';
246
    }
247
248
    /**
249
     * {@inheritdoc}
250
     */
251 2
    public function process(ContainerBuilder $container): void
252
    {
253 2
        $input = $container->get('cli.input');
254 2
        if ($input->hasParameterOption('--no-coverage')) {
255
            $container->getParameterBag()->set('behat.code_coverage.skip', true);
256
        }
257
258 2
        $this->setupDriver($container);
259 2
        $this->setupFactory($container);
260 2
        $this->setupCodeCoverage($container);
261 2
        $this->setupCodeCoverageFilter($container);
262 1
    }
263
264 2
    private function setupDriver(ContainerBuilder $container): void
265
    {
266 2
        if (!$container->hasDefinition('behat.code_coverage.driver.proxy')) {
267 2
            return;
268
        }
269
270
        $proxy = $container->getDefinition('behat.code_coverage.driver.proxy');
271
        $enabled = $container->getParameter('behat.code_coverage.config.drivers');
272
273
        foreach ($container->findTaggedServiceIds('behat.code_coverage.driver') as $id => $tagAttributes) {
274
            foreach ($tagAttributes as $attributes) {
275
                if (isset($attributes['alias'])
276
                    && in_array($attributes['alias'], $enabled)
277
                ) {
278
                    $proxy->addMethodCall('addDriver', [new Reference($id)]);
279
                }
280
            }
281
        }
282
    }
283
284 2
    public function setupFactory(ContainerBuilder $container): void
285
    {
286 2
        if (!$container->hasDefinition('dvdoug.code_coverage.driver.factory')) {
287 2
            return;
288
        }
289
290
        $factory = $container->getDefinition('dvdoug.code_coverage.driver.factory');
291
        $drivers = [];
292
        $ids = $container->findTaggedServiceIds('dvdoug.code_coverage.driver');
293
294
        foreach ($ids as $id => $attributes) {
295
            $drivers[] = $container->getDefinition($id)->getClass();
296
        }
297
298
        $factory->setArguments([$drivers]);
299
    }
300
301 2
    private function setupCodeCoverage(ContainerBuilder $container): void
302
    {
303 2
        if (!$container->hasDefinition('behat.code_coverage.php_code_coverage')) {
304 2
            return;
305
        }
306
307
        $coverage = $container->getDefinition('behat.code_coverage.php_code_coverage');
308
        $config = $container->getParameter('behat.code_coverage.config.filter');
309
310
        $coverage->addMethodCall(
311
            'setAddUncoveredFilesFromWhitelist',
312
            [$config['whitelist']['addUncoveredFilesFromWhitelist']]
313
        );
314
        $coverage->addMethodCall(
315
            'setProcessUncoveredFilesFromWhiteList',
316
            [$config['whitelist']['processUncoveredFilesFromWhitelist']]
317
        );
318
        $coverage->addMethodCall(
319
            'setForceCoversAnnotation',
320
            [$config['forceCoversAnnotation']]
321
        );
322
    }
323
324 2
    private function setupCodeCoverageFilter(ContainerBuilder $container): void
325
    {
326 2
        if (!$container->hasDefinition('behat.code_coverage.php_code_coverage_filter')) {
327 2
            return;
328
        }
329
330
        $filter = $container->getDefinition('behat.code_coverage.php_code_coverage_filter');
331
        $config = $container->getParameter('behat.code_coverage.config.filter');
332
333
        $dirs = [
334
            'addDirectoryToWhiteList' => ['whitelist', 'include', 'directories'],
335
            'removeDirectoryFromWhiteList' => ['whitelist', 'exclude', 'directories'],
336
        ];
337
338
        foreach ($dirs as $method => $hiera) {
339
            foreach ($config[$hiera[0]][$hiera[1]][$hiera[2]] as $path => $dir) {
340
                $filter->addMethodCall($method, [$path, $dir['suffix'], $dir['prefix']]);
341
            }
342
        }
343
344
        $files = [
345
            'addFileToWhiteList' => ['whitelist', 'include', 'files'],
346
            'removeFileFromWhiteList' => ['whitelist', 'exclude', 'files'],
347
        ];
348
349
        foreach ($files as $method => $hiera) {
350
            foreach ($config[$hiera[0]][$hiera[1]][$hiera[2]] as $file) {
351
                $filter->addMethodCall($method, [$file]);
352
            }
353
        }
354
    }
355
}
356