Passed
Push — master ( a684ac...ca5119 )
by Doug
05:20 queued 01:18
created

Extension::setupCodeCoverage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 3.9401

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 20
ccs 3
cts 14
cp 0.2143
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 3.9401
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 4
    public function __construct($configFolder = null)
40
    {
41 4
        $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 2
    public function load(ContainerBuilder $container, array $config): void
55
    {
56 2
        $loader = new XmlFileLoader($container, new FileLocator($this->configFolder));
57
58 2
        $servicesFile = 'services.xml';
59 2
        $loader->load($servicesFile);
60
61 2
        if (!isset($config['auth']['user']) || !isset($config['auth']['password'])) {
62 1
            $config['auth'] = null;
63
        }
64
65 2
        if (!count($config['drivers'])) {
66 1
            $config['drivers'] = ['local'];
67
        }
68
69 2
        if (!count($config['report']['options'])) {
70 1
            $config['report']['options'] = [
71
                'target' => '/tmp',
72
            ];
73
        }
74
75 2
        if (!$container->hasParameter('mink.base_url')) {
76 2
            $container->setParameter('mink.base_url', null);
77
        }
78
79 2
        $container->setParameter('behat.code_coverage.config.auth', $config['auth']);
80 2
        $container->setParameter('behat.code_coverage.config.create', $config['create']);
81 2
        $container->setParameter('behat.code_coverage.config.read', $config['read']);
82 2
        $container->setParameter('behat.code_coverage.config.delete', $config['delete']);
83 2
        $container->setParameter('behat.code_coverage.config.drivers', $config['drivers']);
84 2
        $container->setParameter('behat.code_coverage.config.filter', $config['filter']);
85 2
        $container->setParameter('behat.code_coverage.config.report', $config['report']);
86 2
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91 1
    public function configure(ArrayNodeDefinition $builder): void
92
    {
93
        $builder
94 1
            ->addDefaultsIfNotSet()
95 1
            ->children()
96 1
                ->arrayNode('auth')
97 1
                    ->children()
98 1
                        ->scalarNode('user')->end()
99 1
                        ->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 1
                    ->end()
101 1
                ->end()
102 1
                ->arrayNode('create')
103 1
                    ->addDefaultsIfNotSet()
104 1
                    ->children()
105 1
                        ->scalarNode('method')->defaultValue('POST')->end()
106 1
                        ->scalarNode('path')->defaultValue('/')->end()
107 1
                    ->end()
108 1
                ->end()
109 1
                ->arrayNode('read')
110 1
                    ->addDefaultsIfNotSet()
111 1
                    ->children()
112 1
                        ->scalarNode('method')->defaultValue('GET')->end()
113 1
                        ->scalarNode('path')->defaultValue('/')->end()
114 1
                    ->end()
115 1
                ->end()
116 1
                ->arrayNode('delete')
117 1
                    ->addDefaultsIfNotSet()
118 1
                    ->children()
119 1
                        ->scalarNode('method')->defaultValue('DELETE')->end()
120 1
                        ->scalarNode('path')->defaultValue('/')->end()
121 1
                    ->end()
122 1
                ->end()
123 1
                ->arrayNode('drivers')
124 1
                    ->prototype('scalar')->end()
125 1
                ->end()
126 1
                ->arrayNode('filter')
127 1
                    ->addDefaultsIfNotSet()
128 1
                    ->children()
129 1
                        ->scalarNode('forceCoversAnnotation')
130 1
                            ->defaultFalse()
131 1
                        ->end()
132 1
                        ->scalarNode('mapTestClassNameToCoveredClassName')
133 1
                            ->defaultFalse()
134 1
                        ->end()
135 1
                        ->arrayNode('whitelist')
136 1
                            ->addDefaultsIfNotSet()
137 1
                            ->children()
138 1
                                ->scalarNode('addUncoveredFilesFromWhitelist')
139 1
                                    ->defaultTrue()
140 1
                                ->end()
141 1
                                ->scalarNode('processUncoveredFilesFromWhitelist')
142 1
                                    ->defaultFalse()
143 1
                                ->end()
144 1
                                ->arrayNode('include')
145 1
                                    ->addDefaultsIfNotSet()
146 1
                                    ->children()
147 1
                                        ->arrayNode('directories')
148 1
                                           ->useAttributeAsKey('name')
149 1
                                           ->normalizeKeys(false)
150 1
                                           ->prototype('array')
151 1
                                               ->children()
152 1
                                                   ->scalarNode('prefix')->defaultValue('')->end()
153 1
                                                   ->scalarNode('suffix')->defaultValue('.php')->end()
154 1
                                               ->end()
155 1
                                           ->end()
156 1
                                        ->end()
157 1
                                        ->arrayNode('files')
158 1
                                           ->prototype('scalar')->end()
159 1
                                        ->end()
160 1
                                    ->end()
161 1
                                ->end()
162 1
                                ->arrayNode('exclude')
163 1
                                    ->addDefaultsIfNotSet()
164 1
                                    ->children()
165 1
                                        ->arrayNode('directories')
166 1
                                           ->useAttributeAsKey('name')
167 1
                                           ->normalizeKeys(false)
168 1
                                           ->prototype('array')
169 1
                                               ->children()
170 1
                                                   ->scalarNode('prefix')->defaultValue('')->end()
171 1
                                                   ->scalarNode('suffix')->defaultValue('.php')->end()
172 1
                                               ->end()
173 1
                                           ->end()
174 1
                                        ->end()
175 1
                                        ->arrayNode('files')
176 1
                                           ->prototype('scalar')->end()
177 1
                                        ->end()
178 1
                                    ->end()
179 1
                                ->end()
180 1
                            ->end()
181 1
                        ->end()
182 1
                    ->end()
183 1
                ->end()
184 1
                ->arrayNode('report')
185 1
                    ->children()
186 1
                        ->scalarNode('format')->defaultValue('html')->end()
187 1
                        ->arrayNode('options')
188 1
                            ->useAttributeAsKey('name')
189 1
                            ->prototype('scalar')->end()
190 1
                        ->end()
191 1
                    ->end()
192 1
                ->end()
193 1
            ->end()
194 1
        ->end();
195 1
    }
196
197
    /**
198
     * {@inheritdoc}
199
     */
200
    public function getConfigKey()
201
    {
202
        return 'code_coverage';
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208 1
    public function process(ContainerBuilder $container): void
209
    {
210 1
        $input = $container->get('cli.input');
211 1
        if ($input->hasParameterOption('--no-coverage')) {
212
            $container->getParameterBag()->set('behat.code_coverage.skip', true);
213
        }
214
215 1
        $this->setupDriver($container);
216 1
        $this->setupFactory($container);
217 1
        $this->setupCodeCoverage($container);
218 1
        $this->setupCodeCoverageFilter($container);
219 1
    }
220
221
    /**
222
     * @param ContainerBuilder $container
223
     */
224 1
    private function setupDriver(ContainerBuilder $container): void
225
    {
226 1
        if (!$container->hasDefinition('behat.code_coverage.driver.proxy')) {
227 1
            return;
228
        }
229
230
        $proxy = $container->getDefinition('behat.code_coverage.driver.proxy');
231
        $enabled = $container->getParameter('behat.code_coverage.config.drivers');
232
233
        foreach ($container->findTaggedServiceIds('behat.code_coverage.driver') as $id => $tagAttributes) {
234
            foreach ($tagAttributes as $attributes) {
235
                if (isset($attributes['alias'])
236
                    && in_array($attributes['alias'], $enabled)
237
                ) {
238
                    $proxy->addMethodCall('addDriver', [new Reference($id)]);
239
                }
240
            }
241
        }
242
    }
243
244
    /**
245
     * @param ContainerBuilder $container
246
     */
247 1
    public function setupFactory(ContainerBuilder $container): void
248
    {
249 1
        if (!$container->hasDefinition('dvdoug.code_coverage.driver.factory')) {
250 1
            return;
251
        }
252
253
        $factory = $container->getDefinition('dvdoug.code_coverage.driver.factory');
254
        $drivers = [];
255
        $ids = $container->findTaggedServiceIds('dvdoug.code_coverage.driver');
256
257
        foreach ($ids as $id => $attributes) {
258
            $drivers[] = $container->getDefinition($id)->getClass();
259
        }
260
261
        $factory->setArguments([$drivers]);
262
    }
263
264
    /**
265
     * @param ContainerBuilder $container
266
     */
267 1
    private function setupCodeCoverage(ContainerBuilder $container): void
268
    {
269 1
        if (!$container->hasDefinition('behat.code_coverage.php_code_coverage')) {
270 1
            return;
271
        }
272
273
        $coverage = $container->getDefinition('behat.code_coverage.php_code_coverage');
274
        $config = $container->getParameter('behat.code_coverage.config.filter');
275
276
        $coverage->addMethodCall(
277
            'setAddUncoveredFilesFromWhitelist',
278
            [$config['whitelist']['addUncoveredFilesFromWhitelist']]
279
        );
280
        $coverage->addMethodCall(
281
            'setProcessUncoveredFilesFromWhiteList',
282
            [$config['whitelist']['processUncoveredFilesFromWhitelist']]
283
        );
284
        $coverage->addMethodCall(
285
            'setForceCoversAnnotation',
286
            [$config['forceCoversAnnotation']]
287
        );
288
    }
289
290
    /**
291
     * @param ContainerBuilder $container
292
     */
293 1
    private function setupCodeCoverageFilter(ContainerBuilder $container): void
294
    {
295 1
        if (!$container->hasDefinition('behat.code_coverage.php_code_coverage_filter')) {
296 1
            return;
297
        }
298
299
        $filter = $container->getDefinition('behat.code_coverage.php_code_coverage_filter');
300
        $config = $container->getParameter('behat.code_coverage.config.filter');
301
302
        $dirs = [
303
            'addDirectoryToWhiteList' => ['whitelist', 'include', 'directories'],
304
            'removeDirectoryFromWhiteList' => ['whitelist', 'exclude', 'directories'],
305
        ];
306
307
        foreach ($dirs as $method => $hiera) {
308
            foreach ($config[$hiera[0]][$hiera[1]][$hiera[2]] as $path => $dir) {
309
                $filter->addMethodCall($method, [$path, $dir['suffix'], $dir['prefix']]);
310
            }
311
        }
312
313
        $files = [
314
            'addFileToWhiteList' => ['whitelist', 'include', 'files'],
315
            'removeFileFromWhiteList' => ['whitelist', 'exclude', 'files'],
316
        ];
317
318
        foreach ($files as $method => $hiera) {
319
            foreach ($config[$hiera[0]][$hiera[1]][$hiera[2]] as $file) {
320
                $filter->addMethodCall($method, [$file]);
321
            }
322
        }
323
    }
324
}
325