Completed
Push — master ( 11abf2...a9443a )
by Jonathan
02:46
created

TestCounter::countNumTestsInFile()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4.0378

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 13
cts 15
cp 0.8667
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 15
nc 4
nop 1
crap 4.0378
1
<?php
2
3
namespace PHPChunkit;
4
5
use ReflectionClass;
6
7
/**
8
 * @testClass PHPChunkit\Test\TestCounterTest
9
 */
10
class TestCounter
11
{
12
    /**
13
     * @var FileClassesHelper
14
     */
15
    private $fileClassesHelper;
16
17
    /**
18
     * @var array
19
     */
20
    private $cache = [];
21
22
    /**
23
     * @var string
24
     */
25
    private $cachePath = '';
26
27
    /**
28
     * @param FileClassesHelper $fileClassesHelper
29
     */
30 7
    public function __construct(FileClassesHelper $fileClassesHelper)
31
    {
32 7
        $this->fileClassesHelper = $fileClassesHelper;
33 7
        $this->cachePath = sprintf('%s/testcounter.cache', sys_get_temp_dir());
34
35 7
        $this->loadCache();
36 7
    }
37
38 1
    public function __destruct()
39
    {
40 1
        $this->writeCache();
41 1
    }
42
43 2
    public function countNumTestsInFile(string $file) : int
44
    {
45 2
        $cacheKey = $file.@filemtime($file);
46
47 2
        if (isset($this->cache[$cacheKey])) {
48 1
            return $this->cache[$cacheKey];
49
        }
50
51 2
        $numTestsInFile = 0;
52
53 2
        $classes = $this->fileClassesHelper->getFileClasses($file);
54
55 2
        if (empty($classes)) {
56
            $this->cache[$cacheKey] = $numTestsInFile;
57
58
            return $numTestsInFile;
59
        }
60
61 2
        $className = $classes[0];
62
63 2
        require_once $file;
64
65 2
        foreach ($classes as $className) {
66 2
            $numTestsInFile += $this->countNumTestsInClass($className);
67
        }
68
69 2
        $this->cache[$cacheKey] = $numTestsInFile;
70
71 2
        return $numTestsInFile;
72
    }
73
74 7
    public function clearCache()
75
    {
76 7
        if (file_exists($this->cachePath)) {
77 1
            unlink($this->cachePath);
78
        }
79
80 7
        $this->cache = [];
81 7
    }
82
83 1
    protected function loadCache()
84
    {
85 1
        if (file_exists($this->cachePath)) {
86
            $this->cache = include($this->cachePath);
87
        }
88 1
    }
89
90 1
    protected function writeCache()
91
    {
92 1
        file_put_contents($this->cachePath, '<?php return '.var_export($this->cache, true).';');
93 1
    }
94
95 2
    private function countNumTestsInClass(string $className) : int
96
    {
97 2
        $reflectionClass = new ReflectionClass($className);
98
99 2
        if ($reflectionClass->isAbstract()) {
100 2
            return 0;
101
        }
102
103 2
        $numTests = 0;
104
105 2
        $methods = $reflectionClass->getMethods();
106
107 2
        foreach ($methods as $method) {
108 2
            if (strpos($method->name, 'test') === 0) {
109 2
                $docComment = $method->getDocComment();
110
111 2
                if ($docComment) {
112 2
                    preg_match_all('/@dataProvider\s([a-zA-Z0-9_]+)/', $docComment, $dataProvider);
113
114 2
                    if (isset($dataProvider[1][0])) {
115 2
                        $providerMethod = $dataProvider[1][0];
116
117 2
                        $test = new $className();
118
119 2
                        $numTests = $numTests + count($test->$providerMethod());
120
121 2
                        continue;
122
                    }
123
                }
124
125 2
                $numTests++;
126
            } else {
127 2
                $docComment = $method->getDocComment();
128
129 2
                preg_match_all('/@test/', $docComment, $tests);
130
131 2
                if ($tests[0]) {
132 2
                    $numTests = $numTests + count($tests[0]);
133
                }
134
            }
135
        }
136
137 2
        return $numTests;
138
    }
139
}
140