Completed
Push — master ( 743834...4ffa9b )
by Julian
12s
created

Configuration::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace ParaTest\Runners\PHPUnit;
4
5
/**
6
 * Class Configuration.
7
 *
8
 * Stores information about the phpunit xml
9
 * configuration being used to run tests
10
 */
11
class Configuration
12
{
13
    /**
14
     * Path to the configuration file.
15
     *
16
     * @var string
17
     */
18
    protected $path;
19
20
    /**
21
     * @var \SimpleXMLElement
22
     */
23
    protected $xml;
24
25
    protected $availableNodes = ['exclude', 'file', 'directory', 'testsuite'];
26
27
    /**
28
     * A collection of datastructures
29
     * build from the <testsuite> nodes inside of a
30
     * PHPUnit configuration.
31
     *
32
     * @var array
33
     */
34
    protected $suites = [];
35
36 59
    public function __construct($path)
37
    {
38 59
        $this->path = $path;
39 59
        if (file_exists($path)) {
40 52
            $this->xml = simplexml_load_string(file_get_contents($path));
41
        }
42 59
    }
43
44
    /**
45
     * Converting the configuration to a string
46
     * returns the configuration path.
47
     *
48
     * @return string
49
     */
50 3
    public function __toString()
51
    {
52 3
        return $this->path;
53
    }
54
55
    /**
56
     * Get the bootstrap PHPUnit configuration attribute.
57
     *
58
     * @return string The bootstrap attribute or empty string if not set
59
     */
60 4
    public function getBootstrap()
61
    {
62 4
        if ($this->xml) {
63 4
            return (string) $this->xml->attributes()->bootstrap;
64
        }
65
66
        return '';
67
    }
68
69
    /**
70
     * Returns the path to the phpunit configuration
71
     * file.
72
     *
73
     * @return string
74
     */
75 15
    public function getPath()
76
    {
77 15
        return $this->path;
78
    }
79
80
    /**
81
     * Return the contents of the <testsuite> nodes
82
     * contained in a PHPUnit configuration.
83
     *
84
     * @return SuitePath[][]|null
85
     */
86 6
    public function getSuites()
87
    {
88 6
        if (!$this->xml) {
89 1
            return;
90
        }
91 5
        $suites = [];
92 5
        $nodes = $this->xml->xpath('//testsuites/testsuite');
93
94 5
        foreach ($nodes as $node) {
95 5
            $suites = array_merge_recursive($suites, $this->getSuiteByName((string) $node['name']));
96
        }
97
98 4
        return $suites;
99
    }
100
101
    /**
102
     * Return the contents of the <testsuite> nodes
103
     * contained in a PHPUnit configuration.
104
     *
105
     * @param string $suiteName
106
     *
107
     * @return SuitePath[]|null
108
     */
109 15
    public function getSuiteByName($suiteName)
110
    {
111 15
        $nodes = $this->xml->xpath(sprintf('//testsuite[@name="%s"]', $suiteName));
112
113 15
        $suites = [];
114 15
        $excludedPaths = [];
115 15
        foreach ($nodes as $node) {
116 15
            foreach ($this->availableNodes as $nodeName) {
117 15
                foreach ($node->{$nodeName} as $nodeContent) {
118
                    switch ($nodeName) {
119 15
                        case 'exclude':
120 3
                            foreach ($this->getSuitePaths((string) $nodeContent) as $excludedPath) {
121 3
                                $excludedPaths[$excludedPath] = $excludedPath;
122
                            }
123 3
                            break;
124 15
                        case 'testsuite':
125 1
                            $suites = array_merge_recursive($suites, $this->getSuiteByName((string) $nodeContent));
126 1
                            break;
127 15
                        case 'directory':
128
                            // Replicate behaviour of PHPUnit
129
                            // if a directory is included and excluded at the same time, then it is considered included
130 12
                            foreach ($this->getSuitePaths((string) $nodeContent) as $dir) {
131 11
                                if (array_key_exists($dir, $excludedPaths)) {
132 11
                                    unset($excludedPaths[$dir]);
133
                                }
134
                            }
135
                            // not breaking on purpose
136
                        default:
137 14
                            foreach ($this->getSuitePaths((string) $nodeContent) as $path) {
138 14
                                $suites[(string) $node['name']][] = new SuitePath(
139 14
                                    $path,
140 14
                                    $excludedPaths,
141 14
                                    $nodeContent->attributes()->suffix
142
                                );
143
                            }
144 15
                            break;
145
                    }
146
                }
147
            }
148
        }
149
150 14
        return $suites;
151
    }
152
153
    /**
154
     * Return the path of the directory
155
     * that contains the phpunit configuration.
156
     *
157
     * @return string
158
     */
159 19
    public function getConfigDir()
160
    {
161 19
        return dirname($this->path) . DIRECTORY_SEPARATOR;
162
    }
163
164
    /**
165
     * Returns a suite paths relative to the config file.
166
     *
167
     * @param $path
168
     *
169
     * @return array|string[]
170
     */
171 15
    public function getSuitePaths($path)
172
    {
173 15
        $real = realpath($this->getConfigDir() . $path);
174
175 15
        if ($real !== false) {
176 13
            return [$real];
177
        }
178
179 2
        if ($this->isGlobRequired($path)) {
180 1
            $paths = [];
181 1
            foreach (glob($this->getConfigDir() . $path, GLOB_ONLYDIR) as $path) {
182 1
                if (($path = realpath($path)) !== false) {
183 1
                    $paths[] = $path;
184
                }
185
            }
186
187 1
            return $paths;
188
        }
189
190 1
        throw new \RuntimeException("Suite path $path could not be found");
191
    }
192
193
    /**
194
     * Returns true if path needs globbing (like a /path/*-to/string).
195
     *
196
     * @param string $path
197
     *
198
     * @return bool
199
     */
200 2
    public function isGlobRequired($path)
201
    {
202 2
        return strpos($path, '*') !== false;
203
    }
204
}
205