Passed
Push — master ( 931977...de7692 )
by Doug
04:01
created

Extension::setupDriver()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 18.348

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 15
ccs 3
cts 10
cp 0.3
rs 9.2222
c 0
b 0
f 0
cc 6
nc 5
nop 1
crap 18.348
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 1
    private function setupDriver(ContainerBuilder $container): void
222
    {
223 1
        if (!$container->hasDefinition('behat.code_coverage.driver.proxy')) {
224 1
            return;
225
        }
226
227
        $proxy = $container->getDefinition('behat.code_coverage.driver.proxy');
228
        $enabled = $container->getParameter('behat.code_coverage.config.drivers');
229
230
        foreach ($container->findTaggedServiceIds('behat.code_coverage.driver') as $id => $tagAttributes) {
231
            foreach ($tagAttributes as $attributes) {
232
                if (isset($attributes['alias'])
233
                    && in_array($attributes['alias'], $enabled)
234
                ) {
235
                    $proxy->addMethodCall('addDriver', [new Reference($id)]);
236
                }
237
            }
238
        }
239
    }
240
241 1
    public function setupFactory(ContainerBuilder $container): void
242
    {
243 1
        if (!$container->hasDefinition('dvdoug.code_coverage.driver.factory')) {
244 1
            return;
245
        }
246
247
        $factory = $container->getDefinition('dvdoug.code_coverage.driver.factory');
248
        $drivers = [];
249
        $ids = $container->findTaggedServiceIds('dvdoug.code_coverage.driver');
250
251
        foreach ($ids as $id => $attributes) {
252
            $drivers[] = $container->getDefinition($id)->getClass();
253
        }
254
255
        $factory->setArguments([$drivers]);
256
    }
257
258 1
    private function setupCodeCoverage(ContainerBuilder $container): void
259
    {
260 1
        if (!$container->hasDefinition('behat.code_coverage.php_code_coverage')) {
261 1
            return;
262
        }
263
264
        $coverage = $container->getDefinition('behat.code_coverage.php_code_coverage');
265
        $config = $container->getParameter('behat.code_coverage.config.filter');
266
267
        $coverage->addMethodCall(
268
            'setAddUncoveredFilesFromWhitelist',
269
            [$config['whitelist']['addUncoveredFilesFromWhitelist']]
270
        );
271
        $coverage->addMethodCall(
272
            'setProcessUncoveredFilesFromWhiteList',
273
            [$config['whitelist']['processUncoveredFilesFromWhitelist']]
274
        );
275
        $coverage->addMethodCall(
276
            'setForceCoversAnnotation',
277
            [$config['forceCoversAnnotation']]
278
        );
279
    }
280
281 1
    private function setupCodeCoverageFilter(ContainerBuilder $container): void
282
    {
283 1
        if (!$container->hasDefinition('behat.code_coverage.php_code_coverage_filter')) {
284 1
            return;
285
        }
286
287
        $filter = $container->getDefinition('behat.code_coverage.php_code_coverage_filter');
288
        $config = $container->getParameter('behat.code_coverage.config.filter');
289
290
        $dirs = [
291
            'addDirectoryToWhiteList' => ['whitelist', 'include', 'directories'],
292
            'removeDirectoryFromWhiteList' => ['whitelist', 'exclude', 'directories'],
293
        ];
294
295
        foreach ($dirs as $method => $hiera) {
296
            foreach ($config[$hiera[0]][$hiera[1]][$hiera[2]] as $path => $dir) {
297
                $filter->addMethodCall($method, [$path, $dir['suffix'], $dir['prefix']]);
298
            }
299
        }
300
301
        $files = [
302
            'addFileToWhiteList' => ['whitelist', 'include', 'files'],
303
            'removeFileFromWhiteList' => ['whitelist', 'exclude', 'files'],
304
        ];
305
306
        foreach ($files as $method => $hiera) {
307
            foreach ($config[$hiera[0]][$hiera[1]][$hiera[2]] as $file) {
308
                $filter->addMethodCall($method, [$file]);
309
            }
310
        }
311
    }
312
}
313