Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of phpunit/php-code-coverage.
4
 *
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace SebastianBergmann\CodeCoverage\Report\Html;
11
 
12
use function array_pop;
13
use function count;
14
use function sprintf;
15
use function str_repeat;
16
use function substr_count;
17
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
18
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
19
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
20
use SebastianBergmann\CodeCoverage\Version;
21
use SebastianBergmann\Environment\Runtime;
22
use SebastianBergmann\Template\Template;
23
 
24
/**
25
 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
26
 */
27
abstract class Renderer
28
{
29
    /**
30
     * @var string
31
     */
32
    protected $templatePath;
33
 
34
    /**
35
     * @var string
36
     */
37
    protected $generator;
38
 
39
    /**
40
     * @var string
41
     */
42
    protected $date;
43
 
44
    /**
45
     * @var int
46
     */
47
    protected $lowUpperBound;
48
 
49
    /**
50
     * @var int
51
     */
52
    protected $highLowerBound;
53
 
54
    /**
55
     * @var bool
56
     */
57
    protected $hasBranchCoverage;
58
 
59
    /**
60
     * @var string
61
     */
62
    protected $version;
63
 
64
    public function __construct(string $templatePath, string $generator, string $date, int $lowUpperBound, int $highLowerBound, bool $hasBranchCoverage)
65
    {
66
        $this->templatePath      = $templatePath;
67
        $this->generator         = $generator;
68
        $this->date              = $date;
69
        $this->lowUpperBound     = $lowUpperBound;
70
        $this->highLowerBound    = $highLowerBound;
71
        $this->version           = Version::id();
72
        $this->hasBranchCoverage = $hasBranchCoverage;
73
    }
74
 
75
    protected function renderItemTemplate(Template $template, array $data): string
76
    {
77
        $numSeparator = '&nbsp;/&nbsp;';
78
 
79
        if (isset($data['numClasses']) && $data['numClasses'] > 0) {
80
            $classesLevel = $this->colorLevel($data['testedClassesPercent']);
81
 
82
            $classesNumber = $data['numTestedClasses'] . $numSeparator .
83
                $data['numClasses'];
84
 
85
            $classesBar = $this->coverageBar(
86
                $data['testedClassesPercent']
87
            );
88
        } else {
89
            $classesLevel                         = '';
90
            $classesNumber                        = '0' . $numSeparator . '0';
91
            $classesBar                           = '';
92
            $data['testedClassesPercentAsString'] = 'n/a';
93
        }
94
 
95
        if ($data['numMethods'] > 0) {
96
            $methodsLevel = $this->colorLevel($data['testedMethodsPercent']);
97
 
98
            $methodsNumber = $data['numTestedMethods'] . $numSeparator .
99
                $data['numMethods'];
100
 
101
            $methodsBar = $this->coverageBar(
102
                $data['testedMethodsPercent']
103
            );
104
        } else {
105
            $methodsLevel                         = '';
106
            $methodsNumber                        = '0' . $numSeparator . '0';
107
            $methodsBar                           = '';
108
            $data['testedMethodsPercentAsString'] = 'n/a';
109
        }
110
 
111
        if ($data['numExecutableLines'] > 0) {
112
            $linesLevel = $this->colorLevel($data['linesExecutedPercent']);
113
 
114
            $linesNumber = $data['numExecutedLines'] . $numSeparator .
115
                $data['numExecutableLines'];
116
 
117
            $linesBar = $this->coverageBar(
118
                $data['linesExecutedPercent']
119
            );
120
        } else {
121
            $linesLevel                           = '';
122
            $linesNumber                          = '0' . $numSeparator . '0';
123
            $linesBar                             = '';
124
            $data['linesExecutedPercentAsString'] = 'n/a';
125
        }
126
 
127
        if ($data['numExecutablePaths'] > 0) {
128
            $pathsLevel = $this->colorLevel($data['pathsExecutedPercent']);
129
 
130
            $pathsNumber = $data['numExecutedPaths'] . $numSeparator .
131
                $data['numExecutablePaths'];
132
 
133
            $pathsBar = $this->coverageBar(
134
                $data['pathsExecutedPercent']
135
            );
136
        } else {
137
            $pathsLevel                           = '';
138
            $pathsNumber                          = '0' . $numSeparator . '0';
139
            $pathsBar                             = '';
140
            $data['pathsExecutedPercentAsString'] = 'n/a';
141
        }
142
 
143
        if ($data['numExecutableBranches'] > 0) {
144
            $branchesLevel = $this->colorLevel($data['branchesExecutedPercent']);
145
 
146
            $branchesNumber = $data['numExecutedBranches'] . $numSeparator .
147
                $data['numExecutableBranches'];
148
 
149
            $branchesBar = $this->coverageBar(
150
                $data['branchesExecutedPercent']
151
            );
152
        } else {
153
            $branchesLevel                           = '';
154
            $branchesNumber                          = '0' . $numSeparator . '0';
155
            $branchesBar                             = '';
156
            $data['branchesExecutedPercentAsString'] = 'n/a';
157
        }
158
 
159
        $template->setVar(
160
            [
161
                'icon'                      => $data['icon'] ?? '',
162
                'crap'                      => $data['crap'] ?? '',
163
                'name'                      => $data['name'],
164
                'lines_bar'                 => $linesBar,
165
                'lines_executed_percent'    => $data['linesExecutedPercentAsString'],
166
                'lines_level'               => $linesLevel,
167
                'lines_number'              => $linesNumber,
168
                'paths_bar'                 => $pathsBar,
169
                'paths_executed_percent'    => $data['pathsExecutedPercentAsString'],
170
                'paths_level'               => $pathsLevel,
171
                'paths_number'              => $pathsNumber,
172
                'branches_bar'              => $branchesBar,
173
                'branches_executed_percent' => $data['branchesExecutedPercentAsString'],
174
                'branches_level'            => $branchesLevel,
175
                'branches_number'           => $branchesNumber,
176
                'methods_bar'               => $methodsBar,
177
                'methods_tested_percent'    => $data['testedMethodsPercentAsString'],
178
                'methods_level'             => $methodsLevel,
179
                'methods_number'            => $methodsNumber,
180
                'classes_bar'               => $classesBar,
181
                'classes_tested_percent'    => $data['testedClassesPercentAsString'] ?? '',
182
                'classes_level'             => $classesLevel,
183
                'classes_number'            => $classesNumber,
184
            ]
185
        );
186
 
187
        return $template->render();
188
    }
189
 
190
    protected function setCommonTemplateVariables(Template $template, AbstractNode $node): void
191
    {
192
        $template->setVar(
193
            [
194
                'id'               => $node->id(),
195
                'full_path'        => $node->pathAsString(),
196
                'path_to_root'     => $this->pathToRoot($node),
197
                'breadcrumbs'      => $this->breadcrumbs($node),
198
                'date'             => $this->date,
199
                'version'          => $this->version,
200
                'runtime'          => $this->runtimeString(),
201
                'generator'        => $this->generator,
202
                'low_upper_bound'  => $this->lowUpperBound,
203
                'high_lower_bound' => $this->highLowerBound,
204
            ]
205
        );
206
    }
207
 
208
    protected function breadcrumbs(AbstractNode $node): string
209
    {
210
        $breadcrumbs = '';
211
        $path        = $node->pathAsArray();
212
        $pathToRoot  = [];
213
        $max         = count($path);
214
 
215
        if ($node instanceof FileNode) {
216
            $max--;
217
        }
218
 
219
        for ($i = 0; $i < $max; $i++) {
220
            $pathToRoot[] = str_repeat('../', $i);
221
        }
222
 
223
        foreach ($path as $step) {
224
            if ($step !== $node) {
225
                $breadcrumbs .= $this->inactiveBreadcrumb(
226
                    $step,
227
                    array_pop($pathToRoot)
228
                );
229
            } else {
230
                $breadcrumbs .= $this->activeBreadcrumb($step);
231
            }
232
        }
233
 
234
        return $breadcrumbs;
235
    }
236
 
237
    protected function activeBreadcrumb(AbstractNode $node): string
238
    {
239
        $buffer = sprintf(
240
            '         <li class="breadcrumb-item active">%s</li>' . "\n",
241
            $node->name()
242
        );
243
 
244
        if ($node instanceof DirectoryNode) {
245
            $buffer .= '         <li class="breadcrumb-item">(<a href="dashboard.html">Dashboard</a>)</li>' . "\n";
246
        }
247
 
248
        return $buffer;
249
    }
250
 
251
    protected function inactiveBreadcrumb(AbstractNode $node, string $pathToRoot): string
252
    {
253
        return sprintf(
254
            '         <li class="breadcrumb-item"><a href="%sindex.html">%s</a></li>' . "\n",
255
            $pathToRoot,
256
            $node->name()
257
        );
258
    }
259
 
260
    protected function pathToRoot(AbstractNode $node): string
261
    {
262
        $id    = $node->id();
263
        $depth = substr_count($id, '/');
264
 
265
        if ($id !== 'index' &&
266
            $node instanceof DirectoryNode) {
267
            $depth++;
268
        }
269
 
270
        return str_repeat('../', $depth);
271
    }
272
 
273
    protected function coverageBar(float $percent): string
274
    {
275
        $level = $this->colorLevel($percent);
276
 
277
        $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'coverage_bar_branch.html' : 'coverage_bar.html');
278
        $template     = new Template(
279
            $templateName,
280
            '{{',
281
            '}}'
282
        );
283
 
284
        $template->setVar(['level' => $level, 'percent' => sprintf('%.2F', $percent)]);
285
 
286
        return $template->render();
287
    }
288
 
289
    protected function colorLevel(float $percent): string
290
    {
291
        if ($percent <= $this->lowUpperBound) {
292
            return 'danger';
293
        }
294
 
295
        if ($percent > $this->lowUpperBound &&
296
            $percent < $this->highLowerBound) {
297
            return 'warning';
298
        }
299
 
300
        return 'success';
301
    }
302
 
303
    private function runtimeString(): string
304
    {
305
        $runtime = new Runtime;
306
 
307
        return sprintf(
308
            '<a href="%s" target="_top">%s %s</a>',
309
            $runtime->getVendorUrl(),
310
            $runtime->getName(),
311
            $runtime->getVersion()
312
        );
313
    }
314
}