Completed
Push — develop ( d2e190...d276d7 )
by Alec
10:43 queued 07:55
created

BenchmarkFunctionFormatter::formatException()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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