Completed
Push — master ( c7a3c9...eed046 )
by Alec
16:25
created

BenchmarkReportFormatter::process()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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