Passed
Push — master ( 4679bc...32cf9c )
by Alec
03:27 queued 52s
created

BenchmarkFunctionFormatter::getExporter()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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