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