]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/PHPUnit/Util/Log/XML.php
Added unit tests.
[Github/sugarcrm.git] / tests / PHPUnit / Util / Log / XML.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 2.3.0
45  */
46
47 require_once 'PHPUnit/Framework.php';
48 require_once 'PHPUnit/Util/Class.php';
49 require_once 'PHPUnit/Util/Filter.php';
50 require_once 'PHPUnit/Util/Printer.php';
51 require_once 'PHPUnit/Util/XML.php';
52
53 PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
54
55 /**
56  * A TestListener that generates a logfile of the test execution in XML markup.
57  *
58  * The XML markup used is the same as the one that is used by the JUnit Ant task.
59  *
60  * @category   Testing
61  * @package    PHPUnit
62  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
63  * @copyright  2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
64  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
65  * @version    Release: 3.3.17
66  * @link       http://www.phpunit.de/
67  * @since      Class available since Release 2.1.0
68  */
69 class PHPUnit_Util_Log_XML extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
70 {
71     /**
72      * @var    DOMDocument
73      */
74     protected $document;
75
76     /**
77      * @var    DOMElement
78      */
79     protected $root;
80
81     /**
82      * @var    boolean
83      */
84     protected $logIncompleteSkipped = FALSE;
85
86     /**
87      * @var    boolean
88      */
89     protected $writeDocument = TRUE;
90
91     /**
92      * @var    DOMElement[]
93      */
94     protected $testSuites = array();
95
96     /**
97      * @var    integer[]
98      */
99     protected $testSuiteTests = array(0);
100
101     /**
102      * @var    integer[]
103      */
104     protected $testSuiteAssertions = array(0);
105
106     /**
107      * @var    integer[]
108      */
109     protected $testSuiteErrors = array(0);
110
111     /**
112      * @var    integer[]
113      */
114     protected $testSuiteFailures = array(0);
115
116     /**
117      * @var    integer[]
118      */
119     protected $testSuiteTimes = array(0);
120
121     /**
122      * @var    integer
123      */
124     protected $testSuiteLevel = 0;
125
126     /**
127      * @var    DOMElement
128      */
129     protected $currentTestCase = NULL;
130
131     /**
132      * @var    boolean
133      */
134     protected $attachCurrentTestCase = TRUE;
135
136     /**
137      * Constructor.
138      *
139      * @param  mixed   $out
140      * @param  boolean $logIncompleteSkipped
141      */
142     public function __construct($out = NULL, $logIncompleteSkipped = FALSE)
143     {
144         $this->document = new DOMDocument('1.0', 'UTF-8');
145         $this->document->formatOutput = TRUE;
146
147         $this->root = $this->document->createElement('testsuites');
148         $this->document->appendChild($this->root);
149
150         parent::__construct($out);
151
152         $this->logIncompleteSkipped = $logIncompleteSkipped;
153     }
154
155     /**
156      * Flush buffer and close output.
157      *
158      */
159     public function flush()
160     {
161         if ($this->writeDocument === TRUE) {
162             $this->write($this->getXML());
163         }
164
165         parent::flush();
166     }
167
168     /**
169      * An error occurred.
170      *
171      * @param  PHPUnit_Framework_Test $test
172      * @param  Exception              $e
173      * @param  float                  $time
174      */
175     public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
176     {
177         if ($test instanceof PHPUnit_Framework_SelfDescribing) {
178             $buffer = $test->toString() . "\n";
179         } else {
180             $buffer = '';
181         }
182
183         $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) . "\n" .
184                    PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE);
185
186         $error = $this->document->createElement(
187           'error',
188           htmlspecialchars(
189             PHPUnit_Util_XML::convertToUtf8($buffer),
190             ENT_COMPAT,
191             'UTF-8'
192           )
193         );
194
195         $error->setAttribute('type', get_class($e));
196
197         $this->currentTestCase->appendChild($error);
198
199         $this->testSuiteErrors[$this->testSuiteLevel]++;
200     }
201
202     /**
203      * A failure occurred.
204      *
205      * @param  PHPUnit_Framework_Test                 $test
206      * @param  PHPUnit_Framework_AssertionFailedError $e
207      * @param  float                                  $time
208      */
209     public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
210     {
211         if (!$test instanceof PHPUnit_Framework_Warning) {
212             if ($test instanceof PHPUnit_Framework_SelfDescribing) {
213                 $buffer = $test->toString() . "\n";
214             } else {
215                 $buffer = '';
216             }
217
218             $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) . "\n" .
219                        PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE);
220
221             $failure = $this->document->createElement(
222               'failure',
223               htmlspecialchars(
224                 PHPUnit_Util_XML::convertToUtf8($buffer),
225                 ENT_COMPAT,
226                 'UTF-8'
227               )
228             );
229
230             $failure->setAttribute('type', get_class($e));
231
232             $this->currentTestCase->appendChild($failure);
233
234             $this->testSuiteFailures[$this->testSuiteLevel]++;
235         }
236     }
237
238     /**
239      * Incomplete test.
240      *
241      * @param  PHPUnit_Framework_Test $test
242      * @param  Exception              $e
243      * @param  float                  $time
244      */
245     public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
246     {
247         if ($this->logIncompleteSkipped) {
248             $error = $this->document->createElement(
249               'error',
250               htmlspecialchars(
251                 PHPUnit_Util_XML::convertToUtf8(
252                   "Incomplete Test\n" .
253                   PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE)
254                 ),
255                 ENT_COMPAT,
256                 'UTF-8'
257               )
258             );
259
260             $error->setAttribute('type', get_class($e));
261
262             $this->currentTestCase->appendChild($error);
263
264             $this->testSuiteErrors[$this->testSuiteLevel]++;
265         } else {
266             $this->attachCurrentTestCase = FALSE;
267         }
268     }
269
270     /**
271      * Skipped test.
272      *
273      * @param  PHPUnit_Framework_Test $test
274      * @param  Exception              $e
275      * @param  float                  $time
276      * @since  Method available since Release 3.0.0
277      */
278     public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
279     {
280         if ($this->logIncompleteSkipped) {
281             $error = $this->document->createElement(
282               'error',
283               htmlspecialchars(
284                 PHPUnit_Util_XML::convertToUtf8(
285                   "Skipped Test\n" .
286                   PHPUnit_Util_Filter::getFilteredStacktrace($e, FALSE)
287                 ),
288                 ENT_COMPAT,
289                 'UTF-8'
290               )
291             );
292
293             $error->setAttribute('type', get_class($e));
294
295             $this->currentTestCase->appendChild($error);
296
297             $this->testSuiteErrors[$this->testSuiteLevel]++;
298         } else {
299             $this->attachCurrentTestCase = FALSE;
300         }
301     }
302
303     /**
304      * A testsuite started.
305      *
306      * @param  PHPUnit_Framework_TestSuite $suite
307      * @since  Method available since Release 2.2.0
308      */
309     public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
310     {
311         $testSuite = $this->document->createElement('testsuite');
312         $testSuite->setAttribute('name', $suite->getName());
313
314         if (class_exists($suite->getName(), FALSE)) {
315             try {
316                 $class = new ReflectionClass($suite->getName());
317
318                 $testSuite->setAttribute('file', $class->getFileName());
319
320                 $packageInformation = PHPUnit_Util_Class::getPackageInformation(
321                   $suite->getName()
322                 );
323
324                 if (!empty($packageInformation['namespace'])) {
325                     $testSuite->setAttribute('namespace', $packageInformation['namespace']);
326                 }
327
328                 if (!empty($packageInformation['fullPackage'])) {
329                     $testSuite->setAttribute('fullPackage', $packageInformation['fullPackage']);
330                 }
331
332                 if (!empty($packageInformation['category'])) {
333                     $testSuite->setAttribute('category', $packageInformation['category']);
334                 }
335
336                 if (!empty($packageInformation['package'])) {
337                     $testSuite->setAttribute('package', $packageInformation['package']);
338                 }
339
340                 if (!empty($packageInformation['subpackage'])) {
341                     $testSuite->setAttribute('subpackage', $packageInformation['subpackage']);
342                 }
343             }
344
345             catch (ReflectionException $e) {
346             }
347         }
348
349         if ($this->testSuiteLevel > 0) {
350             $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite);
351         } else {
352             $this->root->appendChild($testSuite);
353         }
354
355         $this->testSuiteLevel++;
356         $this->testSuites[$this->testSuiteLevel]          = $testSuite;
357         $this->testSuiteTests[$this->testSuiteLevel]      = 0;
358         $this->testSuiteAssertions[$this->testSuiteLevel] = 0;
359         $this->testSuiteErrors[$this->testSuiteLevel]     = 0;
360         $this->testSuiteFailures[$this->testSuiteLevel]   = 0;
361         $this->testSuiteTimes[$this->testSuiteLevel]      = 0;
362     }
363
364     /**
365      * A testsuite ended.
366      *
367      * @param  PHPUnit_Framework_TestSuite $suite
368      * @since  Method available since Release 2.2.0
369      */
370     public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
371     {
372         $this->testSuites[$this->testSuiteLevel]->setAttribute('tests', $this->testSuiteTests[$this->testSuiteLevel]);
373         $this->testSuites[$this->testSuiteLevel]->setAttribute('assertions', $this->testSuiteAssertions[$this->testSuiteLevel]);
374         $this->testSuites[$this->testSuiteLevel]->setAttribute('failures', $this->testSuiteFailures[$this->testSuiteLevel]);
375         $this->testSuites[$this->testSuiteLevel]->setAttribute('errors', $this->testSuiteErrors[$this->testSuiteLevel]);
376         $this->testSuites[$this->testSuiteLevel]->setAttribute('time', sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel]));
377
378         if ($this->testSuiteLevel > 1) {
379             $this->testSuiteTests[$this->testSuiteLevel - 1]      += $this->testSuiteTests[$this->testSuiteLevel];
380             $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel];
381             $this->testSuiteErrors[$this->testSuiteLevel - 1]     += $this->testSuiteErrors[$this->testSuiteLevel];
382             $this->testSuiteFailures[$this->testSuiteLevel - 1]   += $this->testSuiteFailures[$this->testSuiteLevel];
383             $this->testSuiteTimes[$this->testSuiteLevel - 1]      += $this->testSuiteTimes[$this->testSuiteLevel];
384         }
385
386         $this->testSuiteLevel--;
387     }
388
389     /**
390      * A test started.
391      *
392      * @param  PHPUnit_Framework_Test $test
393      */
394     public function startTest(PHPUnit_Framework_Test $test)
395     {
396         if (!$test instanceof PHPUnit_Framework_Warning) {
397             $testCase = $this->document->createElement('testcase');
398             $testCase->setAttribute('name', $test->getName());
399
400             if ($test instanceof PHPUnit_Framework_TestCase) {
401                 $class      = new ReflectionClass($test);
402                 $methodName = $test->getName();
403
404                 if ($class->hasMethod($methodName)) {
405                     $method = $class->getMethod($test->getName());
406
407                     $testCase->setAttribute('class', $class->getName());
408                     $testCase->setAttribute('file', $class->getFileName());
409                     $testCase->setAttribute('line', $method->getStartLine());
410                 }
411             }
412
413             $this->currentTestCase = $testCase;
414         }
415     }
416
417     /**
418      * A test ended.
419      *
420      * @param  PHPUnit_Framework_Test $test
421      * @param  float                  $time
422      */
423     public function endTest(PHPUnit_Framework_Test $test, $time)
424     {
425         if (!$test instanceof PHPUnit_Framework_Warning) {
426             if ($this->attachCurrentTestCase) {
427                 if ($test instanceof PHPUnit_Framework_TestCase) {
428                     $numAssertions = $test->getNumAssertions();
429                     $this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions;
430
431                     $this->currentTestCase->setAttribute('assertions', $numAssertions);
432                 }
433
434                 $this->currentTestCase->setAttribute('time', sprintf('%F', $time));
435
436                 $this->testSuites[$this->testSuiteLevel]->appendChild(
437                   $this->currentTestCase
438                 );
439
440                 $this->testSuiteTests[$this->testSuiteLevel]++;
441                 $this->testSuiteTimes[$this->testSuiteLevel] += $time;
442             }
443         }
444
445         $this->attachCurrentTestCase = TRUE;
446         $this->currentTestCase       = NULL;
447     }
448
449     /**
450      * Returns the XML as a string.
451      *
452      * @return string
453      * @since  Method available since Release 2.2.0
454      */
455     public function getXML()
456     {
457         return $this->document->saveXML();
458     }
459
460     /**
461      * Enables or disables the writing of the document
462      * in flush().
463      *
464      * This is a "hack" needed for the integration of
465      * PHPUnit with Phing.
466      *
467      * @return string
468      * @since  Method available since Release 2.2.0
469      */
470     public function setWriteDocument($flag)
471     {
472         if (is_bool($flag)) {
473             $this->writeDocument = $flag;
474         }
475     }
476 }
477 ?>