GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 7287da...18db10 )
by joseph
02:16 queued 02:12
created

CheckAnnotations::isAnnotationInClassDocBlock()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 2
dl 0
loc 16
ccs 10
cts 10
cp 1
crap 2
rs 9.8666
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\PHPQA\PHPUnit;
4
5
/**
6
 * Class CheckForLargeAndMediumAnnotations
7
 *
8
 * This class checks a test directory structure and if it is using the Edmonds Commerce recommended style of a
9
 * `Large`,`Medium` and `Large` sub directory structure, then we will also ensure that the large and medium tests are
10
 * correctly annotated
11
 *
12
 * @package EdmondsCommerce\PHPQA\PHPUnit
13
 */
14
class CheckAnnotations
15
{
16
    /**
17
     * @var string
18
     */
19
    private $largePath;
20
    /**
21
     * @var string
22
     */
23
    private $mediumPath;
24
25
    /**
26
     * @var string
27
     */
28
    private $smallPath;
29
30
    /**
31
     * @var array
32
     */
33
    private $errors = [];
34
35
    /**
36
     * Check the Large and Medium directories, if they exist, and then assert that all tests have the correct annotation
37
     *
38
     * @param string $pathToTestsDirectory
39
     *
40
     * @return array of errors
41
     */
42 6
    public function main(string $pathToTestsDirectory): array
43
    {
44 6
        if (!is_dir($pathToTestsDirectory)) {
45 1
            throw new \InvalidArgumentException(
46 1
                '$pathToTestsDirectory "'.$pathToTestsDirectory.'" does not exist"'
47
            );
48
        }
49 5
        $this->largePath  = $pathToTestsDirectory.'/Large';
50 5
        $this->mediumPath = $pathToTestsDirectory.'/Medium';
51 5
        $this->smallPath  = $pathToTestsDirectory.'/Small';
52 5
        $this->checkLarge();
53 5
        $this->checkMedium();
54 5
        $this->checkSmall();
55
56 5
        return $this->errors;
57
    }
58
59 5
    private function checkLarge(): void
60
    {
61 5
        if (!is_dir($this->largePath)) {
62 3
            return;
63
        }
64 2
        $this->checkDirectory($this->largePath, 'large');
65 2
    }
66
67 5
    private function checkMedium(): void
68
    {
69 5
        if (!is_dir($this->mediumPath)) {
70 1
            return;
71
        }
72 4
        $this->checkDirectory($this->mediumPath, 'medium');
73 4
    }
74
75 5
    private function checkSmall(): void
76
    {
77 5
        if (!is_dir($this->smallPath)) {
78 2
            return;
79
        }
80 3
        $this->checkDirectory($this->smallPath, 'small');
81 3
    }
82
83 4
    private function checkDirectory(string $path, string $annotation): void
84
    {
85 4
        foreach ($this->yieldTestFilesInPath($path) as $fileInfo) {
86 4
            if (false === strpos($fileInfo->getFilename(), 'Test.php')) {
87 4
                continue;
88
            }
89 4
            $this->checkFile($fileInfo, $annotation);
90
        }
91 4
    }
92
93
    /**
94
     * @param \SplFileInfo $fileInfo
95
     * @param string       $annotation
96
     *
97
     */
98 4
    private function checkFile(\SplFileInfo $fileInfo, string $annotation): void
99
    {
100 4
        $contents = (string)file_get_contents($fileInfo->getPathname());
101 4
        if($this->isAnnotationInClassDocBlock($contents, $annotation) === true) {
102 1
            return;
103
        }
104
105 4
        $matches  = [];
106 4
        preg_match_all(
107
            <<<REGEXP
108
%(?<docblock>/\*(?:[^*]|\n|(?:\*(?:[^/]|\n)))*\*/)\s+?public\s+?function\s+?(?<method>.+?)\(%
109
REGEXP
110 4
            .'si',
111 4
            $contents,
112 4
            $matches
113
        );
114 4
        if ('' === $matches[0]) {
115
            $this->errors[$fileInfo->getFilename()][] = 'Failed finding any doc blocks';
116
117
            return;
118
        }
119 4
        foreach ($matches['docblock'] as $key => $docblock) {
120 4
            if (false !== strpos($docblock, '@'.$annotation)) {
121 4
                continue;
122
            }
123 3
            $this->errors[$fileInfo->getFilename()][] =
124 3
                'Failed finding @'.$annotation.' for method: '.$matches['method'][$key];
125
        }
126 4
    }
127
128
    /**
129
     * It is possible to put the annotation in the class doc, and have it apply to all tests in the file. This checks
130
     * the class docblock and if the annotation is found there returns true. If not it returns false and the rest of the
131
     * self::checkFile method runs looking for it in the method docblocks
132
     *
133
     * @param string $fileContent
134
     * @param string $annotation
135
     *
136
     * @return bool
137
     */
138 4
    private function isAnnotationInClassDocBlock(string $fileContent, string $annotation):bool
139
    {
140 4
        $matches = [];
141 4
        preg_match_all(
142
            <<<REGEXP
143
%(?<docblock>/\*(?:[^*]|\n|(?:\*(?:[^/]|\n)))*\*/)\s+?class\s+?(?<classname>.+?)\s+?extends%
144
REGEXP
145 4
            . 'si',
146 4
            $fileContent,
147 4
            $matches
148
        );
149 4
        if (count($matches['docblock']) !== 1) {
150 4
            return false;
151
        }
152 1
        $docBlock = array_shift($matches['docblock']);
153 1
        return strpos($docBlock, '@'. $annotation) !== false;
154
    }
155
156
157
    /**
158
     * @param string $path
159
     *
160
     * @return \Generator|\SplFileInfo[]
161
     */
162 4
    private function yieldTestFilesInPath(string $path): \Generator
163
    {
164 4
        $recursiveDirectoryIterator = new \RecursiveDirectoryIterator($path);
165 4
        $iterator                   = new \RecursiveIteratorIterator($recursiveDirectoryIterator);
166 4
        foreach ($iterator as $fileInfo) {
167 4
            yield $fileInfo;
168
        }
169 4
    }
170
}
171