Вход Регистрация
Файл: 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 = null, bool $verbose = false, string $colors = self::COLOR_DEFAULT, bool $debug = false, $numberOfColumns = 80, bool $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 $test, float $time): void
    
{
        if (!
$test instanceof TestCase && !$test instanceof PhptTestCase && !$test instanceof TestSuite) {
            return;
        }

        if (
$this->testHasPassed()) {
            
$this->registerTestResult($test, null, BaseTestRunner::STATUS_PASSED, $time, false);
        }

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

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

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addError(Test $test, Throwable $t, float $time): void
    
{
        
$this->registerTestResult($test, $t, BaseTestRunner::STATUS_ERROR, $time, true);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addWarning(Test $test, Warning $e, float $time): void
    
{
        
$this->registerTestResult($test, $e, BaseTestRunner::STATUS_WARNING, $time, true);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addFailure(Test $test, AssertionFailedError $e, float $time): void
    
{
        
$this->registerTestResult($test, $e, BaseTestRunner::STATUS_FAILURE, $time, true);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addIncompleteTest(Test $test, Throwable $t, float $time): void
    
{
        
$this->registerTestResult($test, $t, BaseTestRunner::STATUS_INCOMPLETE, $time, false);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addRiskyTest(Test $test, Throwable $t, float $time): void
    
{
        
$this->registerTestResult($test, $t, BaseTestRunner::STATUS_RISKY, $time, false);
    }

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
public function addSkippedTest(Test $test, Throwable $t, float $time): void
    
{
        
$this->registerTestResult($test, $t, BaseTestRunner::STATUS_SKIPPED, $time, false);
    }

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

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

    
/**
     * @throws SebastianBergmannRecursionContextInvalidArgumentException
     */
    
protected function registerTestResult(Test $test, ?Throwable $t, int $status, float $time, bool $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 $result, string $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 $prefix, string $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
Реклама