Passed
Push — main ( d846f8...8b63c1 )
by mikhail
04:31
created

CDS::calculateRawScore()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 14
ccs 9
cts 9
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SavinMikhail\CommentsDensity\Metrics;
6
7
use Mikhail\PrimitiveWrappers\Int\Integer;
8
use SavinMikhail\CommentsDensity\Comments\CommentFactory;
9
use SavinMikhail\CommentsDensity\Comments\DocBlockComment;
10
use SavinMikhail\CommentsDensity\DTO\Output\CdsDTO;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\DTO\Output\CdsDTO 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
12
use function in_array;
13
use function round;
14
15
final class CDS
16
{
17
    private const MISSING_DOCBLOCK_WEIGHT = -1;
18
19
    private bool $exceedThreshold = false;
20
21 4
    public function __construct(
22
        private readonly array $thresholds,
23
        private readonly CommentFactory $commentFactory,
24
    ) {
25 4
    }
26
27 2
    public function calculateCDS(array $commentStatistics): float
28
    {
29 2
        $rawScore = $this->calculateRawScore($commentStatistics);
30 2
        $minPossibleScore = $this->getMinPossibleScore($commentStatistics);
31 2
        $maxPossibleScore = $this->getMaxPossibleScore($commentStatistics);
32
33
        try {
34 2
            return (new Integer(0))
35 2
                ->scaleToRange($rawScore, $minPossibleScore, $maxPossibleScore);
36
        } catch (\InvalidArgumentException) {
37
            return 0;
38
        }
39
    }
40
41 2
    private function calculateRawScore(array $commentStatistics): float
42
    {
43 2
        $rawScore = 0;
44
45 2
        foreach ($commentStatistics as $type => $count) {
46 2
            $comment = $this->commentFactory->getCommentType($type);
47 2
            if ($comment) {
48 2
                $rawScore += $count * $comment->getWeight();
49 2
                continue;
50
            }
51 2
            $rawScore += $count * self::MISSING_DOCBLOCK_WEIGHT;
52
        }
53
54 2
        return $rawScore;
55
    }
56
57 2
    private function getMinPossibleScore(array $commentStatistics): float
58
    {
59 2
        $minScore = 0;
60 2
        foreach ($commentStatistics as $type => $count) {
61 2
            $comment = $this->commentFactory->getCommentType($type);
62 2
            if (!$comment) {
63 2
                $minScore += self::MISSING_DOCBLOCK_WEIGHT * $count;
64 2
                continue;
65
            }
66 2
            if (in_array($comment->getAttitude(), ['bad', 'unwanted'])) {
67 2
                $minScore += $comment->getWeight() * $count;
68 2
                continue;
69
            }
70 2
            $minScore -= $comment->getWeight() * $count;
71
        }
72 2
        return $minScore;
73
    }
74
75 2
    private function getMaxPossibleScore(array $commentStatistics): float
76
    {
77 2
        return (
78 2
                ($commentStatistics['missingDocblock'] ?? 0)
79 2
                + ($commentStatistics['docblock'] ?? 0)
80 2
            )
81 2
            * ((new DocBlockComment())->getWeight());
82
    }
83
84 1
    public function prepareCDS(float $cds): CdsDTO
85
    {
86 1
        $cds = round($cds, 2);
87 1
        return new CdsDTO(
88 1
            $cds,
89 1
            $this->getColorForCDS($cds),
90 1
        );
91
    }
92
93 1
    private function getColorForCDS(float $cds): string
94
    {
95 1
        if (! isset($this->thresholds['CDS'])) {
96
            return 'white';
97
        }
98 1
        if ($cds >= $this->thresholds['CDS']) {
99
            return 'green';
100
        }
101 1
        $this->exceedThreshold = true;
102 1
        return 'red';
103
    }
104
105 1
    public function hasExceededThreshold(): bool
106
    {
107 1
        return $this->exceedThreshold;
108
    }
109
}
110