Вход Регистрация
Файл: vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php
Строк: 365
<?php declare(strict_types=1);
/*
 * This file is part of phpunit/php-code-coverage.
 *
 * (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 SebastianBergmannCodeCoverageReportXml;

use const 
DIRECTORY_SEPARATOR;
use const 
PHP_EOL;
use function 
count;
use function 
dirname;
use function 
file_get_contents;
use function 
file_put_contents;
use function 
is_array;
use function 
is_dir;
use function 
is_file;
use function 
is_writable;
use function 
libxml_clear_errors;
use function 
libxml_get_errors;
use function 
libxml_use_internal_errors;
use function 
sprintf;
use function 
strlen;
use function 
substr;
use 
DateTimeImmutable;
use 
DOMDocument;
use 
SebastianBergmannCodeCoverageCodeCoverage;
use 
SebastianBergmannCodeCoverageDriverPathExistsButIsNotDirectoryException;
use 
SebastianBergmannCodeCoverageDriverWriteOperationFailedException;
use 
SebastianBergmannCodeCoverageNodeAbstractNode;
use 
SebastianBergmannCodeCoverageNodeDirectory as DirectoryNode;
use 
SebastianBergmannCodeCoverageNodeFile as FileNode;
use 
SebastianBergmannCodeCoverageUtilFilesystem as DirectoryUtil;
use 
SebastianBergmannCodeCoverageVersion;
use 
SebastianBergmannCodeCoverageXmlException;
use 
SebastianBergmannEnvironmentRuntime;

final class 
Facade
{
    
/**
     * @var string
     */
    
private $target;

    
/**
     * @var Project
     */
    
private $project;

    
/**
     * @var string
     */
    
private $phpUnitVersion;

    public function 
__construct(string $version)
    {
        
$this->phpUnitVersion $version;
    }

    
/**
     * @throws XmlException
     */
    
public function process(CodeCoverage $coveragestring $target): void
    
{
        if (
substr($target, -11) !== DIRECTORY_SEPARATOR) {
            
$target .= DIRECTORY_SEPARATOR;
        }

        
$this->target $target;
        
$this->initTargetDirectory($target);

        
$report $coverage->getReport();

        
$this->project = new Project(
            
$coverage->getReport()->name()
        );

        
$this->setBuildInformation();
        
$this->processTests($coverage->getTests());
        
$this->processDirectory($report$this->project);

        
$this->saveDocument($this->project->asDom(), 'index');
    }

    private function 
setBuildInformation(): void
    
{
        
$buildNode $this->project->buildInformation();
        
$buildNode->setRuntimeInformation(new Runtime);
        
$buildNode->setBuildTime(new DateTimeImmutable);
        
$buildNode->setGeneratorVersions($this->phpUnitVersionVersion::id());
    }

    
/**
     * @throws PathExistsButIsNotDirectoryException
     * @throws WriteOperationFailedException
     */
    
private function initTargetDirectory(string $directory): void
    
{
        if (
is_file($directory)) {
            if (!
is_dir($directory)) {
                throw new 
PathExistsButIsNotDirectoryException($directory);
            }

            if (!
is_writable($directory)) {
                throw new 
WriteOperationFailedException($directory);
            }
        }

        
DirectoryUtil::createDirectory($directory);
    }

    
/**
     * @throws XmlException
     */
    
private function processDirectory(DirectoryNode $directoryNode $context): void
    
{
        
$directoryName $directory->name();

        if (
$this->project->projectSourceDirectory() === $directoryName) {
            
$directoryName '/';
        }

        
$directoryObject $context->addDirectory($directoryName);

        
$this->setTotals($directory$directoryObject->totals());

        foreach (
$directory->directories() as $node) {
            
$this->processDirectory($node$directoryObject);
        }

        foreach (
$directory->files() as $node) {
            
$this->processFile($node$directoryObject);
        }
    }

    
/**
     * @throws XmlException
     */
    
private function processFile(FileNode $fileDirectory $context): void
    
{
        
$fileObject $context->addFile(
            
$file->name(),
            
$file->id() . '.xml'
        
);

        
$this->setTotals($file$fileObject->totals());

        
$path substr(
            
$file->pathAsString(),
            
strlen($this->project->projectSourceDirectory())
        );

        
$fileReport = new Report($path);

        
$this->setTotals($file$fileReport->totals());

        foreach (
$file->classesAndTraits() as $unit) {
            
$this->processUnit($unit$fileReport);
        }

        foreach (
$file->functions() as $function) {
            
$this->processFunction($function$fileReport);
        }

        foreach (
$file->lineCoverageData() as $line => $tests) {
            if (!
is_array($tests) || count($tests) === 0) {
                continue;
            }

            
$coverage $fileReport->lineCoverage((string) $line);

            foreach (
$tests as $test) {
                
$coverage->addTest($test);
            }

            
$coverage->finalize();
        }

        
$fileReport->source()->setSourceCode(
            
file_get_contents($file->pathAsString())
        );

        
$this->saveDocument($fileReport->asDom(), $file->id());
    }

    private function 
processUnit(array $unitReport $report): void
    
{
        if (isset(
$unit['className'])) {
            
$unitObject $report->classObject($unit['className']);
        } else {
            
$unitObject $report->traitObject($unit['traitName']);
        }

        
$unitObject->setLines(
            
$unit['startLine'],
            
$unit['executableLines'],
            
$unit['executedLines']
        );

        
$unitObject->setCrap((float) $unit['crap']);
        
$unitObject->setNamespace($unit['namespace']);

        foreach (
$unit['methods'] as $method) {
            
$methodObject $unitObject->addMethod($method['methodName']);
            
$methodObject->setSignature($method['signature']);
            
$methodObject->setLines((string) $method['startLine'], (string) $method['endLine']);
            
$methodObject->setCrap($method['crap']);
            
$methodObject->setTotals(
                (string) 
$method['executableLines'],
                (string) 
$method['executedLines'],
                (string) 
$method['coverage']
            );
        }
    }

    private function 
processFunction(array $functionReport $report): void
    
{
        
$functionObject $report->functionObject($function['functionName']);

        
$functionObject->setSignature($function['signature']);
        
$functionObject->setLines((string) $function['startLine']);
        
$functionObject->setCrap($function['crap']);
        
$functionObject->setTotals((string) $function['executableLines'], (string) $function['executedLines'], (string) $function['coverage']);
    }

    private function 
processTests(array $tests): void
    
{
        
$testsObject $this->project->tests();

        foreach (
$tests as $test => $result) {
            
$testsObject->addTest($test$result);
        }
    }

    private function 
setTotals(AbstractNode $nodeTotals $totals): void
    
{
        
$loc $node->linesOfCode();

        
$totals->setNumLines(
            
$loc['linesOfCode'],
            
$loc['commentLinesOfCode'],
            
$loc['nonCommentLinesOfCode'],
            
$node->numberOfExecutableLines(),
            
$node->numberOfExecutedLines()
        );

        
$totals->setNumClasses(
            
$node->numberOfClasses(),
            
$node->numberOfTestedClasses()
        );

        
$totals->setNumTraits(
            
$node->numberOfTraits(),
            
$node->numberOfTestedTraits()
        );

        
$totals->setNumMethods(
            
$node->numberOfMethods(),
            
$node->numberOfTestedMethods()
        );

        
$totals->setNumFunctions(
            
$node->numberOfFunctions(),
            
$node->numberOfTestedFunctions()
        );
    }

    private function 
targetDirectory(): string
    
{
        return 
$this->target;
    }

    
/**
     * @throws XmlException
     */
    
private function saveDocument(DOMDocument $documentstring $name): void
    
{
        
$filename sprintf('%s/%s.xml'$this->targetDirectory(), $name);

        
$document->formatOutput       true;
        
$document->preserveWhiteSpace false;
        
$this->initTargetDirectory(dirname($filename));

        
file_put_contents($filename$this->documentAsString($document));
    }

    
/**
     * @throws XmlException
     *
     * @see https://bugs.php.net/bug.php?id=79191
     */
    
private function documentAsString(DOMDocument $document): string
    
{
        
$xmlErrorHandling libxml_use_internal_errors(true);
        
$xml              $document->saveXML();

        if (
$xml === false) {
            
$message 'Unable to generate the XML';

            foreach (
libxml_get_errors() as $error) {
                
$message .= PHP_EOL $error->message;
            }

            throw new 
XmlException($message);
        }

        
libxml_clear_errors();
        
libxml_use_internal_errors($xmlErrorHandling);

        return 
$xml;
    }
}
Онлайн: 0
Реклама