Вход Регистрация
Файл: vendor/phpunit/phpunit/src/TextUI/DefaultResultPrinter.php
Строк: 482
<?php declare(strict_types=1);
/*
 * This file is part of PHPUnit.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PHPUnitTextUI;

use const 
PHP_EOL;
use function 
array_map;
use function 
array_reverse;
use function 
count;
use function 
floor;
use function 
implode;
use function 
in_array;
use function 
is_int;
use function 
max;
use function 
preg_split;
use function 
sprintf;
use function 
str_pad;
use function 
str_repeat;
use function 
strlen;
use function 
trim;
use function 
vsprintf;
use 
PHPUnitFrameworkAssertionFailedError;
use 
PHPUnitFrameworkException;
use 
PHPUnitFrameworkInvalidArgumentException;
use 
PHPUnitFrameworkTest;
use 
PHPUnitFrameworkTestCase;
use 
PHPUnitFrameworkTestFailure;
use 
PHPUnitFrameworkTestResult;
use 
PHPUnitFrameworkTestSuite;
use 
PHPUnitFrameworkWarning;
use 
PHPUnitRunnerPhptTestCase;
use 
PHPUnitUtilColor;
use 
PHPUnitUtilPrinter;
use 
SebastianBergmannEnvironmentConsole;
use 
SebastianBergmannTimerResourceUsageFormatter;
use 
SebastianBergmannTimerTimer;
use 
Throwable;

/**
 * @internal This class is not covered by the backward compatibility promise for PHPUnit
 */
class DefaultResultPrinter extends Printer implements ResultPrinter
{
    public const 
EVENT_TEST_START 0;

    public const 
EVENT_TEST_END 1;

    public const 
EVENT_TESTSUITE_START 2;

    public const 
EVENT_TESTSUITE_END 3;

    public const 
COLOR_NEVER 'never';

    public const 
COLOR_AUTO 'auto';

    public const 
COLOR_ALWAYS 'always';

    public const 
COLOR_DEFAULT self::COLOR_NEVER;

    private const 
AVAILABLE_COLORS = [self::COLOR_NEVERself::COLOR_AUTOself::COLOR_ALWAYS];

    
/**
     * @var int
     */
    
protected $column 0;

    
/**
     * @var int
     */
    
protected $maxColumn;

    
/**
     * @var bool
     */
    
protected $lastTestFailed false;

    
/**
     * @var int
     */
    
protected $numAssertions 0;

    
/**
     * @var int
     */
    
protected $numTests = -1;

    
/**
     * @var int
     */
    
protected $numTestsRun 0;

    
/**
     * @var int
     */
    
protected $numTestsWidth;

    
/**
     * @var bool
     */
    
protected $colors false;

    
/**
     * @var bool
     */
    
protected $debug false;

    
/**
     * @var bool
     */
    
protected $verbose false;

    
/**
     * @var int
     */
    
private $numberOfColumns;

    
/**
     * @var bool
     */
    
private $reverse;

    
/**
     * @var bool
     */
    
private $defectListPrinted false;

    
/**
     * @var Timer
     */
    
private $timer;

    
/**
     * Constructor.
     *
     * @param null|resource|string $out
     * @param int|string           $numberOfColumns
     *
     * @throws Exception
     */
    
public function __construct($out nullbool $verbose falsestring $colors self::COLOR_DEFAULTbool $debug false$numberOfColumns 80bool $reverse false)
    {
        
parent::__construct($out);

        if (!
in_array($colorsself::AVAILABLE_COLORStrue)) {
            throw 
InvalidArgumentException::create(
                
3,
                
vsprintf('value from "%s", "%s" or "%s"'self::AVAILABLE_COLORS)
            );
        }

        if (!
is_int($numberOfColumns) && $numberOfColumns !== 'max') {
            throw 
InvalidArgumentException::create(5'integer or "max"');
        }

        
$console            = new Console;
        
$maxNumberOfColumns $console->getNumberOfColumns();

        if (
$numberOfColumns === 'max' || ($numberOfColumns !== 80 && $numberOfColumns $maxNumberOfColumns)) {
            
$numberOfColumns $maxNumberOfColumns;
        }

        
$this->numberOfColumns $numberOfColumns;
        
$this->verbose         $verbose;
        
$this->debug           $debug;
        
$this->reverse         $reverse;

        if (
$colors === self::COLOR_AUTO && $console->hasColorSupport()) {
            
$this->colors true;
        } else {
            
$this->colors = (self::COLOR_ALWAYS === $colors);
        }

        
$this->timer = new Timer;

        
$this->timer->start();
    }

    public function 
printResult(TestResult $result): void
    
{
        
$this->printHeader($result);
        
$this->printErrors($result);
        
$this->printWarnings($result);
        
$this->printFailures($result);
        
$this->printRisky($result);

        if (
$this->verbose) {
            
$this->printIncompletes($result);
            
$this->printSkipped($result);
        }

        
$this->printFooter($result);
    }

    
/**
     * An error occurred.
     */
    
public function addError(Test $testThrowable $tfloat $time): void
    
{
        
$this->writeProgressWithColor('fg-red, bold''E');
        
$this->lastTestFailed true;
    }

    
/**
     * A failure occurred.
     */
    
public function addFailure(Test $testAssertionFailedError $efloat $time): void
    
{
        
$this->writeProgressWithColor('bg-red, fg-white''F');
        
$this->lastTestFailed true;
    }

    
/**
     * A warning occurred.
     */
    
public function addWarning(Test $testWarning $efloat $time): void
    
{
        
$this->writeProgressWithColor('fg-yellow, bold''W');
        
$this->lastTestFailed true;
    }

    
/**
     * Incomplete test.
     */
    
public function addIncompleteTest(Test $testThrowable $tfloat $time): void
    
{
        
$this->writeProgressWithColor('fg-yellow, bold''I');
        
$this->lastTestFailed true;
    }

    
/**
     * Risky test.
     */
    
public function addRiskyTest(Test $testThrowable $tfloat $time): void
    
{
        
$this->writeProgressWithColor('fg-yellow, bold''R');
        
$this->lastTestFailed true;
    }

    
/**
     * Skipped test.
     */
    
public function addSkippedTest(Test $testThrowable $tfloat $time): void
    
{
        
$this->writeProgressWithColor('fg-cyan, bold''S');
        
$this->lastTestFailed true;
    }

    
/**
     * A testsuite started.
     */
    
public function startTestSuite(TestSuite $suite): void
    
{
        if (
$this->numTests == -1) {
            
$this->numTests      count($suite);
            
$this->numTestsWidth strlen((string) $this->numTests);
            
$this->maxColumn     $this->numberOfColumns strlen('  /  (XXX%)') - ($this->numTestsWidth);
        }
    }

    
/**
     * A testsuite ended.
     */
    
public function endTestSuite(TestSuite $suite): void
    
{
    }

    
/**
     * A test started.
     */
    
public function startTest(Test $test): void
    
{
        if (
$this->debug) {
            
$this->write(
                
sprintf(
                    
"Test '%s' startedn",
                    
PHPUnitUtilTest::describeAsString($test)
                )
            );
        }
    }

    
/**
     * A test ended.
     */
    
public function endTest(Test $testfloat $time): void
    
{
        if (
$this->debug) {
            
$this->write(
                
sprintf(
                    
"Test '%s' endedn",
                    
PHPUnitUtilTest::describeAsString($test)
                )
            );
        }

        if (!
$this->lastTestFailed) {
            
$this->writeProgress('.');
        }

        if (
$test instanceof TestCase) {
            
$this->numAssertions += $test->getNumAssertions();
        } elseif (
$test instanceof PhptTestCase) {
            
$this->numAssertions++;
        }

        
$this->lastTestFailed false;

        if (
$test instanceof TestCase && !$test->hasExpectationOnOutput()) {
            
$this->write($test->getActualOutput());
        }
    }

    protected function 
printDefects(array $defectsstring $type): void
    
{
        
$count count($defects);

        if (
$count == 0) {
            return;
        }

        if (
$this->defectListPrinted) {
            
$this->write("n--nn");
        }

        
$this->write(
            
sprintf(
                
"There %s %d %s%s:n",
                (
$count == 1) ? 'was' 'were',
                
$count,
                
$type,
                (
$count == 1) ? '' 's'
            
)
        );

        
$i 1;

        if (
$this->reverse) {
            
$defects array_reverse($defects);
        }

        foreach (
$defects as $defect) {
            
$this->printDefect($defect$i++);
        }

        
$this->defectListPrinted true;
    }

    protected function 
printDefect(TestFailure $defectint $count): void
    
{
        
$this->printDefectHeader($defect$count);
        
$this->printDefectTrace($defect);
    }

    protected function 
printDefectHeader(TestFailure $defectint $count): void
    
{
        
$this->write(
            
sprintf(
                
"n%d) %sn",
                
$count,
                
$defect->getTestName()
            )
        );
    }

    protected function 
printDefectTrace(TestFailure $defect): void
    
{
        
$e $defect->thrownException();

        
$this->write((string) $e);

        while (
$e $e->getPrevious()) {
            
$this->write("nCaused byn" trim((string) $e) . "n");
        }
    }

    protected function 
printErrors(TestResult $result): void
    
{
        
$this->printDefects($result->errors(), 'error');
    }

    protected function 
printFailures(TestResult $result): void
    
{
        
$this->printDefects($result->failures(), 'failure');
    }

    protected function 
printWarnings(TestResult $result): void
    
{
        
$this->printDefects($result->warnings(), 'warning');
    }

    protected function 
printIncompletes(TestResult $result): void
    
{
        
$this->printDefects($result->notImplemented(), 'incomplete test');
    }

    protected function 
printRisky(TestResult $result): void
    
{
        
$this->printDefects($result->risky(), 'risky test');
    }

    protected function 
printSkipped(TestResult $result): void
    
{
        
$this->printDefects($result->skipped(), 'skipped test');
    }

    protected function 
printHeader(TestResult $result): void
    
{
        if (
count($result) > 0) {
            
$this->write(PHP_EOL PHP_EOL . (new ResourceUsageFormatter)->resourceUsage($this->timer->stop()) . PHP_EOL PHP_EOL);
        }
    }

    protected function 
printFooter(TestResult $result): void
    
{
        if (
count($result) === 0) {
            
$this->writeWithColor(
                
'fg-black, bg-yellow',
                
'No tests executed!'
            
);

            return;
        }

        if (
$result->wasSuccessfulAndNoTestIsRiskyOrSkippedOrIncomplete()) {
            
$this->writeWithColor(
                
'fg-black, bg-green',
                
sprintf(
                    
'OK (%d test%s, %d assertion%s)',
                    
count($result),
                    (
count($result) === 1) ? '' 's',
                    
$this->numAssertions,
                    (
$this->numAssertions === 1) ? '' 's'
                
)
            );

            return;
        }

        
$color 'fg-black, bg-yellow';

        if (
$result->wasSuccessful()) {
            if (
$this->verbose || !$result->allHarmless()) {
                
$this->write("n");
            }

            
$this->writeWithColor(
                
$color,
                
'OK, but incomplete, skipped, or risky tests!'
            
);
        } else {
            
$this->write("n");

            if (
$result->errorCount()) {
                
$color 'fg-white, bg-red';

                
$this->writeWithColor(
                    
$color,
                    
'ERRORS!'
                
);
            } elseif (
$result->failureCount()) {
                
$color 'fg-white, bg-red';

                
$this->writeWithColor(
                    
$color,
                    
'FAILURES!'
                
);
            } elseif (
$result->warningCount()) {
                
$color 'fg-black, bg-yellow';

                
$this->writeWithColor(
                    
$color,
                    
'WARNINGS!'
                
);
            }
        }

        
$this->writeCountString(count($result), 'Tests'$colortrue);
        
$this->writeCountString($this->numAssertions'Assertions'$colortrue);
        
$this->writeCountString($result->errorCount(), 'Errors'$color);
        
$this->writeCountString($result->failureCount(), 'Failures'$color);
        
$this->writeCountString($result->warningCount(), 'Warnings'$color);
        
$this->writeCountString($result->skippedCount(), 'Skipped'$color);
        
$this->writeCountString($result->notImplementedCount(), 'Incomplete'$color);
        
$this->writeCountString($result->riskyCount(), 'Risky'$color);
        
$this->writeWithColor($color'.');
    }

    protected function 
writeProgress(string $progress): void
    
{
        if (
$this->debug) {
            return;
        }

        
$this->write($progress);
        
$this->column++;
        
$this->numTestsRun++;

        if (
$this->column == $this->maxColumn || $this->numTestsRun == $this->numTests) {
            if (
$this->numTestsRun == $this->numTests) {
                
$this->write(str_repeat(' '$this->maxColumn $this->column));
            }

            
$this->write(
                
sprintf(
                    
' %' $this->numTestsWidth 'd / %' .
                    
$this->numTestsWidth 'd (%3s%%)',
                    
$this->numTestsRun,
                    
$this->numTests,
                    
floor(($this->numTestsRun $this->numTests) * 100)
                )
            );

            if (
$this->column == $this->maxColumn) {
                
$this->writeNewLine();
            }
        }
    }

    protected function 
writeNewLine(): void
    
{
        
$this->column 0;
        
$this->write("n");
    }

    
/**
     * Formats a buffer with a specified ANSI color sequence if colors are
     * enabled.
     */
    
protected function colorizeTextBox(string $colorstring $buffer): string
    
{
        if (!
$this->colors) {
            return 
$buffer;
        }

        
$lines   preg_split('/rn|r|n/'$buffer);
        
$padding max(array_map('strlen'$lines));

        
$styledLines = [];

        foreach (
$lines as $line) {
            
$styledLines[] = Color::colorize($colorstr_pad($line$padding));
        }

        return 
implode(PHP_EOL$styledLines);
    }

    
/**
     * Writes a buffer out with a color sequence if colors are enabled.
     */
    
protected function writeWithColor(string $colorstring $bufferbool $lf true): void
    
{
        
$this->write($this->colorizeTextBox($color$buffer));

        if (
$lf) {
            
$this->write(PHP_EOL);
        }
    }

    
/**
     * Writes progress with a color sequence if colors are enabled.
     */
    
protected function writeProgressWithColor(string $colorstring $buffer): void
    
{
        
$buffer $this->colorizeTextBox($color$buffer);
        
$this->writeProgress($buffer);
    }

    private function 
writeCountString(int $countstring $namestring $colorbool $always false): void
    
{
        static 
$first true;

        if (
$always || $count 0) {
            
$this->writeWithColor(
                
$color,
                
sprintf(
                    
'%s%s: %d',
                    !
$first ', ' '',
                    
$name,
                    
$count
                
),
                
false
            
);

            
$first false;
        }
    }
}
Онлайн: 1
Реклама