ParallelContainerDefinition::configurePrinter()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 1

Importance

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