Completed
Pull Request — master (#83)
by Alessandro
35:34 queued 20:03
created

Filter::filterByString()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

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