]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/PHPUnit/TextUI/ResultPrinter.php
Added unit tests.
[Github/sugarcrm.git] / tests / PHPUnit / TextUI / ResultPrinter.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.0.0
45  */
46
47 require_once 'PHPUnit/Framework.php';
48 require_once 'PHPUnit/Util/Filter.php';
49 require_once 'PHPUnit/Util/Printer.php';
50 require_once 'PHPUnit/Util/Test.php';
51
52 PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
53
54 /**
55  * Prints the result of a TextUI TestRunner run.
56  *
57  * @category   Testing
58  * @package    PHPUnit
59  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
60  * @copyright  2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
61  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
62  * @version    Release: 3.3.17
63  * @link       http://www.phpunit.de/
64  * @since      Class available since Release 2.0.0
65  */
66 class PHPUnit_TextUI_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
67 {
68     const EVENT_TEST_START      = 0;
69     const EVENT_TEST_END        = 1;
70     const EVENT_TESTSUITE_START = 2;
71     const EVENT_TESTSUITE_END   = 3;
72
73     /**
74      * @var    integer
75      */
76     protected $column = 0;
77
78     /**
79      * @var    array
80      */
81     protected $numberOfTests = array();
82
83     /**
84      * @var    array
85      */
86     protected $testSuiteSize = array();
87
88     /**
89      * @var    integer
90      */
91     protected $lastEvent = -1;
92
93     /**
94      * @var    boolean
95      */
96     protected $lastTestFailed = FALSE;
97
98     /**
99      * @var    boolean
100      */
101     protected $colors = FALSE;
102
103     /**
104      * @var    boolean
105      */
106     protected $debug = FALSE;
107
108     /**
109      * @var    boolean
110      */
111     protected $verbose = FALSE;
112
113     /**
114      * @var    integer
115      */
116     protected $numAssertions = 0;
117
118     /**
119      * Constructor.
120      *
121      * @param  mixed   $out
122      * @param  boolean $verbose
123      * @param  boolean $colors
124      * @param  boolean $debug
125      * @throws InvalidArgumentException
126      * @since  Method available since Release 3.0.0
127      */
128     public function __construct($out = NULL, $verbose = FALSE, $colors = FALSE, $debug = FALSE)
129     {
130         parent::__construct($out);
131
132         if (is_bool($colors)) {
133             $this->colors = $colors;
134         } else {
135             throw new InvalidArgumentException;
136         }
137
138         if (is_bool($debug)) {
139             $this->debug = $debug;
140         } else {
141             throw new InvalidArgumentException;
142         }
143
144         if (is_bool($verbose)) {
145             $this->verbose = $verbose;
146         } else {
147             throw new InvalidArgumentException;
148         }
149     }
150
151     /**
152      * @param  PHPUnit_Framework_TestResult $result
153      */
154     public function printResult(PHPUnit_Framework_TestResult $result)
155     {
156         $this->printHeader($result->time());
157
158         if ($result->errorCount() > 0) {
159             $this->printErrors($result);
160         }
161
162         if ($result->failureCount() > 0) {
163             if ($result->errorCount() > 0) {
164                 print "\n--\n\n";
165             }
166
167             $this->printFailures($result);
168         }
169
170         if ($this->verbose) {
171             if ($result->notImplementedCount() > 0) {
172                 if ($result->failureCount() > 0) {
173                     print "\n--\n\n";
174                 }
175
176                 $this->printIncompletes($result);
177             }
178
179             if ($result->skippedCount() > 0) {
180                 if ($result->notImplementedCount() > 0) {
181                     print "\n--\n\n";
182                 }
183
184                 $this->printSkipped($result);
185             }
186         }
187
188         $this->printFooter($result);
189     }
190
191     /**
192      * @param  array   $defects
193      * @param  integer $count
194      * @param  string  $type
195      */
196     protected function printDefects(array $defects, $count, $type)
197     {
198         static $called = FALSE;
199
200         if ($count == 0) {
201             return;
202         }
203
204         $this->write(
205           sprintf(
206             "%sThere %s %d %s%s:\n",
207
208             $called ? "\n" : '',
209             ($count == 1) ? 'was' : 'were',
210             $count,
211             $type,
212             ($count == 1) ? '' : 's'
213           )
214         );
215
216         $i = 1;
217
218         foreach ($defects as $defect) {
219             $this->printDefect($defect, $i++);
220         }
221
222         $called = TRUE;
223     }
224
225     /**
226      * @param  PHPUnit_Framework_TestFailure $defect
227      * @param  integer                       $count
228      */
229     protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count)
230     {
231         $this->printDefectHeader($defect, $count);
232         $this->printDefectTrace($defect);
233     }
234
235     /**
236      * @param  PHPUnit_Framework_TestFailure $defect
237      * @param  integer                       $count
238      */
239     protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count)
240     {
241         $failedTest = $defect->failedTest();
242
243         if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) {
244             $testName = $failedTest->toString();
245         } else {
246             $testName = get_class($failedTest);
247         }
248
249         $this->write(
250           sprintf(
251             "\n%d) %s\n",
252
253             $count,
254             $testName
255           )
256         );
257     }
258
259     /**
260      * @param  PHPUnit_Framework_TestFailure $defect
261      */
262     protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect)
263     {
264         $this->write(
265           $defect->toStringVerbose($this->verbose) .
266           PHPUnit_Util_Filter::getFilteredStacktrace(
267             $defect->thrownException(),
268             FALSE
269           )
270         );
271     }
272
273     /**
274      * @param  PHPUnit_Framework_TestResult  $result
275      */
276     protected function printErrors(PHPUnit_Framework_TestResult $result)
277     {
278         $this->printDefects($result->errors(), $result->errorCount(), 'error');
279     }
280
281     /**
282      * @param  PHPUnit_Framework_TestResult  $result
283      */
284     protected function printFailures(PHPUnit_Framework_TestResult $result)
285     {
286         $this->printDefects($result->failures(), $result->failureCount(), 'failure');
287     }
288
289     /**
290      * @param  PHPUnit_Framework_TestResult  $result
291      */
292     protected function printIncompletes(PHPUnit_Framework_TestResult $result)
293     {
294         $this->printDefects($result->notImplemented(), $result->notImplementedCount(), 'incomplete test');
295     }
296
297     /**
298      * @param  PHPUnit_Framework_TestResult  $result
299      * @since  Method available since Release 3.0.0
300      */
301     protected function printSkipped(PHPUnit_Framework_TestResult $result)
302     {
303         $this->printDefects($result->skipped(), $result->skippedCount(), 'skipped test');
304     }
305
306     /**
307      * @param  float   $timeElapsed
308      */
309     protected function printHeader($timeElapsed)
310     {
311         $this->write(
312           sprintf(
313             "%sTime: %s\n\n",
314             $this->verbose ? "\n" : "\n\n",
315             PHPUnit_Util_Timer::secondsToTimeString($timeElapsed)
316           )
317         );
318     }
319
320     /**
321      * @param  PHPUnit_Framework_TestResult  $result
322      */
323     protected function printFooter(PHPUnit_Framework_TestResult $result)
324     {
325         if ($result->wasSuccessful() &&
326             $result->allCompletlyImplemented() &&
327             $result->noneSkipped()) {
328             if ($this->colors) {
329                 $this->write("\x1b[30;42m\x1b[2K");
330             }
331
332             $this->write(
333               sprintf(
334                 "OK (%d test%s, %d assertion%s)\n",
335
336                 count($result),
337                 (count($result) == 1) ? '' : 's',
338                 $this->numAssertions,
339                 ($this->numAssertions == 1) ? '' : 's'
340               )
341             );
342
343             if ($this->colors) {
344                 $this->write("\x1b[0m\x1b[2K");
345             }
346         }
347
348         else if ((!$result->allCompletlyImplemented() ||
349                   !$result->noneSkipped())&&
350                  $result->wasSuccessful()) {
351             if ($this->colors) {
352                 $this->write("\x1b[30;43m\x1b[2KOK, but incomplete or skipped tests!\n\x1b[0m\x1b[30;43m\x1b[2K");
353             } else {
354                 $this->write("OK, but incomplete or skipped tests!\n");
355             }
356
357             $this->write(
358               sprintf(
359                 "Tests: %d, Assertions: %d%s%s.\n",
360
361                 count($result),
362                 $this->numAssertions,
363                 $this->getCountString($result->notImplementedCount(), 'Incomplete'),
364                 $this->getCountString($result->skippedCount(), 'Skipped')
365               )
366             );
367
368             if ($this->colors) {
369                 $this->write("\x1b[0m\x1b[2K");
370             }
371         }
372
373         else {
374             $this->write("\n");
375
376             if ($this->colors) {
377                 $this->write("\x1b[37;41m\x1b[2KFAILURES!\n\x1b[0m\x1b[37;41m\x1b[2K");
378             } else {
379                 $this->write("FAILURES!\n");
380             }
381
382             $this->write(
383               sprintf(
384                 "Tests: %d, Assertions: %s%s%s%s%s.\n",
385
386                 count($result),
387                 $this->numAssertions,
388                 $this->getCountString($result->failureCount(), 'Failures'),
389                 $this->getCountString($result->errorCount(), 'Errors'),
390                 $this->getCountString($result->notImplementedCount(), 'Incomplete'),
391                 $this->getCountString($result->skippedCount(), 'Skipped')
392               )
393             );
394
395             if ($this->colors) {
396                 $this->write("\x1b[0m\x1b[2K");
397             }
398         }
399     }
400
401     /**
402      * @param  integer $count
403      * @param  string  $name
404      * @return string
405      * @since  Method available since Release 3.0.0
406      */
407     protected function getCountString($count, $name)
408     {
409         $string = '';
410
411         if ($count > 0) {
412             $string = sprintf(
413               ', %s: %d',
414
415               $name,
416               $count
417             );
418         }
419
420         return $string;
421     }
422
423     /**
424      */
425     public function printWaitPrompt()
426     {
427         $this->write("\n<RETURN> to continue\n");
428     }
429
430     /**
431      * An error occurred.
432      *
433      * @param  PHPUnit_Framework_Test $test
434      * @param  Exception              $e
435      * @param  float                  $time
436      */
437     public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
438     {
439         $this->writeProgress('E');
440         $this->lastTestFailed = TRUE;
441     }
442
443     /**
444      * A failure occurred.
445      *
446      * @param  PHPUnit_Framework_Test                 $test
447      * @param  PHPUnit_Framework_AssertionFailedError $e
448      * @param  float                                  $time
449      */
450     public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
451     {
452         $this->writeProgress('F');
453         $this->lastTestFailed = TRUE;
454     }
455
456     /**
457      * Incomplete test.
458      *
459      * @param  PHPUnit_Framework_Test $test
460      * @param  Exception              $e
461      * @param  float                  $time
462      */
463     public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
464     {
465         $this->writeProgress('I');
466         $this->lastTestFailed = TRUE;
467     }
468
469     /**
470      * Skipped test.
471      *
472      * @param  PHPUnit_Framework_Test $test
473      * @param  Exception              $e
474      * @param  float                  $time
475      * @since  Method available since Release 3.0.0
476      */
477     public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
478     {
479         $this->writeProgress('S');
480         $this->lastTestFailed = TRUE;
481     }
482
483     /**
484      * A testsuite started.
485      *
486      * @param  PHPUnit_Framework_TestSuite $suite
487      * @since  Method available since Release 2.2.0
488      */
489     public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
490     {
491         if ($this->verbose) {
492             $name = $suite->getName();
493
494             if (empty($name)) {
495                 $name = 'Test Suite';
496             }
497
498             $this->write(
499               sprintf(
500                 "%s%s%s\n",
501
502                 $this->lastEvent == self::EVENT_TESTSUITE_END ? "\n" : '',
503                 str_repeat(' ', count($this->testSuiteSize)),
504                 $name
505               )
506             );
507         }
508
509         if ($this->verbose || empty($this->numberOfTests)) {
510             array_push($this->numberOfTests, 0);
511             array_push($this->testSuiteSize, count($suite));
512         }
513
514         $this->lastEvent = self::EVENT_TESTSUITE_START;
515     }
516
517     /**
518      * A testsuite ended.
519      *
520      * @param  PHPUnit_Framework_TestSuite $suite
521      * @since  Method available since Release 2.2.0
522      */
523     public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
524     {
525         if ($this->verbose) {
526             array_pop($this->numberOfTests);
527             array_pop($this->testSuiteSize);
528
529             $this->column = 0;
530
531             if ($this->lastEvent != self::EVENT_TESTSUITE_END) {
532                 $this->write("\n");
533             }
534         }
535
536         $this->lastEvent = self::EVENT_TESTSUITE_END;
537     }
538
539     /**
540      * A test started.
541      *
542      * @param  PHPUnit_Framework_Test $test
543      */
544     public function startTest(PHPUnit_Framework_Test $test)
545     {
546         if ($this->verbose) {
547             $this->numberOfTests[count($this->numberOfTests)-1]++;
548         }
549
550         else if (isset($this->numberOfTests[0])) {
551             $this->numberOfTests[0]++;
552         }
553
554         else {
555             $this->numberOfTests = array(1);
556         }
557
558         $this->lastEvent = self::EVENT_TEST_START;
559
560         if ($this->debug) {
561             $this->write(
562               sprintf(
563                 "\nStarting test '%s'.\n", PHPUnit_Util_Test::describe($test)
564               )
565             );
566         }
567     }
568
569     /**
570      * A test ended.
571      *
572      * @param  PHPUnit_Framework_Test $test
573      * @param  float                  $time
574      */
575     public function endTest(PHPUnit_Framework_Test $test, $time)
576     {
577         if (!$this->lastTestFailed) {
578             $this->writeProgress('.');
579         }
580
581         if ($test instanceof PHPUnit_Framework_TestCase) {
582             $this->numAssertions += $test->getNumAssertions();
583         }
584
585         $this->lastEvent      = self::EVENT_TEST_END;
586         $this->lastTestFailed = FALSE;
587     }
588
589     /**
590      * @param  string $progress
591      */
592     protected function writeProgress($progress)
593     {
594         $indent = max(0, count($this->testSuiteSize) - 1);
595
596         if ($this->column == 0) {
597             $this->write(str_repeat(' ', $indent));
598         }
599
600         $this->write($progress);
601
602         if ($this->column++ == 60 - 1 - $indent) {
603             if ($this->verbose) {
604                 $numberOfTests = $this->numberOfTests[count($this->numberOfTests)-1];
605                 $testSuiteSize = $this->testSuiteSize[count($this->testSuiteSize)-1];
606             } else {
607                 $numberOfTests = $this->numberOfTests[0];
608                 $testSuiteSize = $this->testSuiteSize[0];
609             }
610
611             $width = strlen((string)$testSuiteSize);
612
613             $this->write(
614               sprintf(
615                 ' %' . $width . 'd / %' . $width . "d\n",
616
617                 $numberOfTests,
618                 $testSuiteSize
619               )
620             );
621
622             $this->column = 0;
623         }
624     }
625 }
626 ?>