Passed
Pull Request — master (#350)
by Fabien
02:06
created

CyclomaticComplexityAssessor::getFileContents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Churn\Assessor;
6
7
/**
8
 * @internal
9
 */
10
class CyclomaticComplexityAssessor
11
{
12
    /**
13
     * The total cyclomatic complexity score.
14
     *
15
     * @var integer
16
     */
17
    private $score = 0;
18
19
    /**
20
     * Asses the files cyclomatic complexity.
21
     *
22
     * @param string $contents The contents of a PHP file.
23
     */
24
    public function assess(string $contents): int
25
    {
26
        $this->score = 0;
27
        $this->hasAtLeastOneMethod($contents);
28
        $this->countTheIfStatements($contents);
29
        $this->countTheElseIfStatements($contents);
30
        $this->countTheWhileLoops($contents);
31
        $this->countTheForLoops($contents);
32
        $this->countTheCaseStatements($contents);
33
        $this->countTheTernaryOperators($contents);
34
        $this->countTheLogicalAnds($contents);
35
        $this->countTheLogicalOrs($contents);
36
37
        if (0 === $this->score) {
38
            $this->score = 1;
39
        }
40
41
        return $this->score;
42
    }
43
44
    /**
45
     * Does the class have at least one method?
46
     *
47
     * @param string $contents File contents.
48
     */
49
    private function hasAtLeastOneMethod(string $contents): void
50
    {
51
        \preg_match("/[ ]function[ ]/", $contents, $matches);
52
53
        if (!isset($matches[0])) {
54
            return;
55
        }
56
57
        $this->score++;
58
    }
59
60
    /**
61
     * Count how many if statements there are.
62
     *
63
     * @param string $contents File contents.
64
     */
65
    private function countTheIfStatements(string $contents): void
66
    {
67
        $this->score += $this->howManyPatternMatches("/[ ]if[ ]{0,}\(/", $contents);
68
    }
69
70
    /**
71
     * Count how many else if statements there are.
72
     *
73
     * @param string $contents File contents.
74
     */
75
    private function countTheElseIfStatements(string $contents): void
76
    {
77
        $this->score += $this->howManyPatternMatches("/else[ ]{0,}if[ ]{0,}\(/", $contents);
78
    }
79
80
    /**
81
     * Count how many while loops there are.
82
     *
83
     * @param string $contents File contents.
84
     */
85
    private function countTheWhileLoops(string $contents): void
86
    {
87
        $this->score += $this->howManyPatternMatches("/while[ ]{0,}\(/", $contents);
88
    }
89
90
    /**
91
     * Count how many for loops there are.
92
     *
93
     * @param string $contents File contents.
94
     */
95
    private function countTheForLoops(string $contents): void
96
    {
97
        $this->score += $this->howManyPatternMatches("/[ ]for(each){0,1}[ ]{0,}\(/", $contents);
98
    }
99
100
    /**
101
     * Count how many case statements there are.
102
     *
103
     * @param string $contents File contents.
104
     */
105
    private function countTheCaseStatements(string $contents): void
106
    {
107
        $this->score += $this->howManyPatternMatches("/[ ]case[ ]{1}(.*)\:/", $contents);
108
    }
109
110
    /**
111
     * Count how many ternary operators there are.
112
     *
113
     * @param string $contents File contents.
114
     */
115
    private function countTheTernaryOperators(string $contents): void
116
    {
117
        $this->score += $this->howManyPatternMatches("/[ ]\?.*:.*;/", $contents);
118
    }
119
120
    /**
121
     * Count how many '&&' there are.
122
     *
123
     * @param string $contents File contents.
124
     */
125
    private function countTheLogicalAnds(string $contents): void
126
    {
127
        $this->score += $this->howManyPatternMatches("/[ ]&&[ ]/", $contents);
128
    }
129
130
    /**
131
     * Count how many '||' there are.
132
     *
133
     * @param string $contents File contents.
134
     */
135
    private function countTheLogicalOrs(string $contents): void
136
    {
137
        $this->score += $this->howManyPatternMatches("/[ ]\|\|[ ]/", $contents);
138
    }
139
140
    /**
141
     * For the given $pattern on $string, how many matches are returned?
142
     *
143
     * @param string $pattern Regex pattern.
144
     * @param string $string Any string.
145
     */
146
    private function howManyPatternMatches(string $pattern, string $string): int
147
    {
148
        return (int) \preg_match_all($pattern, $string);
149
    }
150
}
151