]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/PHPUnit/Util/Configuration.php
Added unit tests.
[Github/sugarcrm.git] / tests / PHPUnit / Util / Configuration.php
1 <?php
2 /**
3  * PHPUnit
4  *
5  * Copyright (c) 2002-2009, Sebastian Bergmann <sb@sebastian-bergmann.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  * @category   Testing
38  * @package    PHPUnit
39  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
40  * @copyright  2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
41  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
42
43  * @link       http://www.phpunit.de/
44  * @since      File available since Release 3.2.0
45  */
46
47 require_once 'PHPUnit/Util/Filter.php';
48 require_once 'PHPUnit/Runner/IncludePathTestCollector.php';
49 require_once 'PHPUnit/Util/XML.php';
50
51 PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
52
53 /**
54  * Wrapper for the PHPUnit XML configuration file.
55  *
56  * Example XML configuration file:
57  * <code>
58  * <?xml version="1.0" encoding="utf-8" ?>
59  *
60  * <phpunit bootstrap="/path/to/bootstrap.php"
61  *          colors="false"
62  *          convertErrorsToExceptions="true"
63  *          convertNoticesToExceptions="true"
64  *          convertWarningsToExceptions="true"
65  *          stopOnFailure="false">
66  *   <testsuite name="My Test Suite">
67  *     <directory suffix="Test.php">/path/to/files</directory>
68  *     <file>/path/to/MyTest.php</file>
69  *   </testsuite>
70  *
71  *   <groups>
72  *     <include>
73  *       <group>name</group>
74  *     </include>
75  *     <exclude>
76  *       <group>name</group>
77  *     </exclude>
78  *   </groups>
79  *
80  *   <filter>
81  *     <blacklist>
82  *       <directory suffix=".php">/path/to/files</directory>
83  *       <file>/path/to/file</file>
84  *       <exclude>
85  *         <directory suffix=".php">/path/to/files</directory>
86  *         <file>/path/to/file</file>
87  *       </exclude>
88  *     </blacklist>
89  *     <whitelist addUncoveredFilesFromWhitelist="true">
90  *       <directory suffix=".php">/path/to/files</directory>
91  *       <file>/path/to/file</file>
92  *       <exclude>
93  *         <directory suffix=".php">/path/to/files</directory>
94  *         <file>/path/to/file</file>
95  *       </exclude>
96  *     </whitelist>
97  *   </filter>
98  *
99  *   <logging>
100  *     <log type="coverage-html" target="/tmp/report" charset="UTF-8"
101  *          yui="true" highlight="false"
102  *          lowUpperBound="35" highLowerBound="70"/>
103  *     <log type="coverage-clover" target="/tmp/clover.xml"/>
104  *     <log type="coverage-source" target="/tmp/coverage"/>
105  *     <log type="graphviz" target="/tmp/logfile.dot"/>
106  *     <log type="json" target="/tmp/logfile.json"/>
107  *     <log type="metrics-xml" target="/tmp/metrics.xml"/>
108  *     <log type="plain" target="/tmp/logfile.txt"/>
109  *     <log type="pmd-xml" target="/tmp/pmd.xml" cpdMinLines="5" cpdMinMatches="70"/>
110  *     <log type="tap" target="/tmp/logfile.tap"/>
111  *     <log type="test-xml" target="/tmp/logfile.xml" logIncompleteSkipped="false"/>
112  *     <log type="story-html" target="/tmp/story.html"/>
113  *     <log type="story-text" target="/tmp/story.txt"/>
114  *     <log type="testdox-html" target="/tmp/testdox.html"/>
115  *     <log type="testdox-text" target="/tmp/testdox.txt"/>
116  *
117  *     <pmd>
118  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Project_CRAP"
119  *             threshold="5,30" priority="1"/>
120  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_DepthOfInheritanceTree"
121  *             threshold="6" priority="1"/>
122  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_EfferentCoupling"
123  *             threshold="20" priority="1"/>
124  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_ExcessiveClassLength"
125  *             threshold="1000" priority="1"/>
126  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_ExcessivePublicCount"
127  *             threshold="45" priority="1"/>
128  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_TooManyFields"
129  *             threshold="15" priority="1"/>
130  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_CodeCoverage"
131  *             threshold="35,70" priority="1"/>
132  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_CRAP"
133  *             threshold="30" priority="1"/>
134  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_CyclomaticComplexity"
135  *             threshold="20" priority="1"/>
136  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_ExcessiveMethodLength"
137  *             threshold="100" priority="1"/>
138  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_ExcessiveParameterList"
139  *             threshold="10" priority="1"/>
140  *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_NPathComplexity"
141  *             threshold="200" priority="1"/>
142  *     </pmd>
143  *   </logging>
144  *
145  *   <php>
146  *     <ini name="foo" value="bar"/>
147  *     <var name="foo" value="bar"/>
148  *   </php>
149  *
150  *   <selenium>
151  *     <browser name="Firefox on Linux"
152  *              browser="*firefox /usr/lib/firefox/firefox-bin"
153  *              host="my.linux.box"
154  *              port="4444"
155  *              timeout="30000"/>
156  *   </selenium>
157  * </phpunit>
158  * </code>
159  *
160  * @category   Testing
161  * @package    PHPUnit
162  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
163  * @copyright  2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
164  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
165  * @version    Release: 3.3.17
166  * @link       http://www.phpunit.de/
167  * @since      Class available since Release 3.2.0
168  */
169 class PHPUnit_Util_Configuration
170 {
171     protected $document;
172     protected $xpath;
173
174     /**
175      * Loads a PHPUnit configuration file.
176      *
177      * @param  string $filename
178      */
179     public function __construct($filename)
180     {
181         $this->document = PHPUnit_Util_XML::loadFile($filename);
182         $this->xpath    = new DOMXPath($this->document);
183     }
184
185     /**
186      * Returns the configuration for SUT filtering.
187      *
188      * @return array
189      * @since  Method available since Release 3.2.1
190      */
191     public function getFilterConfiguration()
192     {
193         $addUncoveredFilesFromWhitelist = TRUE;
194
195         $tmp = $this->xpath->query('filter/whitelist');
196
197         if ($tmp->length == 1 &&
198             $tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) {
199             $addUncoveredFilesFromWhitelist = $this->getBoolean(
200               (string)$tmp->item(0)->getAttribute('addUncoveredFilesFromWhitelist'),
201               TRUE
202             );
203         }
204
205         return array(
206           'blacklist' => array(
207             'include' => array(
208               'directory' => $this->readFilterDirectories(
209                 'filter/blacklist/directory'
210               ),
211               'file' => $this->readFilterFiles(
212                 'filter/blacklist/file'
213               )
214             ),
215             'exclude' => array(
216               'directory' => $this->readFilterDirectories(
217                 'filter/blacklist/exclude/directory'
218                ),
219               'file' => $this->readFilterFiles(
220                 'filter/blacklist/exclude/file'
221               )
222             )
223           ),
224           'whitelist' => array(
225             'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist,
226             'include' => array(
227               'directory' => $this->readFilterDirectories(
228                 'filter/whitelist/directory'
229               ),
230               'file' => $this->readFilterFiles(
231                 'filter/whitelist/file'
232               )
233             ),
234             'exclude' => array(
235               'directory' => $this->readFilterDirectories(
236                 'filter/whitelist/exclude/directory'
237               ),
238               'file' => $this->readFilterFiles(
239                 'filter/whitelist/exclude/file'
240               )
241             )
242           )
243         );
244     }
245
246     /**
247      * Returns the configuration for groups.
248      *
249      * @return array
250      * @since  Method available since Release 3.2.1
251      */
252     public function getGroupConfiguration()
253     {
254         $groups = array(
255           'include' => array(),
256           'exclude' => array()
257         );
258
259         foreach ($this->xpath->query('groups/include/group') as $group) {
260             $groups['include'][] = (string)$group->nodeValue;
261         }
262
263         foreach ($this->xpath->query('groups/exclude/group') as $group) {
264             $groups['exclude'][] = (string)$group->nodeValue;
265         }
266
267         return $groups;
268     }
269
270     /**
271      * Returns the logging configuration.
272      *
273      * @return array
274      */
275     public function getLoggingConfiguration()
276     {
277         $result = array();
278
279         foreach ($this->xpath->query('logging/log') as $log) {
280             $type   = (string)$log->getAttribute('type');
281             $target = (string)$log->getAttribute('target');
282
283             if ($type == 'coverage-html') {
284                 if ($log->hasAttribute('charset')) {
285                     $result['charset'] = (string)$log->getAttribute('charset');
286                 }
287
288                 if ($log->hasAttribute('lowUpperBound')) {
289                     $result['lowUpperBound'] = (string)$log->getAttribute('lowUpperBound');
290                 }
291
292                 if ($log->hasAttribute('highLowerBound')) {
293                     $result['highLowerBound'] = (string)$log->getAttribute('highLowerBound');
294                 }
295
296                 if ($log->hasAttribute('yui')) {
297                     $result['yui'] = $this->getBoolean(
298                       (string)$log->getAttribute('yui'),
299                       FALSE
300                     );
301                 }
302
303                 if ($log->hasAttribute('highlight')) {
304                     $result['highlight'] = $this->getBoolean(
305                       (string)$log->getAttribute('highlight'),
306                       FALSE
307                     );
308                 }
309             }
310
311             else if ($type == 'pmd-xml') {
312                 if ($log->hasAttribute('cpdMinLines')) {
313                     $result['cpdMinLines'] = (string)$log->getAttribute('cpdMinLines');
314                 }
315
316                 if ($log->hasAttribute('cpdMinMatches')) {
317                     $result['cpdMinMatches'] = (string)$log->getAttribute('cpdMinMatches');
318                 }
319             }
320
321             else if ($type == 'test-xml') {
322                 if ($log->hasAttribute('logIncompleteSkipped')) {
323                     $result['logIncompleteSkipped'] = $this->getBoolean(
324                       (string)$log->getAttribute('logIncompleteSkipped'),
325                       FALSE
326                     );
327                 }
328             }
329
330             $result[$type] = $target;
331         }
332
333         return $result;
334     }
335
336     /**
337      * Returns the PHP configuration.
338      *
339      * @return array
340      * @since  Method available since Release 3.2.1
341      */
342     public function getPHPConfiguration()
343     {
344         $result = array(
345           'ini' => array(),
346           'var' => array()
347         );
348
349         foreach ($this->xpath->query('php/ini') as $ini) {
350             $name  = (string)$ini->getAttribute('name');
351             $value = (string)$ini->getAttribute('value');
352
353             $result['ini'][$name] = $value;
354         }
355
356         foreach ($this->xpath->query('php/var') as $var) {
357             $name  = (string)$var->getAttribute('name');
358             $value = (string)$var->getAttribute('value');
359
360             if (strtolower($value) == 'false') {
361                 $value = FALSE;
362             }
363
364             else if (strtolower($value) == 'true') {
365                 $value = TRUE;
366             }
367
368             $result['var'][$name] = $value;
369         }
370
371         return $result;
372     }
373
374     /**
375      * Handles the PHP configuration.
376      *
377      * @since  Method available since Release 3.2.20
378      */
379     public function handlePHPConfiguration()
380     {
381         $configuration = $this->getPHPConfiguration();
382
383         foreach ($configuration['ini'] as $name => $value) {
384             if (defined($value)) {
385                 $value = constant($value);
386             }
387
388             ini_set($name, $value);
389         }
390
391         foreach ($configuration['var'] as $name => $value) {
392             $GLOBALS[$name] = $value;
393         }
394     }
395
396     /**
397      * Returns the PHPUnit configuration.
398      *
399      * @return array
400      * @since  Method available since Release 3.2.14
401      */
402     public function getPHPUnitConfiguration()
403     {
404         $result = array();
405
406         if ($this->document->documentElement->hasAttribute('colors')) {
407             $result['colors'] = $this->getBoolean(
408               (string)$this->document->documentElement->getAttribute('colors'),
409               FALSE
410             );
411         }
412
413         else if ($this->document->documentElement->hasAttribute('ansi')) {
414             $result['colors'] = $this->getBoolean(
415               (string)$this->document->documentElement->getAttribute('ansi'),
416               FALSE
417             );
418         }
419
420         if ($this->document->documentElement->hasAttribute('bootstrap')) {
421             $result['bootstrap'] = (string)$this->document->documentElement->getAttribute('bootstrap');
422         }
423
424         if ($this->document->documentElement->hasAttribute('convertErrorsToExceptions')) {
425             $result['convertErrorsToExceptions'] = $this->getBoolean(
426               (string)$this->document->documentElement->getAttribute('convertErrorsToExceptions'),
427               TRUE
428             );
429         }
430
431         if ($this->document->documentElement->hasAttribute('convertNoticesToExceptions')) {
432             $result['convertNoticesToExceptions'] = $this->getBoolean(
433               (string)$this->document->documentElement->getAttribute('convertNoticesToExceptions'),
434               TRUE
435             );
436         }
437
438         if ($this->document->documentElement->hasAttribute('convertWarningsToExceptions')) {
439             $result['convertWarningsToExceptions'] = $this->getBoolean(
440               (string)$this->document->documentElement->getAttribute('convertWarningsToExceptions'),
441               TRUE
442             );
443         }
444
445         if ($this->document->documentElement->hasAttribute('stopOnFailure')) {
446             $result['stopOnFailure'] = $this->getBoolean(
447               (string)$this->document->documentElement->getAttribute('stopOnFailure'),
448               FALSE
449             );
450         }
451
452         return $result;
453     }
454
455     /**
456      * Returns the configuration for PMD rules.
457      *
458      * @return array
459      */
460     public function getPMDConfiguration()
461     {
462         $result = array();
463
464         foreach ($this->xpath->query('logging/pmd/rule') as $rule) {
465             $class     = (string)$rule->getAttribute('class');
466
467             $threshold = (string)$rule->getAttribute('threshold');
468             $threshold = explode(',', $threshold);
469
470             if (count($threshold) == 1) {
471                 $threshold = $threshold[0];
472             }
473
474             $priority = (int)$rule->getAttribute('priority');
475
476             $result[$class] = array(
477               'threshold' => $threshold,
478               'priority'  => $priority
479             );
480         }
481
482         return $result;
483     }
484
485     /**
486      * Returns the SeleniumTestCase browser configuration.
487      *
488      * @return array
489      * @since  Method available since Release 3.2.9
490      */
491     public function getSeleniumBrowserConfiguration()
492     {
493         $result = array();
494
495         foreach ($this->xpath->query('selenium/browser') as $config) {
496             $name    = (string)$config->getAttribute('name');
497             $browser = (string)$config->getAttribute('browser');
498
499             if ($config->hasAttribute('host')) {
500                 $host = (string)$config->getAttribute('host');
501             } else {
502                 $host = 'localhost';
503             }
504
505             if ($config->hasAttribute('port')) {
506                 $port = (int)$config->getAttribute('port');
507             } else {
508                 $port = 4444;
509             }
510
511             if ($config->hasAttribute('timeout')) {
512                 $timeout = (int)$config->getAttribute('timeout');
513             } else {
514                 $timeout = 30000;
515             }
516
517             $result[] = array(
518               'name'    => $name,
519               'browser' => $browser,
520               'host'    => $host,
521               'port'    => $port,
522               'timeout' => $timeout
523             );
524         }
525
526         return $result;
527     }
528
529     /**
530      * Returns the test suite configuration.
531      *
532      * @param  boolean $syntaxCheck
533      * @return PHPUnit_Framework_TestSuite
534      * @since  Method available since Release 3.2.1
535      */
536     public function getTestSuiteConfiguration($syntaxCheck = TRUE)
537     {
538         $testSuiteNode = $this->xpath->query('testsuite');
539
540         if ($testSuiteNode->length > 0) {
541             $testSuiteNode = $testSuiteNode->item(0);
542
543             if ($testSuiteNode->hasAttribute('name')) {
544                 $suite = new PHPUnit_Framework_TestSuite(
545                   (string)$testSuiteNode->getAttribute('name')
546                 );
547             } else {
548                 $suite = new PHPUnit_Framework_TestSuite;
549             }
550
551             foreach ($this->xpath->query('testsuite/directory') as $directoryNode) {
552                 if ($directoryNode->hasAttribute('suffix')) {
553                     $suffix = (string)$directoryNode->getAttribute('suffix');
554                 } else {
555                     $suffix = 'Test.php';
556                 }
557
558                 $testCollector = new PHPUnit_Runner_IncludePathTestCollector(
559                   array((string)$directoryNode->nodeValue),
560                   $suffix
561                 );
562
563                 $suite->addTestFiles(
564                   $testCollector->collectTests(), $syntaxCheck
565                 );
566             }
567
568             foreach ($this->xpath->query('testsuite/file') as $fileNode) {
569                 $suite->addTestFile((string)$fileNode->nodeValue, $syntaxCheck);
570             }
571
572             return $suite;
573         }
574     }
575
576     /**
577      * @param  string  $value
578      * @param  boolean $default
579      * @return boolean
580      * @since  Method available since Release 3.2.3
581      */
582     protected function getBoolean($value, $default)
583     {
584         if (strtolower($value) == 'false') {
585             return FALSE;
586         }
587
588         else if (strtolower($value) == 'true') {
589             return TRUE;
590         }
591
592         return $default;
593     }
594
595     /**
596      * @param  string $query
597      * @return array
598      * @since  Method available since Release 3.2.3
599      */
600     protected function readFilterDirectories($query)
601     {
602         $directories = array();
603
604         foreach ($this->xpath->query($query) as $directory) {
605             if ($directory->hasAttribute('suffix')) {
606                 $suffix = (string)$directory->getAttribute('suffix');
607             } else {
608                 $suffix = '.php';
609             }
610
611             $directories[] = array(
612               'path'   => (string)$directory->nodeValue,
613               'suffix' => $suffix
614             );
615         }
616
617         return $directories;
618     }
619
620     /**
621      * @param  string $query
622      * @return array
623      * @since  Method available since Release 3.2.3
624      */
625     protected function readFilterFiles($query)
626     {
627         $files = array();
628
629         foreach ($this->xpath->query($query) as $file) {
630             $files[] = (string)$file->nodeValue;
631         }
632
633         return $files;
634     }
635 }
636 ?>