Completed
Push — develop ( 2faf16...be2583 )
by ANTHONIUS
15s queued 11s
created

CoveragePass::createSessionDriver()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 15
nc 1
nop 3
dl 0
loc 22
ccs 14
cts 14
cp 1
crap 1
rs 9.7666
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 4
    public function process(ContainerBuilder $container)
25
    {
26 4
        $this->processFilterOptions($container);
27 4
        $this->processSessions($container);
28 4
        $this->processCoverageOptions($container);
29
30 4
        $definition = $container->getDefinition('doyo.coverage.dispatcher');
31 4
        $tagged     = $container->findTaggedServiceIds('doyo.dispatcher.subscriber');
32
33 4
        foreach ($tagged as $id=>$arguments) {
34 4
            $definition->addMethodCall('addSubscriber', [new Reference($id)]);
35
        }
36
    }
37
38 4
    private function processSessions(ContainerBuilder $container)
39
    {
40 4
        $sessions             = $container->getParameterBag()->get('doyo.coverage.sessions');
41 4
        $codeCoverageOptions  = $container->getParameterBag()->get('doyo.coverage.options');
42
43
        $driverMap = [
44 4
            'local'  => $container->getParameterBag()->get('doyo.coverage.session.local.class'),
45 4
            'remote' => $container->getParameterBag()->get('doyo.coverage.session.remote.class'),
46
        ];
47 4
        foreach ($sessions as $name => $config) {
48 4
            $driver    = $config['driver'];
49 4
            $class     = $driverMap[$driver];
50 4
            $id        = 'doyo.coverage.sessions.'.$name;
51 4
            $driverId  = $this->createSessionDriver($container, $name, $config);
52
53 4
            $definition = new Definition($class);
54 4
            $definition->addTag('doyo.dispatcher.subscriber');
55 4
            $definition->addArgument(new Reference($driverId));
56 4
            $definition->addArgument($codeCoverageOptions);
57 4
            $definition->addArgument(new Reference('doyo.coverage.filter'));
58 4
            $definition->setPublic(true);
59
60 4
            if ('remote' === $driver) {
61 4
                $this->configureRemoteSession($container, $definition, $config);
62
            }
63
64 4
            $container->setDefinition($id, $definition);
65
        }
66
    }
67
68 4
    private function configureRemoteSession(ContainerBuilder $container, Definition $definition, array $config)
69
    {
70 4
        $mink = 'mink';
71 4
        if ($container->has($mink)) {
72 4
            $definition->addMethodCall('setMink', [new Reference($mink)]);
73
        }
74
75 4
        if (!isset($config['remote_url'])) {
76
            throw new ConfigurationLoadingException(sprintf(
77
                'driver parameters: %s should be set when using code coverage remote driver',
78
                'coverage_url'
79
            ));
80
        }
81
82 4
        $client = $container->get('doyo.coverage.http_client');
83 4
        $definition->addMethodCall('setHttpClient', [$client]);
84 4
        $definition->addMethodCall('setRemoteUrl', [$config['remote_url']]);
85
    }
86
87 4
    private function createSessionDriver(ContainerBuilder $container, $name, $config)
88
    {
89 4
        $xdebugPatch = $container->getParameterBag()->get('doyo.coverage.xdebug_patch');
90 4
        $driver = $config['driver'];
91
        $map    = [
92 4
            'local'  => 'doyo.coverage.local_session.class',
93
            'remote' => 'doyo.coverage.remote_session.class',
94
        ];
95 4
        $class      = $container->getParameterBag()->get($map[$driver]);
96 4
        $id         = 'doyo.coverage.sessions.'.$name.'.driver';
97 4
        $definition = new Definition($class);
98 4
        $definition->setPublic(true);
99 4
        $definition->addArgument($name);
100 4
        $definition->addArgument($xdebugPatch);
101
102 4
        $container->setDefinition($id, $definition);
103
104 4
        $processorId = $this->createSessionProcessor($container, $name);
105 4
        $definition->addMethodCall('setProcessor', [new Reference($processorId)]);
106
107
108 4
        return $id;
109
    }
110
111 4
    private function createSessionProcessor(ContainerBuilder $container, $sessionName)
112
    {
113 4
        $id =  'doyo.coverage.sessions.'.$sessionName.'.processor';
114
115 4
        $driverId = $id.'.driver';
116 4
        $driver   = new Definition($container->getParameterBag()->get('doyo.coverage.driver.dummy.class'));
117 4
        $driver->setPublic(true);
118 4
        $container->setDefinition($driverId, $driver);
119
120 4
        $class     = $container->getParameterBag()->get('doyo.coverage.processor.class');
121 4
        $processor = new Definition($class);
122 4
        $processor->addArgument(new Reference($driverId));
123 4
        $processor->addArgument(new Reference('doyo.coverage.filter'));
124 4
        $processor->addTag('doyo.coverage.processor');
125 4
        $processor->setPublic(true);
126 4
        $container->setDefinition($id, $processor);
127
128 4
        return $id;
129
    }
130
131 4
    private function processCoverageOptions(ContainerBuilder $container)
132
    {
133 4
        $options = $container->getParameterBag()->get('doyo.coverage.options');
134
135 4
        $definitions = $container->findTaggedServiceIds('doyo.coverage.processor');
136
        /* @var \Symfony\Component\DependencyInjection\Definition $definition */
137 4
        foreach ($definitions as $id => $test) {
138 4
            $definition = $container->getDefinition($id);
139 4
            $definition->addMethodCall('setCodeCoverageOptions', [$options]);
140
        }
141
    }
142
143 4
    private function processFilterOptions(ContainerBuilder $container)
144
    {
145 4
        $config     = $container->getParameterBag()->get('doyo.coverage.config');
146 4
        $filter     = $config['filter'];
147 4
        $basePath   = $container->getParameterBag()->get('paths.base');
148 4
        $definition = $container->getDefinition('doyo.coverage.filter');
149
150 4
        foreach ($filter as $options) {
151 4
            $options['basePath'] = $basePath;
152 4
            $this->filterWhitelist($definition, $options, 'add');
153 4
            $exclude = $options['exclude'];
154 4
            foreach ($exclude as $item) {
155 4
                $item['basePath'] = $basePath;
156 4
                $this->filterWhitelist($definition, $item, 'remove');
157
            }
158
        }
159
    }
160
161 4
    private function filterWhitelist(Definition $definition, $options, $method)
162
    {
163 4
        $basePath  = $options['basePath'];
164 4
        $suffix    = $options['suffix'] ?: '.php';
165 4
        $prefix    = $options['prefix'] ?: '';
166 4
        $type      = $options['directory'] ? 'directory' : 'file';
167 4
        $directory = $basePath.\DIRECTORY_SEPARATOR.$options['directory'];
168 4
        $file      = $basePath.\DIRECTORY_SEPARATOR.$options['file'];
169
170 4
        if (preg_match('/\/\*(\..+)/', $directory, $matches)) {
171 4
            $suffix    = $matches[1];
172 4
            $directory = str_replace($matches[0], '', $directory);
173
        }
174
175 4
        $methodSuffix = 'add' === $method ? 'ToWhitelist' : 'FromWhitelist';
176 4
        if ('directory' === $type) {
177 4
            $definition->addMethodCall($method.'Directory'.$methodSuffix, [$directory, $suffix, $prefix]);
178
        }
179
180 4
        if ('file' === $type) {
181 4
            $definition->addMethodCall($method.'File'.$methodSuffix, [$file]);
182
        }
183
    }
184
}
185