Completed
Pull Request — master (#114)
by Alessandro
09:19
created

LogParser::onProcessTerminated()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 9
cts 9
cp 1
rs 8.7972
c 0
b 0
f 0
cc 4
eloc 12
nc 4
nop 1
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Paraunit\Parser\JSON;
6
7
use Paraunit\Lifecycle\ProcessEvent;
8
use Paraunit\Process\AbstractParaunitProcess;
9
use Paraunit\TestResult\Interfaces\TestResultHandlerInterface;
10
use Paraunit\TestResult\Interfaces\TestResultInterface;
11
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
12
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
13
14
/**
15
 * Class LogParser
16
 * @package Paraunit\Parser\JSON
17
 */
18
class LogParser implements EventSubscriberInterface
19
{
20
    /** @var LogFetcher */
21
    private $logLocator;
22
23
    /** @var TestResultHandlerInterface */
24
    private $noTestExecutedResultContainer;
25
26
    /** @var EventDispatcherInterface */
27
    private $eventDispatcher;
28
29
    /** @var RetryParser */
30
    private $retryParser;
31
32
    /** @var ParserChainElementInterface[] */
33
    private $parsers;
34
35
    /**
36
     * LogParser constructor.
37
     * @param LogFetcher $logLocator
38 37
     * @param TestResultHandlerInterface $noTestExecutedResultContainer
39
     * @param EventDispatcherInterface $eventDispatcher
40
     * @param RetryParser $retryParser
41
     */
42
    public function __construct(
43 37
        LogFetcher $logLocator,
44 37
        TestResultHandlerInterface $noTestExecutedResultContainer,
45 37
        EventDispatcherInterface $eventDispatcher,
46 37
        RetryParser $retryParser
47
    ) {
48
        $this->logLocator = $logLocator;
49 63
        $this->noTestExecutedResultContainer = $noTestExecutedResultContainer;
50
        $this->eventDispatcher = $eventDispatcher;
51
        $this->retryParser = $retryParser;
52 63
        $this->parsers = [];
53
    }
54
55
    public static function getSubscribedEvents(): array
56
    {
57
        return [
58
            ProcessEvent::PROCESS_TERMINATED => 'onProcessTerminated',
59 37
        ];
60
    }
61 37
62
    /**
63
     * @param ParserChainElementInterface $container
64
     */
65
    public function addParser(ParserChainElementInterface $container)
66
    {
67
        $this->parsers[] = $container;
68
    }
69
70
    /**
71
     * @return ParserChainElementInterface[]
72
     */
73
    public function getParsers(): array
74
    {
75 35
        return $this->parsers;
76
    }
77 35
78 35
    /**
79
     * @param ProcessEvent $processEvent
80 35
     */
81 4
    public function onProcessTerminated(ProcessEvent $processEvent)
82
    {
83 4
        $process = $processEvent->getProcess();
84
        $logs = $this->logLocator->fetch($process);
85
86 31
        if ($this->noTestsExecuted($process, $logs)) {
87 31
            $this->noTestExecutedResultContainer->addProcessToFilenames($process);
88
89
            return;
90 31
        }
91
92
        if ($this->retryParser->processWillBeRetried($process, $logs)) {
93
            $this->eventDispatcher->dispatch(ProcessEvent::PROCESS_TO_BE_RETRIED, new ProcessEvent($process));
94
95
            return;
96
        }
97 31
98
        foreach ($logs as $singleLog) {
99
            $this->processLog($process, $singleLog);
100 31
        }
101 31
102 31
        $this->eventDispatcher->dispatch(ProcessEvent::PROCESS_PARSING_COMPLETED, new ProcessEvent($process));
103
    }
104
105
    /**
106
     * @param AbstractParaunitProcess $process
107
     * @param \stdClass $logItem
108
     */
109
    private function processLog(AbstractParaunitProcess $process, \stdClass $logItem)
110
    {
111
        /** @var ParserChainElementInterface $resultContainer */
112 35
        foreach ($this->parsers as $resultContainer) {
113
            if ($resultContainer->handleLogItem($process, $logItem) instanceof TestResultInterface) {
114 35
                return;
115
            }
116
        }
117
    }
118
119
    /**
120
     * @param AbstractParaunitProcess $process
121
     * @param array $logs
122
     * @return bool
123
     */
124
    private function noTestsExecuted(AbstractParaunitProcess $process, array $logs): bool
125
    {
126
        return $process->getExitCode() === 0 && count($logs) === 1;
127
    }
128
}
129