Passed
Pull Request — develop (#10)
by ANTHONIUS
04:06
created

CoveragePass::createSessionDriver()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 1

Importance

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