Вход Регистрация
Файл: vendor/phpunit/phpunit/src/Util/TestDox/TestDoxPrinter.php
Строк: 377
<?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 PHPUnitUtilTestDox;

use const 
PHP_EOL;
use function 
array_map;
use function 
get_class;
use function 
implode;
use function 
method_exists;
use function 
preg_split;
use function 
trim;
use 
PHPUnitFrameworkAssertionFailedError;
use 
PHPUnitFrameworkReorderable;
use 
PHPUnitFrameworkTest;
use 
PHPUnitFrameworkTestCase;
use 
PHPUnitFrameworkTestResult;
use 
PHPUnitFrameworkTestSuite;
use 
PHPUnitFrameworkWarning;
use 
PHPUnitRunnerBaseTestRunner;
use 
PHPUnitRunnerPhptTestCase;
use 
PHPUnitTextUIDefaultResultPrinter;
use 
Throwable;

/**
 * @internal This class is not covered by the backward compatibility promise for PHPUnit
 */
class TestDoxPrinter extends DefaultResultPrinter
{
    
/**
     * @var NamePrettifier
     */
    
protected $prettifier;

    
/**
     * @var int The number of test results received from the TestRunner
     */
    
protected $testIndex 0;

    
/**
     * @var int The number of test results already sent to the output
     */
    
protected $testFlushIndex 0;

    
/**
     * @var array<int, array> Buffer for test results
     */
    
protected $testResults = [];

    
/**
     * @var array<string, int> Lookup table for testname to testResults[index]
     */
    
protected $testNameResultIndex = [];

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

    
/**
     * @var array array<string>
     */
    
protected $originalExecutionOrder = [];

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

    
/**
     * @var bool
     */
    
protected $showProgress true;

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

        
$this->prettifier = new NamePrettifier($this->colors);
    }

    public function 
setOriginalExecutionOrder(array $order): void
    
{
        
$this->originalExecutionOrder $order;
        
$this->enableOutputBuffer     = !empty($order);
    }

    public function 
setShowProgressAnimation(bool $showProgress): void
    
{
        
$this->showProgress $showProgress;
    }

    public function 
printResult(TestResult $result): void
    
{
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function endTest(Test $testfloat $time): void
    
{
        if (!
$test instanceof TestCase && !$test instanceof PhptTestCase && !$test instanceof TestSuite) {
            return;
        }

        if (
$this->testHasPassed()) {
            
$this->registerTestResult($testnullBaseTestRunner::STATUS_PASSED$timefalse);
        }

        if (
$test instanceof TestCase || $test instanceof PhptTestCase) {
            
$this->testIndex++;
        }

        
parent::endTest($test$time);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addError(Test $testThrowable $tfloat $time): void
    
{
        
$this->registerTestResult($test$tBaseTestRunner::STATUS_ERROR$timetrue);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addWarning(Test $testWarning $efloat $time): void
    
{
        
$this->registerTestResult($test$eBaseTestRunner::STATUS_WARNING$timetrue);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addFailure(Test $testAssertionFailedError $efloat $time): void
    
{
        
$this->registerTestResult($test$eBaseTestRunner::STATUS_FAILURE$timetrue);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addIncompleteTest(Test $testThrowable $tfloat $time): void
    
{
        
$this->registerTestResult($test$tBaseTestRunner::STATUS_INCOMPLETE$timefalse);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addRiskyTest(Test $testThrowable $tfloat $time): void
    
{
        
$this->registerTestResult($test$tBaseTestRunner::STATUS_RISKY$timefalse);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addSkippedTest(Test $testThrowable $tfloat $time): void
    
{
        
$this->registerTestResult($test$tBaseTestRunner::STATUS_SKIPPED$timefalse);
    }

    public function 
writeProgress(string $progress): void
    
{
        
$this->flushOutputBuffer();
    }

    public function 
flush(): void
    
{
        
$this->flushOutputBuffer(true);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
protected function registerTestResult(Test $test, ?Throwable $tint $statusfloat $timebool $verbose): void
    
{
        
$testName $test instanceof Reorderable $test->sortId() : $test->getName();

        
$result = [
            
'className'  => $this->formatClassName($test),
            
'testName'   => $testName,
            
'testMethod' => $this->formatTestName($test),
            
'message'    => '',
            
'status'     => $status,
            
'time'       => $time,
            
'verbose'    => $verbose,
        ];

        if (
$t !== null) {
            
$result['message'] = $this->formatTestResultMessage($t$result);
        }

        
$this->testResults[$this->testIndex]  = $result;
        
$this->testNameResultIndex[$testName] = $this->testIndex;
    }

    protected function 
formatTestName(Test $test): string
    
{
        return 
method_exists($test'getName') ? $test->getName() : '';
    }

    protected function 
formatClassName(Test $test): string
    
{
        return 
get_class($test);
    }

    protected function 
testHasPassed(): bool
    
{
        if (!isset(
$this->testResults[$this->testIndex]['status'])) {
            return 
true;
        }

        if (
$this->testResults[$this->testIndex]['status'] === BaseTestRunner::STATUS_PASSED) {
            return 
true;
        }

        return 
false;
    }

    protected function 
flushOutputBuffer(bool $forceFlush false): void
    
{
        if (
$this->testFlushIndex === $this->testIndex) {
            return;
        }

        if (
$this->testFlushIndex 0) {
            if (
$this->enableOutputBuffer &&
                isset(
$this->originalExecutionOrder[$this->testFlushIndex 1])) {
                
$prevResult $this->getTestResultByName($this->originalExecutionOrder[$this->testFlushIndex 1]);
            } else {
                
$prevResult $this->testResults[$this->testFlushIndex 1];
            }
        } else {
            
$prevResult $this->getEmptyTestResult();
        }

        if (!
$this->enableOutputBuffer) {
            
$this->writeTestResult($prevResult$this->testResults[$this->testFlushIndex++]);
        } else {
            do {
                
$flushed false;

                if (!
$forceFlush && isset($this->originalExecutionOrder[$this->testFlushIndex])) {
                    
$result $this->getTestResultByName($this->originalExecutionOrder[$this->testFlushIndex]);
                } else {
                    
// This test(name) cannot found in original execution order,
                    // flush result to output stream right away
                    
$result $this->testResults[$this->testFlushIndex];
                }

                if (!empty(
$result)) {
                    
$this->hideSpinner();
                    
$this->writeTestResult($prevResult$result);
                    
$this->testFlushIndex++;
                    
$prevResult $result;
                    
$flushed    true;
                } else {
                    
$this->showSpinner();
                }
            } while (
$flushed && $this->testFlushIndex $this->testIndex);
        }
    }

    protected function 
showSpinner(): void
    
{
        if (!
$this->showProgress) {
            return;
        }

        if (
$this->spinState) {
            
$this->undrawSpinner();
        }

        
$this->spinState++;
        
$this->drawSpinner();
    }

    protected function 
hideSpinner(): void
    
{
        if (!
$this->showProgress) {
            return;
        }

        if (
$this->spinState) {
            
$this->undrawSpinner();
        }

        
$this->spinState 0;
    }

    protected function 
drawSpinner(): void
    
{
        
// optional for CLI printers: show the user a 'buffering output' spinner
    
}

    protected function 
undrawSpinner(): void
    
{
        
// remove the spinner from the current line
    
}

    protected function 
writeTestResult(array $prevResult, array $result): void
    
{
    }

    protected function 
getEmptyTestResult(): array
    {
        return [
            
'className' => '',
            
'testName'  => '',
            
'message'   => '',
            
'failed'    => '',
            
'verbose'   => '',
        ];
    }

    protected function 
getTestResultByName(?string $testName): array
    {
        if (isset(
$this->testNameResultIndex[$testName])) {
            return 
$this->testResults[$this->testNameResultIndex[$testName]];
        }

        return [];
    }

    protected function 
formatThrowable(Throwable $t, ?int $status null): string
    
{
        
$message trim(PHPUnitFrameworkTestFailure::exceptionToString($t));

        if (
$message) {
            
$message .= PHP_EOL PHP_EOL $this->formatStacktrace($t);
        } else {
            
$message $this->formatStacktrace($t);
        }

        return 
$message;
    }

    protected function 
formatStacktrace(Throwable $t): string
    
{
        return 
PHPUnitUtilFilter::getFilteredStacktrace($t);
    }

    protected function 
formatTestResultMessage(Throwable $t, array $resultstring $prefix '│'): string
    
{
        
$message $this->formatThrowable($t$result['status']);

        if (
$message === '') {
            return 
'';
        }

        if (!(
$this->verbose || $result['verbose'])) {
            return 
'';
        }

        return 
$this->prefixLines($prefix$message);
    }

    protected function 
prefixLines(string $prefixstring $message): string
    
{
        
$message trim($message);

        return 
implode(
            
PHP_EOL,
            
array_map(
                static function (
string $text) use ($prefix)
                {
                    return 
'   ' $prefix . ($text ' ' $text '');
                },
                
preg_split('/rn|r|n/'$message)
            )
        );
    }
}
Онлайн: 0
Реклама