Passed
Pull Request — develop (#8)
by ANTHONIUS
04:34
created

CoveragePass::compileDrivers()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 16
nc 2
nop 1
dl 0
loc 23
ccs 16
cts 16
cp 1
crap 2
rs 9.7333
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the doyo/behat-coverage-extension project.
5
 *
6
 * (c) Anthonius Munthi <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Doyo\Behat\Coverage\Compiler;
15
16
use Behat\Testwork\ServiceContainer\Exception\ConfigurationLoadingException;
17
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
18
use Symfony\Component\DependencyInjection\ContainerBuilder;
19
use Symfony\Component\DependencyInjection\Definition;
20
use Symfony\Component\DependencyInjection\Reference;
21
22
class CoveragePass implements CompilerPassInterface
23
{
24 6
    public function process(ContainerBuilder $container)
25
    {
26 6
        $this->compileFilterOptions($container);
27 6
        $this->processSessions($container);
28 6
        $this->compileCoverageOptions($container);
29
30 6
        $definition = $container->getDefinition('doyo.coverage.dispatcher');
31 6
        $tagged     = $container->findTaggedServiceIds('doyo.dispatcher.subscriber');
32
33 6
        foreach ($tagged as $id=>$arguments) {
34 6
            $definition->addMethodCall('addSubscriber', [new Reference($id)]);
35
        }
36
    }
37
38 6
    private function processSessions(ContainerBuilder $container)
39
    {
40 6
        $sessions             = $container->getParameterBag()->get('doyo.coverage.sessions');
41 6
        $codeCoverageOptions  = $container->getParameterBag()->get('doyo.coverage.options');
42
43
        $driverMap = [
44 6
            'local'  => $container->getParameterBag()->get('doyo.coverage.session.local.class'),
45 6
            'remote' => $container->getParameterBag()->get('doyo.coverage.session.remote.class'),
46
        ];
47 6
        foreach ($sessions as $name => $config) {
48 6
            $driver    = $config['driver'];
49 6
            $class     = $driverMap[$driver];
50 6
            $id        = 'doyo.coverage.sessions.'.$name;
51 6
            $driverId  = $this->createSessionDriverDefinition($container, $name, $config);
52
53 6
            $definition = new Definition($class);
54 6
            $definition->addTag('doyo.dispatcher.subscriber');
55 6
            $definition->addArgument(new Reference($driverId));
56 6
            $definition->addArgument($codeCoverageOptions);
57 6
            $definition->addArgument(new Reference('doyo.coverage.filter'));
58 6
            $definition->setPublic(true);
59
60 6
            if('remote' === $driver){
61 6
                $this->configureRemoteSession($container, $definition, $config);
62
63
            }
64
65 6
            $container->setDefinition($id, $definition);
66
        }
67
    }
68
69 6
    private function configureRemoteSession(ContainerBuilder $container, Definition $definition, array $config)
70
    {
71 6
        $mink = 'mink';
72 6
        if($container->has($mink)){
73 6
            $definition->addMethodCall('setMink', [new Reference($mink)]);
74
        }
75
76 6
        if(!isset($config['remote_url'])){
77
            throw new ConfigurationLoadingException(sprintf(
78
                'driver parameters: %s should be set when using code coverage remote driver',
79
                'coverage_url'
80
            ));
81
        }
82
83 6
        $client = $container->get('doyo.coverage.http_client');
84 6
        $definition->addMethodCall('setHttpClient', [$client]);
85 6
        $definition->addMethodCall('setRemoteUrl',[$config['remote_url']]);
86
    }
87
88 6
    private function createSessionDriverDefinition(ContainerBuilder $container, $name, $config)
89
    {
90 6
        $driver = $config['driver'];
91
        $map = [
92 6
            'local'  => 'doyo.coverage.local_session.class',
93
            'remote' => 'doyo.coverage.remote_session.class',
94
        ];
95 6
        $class      = $container->getParameterBag()->get($map[$driver]);
96 6
        $id         = 'doyo.coverage.sessions.'.$name.'.driver';
97 6
        $definition = new Definition($class);
98 6
        $definition->setPublic(true);
99 6
        $definition->addArgument($name);
100
101 6
        $container->setDefinition($id, $definition);
102 6
        return $id;
103
    }
104
105 6
    private function compileCoverageOptions(ContainerBuilder $container)
106
    {
107 6
        $options = $container->getParameterBag()->get('doyo.coverage.options');
108
109 6
        $definitions = $container->findTaggedServiceIds('doyo.coverage.processor');
110
        /* @var \Symfony\Component\DependencyInjection\Definition $definition */
111 6
        foreach ($definitions as $id => $test) {
112 6
            $definition = $container->getDefinition($id);
113 6
            $this->addCoverageOption($definition, $options);
114
        }
115
    }
116
117 6
    private function addCoverageOption(Definition $definition, array $options)
118
    {
119 6
        foreach ($options as $name => $value) {
120 6
            $method = 'set'.ucfirst($name);
121 6
            $definition->addMethodCall($method, [$value]);
122
        }
123
    }
124
125 6
    private function compileFilterOptions(ContainerBuilder $container)
126
    {
127 6
        $config     = $container->getParameterBag()->get('doyo.coverage.config');
128 6
        $filter     = $config['filter'];
129 6
        $basePath   = $container->getParameterBag()->get('paths.base');
130 6
        $definition = $container->getDefinition('doyo.coverage.filter');
131
132 6
        foreach ($filter as $options) {
133 6
            $options['basePath'] = $basePath;
134 6
            $this->filterWhitelist($definition, $options, 'add');
135 6
            $exclude = $options['exclude'];
136 6
            foreach ($exclude as $item) {
137 6
                $item['basePath'] = $basePath;
138 6
                $this->filterWhitelist($definition, $item, 'remove');
139
            }
140
        }
141
    }
142
143 6
    private function filterWhitelist(Definition $definition, $options, $method)
144
    {
145 6
        $basePath  = $options['basePath'];
146 6
        $suffix    = $options['suffix'] ?: '.php';
147 6
        $prefix    = $options['prefix'] ?: '';
148 6
        $type      = $options['directory'] ? 'directory' : 'file';
149 6
        $directory = $basePath.\DIRECTORY_SEPARATOR.$options['directory'];
150 6
        $file      = $basePath.\DIRECTORY_SEPARATOR.$options['file'];
151
152 6
        if (preg_match('/\/\*(\..+)/', $directory, $matches)) {
153 6
            $suffix    = $matches[1];
154 6
            $directory = str_replace($matches[0], '', $directory);
155
        }
156
157 6
        $methodSuffix = 'add' === $method ? 'ToWhitelist' : 'FromWhitelist';
158 6
        if ('directory' === $type) {
159 6
            $definition->addMethodCall($method.'Directory'.$methodSuffix, [$directory, $suffix, $prefix]);
160
        }
161
162 6
        if ('file' === $type) {
163 6
            $definition->addMethodCall($method.'File'.$methodSuffix, [$file]);
164
        }
165
    }
166
}
167