Completed
Push — develop ( eb616e...328010 )
by Alec
03:31
created

BenchmarkFunctionFormatter::average()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 7
ccs 6
cts 6
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace AlecRabbit\Tools\Reports\Formatters;
4
5
use AlecRabbit\Accessories\Pretty;
6
use AlecRabbit\Tools\Formattable;
7
use AlecRabbit\Tools\Internal\BenchmarkFunction;
8
use AlecRabbit\Tools\Internal\BenchmarkRelative;
9
use AlecRabbit\Tools\Reports\Formatters\Contracts\BenchmarkFunctionFormatterInterface;
10
use SebastianBergmann\Exporter\Exporter;
11
use function AlecRabbit\typeOf;
12
13
class BenchmarkFunctionFormatter extends Formatter implements BenchmarkFunctionFormatterInterface
14
{
15
    /** @var null|Exporter */
16
    protected static $exporter;
17
18
    /** @var bool */
19
    protected $equalReturns = false;
20
21
    /**
22
     * @return Exporter
23
     */
24 6
    protected static function getExporter(): Exporter
25
    {
26 6
        if (null === static::$exporter) {
27 1
            static::$exporter = new Exporter();
28
        }
29 6
        return static::$exporter;
30
    }
31
32
    /** {@inheritdoc} */
33 11
    public function resetEqualReturns(): BenchmarkFunctionFormatter
34
    {
35
        return
36 11
            $this->noReturnIf();
37
    }
38
39
    /** {@inheritdoc} */
40 11
    public function noReturnIf(bool $equalReturns = false): BenchmarkFunctionFormatter
41
    {
42 11
        $this->equalReturns = $equalReturns;
43 11
        return $this;
44
    }
45
46
    /** {@inheritdoc} */
47 12
    public function process(Formattable $function): string
48
    {
49 12
        if ($function instanceof BenchmarkFunction) {
50
            return
51 11
                $this->formatBenchmarkRelative($function) .
52 11
                (empty($exception = $this->formatException($function)) ?
53 11
                    PHP_EOL :
54 11
                    static::EXCEPTIONS . PHP_EOL . $exception);
55
        }
56 1
        $this->wrongFormattableType(BenchmarkFunction::class, $function);
57
        // @codeCoverageIgnoreStart
58
        return ''; // never executes
59
        // @codeCoverageIgnoreEnd
60
    }
61
62
    /**
63
     * @param BenchmarkFunction $function
64
     * @return string
65
     */
66 11
    protected function formatBenchmarkRelative(BenchmarkFunction $function): string
67
    {
68 11
        if ($br = $function->getBenchmarkRelative()) {
69 11
            $argumentsTypes = $this->extractArgumentsTypes($function->getArgs());
70 11
            $executionReturn = $function->getReturn();
71 11
            if ($this->equalReturns || $function->isNotShowReturns()) {
72 7
                return $this->preformatFunction($br, $function, $argumentsTypes);
73
            }
74
            return
75 4
                sprintf(
76 4
                    '%s %s %s %s',
77 4
                    $this->preformatFunction($br, $function, $argumentsTypes),
78 4
                    PHP_EOL,
79 4
                    static::returnToString($executionReturn),
80 4
                    PHP_EOL
81
                );
82
        }
83 6
        return '';
84
    }
85
86
    /**
87
     * @param array $arguments
88
     * @return array
89
     */
90 11
    protected function extractArgumentsTypes(array $arguments): array
91
    {
92 11
        $types = [];
93 11
        if (!empty($arguments)) {
94 8
            foreach ($arguments as $argument) {
95 8
                $types[] = typeOf($argument);
96
            }
97
        }
98 11
        return $types;
99
    }
100
101
    /**
102
     * @param BenchmarkRelative $br
103
     * @param BenchmarkFunction $function
104
     * @param array $argumentsTypes
105
     * @return string
106
     * todo rename method
107
     */
108 11
    protected function preformatFunction(
109
        BenchmarkRelative $br,
110
        BenchmarkFunction $function,
111
        array $argumentsTypes
112
    ): string {
113
        return
114 11
            sprintf(
115 11
                '%s. %s (%s) %s(%s) %s',
116 11
                (string)$br->getRank(),
117 11
                $this->average($br->getAverage()),
118 11
                $this->relativePercent($br->getRelative()),
119 11
                $function->humanReadableName(),
120 11
                implode(', ', $argumentsTypes),
121 11
                $function->comment()
122
            );
123
    }
124
125
    /**
126
     * @param float $average
127
     * @return string
128
     */
129 11
    protected function average(float $average): string
130
    {
131 11
        return str_pad(
132 11
            Pretty::time($average),
133 11
            8,
134 11
            ' ',
135 11
            STR_PAD_LEFT
136
        );
137
    }
138
139
    /**
140
     * @param float $relative
141
     * @return string
142
     */
143 11
    protected function relativePercent(float $relative): string
144
    {
145 11
        return str_pad(
146 11
            Pretty::percent($relative),
147 11
            7,
148 11
            ' ',
149 11
            STR_PAD_LEFT
150
        );
151
    }
152
153
    /** {@inheritdoc} */
154 6
    public static function returnToString($executionReturn): string
155
    {
156 6
        $type = typeOf($executionReturn);
157 6
        $str = static::getExporter()->export($executionReturn);
158
        return
159 6
            'array' === $type ?
160 1
                $str :
161 5
                sprintf(
162 6
                    '%s(%s)',
163
                    $type,
164
                    $str
165
                );
166
    }
167
168
    /**
169
     * @param BenchmarkFunction $function
170
     * @return string
171
     */
172 11
    protected function formatException(BenchmarkFunction $function): string
173
    {
174
175 11
        if ($e = $function->getException()) {
176 4
            $argumentsTypes = $this->extractArgumentsTypes($function->getArgs());
177
178
            return
179 4
                sprintf(
180 4
                    '%s(%s) %s [%s: %s] %s',
181 4
                    $function->humanReadableName(),
182 4
                    implode(', ', $argumentsTypes),
183 4
                    $function->comment(),
184 4
                    typeOf($e),
185 4
                    $e->getMessage(),
186 4
                    PHP_EOL
187
                );
188
        }
189
190 11
        return '';
191
    }
192
}
193