]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/PHPUnit/PHPUnit/Util/Configuration.php
Release 6.2.0
[Github/sugarcrm.git] / tests / PHPUnit / PHPUnit / Util / Configuration.php
1 <?php
2 /**
3  * PHPUnit
4  *
5  * Copyright (c) 2002-2011, Sebastian Bergmann <sebastian@phpunit.de>.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  *   * Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *
15  *   * Redistributions in binary form must reproduce the above copyright
16  *     notice, this list of conditions and the following disclaimer in
17  *     the documentation and/or other materials provided with the
18  *     distribution.
19  *
20  *   * Neither the name of Sebastian Bergmann nor the names of his
21  *     contributors may be used to endorse or promote products derived
22  *     from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * @package    PHPUnit
38  * @subpackage Util
39  * @author     Sebastian Bergmann <sebastian@phpunit.de>
40  * @copyright  2002-2011 Sebastian Bergmann <sebastian@phpunit.de>
41  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
42  * @link       http://www.phpunit.de/
43  * @since      File available since Release 3.2.0
44  */
45
46 /**
47  * Wrapper for the PHPUnit XML configuration file.
48  *
49  * Example XML configuration file:
50  * <code>
51  * <?xml version="1.0" encoding="utf-8" ?>
52  *
53  * <phpunit backupGlobals="true"
54  *          backupStaticAttributes="false"
55  *          bootstrap="/path/to/bootstrap.php"
56  *          colors="false"
57  *          convertErrorsToExceptions="true"
58  *          convertNoticesToExceptions="true"
59  *          convertWarningsToExceptions="true"
60  *          forceCoversAnnotation="false"
61  *          mapTestClassNameToCoveredClassName="false"
62  *          processIsolation="false"
63  *          stopOnError="false"
64  *          stopOnFailure="false"
65  *          stopOnIncomplete="false"
66  *          stopOnSkipped="false"
67  *          syntaxCheck="false"
68  *          testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
69  *          strict="false"
70  *          verbose="false">
71  *   <testsuites>
72  *     <testsuite name="My Test Suite">
73  *       <directory suffix="Test.php">/path/to/files</directory>
74  *       <file>/path/to/MyTest.php</file>
75  *     </testsuite>
76  *   </testsuites>
77  *
78  *   <groups>
79  *     <include>
80  *       <group>name</group>
81  *     </include>
82  *     <exclude>
83  *       <group>name</group>
84  *     </exclude>
85  *   </groups>
86  *
87  *   <filter>
88  *     <blacklist>
89  *       <directory suffix=".php">/path/to/files</directory>
90  *       <file>/path/to/file</file>
91  *       <exclude>
92  *         <directory suffix=".php">/path/to/files</directory>
93  *         <file>/path/to/file</file>
94  *       </exclude>
95  *     </blacklist>
96  *     <whitelist addUncoveredFilesFromWhitelist="true">
97  *       <directory suffix=".php">/path/to/files</directory>
98  *       <file>/path/to/file</file>
99  *       <exclude>
100  *         <directory suffix=".php">/path/to/files</directory>
101  *         <file>/path/to/file</file>
102  *       </exclude>
103  *     </whitelist>
104  *   </filter>
105  *
106  *   <listeners>
107  *     <listener class="MyListener" file="/optional/path/to/MyListener.php">
108  *       <arguments>
109  *         <array>
110  *           <element key="0">
111  *             <string>Sebastian</string>
112  *           </element>
113  *         </array>
114  *         <integer>22</integer>
115  *         <string>April</string>
116  *         <double>19.78</double>
117  *         <null/>
118  *         <object class="stdClass"/>
119  *         <file>MyRelativeFile.php</file>
120  *         <directory>MyRelativeDir</directory>
121  *       </arguments>
122  *     </listener>
123  *   </listeners>
124  *
125  *   <logging>
126  *     <log type="coverage-html" target="/tmp/report" title="My Project"
127             charset="UTF-8" yui="true" highlight="false"
128  *          lowUpperBound="35" highLowerBound="70"/>
129  *     <log type="coverage-clover" target="/tmp/clover.xml"/>
130  *     <log type="json" target="/tmp/logfile.json"/>
131  *     <log type="plain" target="/tmp/logfile.txt"/>
132  *     <log type="tap" target="/tmp/logfile.tap"/>
133  *     <log type="junit" target="/tmp/logfile.xml" logIncompleteSkipped="false"/>
134  *     <log type="story-html" target="/tmp/story.html"/>
135  *     <log type="story-text" target="/tmp/story.txt"/>
136  *     <log type="testdox-html" target="/tmp/testdox.html"/>
137  *     <log type="testdox-text" target="/tmp/testdox.txt"/>
138  *   </logging>
139  *
140  *   <php>
141  *     <includePath>.</includePath>
142  *     <ini name="foo" value="bar"/>
143  *     <const name="foo" value="bar"/>
144  *     <var name="foo" value="bar"/>
145  *     <env name="foo" value="bar"/>
146  *     <post name="foo" value="bar"/>
147  *     <get name="foo" value="bar"/>
148  *     <cookie name="foo" value="bar"/>
149  *     <server name="foo" value="bar"/>
150  *     <files name="foo" value="bar"/>
151  *     <request name="foo" value="bar"/>
152  *   </php>
153  *
154  *   <selenium>
155  *     <browser name="Firefox on Linux"
156  *              browser="*firefox /usr/lib/firefox/firefox-bin"
157  *              host="my.linux.box"
158  *              port="4444"
159  *              timeout="30000"/>
160  *   </selenium>
161  * </phpunit>
162  * </code>
163  *
164  * @package    PHPUnit
165  * @subpackage Util
166  * @author     Sebastian Bergmann <sebastian@phpunit.de>
167  * @copyright  2002-2011 Sebastian Bergmann <sebastian@phpunit.de>
168  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
169  * @version    Release: 3.5.13
170  * @link       http://www.phpunit.de/
171  * @since      Class available since Release 3.2.0
172  */
173 class PHPUnit_Util_Configuration
174 {
175     private static $instances = array();
176
177     protected $document;
178     protected $xpath;
179     protected $filename;
180
181     /**
182      * Loads a PHPUnit configuration file.
183      *
184      * @param  string $filename
185      */
186     protected function __construct($filename)
187     {
188         $this->filename = $filename;
189         $this->document = PHPUnit_Util_XML::loadFile($filename);
190         $this->xpath    = new DOMXPath($this->document);
191     }
192
193     /**
194      * @since  Method available since Release 3.4.0
195      */
196     private final function __clone()
197     {
198     }
199
200     /**
201      * Returns a PHPUnit configuration object.
202      *
203      * @param  string $filename
204      * @return PHPUnit_Util_Configuration
205      * @since  Method available since Release 3.4.0
206      */
207     public static function getInstance($filename)
208     {
209         $realpath = realpath($filename);
210
211         if ($realpath === FALSE) {
212             throw new PHPUnit_Framework_Exception(
213               sprintf(
214                 'Could not read "%s".',
215                 $filename
216               )
217             );
218         }
219
220         if (!isset(self::$instances[$realpath])) {
221             self::$instances[$realpath] = new PHPUnit_Util_Configuration($realpath);
222         }
223
224         return self::$instances[$realpath];
225     }
226
227     /**
228      * Returns the configuration for SUT filtering.
229      *
230      * @return array
231      * @since  Method available since Release 3.2.1
232      */
233     public function getFilterConfiguration()
234     {
235         $addUncoveredFilesFromWhitelist = TRUE;
236
237         $tmp = $this->xpath->query('filter/whitelist');
238
239         if ($tmp->length == 1 &&
240             $tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) {
241             $addUncoveredFilesFromWhitelist = $this->getBoolean(
242               (string)$tmp->item(0)->getAttribute('addUncoveredFilesFromWhitelist'),
243               TRUE
244             );
245         }
246
247         return array(
248           'blacklist' => array(
249             'include' => array(
250               'directory' => $this->readFilterDirectories(
251                 'filter/blacklist/directory'
252               ),
253               'file' => $this->readFilterFiles(
254                 'filter/blacklist/file'
255               )
256             ),
257             'exclude' => array(
258               'directory' => $this->readFilterDirectories(
259                 'filter/blacklist/exclude/directory'
260                ),
261               'file' => $this->readFilterFiles(
262                 'filter/blacklist/exclude/file'
263               )
264             )
265           ),
266           'whitelist' => array(
267             'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist,
268             'include' => array(
269               'directory' => $this->readFilterDirectories(
270                 'filter/whitelist/directory'
271               ),
272               'file' => $this->readFilterFiles(
273                 'filter/whitelist/file'
274               )
275             ),
276             'exclude' => array(
277               'directory' => $this->readFilterDirectories(
278                 'filter/whitelist/exclude/directory'
279               ),
280               'file' => $this->readFilterFiles(
281                 'filter/whitelist/exclude/file'
282               )
283             )
284           )
285         );
286     }
287
288     /**
289      * Returns the configuration for groups.
290      *
291      * @return array
292      * @since  Method available since Release 3.2.1
293      */
294     public function getGroupConfiguration()
295     {
296         $groups = array(
297           'include' => array(),
298           'exclude' => array()
299         );
300
301         foreach ($this->xpath->query('groups/include/group') as $group) {
302             $groups['include'][] = (string)$group->nodeValue;
303         }
304
305         foreach ($this->xpath->query('groups/exclude/group') as $group) {
306             $groups['exclude'][] = (string)$group->nodeValue;
307         }
308
309         return $groups;
310     }
311
312     /**
313      * Returns the configuration for listeners.
314      *
315      * @return array
316      * @since  Method available since Release 3.4.0
317      */
318     public function getListenerConfiguration()
319     {
320         $result = array();
321
322         foreach ($this->xpath->query('listeners/listener') as $listener) {
323             $class     = (string)$listener->getAttribute('class');
324             $file      = '';
325             $arguments = array();
326
327             if ($listener->hasAttribute('file')) {
328                 $file = $this->toAbsolutePath((string)$listener->getAttribute('file'));
329             }
330
331             if ($listener->childNodes->item(1) instanceof DOMElement &&
332                 $listener->childNodes->item(1)->tagName == 'arguments') {
333                 foreach ($listener->childNodes->item(1)->childNodes as $argument) {
334                     if ($argument instanceof DOMElement) {
335                         if($argument->tagName == 'file' || $argument->tagName == 'directory') {
336                             $arguments[] = $this->toAbsolutePath((string)$argument->nodeValue);
337                         } else {
338                             $arguments[] = PHPUnit_Util_XML::xmlToVariable($argument);
339                         }
340                     }
341                 }
342             }
343
344             $result[] = array(
345               'class'     => $class,
346               'file'      => $file,
347               'arguments' => $arguments
348             );
349         }
350
351         return $result;
352     }
353
354     /**
355      * Returns the logging configuration.
356      *
357      * @return array
358      */
359     public function getLoggingConfiguration()
360     {
361         $result = array();
362
363         foreach ($this->xpath->query('logging/log') as $log) {
364             $type   = (string)$log->getAttribute('type');
365             $target = $this->toAbsolutePath((string)$log->getAttribute('target'));
366
367             if ($type == 'coverage-html') {
368                 if ($log->hasAttribute('title')) {
369                     $result['title'] = (string)$log->getAttribute('title');
370                 }
371
372                 if ($log->hasAttribute('charset')) {
373                     $result['charset'] = (string)$log->getAttribute('charset');
374                 }
375
376                 if ($log->hasAttribute('lowUpperBound')) {
377                     $result['lowUpperBound'] = (string)$log->getAttribute('lowUpperBound');
378                 }
379
380                 if ($log->hasAttribute('highLowerBound')) {
381                     $result['highLowerBound'] = (string)$log->getAttribute('highLowerBound');
382                 }
383
384                 if ($log->hasAttribute('yui')) {
385                     $result['yui'] = $this->getBoolean(
386                       (string)$log->getAttribute('yui'),
387                       FALSE
388                     );
389                 }
390
391                 if ($log->hasAttribute('highlight')) {
392                     $result['highlight'] = $this->getBoolean(
393                       (string)$log->getAttribute('highlight'),
394                       FALSE
395                     );
396                 }
397             }
398
399             else if ($type == 'junit') {
400                 if ($log->hasAttribute('logIncompleteSkipped')) {
401                     $result['logIncompleteSkipped'] = $this->getBoolean(
402                       (string)$log->getAttribute('logIncompleteSkipped'),
403                       FALSE
404                     );
405                 }
406             }
407
408             $result[$type] = $target;
409         }
410
411         return $result;
412     }
413
414     /**
415      * Returns the PHP configuration.
416      *
417      * @return array
418      * @since  Method available since Release 3.2.1
419      */
420     public function getPHPConfiguration()
421     {
422         $result = array(
423           'include_path' => '',
424           'ini'          => array(),
425           'const'        => array(),
426           'var'          => array(),
427           'env'          => array(),
428           'post'         => array(),
429           'get'          => array(),
430           'cookie'       => array(),
431           'server'       => array(),
432           'files'        => array(),
433           'request'      => array()
434         );
435
436         $nl = $this->xpath->query('php/includePath');
437
438         if ($nl->length == 1) {
439             $result['include_path'] = $this->toAbsolutePath((string)$nl->item(0)->nodeValue);
440         }
441
442         foreach ($this->xpath->query('php/ini') as $ini) {
443             $name  = (string)$ini->getAttribute('name');
444             $value = (string)$ini->getAttribute('value');
445
446             $result['ini'][$name] = $value;
447         }
448
449         foreach ($this->xpath->query('php/const') as $const) {
450             $name  = (string)$const->getAttribute('name');
451             $value = (string)$const->getAttribute('value');
452
453             $result['const'][$name] = $this->getBoolean($value, $value);
454         }
455
456         foreach (array('var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
457             foreach ($this->xpath->query('php/' . $array) as $var) {
458                 $name  = (string)$var->getAttribute('name');
459                 $value = (string)$var->getAttribute('value');
460
461                 $result[$array][$name] = $this->getBoolean($value, $value);
462             }
463         }
464
465         return $result;
466     }
467
468     /**
469      * Handles the PHP configuration.
470      *
471      * @since  Method available since Release 3.2.20
472      */
473     public function handlePHPConfiguration()
474     {
475         $configuration = $this->getPHPConfiguration();
476
477         if ($configuration['include_path'] != '') {
478             ini_set(
479               'include_path',
480               $configuration['include_path'] . PATH_SEPARATOR .
481               ini_get('include_path')
482             );
483         }
484
485         foreach ($configuration['ini'] as $name => $value) {
486             if (defined($value)) {
487                 $value = constant($value);
488             }
489
490             ini_set($name, $value);
491         }
492
493         foreach ($configuration['const'] as $name => $value) {
494             if (!defined($name)) {
495                 define($name, $value);
496             }
497         }
498
499         foreach (array('var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
500             if ($array == 'var') {
501                 $target = &$GLOBALS;
502             } else {
503                 $target = &$GLOBALS['_' . strtoupper($array)];
504             }
505
506             foreach ($configuration[$array] as $name => $value) {
507                 $target[$name] = $value;
508             }
509         }
510     }
511
512     /**
513      * Returns the PHPUnit configuration.
514      *
515      * @return array
516      * @since  Method available since Release 3.2.14
517      */
518     public function getPHPUnitConfiguration()
519     {
520         $result = array();
521         $root   = $this->document->documentElement;
522
523         if ($root->hasAttribute('colors')) {
524             $result['colors'] = $this->getBoolean(
525               (string)$root->getAttribute('colors'), FALSE
526             );
527         }
528
529         if ($root->hasAttribute('backupGlobals')) {
530             $result['backupGlobals'] = $this->getBoolean(
531               (string)$root->getAttribute('backupGlobals'), TRUE
532             );
533         }
534
535         if ($root->hasAttribute('backupStaticAttributes')) {
536             $result['backupStaticAttributes'] = $this->getBoolean(
537               (string)$root->getAttribute('backupStaticAttributes'), FALSE
538             );
539         }
540
541         if ($root->hasAttribute('bootstrap')) {
542             $result['bootstrap'] = $this->toAbsolutePath(
543               (string)$root->getAttribute('bootstrap')
544             );
545         }
546
547         if ($root->hasAttribute('convertErrorsToExceptions')) {
548             $result['convertErrorsToExceptions'] = $this->getBoolean(
549               (string)$root->getAttribute('convertErrorsToExceptions'), TRUE
550             );
551         }
552
553         if ($root->hasAttribute('convertNoticesToExceptions')) {
554             $result['convertNoticesToExceptions'] = $this->getBoolean(
555               (string)$root->getAttribute('convertNoticesToExceptions'), TRUE
556             );
557         }
558
559         if ($root->hasAttribute('convertWarningsToExceptions')) {
560             $result['convertWarningsToExceptions'] = $this->getBoolean(
561               (string)$root->getAttribute('convertWarningsToExceptions'), TRUE
562             );
563         }
564
565         if ($root->hasAttribute('forceCoversAnnotation')) {
566             $result['forceCoversAnnotation'] = $this->getBoolean(
567               (string)$root->getAttribute('forceCoversAnnotation'), FALSE
568             );
569         }
570
571         if ($root->hasAttribute('mapTestClassNameToCoveredClassName')) {
572             $result['mapTestClassNameToCoveredClassName'] = $this->getBoolean(
573               (string)$root->getAttribute('mapTestClassNameToCoveredClassName'),
574               FALSE
575             );
576         }
577
578         if ($root->hasAttribute('processIsolation')) {
579             $result['processIsolation'] = $this->getBoolean(
580               (string)$root->getAttribute('processIsolation'), FALSE
581             );
582         }
583
584         if ($root->hasAttribute('stopOnError')) {
585             $result['stopOnError'] = $this->getBoolean(
586               (string)$root->getAttribute('stopOnError'), FALSE
587             );
588         }
589
590         if ($root->hasAttribute('stopOnFailure')) {
591             $result['stopOnFailure'] = $this->getBoolean(
592               (string)$root->getAttribute('stopOnFailure'), FALSE
593             );
594         }
595
596         if ($root->hasAttribute('stopOnIncomplete')) {
597             $result['stopOnIncomplete'] = $this->getBoolean(
598               (string)$root->getAttribute('stopOnIncomplete'), FALSE
599             );
600         }
601
602         if ($root->hasAttribute('stopOnSkipped')) {
603             $result['stopOnSkipped'] = $this->getBoolean(
604               (string)$root->getAttribute('stopOnSkipped'), FALSE
605             );
606         }
607
608         if ($root->hasAttribute('syntaxCheck')) {
609             $result['syntaxCheck'] = $this->getBoolean(
610               (string)$root->getAttribute('syntaxCheck'), FALSE
611             );
612         }
613
614         if ($root->hasAttribute('testSuiteLoaderClass')) {
615             $result['testSuiteLoaderClass'] = (string)$root->getAttribute(
616               'testSuiteLoaderClass'
617             );
618         }
619
620         if ($root->hasAttribute('testSuiteLoaderFile')) {
621             $result['testSuiteLoaderFile'] = (string)$root->getAttribute(
622               'testSuiteLoaderFile'
623             );
624         }
625
626         if ($root->hasAttribute('strict')) {
627             $result['strict'] = $this->getBoolean(
628               (string)$root->getAttribute('strict'), FALSE
629             );
630         }
631
632         if ($root->hasAttribute('verbose')) {
633             $result['verbose'] = $this->getBoolean(
634               (string)$root->getAttribute('verbose'), FALSE
635             );
636         }
637
638         return $result;
639     }
640
641     /**
642      * Returns the SeleniumTestCase browser configuration.
643      *
644      * @return array
645      * @since  Method available since Release 3.2.9
646      */
647     public function getSeleniumBrowserConfiguration()
648     {
649         $result = array();
650
651         foreach ($this->xpath->query('selenium/browser') as $config) {
652             $name    = (string)$config->getAttribute('name');
653             $browser = (string)$config->getAttribute('browser');
654
655             if ($config->hasAttribute('host')) {
656                 $host = (string)$config->getAttribute('host');
657             } else {
658                 $host = 'localhost';
659             }
660
661             if ($config->hasAttribute('port')) {
662                 $port = (int)$config->getAttribute('port');
663             } else {
664                 $port = 4444;
665             }
666
667             if ($config->hasAttribute('timeout')) {
668                 $timeout = (int)$config->getAttribute('timeout');
669             } else {
670                 $timeout = 30000;
671             }
672
673             $result[] = array(
674               'name'    => $name,
675               'browser' => $browser,
676               'host'    => $host,
677               'port'    => $port,
678               'timeout' => $timeout
679             );
680         }
681
682         return $result;
683     }
684
685     /**
686      * Returns the test suite configuration.
687      *
688      * @param  boolean $syntaxCheck
689      * @return PHPUnit_Framework_TestSuite
690      * @since  Method available since Release 3.2.1
691      */
692     public function getTestSuiteConfiguration($syntaxCheck = FALSE)
693     {
694         $testSuiteNodes = $this->xpath->query('testsuites/testsuite');
695
696         if ($testSuiteNodes->length == 0) {
697             $testSuiteNodes = $this->xpath->query('testsuite');
698         }
699
700         if ($testSuiteNodes->length == 1) {
701             return $this->getTestSuite($testSuiteNodes->item(0), $syntaxCheck);
702         }
703
704         if ($testSuiteNodes->length > 1) {
705             $suite = new PHPUnit_Framework_TestSuite;
706
707             foreach ($testSuiteNodes as $testSuiteNode) {
708                 $suite->addTestSuite(
709                   $this->getTestSuite($testSuiteNode, $syntaxCheck)
710                 );
711             }
712
713             return $suite;
714         }
715     }
716
717     /**
718      * @param  DOMElement $testSuiteNode
719      * @param  boolean    $syntaxCheck
720      * @return PHPUnit_Framework_TestSuite
721      * @since  Method available since Release 3.4.0
722      */
723     protected function getTestSuite(DOMElement $testSuiteNode, $syntaxCheck)
724     {
725         if ($testSuiteNode->hasAttribute('name')) {
726             $suite = new PHPUnit_Framework_TestSuite(
727               (string)$testSuiteNode->getAttribute('name')
728             );
729         } else {
730             $suite = new PHPUnit_Framework_TestSuite;
731         }
732
733         foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) {
734             $directory = (string)$directoryNode->nodeValue;
735
736             if (empty($directory)) {
737                 continue;
738             }
739
740             if ($directoryNode->hasAttribute('prefix')) {
741                 $prefix = (string)$directoryNode->getAttribute('prefix');
742             } else {
743                 $prefix = '';
744             }
745
746             if ($directoryNode->hasAttribute('suffix')) {
747                 $suffix = (string)$directoryNode->getAttribute('suffix');
748             } else {
749                 $suffix = 'Test.php';
750             }
751
752             $testCollector = new PHPUnit_Runner_IncludePathTestCollector(
753               array($this->toAbsolutePath($directory)), $suffix, $prefix
754             );
755
756             $suite->addTestFiles($testCollector->collectTests(), $syntaxCheck);
757         }
758
759         foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) {
760             $file = (string)$fileNode->nodeValue;
761
762             if (empty($file)) {
763                 continue;
764             }
765
766             $suite->addTestFile($file, $syntaxCheck);
767         }
768
769         return $suite;
770     }
771
772     /**
773      * @param  string  $value
774      * @param  boolean $default
775      * @return boolean
776      * @since  Method available since Release 3.2.3
777      */
778     protected function getBoolean($value, $default)
779     {
780         if (strtolower($value) == 'false') {
781             return FALSE;
782         }
783
784         else if (strtolower($value) == 'true') {
785             return TRUE;
786         }
787
788         return $default;
789     }
790
791     /**
792      * @param  string $query
793      * @return array
794      * @since  Method available since Release 3.2.3
795      */
796     protected function readFilterDirectories($query)
797     {
798         $directories = array();
799
800         foreach ($this->xpath->query($query) as $directory) {
801             if ($directory->hasAttribute('prefix')) {
802                 $prefix = (string)$directory->getAttribute('prefix');
803             } else {
804                 $prefix = '';
805             }
806
807             if ($directory->hasAttribute('suffix')) {
808                 $suffix = (string)$directory->getAttribute('suffix');
809             } else {
810                 $suffix = '.php';
811             }
812
813             if ($directory->hasAttribute('group')) {
814                 $group = (string)$directory->getAttribute('group');
815             } else {
816                 $group = 'DEFAULT';
817             }
818
819             $directories[] = array(
820               'path'   => $this->toAbsolutePath((string)$directory->nodeValue),
821               'prefix' => $prefix,
822               'suffix' => $suffix,
823               'group'  => $group
824             );
825         }
826
827         return $directories;
828     }
829
830     /**
831      * @param  string $query
832      * @return array
833      * @since  Method available since Release 3.2.3
834      */
835     protected function readFilterFiles($query)
836     {
837         $files = array();
838
839         foreach ($this->xpath->query($query) as $file) {
840             $files[] = $this->toAbsolutePath((string)$file->nodeValue);
841         }
842
843         return $files;
844     }
845
846     /**
847      * @param  string $path
848      * @return string
849      * @since  Method available since Release 3.5.0
850      */
851     protected function toAbsolutePath($path)
852     {
853         // is the path already an absolute path?
854         if ($path[0] === '/' || $path[0] === '\\' ||
855             (strlen($path) > 3 && ctype_alpha($path[0]) &&
856              $path[1] === ':' && ($path[2] === '\\' || $path[2] === '/'))) {
857             return $path;
858         }
859
860         return dirname($this->filename) . DIRECTORY_SEPARATOR . $path;
861     }
862 }