Completed
Pull Request — master (#93)
by Alessandro
10:07
created

Filter   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 187
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 3
dl 0
loc 187
ccs 55
cts 55
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 1
A filterTestFiles() 0 16 3
A testSuitePassFilter() 0 8 2
A addTestsFromTestSuite() 0 9 1
A getExcludesArray() 0 9 2
A addTestsFromDirectoryNodes() 0 17 3
A addTestsFromFileNodes() 0 7 2
A addFileToAggregateArray() 0 5 1
A getDOMNodeAttribute() 0 17 3
A filterByString() 0 10 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Paraunit\Filter;
5
6
use Paraunit\Configuration\PHPUnitConfig;
7
use Paraunit\Proxy\PHPUnitUtilXMLProxy;
8
9
/**
10
 * Class Filter
11
 * @package Paraunit\Filter
12
 */
13
class Filter
14
{
15
    /** @var PHPUnitUtilXMLProxy */
16
    private $utilXml;
17
18
    /** @var \File_Iterator_Facade */
19
    private $fileIteratorFacade;
20
21
    /** @var PHPUnitConfig */
22
    private $configFile;
23
24
    /** @var string | null */
25
    private $relativePath;
26
27
    /** @var string | null */
28
    private $testSuiteFilter;
29
30
    /** @var string | null */
31
    private $stringFilter;
32
33
    /**
34
     * @param PHPUnitUtilXMLProxy $utilXml
35
     * @param \File_Iterator_Facade $fileIteratorFacade
36
     * @param PHPUnitConfig $configFile
37
     * @param string | null $testSuiteFilter
38
     * @param string | null $stringFilter
39 22
     */
40
    public function __construct(
41
        PHPUnitUtilXMLProxy $utilXml,
42
        \File_Iterator_Facade $fileIteratorFacade,
43
        PHPUnitConfig $configFile,
44
        string $testSuiteFilter = null,
45
        string $stringFilter = null
46 22
    ) {
47 22
        $this->utilXml = $utilXml;
48 22
        $this->fileIteratorFacade = $fileIteratorFacade;
49 22
        $this->configFile = $configFile;
50 22
        $this->relativePath = $configFile->getBaseDirectory() . DIRECTORY_SEPARATOR;
51 22
        $this->testSuiteFilter = $testSuiteFilter;
52 22
        $this->stringFilter = $stringFilter;
53
    }
54
55
    /**
56
     * @return string[]
57 22
     * @throws \RuntimeException
58
     */
59 22
    public function filterTestFiles(): array
60
    {
61 22
        $aggregatedFiles = [];
62 22
63
        $document = $this->utilXml->loadFile($this->configFile->getFileFullPath());
64
        $xpath = new \DOMXPath($document);
65 22
66 22
        /** @var \DOMElement $testSuiteNode */
67 22
        foreach ($xpath->query('testsuites/testsuite') as $testSuiteNode) {
68
            if ($this->testSuitePassFilter($testSuiteNode, $this->testSuiteFilter)) {
69
                $this->addTestsFromTestSuite($testSuiteNode, $aggregatedFiles);
70
            }
71 22
        }
72
73
        return $this->filterByString($aggregatedFiles, $this->stringFilter);
74
    }
75
76
    private function testSuitePassFilter(\DOMElement $testSuiteNode, string $testSuiteFilter = null): bool
77
    {
78
        if ($testSuiteFilter === null) {
79 22
            return true;
80
        }
81 22
82
        return $this->testSuiteFilter === $this->getDOMNodeAttribute($testSuiteNode, 'name');
83 22
    }
84 22
85
    /**
86 22
     * @param \DOMElement $testSuiteNode
87
     * @param array $aggregatedFiles
88
     * @return string[]
89
     */
90
    private function addTestsFromTestSuite(\DOMElement $testSuiteNode, array &$aggregatedFiles): array
91
    {
92
        $excludes = $this->getExcludesArray($testSuiteNode);
93 22
94
        $this->addTestsFromDirectoryNodes($testSuiteNode, $aggregatedFiles, $excludes);
95 22
        $this->addTestsFromFileNodes($testSuiteNode, $aggregatedFiles);
96 22
97 1
        return $aggregatedFiles;
98
    }
99
100 22
    /**
101
     * @param \DOMElement $testSuiteNode
102
     * @return string[]
103
     */
104
    private function getExcludesArray(\DOMElement $testSuiteNode): array
105
    {
106
        $excludes = [];
107
        foreach ($testSuiteNode->getElementsByTagName('exclude') as $excludeNode) {
108 22
            $excludes[] = (string)$excludeNode->nodeValue;
109
        }
110 22
111 22
        return $excludes;
112
    }
113 22
114 22
    /**
115 22
     * @param \DOMElement $testSuiteNode
116 22
     * @param string[] $aggregatedFiles
117
     * @param string[] $excludes
118
     */
119
    private function addTestsFromDirectoryNodes(\DOMElement $testSuiteNode, array &$aggregatedFiles, array $excludes)
120 22
    {
121 22
        foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) {
122
            $directory = (string)$directoryNode->nodeValue;
123
124 22
            $files = $this->fileIteratorFacade->getFilesAsArray(
125
                $this->relativePath . $directory,
126
                $this->getDOMNodeAttribute($directoryNode, 'suffix', 'Test.php'),
127
                $this->getDOMNodeAttribute($directoryNode, 'prefix', ''),
128
                $excludes
129
            );
130 22
131
            foreach ($files as $fileName) {
132 22
                $this->addFileToAggregateArray($aggregatedFiles, $fileName);
133 1
            }
134 1
        }
135
    }
136 22
137
    /**
138
     * @param \DOMElement $testSuiteNode
139
     * @param string[] $aggregatedFiles
140
     */
141
    private function addTestsFromFileNodes(\DOMElement $testSuiteNode, array &$aggregatedFiles)
142 22
    {
143
        foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) {
144
            $fileName = $this->relativePath . (string)$fileNode->nodeValue;
145 22
            $this->addFileToAggregateArray($aggregatedFiles, $fileName);
146 22
        }
147
    }
148
149
    /**
150
     * @param array $aggregatedFiles
151
     * @param string $fileName
152
     */
153
    private function addFileToAggregateArray(array &$aggregatedFiles, string $fileName)
154
    {
155 22
        // optimized array_unique
156
        $aggregatedFiles[$fileName] = $fileName;
157
    }
158
159
    /**
160
     * @param \DOMElement $testSuiteNode
161 22
     * @param string $nodeName
162 19
     * @param string|null $defaultValue
163 19
     *
164
     * @return string
165
     */
166
    private function getDOMNodeAttribute(
167 22
        \DOMElement $testSuiteNode,
168
        string $nodeName,
169
        string $defaultValue = null
170
    ): string {
171
        /**
172
         * @var string
173
         * @var \DOMAttr
174
         */
175 22
        foreach ($testSuiteNode->attributes as $attrName => $attrNode) {
176
            if ($attrName === $nodeName) {
177 22
                return $attrNode->value;
178 14
            }
179 14
        }
180 14
181
        return $defaultValue;
182
    }
183 22
184
    /**
185
     * @param array $aggregatedFiles
186
     * @param string | null $stringFilter
187
     * @return string[]
188
     */
189
    private function filterByString(array $aggregatedFiles, $stringFilter): array
190
    {
191
        if ($stringFilter !== null) {
192
            $aggregatedFiles = array_filter($aggregatedFiles, function ($value) use ($stringFilter) {
193
                return stripos($value, $stringFilter) !== false;
194
            });
195
        }
196
197
        return array_values($aggregatedFiles);
198
    }
199
}
200