Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | 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_values;
13
use function arsort;
14
use function asort;
15
use function count;
16
use function explode;
17
use function floor;
18
use function json_encode;
19
use function sprintf;
20
use function str_replace;
21
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
22
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
23
use SebastianBergmann\Template\Template;
24
 
25
/**
26
 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
27
 */
28
final class Dashboard extends Renderer
29
{
30
    public function render(DirectoryNode $node, string $file): void
31
    {
32
        $classes      = $node->classesAndTraits();
33
        $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'dashboard_branch.html' : 'dashboard.html');
34
        $template     = new Template(
35
            $templateName,
36
            '{{',
37
            '}}'
38
        );
39
 
40
        $this->setCommonTemplateVariables($template, $node);
41
 
42
        $baseLink             = $node->id() . '/';
43
        $complexity           = $this->complexity($classes, $baseLink);
44
        $coverageDistribution = $this->coverageDistribution($classes);
45
        $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink);
46
        $projectRisks         = $this->projectRisks($classes, $baseLink);
47
 
48
        $template->setVar(
49
            [
50
                'insufficient_coverage_classes' => $insufficientCoverage['class'],
51
                'insufficient_coverage_methods' => $insufficientCoverage['method'],
52
                'project_risks_classes'         => $projectRisks['class'],
53
                'project_risks_methods'         => $projectRisks['method'],
54
                'complexity_class'              => $complexity['class'],
55
                'complexity_method'             => $complexity['method'],
56
                'class_coverage_distribution'   => $coverageDistribution['class'],
57
                'method_coverage_distribution'  => $coverageDistribution['method'],
58
            ]
59
        );
60
 
61
        $template->renderTo($file);
62
    }
63
 
64
    protected function activeBreadcrumb(AbstractNode $node): string
65
    {
66
        return sprintf(
67
            '         <li class="breadcrumb-item"><a href="index.html">%s</a></li>' . "\n" .
68
            '         <li class="breadcrumb-item active">(Dashboard)</li>' . "\n",
69
            $node->name()
70
        );
71
    }
72
 
73
    /**
74
     * Returns the data for the Class/Method Complexity charts.
75
     */
76
    private function complexity(array $classes, string $baseLink): array
77
    {
78
        $result = ['class' => [], 'method' => []];
79
 
80
        foreach ($classes as $className => $class) {
81
            foreach ($class['methods'] as $methodName => $method) {
82
                if ($className !== '*') {
83
                    $methodName = $className . '::' . $methodName;
84
                }
85
 
86
                $result['method'][] = [
87
                    $method['coverage'],
88
                    $method['ccn'],
89
                    sprintf(
90
                        '<a href="%s">%s</a>',
91
                        str_replace($baseLink, '', $method['link']),
92
                        $methodName
93
                    ),
94
                ];
95
            }
96
 
97
            $result['class'][] = [
98
                $class['coverage'],
99
                $class['ccn'],
100
                sprintf(
101
                    '<a href="%s">%s</a>',
102
                    str_replace($baseLink, '', $class['link']),
103
                    $className
104
                ),
105
            ];
106
        }
107
 
108
        return [
109
            'class'  => json_encode($result['class']),
110
            'method' => json_encode($result['method']),
111
        ];
112
    }
113
 
114
    /**
115
     * Returns the data for the Class / Method Coverage Distribution chart.
116
     */
117
    private function coverageDistribution(array $classes): array
118
    {
119
        $result = [
688 lars 120
            'class' => [
148 lars 121
                '0%'      => 0,
122
                '0-10%'   => 0,
123
                '10-20%'  => 0,
124
                '20-30%'  => 0,
125
                '30-40%'  => 0,
126
                '40-50%'  => 0,
127
                '50-60%'  => 0,
128
                '60-70%'  => 0,
129
                '70-80%'  => 0,
130
                '80-90%'  => 0,
131
                '90-100%' => 0,
132
                '100%'    => 0,
133
            ],
134
            'method' => [
135
                '0%'      => 0,
136
                '0-10%'   => 0,
137
                '10-20%'  => 0,
138
                '20-30%'  => 0,
139
                '30-40%'  => 0,
140
                '40-50%'  => 0,
141
                '50-60%'  => 0,
142
                '60-70%'  => 0,
143
                '70-80%'  => 0,
144
                '80-90%'  => 0,
145
                '90-100%' => 0,
146
                '100%'    => 0,
147
            ],
148
        ];
149
 
150
        foreach ($classes as $class) {
151
            foreach ($class['methods'] as $methodName => $method) {
152
                if ($method['coverage'] === 0) {
153
                    $result['method']['0%']++;
154
                } elseif ($method['coverage'] === 100) {
155
                    $result['method']['100%']++;
156
                } else {
157
                    $key = floor($method['coverage'] / 10) * 10;
158
                    $key = $key . '-' . ($key + 10) . '%';
159
                    $result['method'][$key]++;
160
                }
161
            }
162
 
163
            if ($class['coverage'] === 0) {
164
                $result['class']['0%']++;
165
            } elseif ($class['coverage'] === 100) {
166
                $result['class']['100%']++;
167
            } else {
168
                $key = floor($class['coverage'] / 10) * 10;
169
                $key = $key . '-' . ($key + 10) . '%';
170
                $result['class'][$key]++;
171
            }
172
        }
173
 
174
        return [
175
            'class'  => json_encode(array_values($result['class'])),
176
            'method' => json_encode(array_values($result['method'])),
177
        ];
178
    }
179
 
180
    /**
181
     * Returns the classes / methods with insufficient coverage.
182
     */
183
    private function insufficientCoverage(array $classes, string $baseLink): array
184
    {
185
        $leastTestedClasses = [];
186
        $leastTestedMethods = [];
187
        $result             = ['class' => '', 'method' => ''];
188
 
189
        foreach ($classes as $className => $class) {
190
            foreach ($class['methods'] as $methodName => $method) {
191
                if ($method['coverage'] < $this->highLowerBound) {
192
                    $key = $methodName;
193
 
194
                    if ($className !== '*') {
195
                        $key = $className . '::' . $methodName;
196
                    }
197
 
198
                    $leastTestedMethods[$key] = $method['coverage'];
199
                }
200
            }
201
 
202
            if ($class['coverage'] < $this->highLowerBound) {
203
                $leastTestedClasses[$className] = $class['coverage'];
204
            }
205
        }
206
 
207
        asort($leastTestedClasses);
208
        asort($leastTestedMethods);
209
 
210
        foreach ($leastTestedClasses as $className => $coverage) {
211
            $result['class'] .= sprintf(
212
                '       <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n",
213
                str_replace($baseLink, '', $classes[$className]['link']),
214
                $className,
215
                $coverage
216
            );
217
        }
218
 
219
        foreach ($leastTestedMethods as $methodName => $coverage) {
220
            [$class, $method] = explode('::', $methodName);
221
 
222
            $result['method'] .= sprintf(
223
                '       <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d%%</td></tr>' . "\n",
224
                str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
225
                $methodName,
226
                $method,
227
                $coverage
228
            );
229
        }
230
 
231
        return $result;
232
    }
233
 
234
    /**
235
     * Returns the project risks according to the CRAP index.
236
     */
237
    private function projectRisks(array $classes, string $baseLink): array
238
    {
239
        $classRisks  = [];
240
        $methodRisks = [];
241
        $result      = ['class' => '', 'method' => ''];
242
 
243
        foreach ($classes as $className => $class) {
244
            foreach ($class['methods'] as $methodName => $method) {
245
                if ($method['coverage'] < $this->highLowerBound && $method['ccn'] > 1) {
246
                    $key = $methodName;
247
 
248
                    if ($className !== '*') {
249
                        $key = $className . '::' . $methodName;
250
                    }
251
 
252
                    $methodRisks[$key] = $method['crap'];
253
                }
254
            }
255
 
256
            if ($class['coverage'] < $this->highLowerBound &&
257
                $class['ccn'] > count($class['methods'])) {
258
                $classRisks[$className] = $class['crap'];
259
            }
260
        }
261
 
262
        arsort($classRisks);
263
        arsort($methodRisks);
264
 
265
        foreach ($classRisks as $className => $crap) {
266
            $result['class'] .= sprintf(
267
                '       <tr><td><a href="%s">%s</a></td><td class="text-right">%d</td></tr>' . "\n",
268
                str_replace($baseLink, '', $classes[$className]['link']),
269
                $className,
270
                $crap
271
            );
272
        }
273
 
274
        foreach ($methodRisks as $methodName => $crap) {
275
            [$class, $method] = explode('::', $methodName);
276
 
277
            $result['method'] .= sprintf(
278
                '       <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d</td></tr>' . "\n",
279
                str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
280
                $methodName,
281
                $method,
282
                $crap
283
            );
284
        }
285
 
286
        return $result;
287
    }
288
}