Completed
Push — master ( f9a123...73c14a )
by Alec
18:36
created

BenchmarkReportFormatter   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 25
eloc 94
c 2
b 0
f 0
dl 0
loc 189
ccs 78
cts 78
cp 1
rs 10

9 Methods

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