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