Completed
Push — master ( 1a3a48...6e0e69 )
by Alessandro
09:39 queued 07:07
created

configureEventDispatcher()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2.0811

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 8
cts 11
cp 0.7272
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 12
nc 2
nop 1
crap 2.0811
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Paraunit\Configuration\DependencyInjection;
6
7
use Paraunit\Configuration\ParallelConfiguration;
8
use Paraunit\Configuration\PHPUnitBinFile;
9
use Paraunit\Configuration\PHPUnitConfig;
10
use Paraunit\Configuration\TempFilenameFactory;
11
use Paraunit\File\Cleaner;
12
use Paraunit\File\TempDirectory;
13
use Paraunit\Filter\Filter;
14
use Paraunit\Printer\ConsoleFormatter;
15
use Paraunit\Printer\FailuresPrinter;
16
use Paraunit\Printer\FilesRecapPrinter;
17
use Paraunit\Printer\FinalPrinter;
18
use Paraunit\Printer\ProcessPrinter;
19
use Paraunit\Printer\SharkPrinter;
20
use Paraunit\Printer\SingleResultFormatter;
21
use Paraunit\Process\CommandLine;
22
use Paraunit\Process\ProcessBuilderFactory;
23
use Paraunit\Process\ProcessFactory;
24
use Paraunit\Process\ProcessFactoryInterface;
25
use Paraunit\Proxy\PHPUnitUtilXMLProxy;
26
use Paraunit\Runner\PipelineCollection;
27
use Paraunit\Runner\PipelineFactory;
28
use Paraunit\Runner\Runner;
29
use Paraunit\TestResult\TestResultList;
30
use Symfony\Component\Console\Output\OutputInterface;
31
use Symfony\Component\DependencyInjection\ContainerBuilder;
32
use Symfony\Component\DependencyInjection\Definition;
33
use Symfony\Component\DependencyInjection\Reference;
34
use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
35
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
36
use Symfony\Component\EventDispatcher\EventDispatcher;
37
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
38
use Symfony\Component\Process\Process;
39
40
class ParallelContainerDefinition
41
{
42
    /** @var ParserDefinition */
43
    private $parserDefinition;
44
45
    /** @var TestResultDefinition */
46
    private $testResult;
47
48 20
    public function __construct()
49
    {
50 20
        $this->parserDefinition = new ParserDefinition();
51 20
        $this->testResult = new TestResultDefinition();
52
    }
53
54 64
    public function configure(ContainerBuilder $container): ContainerBuilder
55
    {
56 64
        $container->setParameter('paraunit.max_retry_count', 3);
57 64
        $container->setParameter('kernel.root_dir', 'src');
58 64
        $this->configureConfiguration($container);
59 64
        $this->configureEventDispatcher($container);
60 64
        $this->configureFile($container);
61 64
        $this->parserDefinition->configure($container);
62 64
        $this->configurePrinter($container);
63 64
        $this->configureProcess($container);
64 64
        $this->configureRunner($container);
65 64
        $this->configureServices($container);
66 64
        $this->testResult->configure($container);
67
68 64
        return $container;
69
    }
70
71 64
    private function configureConfiguration(ContainerBuilder $container)
72
    {
73 64
        $container->setDefinition(PHPUnitBinFile::class, new Definition(PHPUnitBinFile::class));
74 64
        $container->setDefinition(PHPUnitConfig::class, new Definition(PHPUnitConfig::class, [
75 64
            '%paraunit.phpunit_config_filename%',
76
        ]))
77 64
            ->setPublic(true);
78 64
        $container->setDefinition(TempFilenameFactory::class, new Definition(TempFilenameFactory::class, [
79 64
            new Reference(TempDirectory::class),
80
        ]));
81
    }
82
83 64
    private function configureEventDispatcher(ContainerBuilder $container)
84
    {
85 64
        if (class_exists('Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument')) {
86 64
            $container->setDefinition(EventDispatcherInterface::class, new Definition(EventDispatcher::class));
87
        } else {
88
            $container->setDefinition(
89
                EventDispatcherInterface::class,
90
                new Definition(ContainerAwareEventDispatcher::class, [new Reference('service_container')])
91
            );
92
        }
93
94 64
        $container->addCompilerPass(
95 64
            new RegisterListenersPass(
96 64
                EventDispatcherInterface::class,
97 64
                '',
98 64
                ParallelConfiguration::TAG_EVENT_SUBSCRIBER
99
            )
100
        );
101
    }
102
103 64
    private function configureFile(ContainerBuilder $container)
104
    {
105 64
        $container->setDefinition(TempDirectory::class, new Definition(TempDirectory::class));
106 64
        $container->setDefinition(Cleaner::class, new Definition(Cleaner::class, [
107 64
            new Reference(TempDirectory::class),
108
        ]));
109
    }
110
111 64
    private function configurePrinter(ContainerBuilder $container)
112
    {
113 64
        $output = new Reference(OutputInterface::class);
114
115 64
        $container->setDefinition(SharkPrinter::class, new Definition(SharkPrinter::class, [
116 64
            $output,
117 64
            '%paraunit.show_logo%',
118
        ]));
119 64
        $container->setDefinition(ProcessPrinter::class, new Definition(ProcessPrinter::class, [
120 64
            new Reference(SingleResultFormatter::class),
121 64
            $output,
122
        ]));
123
124
        $finalPrinterArguments = [
125 64
            new Reference(TestResultList::class),
126 64
            $output,
127
        ];
128 64
        $container->setDefinition(FinalPrinter::class, new Definition(FinalPrinter::class, $finalPrinterArguments));
129 64
        $container->setDefinition(FailuresPrinter::class, new Definition(FailuresPrinter::class, $finalPrinterArguments));
130 64
        $container->setDefinition(FilesRecapPrinter::class, new Definition(FilesRecapPrinter::class, $finalPrinterArguments));
131
132 64
        $container->setDefinition(ConsoleFormatter::class, new Definition(ConsoleFormatter::class, [$output]));
133 64
        $container->setDefinition(SingleResultFormatter::class, new Definition(SingleResultFormatter::class, [
134 64
            new Reference(TestResultList::class),
135
        ]));
136
    }
137
138 64
    private function configureProcess(ContainerBuilder $container)
139
    {
140 64
        $container->setDefinition(CommandLine::class, new Definition(CommandLine::class, [
141 64
            new Reference(PHPUnitBinFile::class),
142
        ]));
143
144 64
        $container->setDefinition(ProcessFactoryInterface::class, new Definition($this->getProcessFactoryClass(), [
145 64
            new Reference(CommandLine::class),
146 64
            new Reference(PHPUnitConfig::class),
147 64
            new Reference(TempFilenameFactory::class),
148
        ]));
149
    }
150
151 64
    private function configureRunner(ContainerBuilder $container)
152
    {
153 64
        $container->setDefinition(PipelineFactory::class, new Definition(PipelineFactory::class, [
154 64
            new Reference(EventDispatcherInterface::class),
155
        ]));
156 64
        $container->setDefinition(PipelineCollection::class, new Definition(PipelineCollection::class, [
157 64
            new Reference(PipelineFactory::class),
158 64
            '%paraunit.max_process_count%',
159
        ]));
160 64
        $container->setDefinition(Runner::class, new Definition(Runner::class, [
161 64
            new Reference(EventDispatcherInterface::class),
162 64
            new Reference(ProcessFactoryInterface::class),
163 64
            new Reference(Filter::class),
164 64
            new Reference(PipelineCollection::class),
165
        ]))
166 64
            ->setPublic(true);
167
    }
168
169 64
    private function configureServices(ContainerBuilder $container)
170
    {
171 64
        $container->register(OutputInterface::class, OutputInterface::class)
172 64
            ->setPublic(true)
173 64
            ->setSynthetic(true);
174 64
        $container->setDefinition(PHPUnitUtilXMLProxy::class, new Definition(PHPUnitUtilXMLProxy::class));
175 64
        $container->setDefinition(\File_Iterator_Facade::class, new Definition(\File_Iterator_Facade::class));
176 64
        $container->setDefinition(Filter::class, new Definition(Filter::class, [
177 64
            new Reference(PHPUnitUtilXMLProxy::class),
178 64
            new Reference(\File_Iterator_Facade::class),
179 64
            new Reference(PHPUnitConfig::class),
180 64
            '%paraunit.testsuite%',
181 64
            '%paraunit.string_filter%',
182
        ]));
183
    }
184
185 64
    private function getProcessFactoryClass(): string
186
    {
187
        // only reliable way to detect symfony/process 3.3+: CLI parsing
188 64
        $process = new Process(['cmd as array']);
189 64
        if (\is_array($process->getCommandLine())) {
190
            // Commandline not parsed, we have Symfony < 3.3
191
            return ProcessBuilderFactory::class;
192
        }
193
194 64
        return ProcessFactory::class;
195
    }
196
}
197