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