Completed
Push — master ( 9d2605...9c3b37 )
by Alec
02:41
created

BenchmarkReportFormatter::build()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 34
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 26
nc 12
nop 1
dl 0
loc 34
ccs 21
cts 21
cp 1
crap 6
rs 8.8817
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace AlecRabbit\Tools\Reports\Formatters;
4
5
use AlecRabbit\Tools\Factory;
6
use AlecRabbit\Tools\Formattable;
7
use AlecRabbit\Tools\Internal\BenchmarkFunction;
8
use AlecRabbit\Tools\Reports\BenchmarkReport;
9
use AlecRabbit\Tools\Reports\Formatters\Contracts\BenchmarkReportFormatterInterface;
10
use function AlecRabbit\array_is_homogeneous;
11
12
/**
13
 * @psalm-suppress MissingConstructor
14
 *
15
 * Class BenchmarkReportFormatter
16
 * @package AlecRabbit\Tools\Reports\Formatters
17
 */
18
class BenchmarkReportFormatter extends ReportFormatter implements BenchmarkReportFormatterInterface
19
{
20
    protected const ALL_RETURNS_ARE_EQUAL = 'All returns are equal';
21
22
    /** @var BenchmarkReport */
23
    protected $report;
24
    /** @var mixed */
25
    protected $lastReturn;
26
    /** @var int */
27
    protected $added;
28
    /** @var int */
29
    protected $benchmarked;
30
    /** @var bool */
31
    protected $equalReturns;
32
    /** @var bool */
33
    protected $benchmarkedAny;
34
    /** @var bool */
35
    protected $anyExceptions;
36
    /** @var bool */
37
    protected $benchmarkedMoreThanOne;
38
39
    /** {@inheritdoc} */
40 12
    public function process(Formattable $formattable): string
41
    {
42 12
        if ($formattable instanceof BenchmarkReport) {
43 11
            return $this->build($formattable);
44
        }
45 1
        $this->wrongFormattableType(BenchmarkReport::class, $formattable);
46
        // @codeCoverageIgnoreStart
47
        return ''; // never executes
48
        // @codeCoverageIgnoreEnd
49
    }
50
51
    /**
52
     * @param BenchmarkReport $report
53
     * @return string
54
     */
55 11
    protected function build(BenchmarkReport $report): string
56
    {
57 11
        $this->report = $report;
58 11
        $str = static::RESULTS . PHP_EOL;
59 11
        $this->computeVariables();
60 11
        if ($this->benchmarkedAny) {
61 10
            $str .= static::BENCHMARK . PHP_EOL;
62
        }
63 11
        if ($this->anyExceptions) {
64 5
            $exceptions = static::EXCEPTIONS . PHP_EOL;
65
        } else {
66 6
            $exceptions = '';
67
        }
68
69
        /** @var BenchmarkFunction $function */
70 11
        foreach ($report->getFunctions() as $name => $function) {
71
            $tmp =
72 10
                Factory::getBenchmarkFunctionFormatter()
73 10
                    ->noReturnIf($this->equalReturns || $this->report->isNotShowReturns())
74 10
                    ->process($function);
75 10
            if (null === $function->getException()) {
76 10
                $str .= $tmp;
77
            } else {
78 5
                $exceptions .= $tmp;
79
            }
80
        }
81
        return
82 11
            sprintf(
83 11
                '%s%s%s%s%s',
84
                $str,
85 11
                $this->strEqualReturns(),
86
                $exceptions,
87 11
                $this->countersStatistics(),
88 11
                PHP_EOL
89
            );
90
//        return
91
//            sprintf(
92
//                '%s%s%s%s%s',
93
//                $str,
94
//                $this->strEqualReturns(),
95
//                $this->countersStatistics(),
96
//                $report->getMemoryUsageReport(),
97
//                PHP_EOL
98
//            );
99
    }
100
101 11
    protected function computeVariables(): void
102
    {
103 11
        $this->added = $this->report->getAdded()->getValue();
104 11
        $this->benchmarked = $this->report->getBenchmarked()->getValue();
105 11
        $this->benchmarkedAny =
106 11
            $this->added !== $this->added - $this->benchmarked;
107 11
        $this->anyExceptions =
108 11
            $this->added !== $this->benchmarked;
109 11
        $this->benchmarkedMoreThanOne =
110 11
            $this->benchmarked > 1;
111 11
        $this->equalReturns = $this->equalReturns();
112 11
    }
113
114
    /**
115
     * @return bool
116
     */
117 11
    protected function equalReturns(): bool
118
    {
119
        return
120 11
            array_is_homogeneous($this->reportFunctionsReturns());
121
    }
122
123
    /**
124
     * @return array
125
     */
126 11
    protected function reportFunctionsReturns(): array
127
    {
128 11
        $returns = [];
129
        /** @var BenchmarkFunction $function */
130 11
        foreach ($this->report->getFunctions() as $name => $function) {
131 10
            if (null !== $function->getBenchmarkRelative()) {
132 10
                $returns[] = $this->lastReturn = $function->getReturn();
133
            }
134
        }
135 11
        return $returns;
136
    }
137
138
    /**
139
     * @return string
140
     */
141 11
    protected function strEqualReturns(): string
142
    {
143 11
        return $this->benchmarkedAny ? $this->allReturnsAreEqual() : '';
144
    }
145
146 10
    private function allReturnsAreEqual(): string
147
    {
148 10
        $str = '';
149 10
        if ($this->equalReturns) {
150 4
            $aRAE = $this->benchmarkedMoreThanOne ? static::ALL_RETURNS_ARE_EQUAL : '';
151 4
            $dLM = $this->benchmarkedMoreThanOne ? '.' : '';
152
            $str .=
153 4
                sprintf(
154 4
                    '%s%s%s',
155
                    $aRAE,
156 4
                    $this->benchmarkedMoreThanOne && $this->report->isShowReturns() ?
157 1
                        ':' . PHP_EOL . Factory::getBenchmarkFunctionFormatter()->returnToString($this->lastReturn) :
158 4
                        $dLM,
159 4
                    PHP_EOL
160
                );
161
        }
162 10
        return $str;
163
    }
164
165
    /**
166
     * @return string
167
     */
168 11
    private function countersStatistics(): string
169
    {
170 11
        if ($this->added === $this->benchmarked) {
171 6
            return sprintf(
172 6
                '%s: %s %s',
173 6
                static::BENCHMARKED,
174 6
                $this->benchmarked,
175 6
                PHP_EOL
176
            );
177
        }
178
179
        return
180 5
            sprintf(
181 5
                '%s: %s %s: %s %s %s',
182 5
                static::ADDED,
183 5
                $this->added,
184 5
                static::BENCHMARKED,
185 5
                $this->benchmarked,
186 5
                $this->countedExceptions(),
187 5
                PHP_EOL
188
            );
189
    }
190
191
    /**
192
     * @return string
193
     */
194 5
    protected function countedExceptions(): string
195
    {
196 5
        if (0 !== $exceptions = $this->added - $this->benchmarked) {
197
            return
198 5
                sprintf(
199 5
                    '%s %s',
200 5
                    static::EXCEPTIONS,
201
                    $exceptions
202
                );
203
        }
204
        // @codeCoverageIgnoreStart
205
        return '';
206
        // @codeCoverageIgnoreEnd
207
    }
208
}
209