5 * Copyright (c) 2002-2011, Sebastian Bergmann <sebastian@phpunit.de>.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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
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.
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.
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.0.0
46 require_once 'PHP/Timer.php';
49 * Prints the result of a TextUI TestRunner run.
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.14
57 * @link http://www.phpunit.de/
58 * @since Class available since Release 2.0.0
60 class PHPUnit_TextUI_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
62 const EVENT_TEST_START = 0;
63 const EVENT_TEST_END = 1;
64 const EVENT_TESTSUITE_START = 2;
65 const EVENT_TESTSUITE_END = 3;
70 protected $column = 0;
80 protected $lastTestFailed = FALSE;
85 protected $numAssertions = 0;
90 protected $numTests = -1;
95 protected $numTestsRun = 0;
100 protected $numTestsWidth;
105 protected $colors = FALSE;
110 protected $debug = FALSE;
115 protected $verbose = FALSE;
121 * @param boolean $verbose
122 * @param boolean $colors
123 * @param boolean $debug
124 * @throws InvalidArgumentException
125 * @since Method available since Release 3.0.0
127 public function __construct($out = NULL, $verbose = FALSE, $colors = FALSE, $debug = FALSE)
129 parent::__construct($out);
131 if (is_bool($verbose)) {
132 $this->verbose = $verbose;
134 throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
137 if (is_bool($colors)) {
138 $this->colors = $colors;
140 throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean');
143 if (is_bool($debug)) {
144 $this->debug = $debug;
146 throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean');
151 * @param PHPUnit_Framework_TestResult $result
153 public function printResult(PHPUnit_Framework_TestResult $result)
155 $this->printHeader();
157 if ($result->errorCount() > 0) {
158 $this->printErrors($result);
161 if ($result->failureCount() > 0) {
162 if ($result->errorCount() > 0) {
166 $this->printFailures($result);
169 if ($this->verbose) {
170 if ($result->deprecatedFeaturesCount() > 0) {
171 if ($result->failureCount() > 0) {
172 print "\n--\n\nDeprecated PHPUnit features are being used";
175 foreach ($result->deprecatedFeatures() as $deprecatedFeature) {
176 $this->write($deprecatedFeature . "\n\n");
180 if ($result->notImplementedCount() > 0) {
181 if ($result->failureCount() > 0) {
185 $this->printIncompletes($result);
188 if ($result->skippedCount() > 0) {
189 if ($result->notImplementedCount() > 0) {
193 $this->printSkipped($result);
197 $this->printFooter($result);
201 * @param array $defects
202 * @param integer $count
203 * @param string $type
205 protected function printDefects(array $defects, $count, $type)
207 static $called = FALSE;
215 "%sThere %s %d %s%s:\n",
218 ($count == 1) ? 'was' : 'were',
221 ($count == 1) ? '' : 's'
227 foreach ($defects as $defect) {
228 $this->printDefect($defect, $i++);
235 * @param PHPUnit_Framework_TestFailure $defect
236 * @param integer $count
238 protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count)
240 $this->printDefectHeader($defect, $count);
241 $this->printDefectTrace($defect);
245 * @param PHPUnit_Framework_TestFailure $defect
246 * @param integer $count
248 protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count)
250 $failedTest = $defect->failedTest();
252 if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) {
253 $testName = $failedTest->toString();
255 $testName = get_class($failedTest);
269 * @param PHPUnit_Framework_TestFailure $defect
271 protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect)
274 $defect->getExceptionAsString() . "\n" .
275 PHPUnit_Util_Filter::getFilteredStacktrace(
276 $defect->thrownException(),
283 * @param PHPUnit_Framework_TestResult $result
285 protected function printErrors(PHPUnit_Framework_TestResult $result)
287 $this->printDefects($result->errors(), $result->errorCount(), 'error');
291 * @param PHPUnit_Framework_TestResult $result
293 protected function printFailures(PHPUnit_Framework_TestResult $result)
297 $result->failureCount(),
303 * @param PHPUnit_Framework_TestResult $result
305 protected function printIncompletes(PHPUnit_Framework_TestResult $result)
308 $result->notImplemented(),
309 $result->notImplementedCount(),
315 * @param PHPUnit_Framework_TestResult $result
316 * @since Method available since Release 3.0.0
318 protected function printSkipped(PHPUnit_Framework_TestResult $result)
322 $result->skippedCount(),
327 protected function printHeader()
329 $this->write("\n\n" . PHP_Timer::resourceUsage() . "\n\n");
333 * @param PHPUnit_Framework_TestResult $result
335 protected function printFooter(PHPUnit_Framework_TestResult $result)
337 if ($result->wasSuccessful() &&
338 $result->allCompletlyImplemented() &&
339 $result->noneSkipped()) {
341 $this->write("\x1b[30;42m\x1b[2K");
346 "OK (%d test%s, %d assertion%s)\n",
349 (count($result) == 1) ? '' : 's',
350 $this->numAssertions,
351 ($this->numAssertions == 1) ? '' : 's'
356 $this->write("\x1b[0m\x1b[2K");
360 else if ((!$result->allCompletlyImplemented() ||
361 !$result->noneSkipped()) &&
362 $result->wasSuccessful()) {
365 "\x1b[30;43m\x1b[2KOK, but incomplete or skipped tests!\n" .
366 "\x1b[0m\x1b[30;43m\x1b[2K"
369 $this->write("OK, but incomplete or skipped tests!\n");
374 "Tests: %d, Assertions: %d%s%s.\n",
377 $this->numAssertions,
378 $this->getCountString(
379 $result->notImplementedCount(), 'Incomplete'
381 $this->getCountString(
382 $result->skippedCount(), 'Skipped'
388 $this->write("\x1b[0m\x1b[2K");
397 "\x1b[37;41m\x1b[2KFAILURES!\n\x1b[0m\x1b[37;41m\x1b[2K"
400 $this->write("FAILURES!\n");
405 "Tests: %d, Assertions: %s%s%s%s%s.\n",
408 $this->numAssertions,
409 $this->getCountString($result->failureCount(), 'Failures'),
410 $this->getCountString($result->errorCount(), 'Errors'),
411 $this->getCountString(
412 $result->notImplementedCount(), 'Incomplete'
414 $this->getCountString($result->skippedCount(), 'Skipped')
419 $this->write("\x1b[0m\x1b[2K");
423 if (!$this->verbose &&
424 $result->deprecatedFeaturesCount() > 0) {
426 "Warning: Deprecated PHPUnit features are being used %s times!\n".
427 "Use --verbose for more information.\n",
428 $result->deprecatedFeaturesCount()
432 $message = "\x1b[37;41m\x1b[2K" . $message .
436 $this->write("\n" . $message);
441 * @param integer $count
442 * @param string $name
444 * @since Method available since Release 3.0.0
446 protected function getCountString($count, $name)
464 public function printWaitPrompt()
466 $this->write("\n<RETURN> to continue\n");
472 * @param PHPUnit_Framework_Test $test
473 * @param Exception $e
476 public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
478 $this->writeProgress('E');
479 $this->lastTestFailed = TRUE;
483 * A failure occurred.
485 * @param PHPUnit_Framework_Test $test
486 * @param PHPUnit_Framework_AssertionFailedError $e
489 public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
491 $this->writeProgress('F');
492 $this->lastTestFailed = TRUE;
498 * @param PHPUnit_Framework_Test $test
499 * @param Exception $e
502 public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
504 $this->writeProgress('I');
505 $this->lastTestFailed = TRUE;
511 * @param PHPUnit_Framework_Test $test
512 * @param Exception $e
514 * @since Method available since Release 3.0.0
516 public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
518 $this->writeProgress('S');
519 $this->lastTestFailed = TRUE;
523 * A testsuite started.
525 * @param PHPUnit_Framework_TestSuite $suite
526 * @since Method available since Release 2.2.0
528 public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
530 if ($this->numTests == -1) {
531 $this->numTests = count($suite);
532 $this->numTestsWidth = strlen((string)$this->numTests);
533 $this->maxColumn = 69 - (2 * $this->numTestsWidth);
540 * @param PHPUnit_Framework_TestSuite $suite
541 * @since Method available since Release 2.2.0
543 public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
550 * @param PHPUnit_Framework_Test $test
552 public function startTest(PHPUnit_Framework_Test $test)
557 "\nStarting test '%s'.\n", PHPUnit_Util_Test::describe($test)
566 * @param PHPUnit_Framework_Test $test
569 public function endTest(PHPUnit_Framework_Test $test, $time)
571 if (!$this->lastTestFailed) {
572 $this->writeProgress('.');
575 if ($test instanceof PHPUnit_Framework_TestCase) {
576 $this->numAssertions += $test->getNumAssertions();
579 $this->lastTestFailed = FALSE;
583 * @param string $progress
585 protected function writeProgress($progress)
587 $this->write($progress);
589 $this->numTestsRun++;
591 if ($this->column == $this->maxColumn) {
594 ' %' . $this->numTestsWidth . 'd / %' .
595 $this->numTestsWidth . 'd (%3s%%)',
599 floor(($this->numTestsRun / $this->numTests) * 100)
603 $this->writeNewLine();
607 protected function writeNewLine()