Test Failed
Push — main ( 645eda...aff472 )
by mikhail
03:07
created

CommentDensity::prepareCommentStatistics()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 6.0026

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 21
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 30
ccs 23
cts 24
cp 0.9583
crap 6.0026
rs 8.9617
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SavinMikhail\CommentsDensity;
6
7
use Generator;
8
use SavinMikhail\CommentsDensity\Comments\CommentFactory;
9
use SavinMikhail\CommentsDensity\Comments\CommentTypeInterface;
10
use SavinMikhail\CommentsDensity\DTO\Input\ConfigDTO;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\DTO\Input\ConfigDTO was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use SavinMikhail\CommentsDensity\DTO\Output\CommentDTO;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\DTO\Output\CommentDTO was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use SavinMikhail\CommentsDensity\DTO\Output\CommentStatisticsDTO;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDen...ut\CommentStatisticsDTO was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use SavinMikhail\CommentsDensity\DTO\Output\OutputDTO;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\DTO\Output\OutputDTO was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use SavinMikhail\CommentsDensity\Metrics\Metrics;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\Metrics\Metrics was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use SavinMikhail\CommentsDensity\Reporters\ReporterInterface;
16
use SplFileInfo;
17
18
use function str_contains;
19
20
final class CommentDensity
21
{
22
    private bool $exceedThreshold = false;
23 5
24
    public function __construct(
25
        private readonly ConfigDTO $configDTO,
26
        private readonly CommentFactory $commentFactory,
27
        private readonly FileAnalyzer $fileAnalyzer,
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\FileAnalyzer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
        private readonly ReporterInterface $reporter,
29
        private readonly MissingDocBlockAnalyzer $missingDocBlock,
30
        private readonly Metrics $metrics,
31 5
    ) {
32
    }
33 1
34
    public function analyze(Generator $files): bool
35 1
    {
36 1
        $this->metrics->startPerformanceMonitoring();
37
        $comments = [];
38
        $commentStatistics = [];
39 2
        $totalLinesOfCode = 0;
40
        $cdsSum = 0;
41 2
        $filesAnalyzed = 0;
42 2
43
        foreach ($files as $file) {
44
            if (! ($file instanceof SplFileInfo)) {
45 1
                continue;
46
            }
47 1
            if ($this->isInWhitelist($file->getRealPath())) {
48 1
                continue;
49 1
            }
50 1
            if ($file->getSize() === 0) {
51 1
                continue;
52
            }
53
54 1
            $this->fileAnalyzer->analyzeFile(
55
                $file,
56
                $commentStatistics,
57 3
                $comments,
58
                $totalLinesOfCode,
59 3
                $cdsSum
60 3
            );
61 3
            $filesAnalyzed++;
62 3
        }
63 3
64 3
        $this->metrics->stopPerformanceMonitoring();
65
66 3
        $averageCds = $totalLinesOfCode === 0 ? 0 : $cdsSum / $totalLinesOfCode;
0 ignored issues
show
introduced by
The condition $totalLinesOfCode === 0 is always true.
Loading history...
67 3
        $outputDTO = $this->createOutputDTO(
68 3
            $comments,
69 3
            $commentStatistics,
70 3
            $totalLinesOfCode,
71 3
            $averageCds,
72 3
            $filesAnalyzed,
73 3
        );
74 3
75 3
        $this->reporter->report($outputDTO);
76
77
        return $this->exceedThreshold;
78
    }
79 3
80
    private function createOutputDTO(
81 3
        array $comments,
82 3
        array $commentStatistics,
83 3
        int $linesOfCode,
84 3
        float $cds,
85 3
        int $filesAnalyzed,
86 3
    ): OutputDTO {
87 3
        $outputDTO = new OutputDTO(
88
            $filesAnalyzed,
89 3
            $this->prepareCommentStatistics($commentStatistics),
90
            $this->prepareComments($comments),
91 3
            $this->metrics->getPerformanceMetrics(),
92
            $this->metrics->prepareComToLoc($commentStatistics, $linesOfCode),
93
            $this->metrics->prepareCDS($cds)
94 3
        );
95
        if ($this->metrics->hasExceededThreshold()) {
96
            $this->exceedThreshold = true;
97
        }
98
        return $outputDTO;
99
    }
100
101 3
    private function prepareCommentStatistics(array $commentStatistics): array
102 3
    {
103 3
        $preparedStatistics = [];
104 3
        foreach ($commentStatistics as $type => $count) {
105 3
            if ($type === 'missingDocblock') {
106 3
                $preparedStatistics[] = new CommentStatisticsDTO(
107 3
                    $this->missingDocBlock->getColor(),
108 3
                    $this->missingDocBlock->getName(),
109 3
                    $count,
110 1
                    $this->missingDocBlock->getStatColor($count, $this->configDTO->thresholds)
111
                );
112 3
                if ($this->missingDocBlock->hasExceededThreshold()) {
113
                    $this->exceedThreshold = true;
114
                }
115 3
                continue;
116
            }
117 3
            $commentType = $this->commentFactory->getCommentType($type);
118 3
            if ($commentType) {
119 3
                $preparedStatistics[] = new CommentStatisticsDTO(
120 3
                    $commentType->getColor(),
121 3
                    $commentType->getName(),
122 3
                    $count,
123 3
                    $commentType->getStatColor($count, $this->configDTO->thresholds)
124 3
                );
125 3
                if ($commentType->hasExceededThreshold()) {
126 3
                    $this->exceedThreshold = true;
127
                }
128
            }
129 3
        }
130
        return $preparedStatistics;
131 3
    }
132 3
133 3
    private function prepareComments(array $comments): array
134 3
    {
135 3
        $preparedComments = [];
136 3
        foreach ($comments as $comment) {
137 3
            /** @var CommentTypeInterface|string $commentType */
138 3
            $commentType = $comment['type'];
139 3
            if ($commentType === 'missingDocblock') {
140
                $preparedComments[] = new CommentDTO(
141
                    'missingDocblock',
142
                    'red',
143
                    $comment['file'],
144 3
                    $comment['line'],
145
                    $comment['content']
146
                );
147 3
                continue;
148
            }
149 3
            if ($commentType->getAttitude() === 'good') {
150 3
                continue;
151
            }
152 3
            $preparedComments[] = new CommentDTO(
153 3
                $commentType->getName(),
154
                $commentType->getColor(),
155
                $comment['file'],
156
                $comment['line'],
157
                $comment['content']
158
            );
159
        }
160
        return $preparedComments;
161
    }
162
163 3
    private function isInWhitelist(string $filePath): bool
164 1
    {
165
        foreach ($this->configDTO->exclude as $whitelistedDir) {
166 3
            if (str_contains($filePath, $whitelistedDir)) {
167 3
                return true;
168 3
            }
169 3
        }
170 3
        return false;
171 3
    }
172
}
173