glastree_on_gitea
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final readonly class BuildInformation
|
||||
{
|
||||
public function __construct(
|
||||
XMLWriter $xmlWriter,
|
||||
Runtime $runtime,
|
||||
DateTimeImmutable $buildDate,
|
||||
string $phpUnitVersion,
|
||||
string $coverageVersion,
|
||||
string $driverExtensionName,
|
||||
string $driverExtensionVersion,
|
||||
) {
|
||||
$xmlWriter->startElement('build');
|
||||
$xmlWriter->writeAttribute('time', $buildDate->format('D M j G:i:s T Y'));
|
||||
$xmlWriter->writeAttribute('phpunit', $phpUnitVersion);
|
||||
$xmlWriter->writeAttribute('coverage', $coverageVersion);
|
||||
|
||||
$xmlWriter->startElement('runtime');
|
||||
$xmlWriter->writeAttribute('name', $runtime->getName());
|
||||
$xmlWriter->writeAttribute('version', $runtime->getVersion());
|
||||
$xmlWriter->writeAttribute('url', $runtime->getVendorUrl());
|
||||
$xmlWriter->endElement();
|
||||
|
||||
$xmlWriter->startElement('driver');
|
||||
$xmlWriter->writeAttribute('name', $driverExtensionName);
|
||||
$xmlWriter->writeAttribute('version', $driverExtensionVersion);
|
||||
$xmlWriter->endElement();
|
||||
|
||||
$xmlWriter->endElement();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Coverage
|
||||
{
|
||||
private readonly XMLWriter $xmlWriter;
|
||||
private readonly string $line;
|
||||
|
||||
public function __construct(
|
||||
XMLWriter $xmlWriter,
|
||||
string $line
|
||||
) {
|
||||
$this->xmlWriter = $xmlWriter;
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
public function finalize(array $tests): void
|
||||
{
|
||||
$writer = $this->xmlWriter;
|
||||
$writer->startElement('line');
|
||||
$writer->writeAttribute('nr', $this->line);
|
||||
|
||||
foreach ($tests as $test) {
|
||||
$writer->startElement('covered');
|
||||
$writer->writeAttribute('by', $test);
|
||||
$writer->endElement();
|
||||
}
|
||||
$writer->endElement();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Directory extends Node
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function file_get_contents;
|
||||
use function is_array;
|
||||
use function is_dir;
|
||||
use function is_file;
|
||||
use function is_writable;
|
||||
use function phpversion;
|
||||
use function sprintf;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
use DateTimeImmutable;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Data\ProcessedClassType;
|
||||
use SebastianBergmann\CodeCoverage\Data\ProcessedFunctionType;
|
||||
use SebastianBergmann\CodeCoverage\Data\ProcessedTraitType;
|
||||
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
|
||||
use SebastianBergmann\CodeCoverage\PathExistsButIsNotDirectoryException;
|
||||
use SebastianBergmann\CodeCoverage\Util\Filesystem;
|
||||
use SebastianBergmann\CodeCoverage\Version;
|
||||
use SebastianBergmann\CodeCoverage\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\XmlException;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @phpstan-import-type TestType from CodeCoverage
|
||||
*/
|
||||
final class Facade
|
||||
{
|
||||
public const string XML_NAMESPACE = 'https://schema.phpunit.de/coverage/1.0';
|
||||
private string $target;
|
||||
private Project $project;
|
||||
private readonly string $phpUnitVersion;
|
||||
private readonly bool $includeSource;
|
||||
|
||||
public function __construct(string $version, bool $includeSource = true)
|
||||
{
|
||||
$this->phpUnitVersion = $version;
|
||||
$this->includeSource = $includeSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws XmlException
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, string $target): void
|
||||
{
|
||||
if (substr($target, -1, 1) !== DIRECTORY_SEPARATOR) {
|
||||
$target .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
$this->target = $target;
|
||||
$this->initTargetDirectory($target);
|
||||
|
||||
$report = $coverage->getReport();
|
||||
|
||||
$writer = new XMLWriter;
|
||||
$writer->openUri($this->targetFilePath('index'));
|
||||
$writer->setIndent(true);
|
||||
$writer->setIndentString(' ');
|
||||
$this->project = new Project(
|
||||
$writer,
|
||||
$coverage->getReport()->name(),
|
||||
);
|
||||
|
||||
$this->setBuildInformation($coverage);
|
||||
|
||||
$this->project->startProject();
|
||||
$this->processTests($coverage->getTests());
|
||||
$this->processDirectory($report, $this->project);
|
||||
$this->project->finalize();
|
||||
}
|
||||
|
||||
private function setBuildInformation(CodeCoverage $coverage): void
|
||||
{
|
||||
if ($coverage->driverIsPcov()) {
|
||||
$driverExtensionName = 'pcov';
|
||||
$driverExtensionVersion = phpversion('pcov');
|
||||
} elseif ($coverage->driverIsXdebug()) {
|
||||
$driverExtensionName = 'xdebug';
|
||||
$driverExtensionVersion = phpversion('xdebug');
|
||||
} else {
|
||||
// @codeCoverageIgnoreStart
|
||||
$driverExtensionName = 'unknown';
|
||||
$driverExtensionVersion = 'unknown';
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
$this->project->buildInformation(
|
||||
new Runtime,
|
||||
new DateTimeImmutable,
|
||||
$this->phpUnitVersion,
|
||||
Version::id(),
|
||||
$driverExtensionName,
|
||||
$driverExtensionVersion,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PathExistsButIsNotDirectoryException
|
||||
* @throws WriteOperationFailedException
|
||||
*/
|
||||
private function initTargetDirectory(string $directory): void
|
||||
{
|
||||
if (is_file($directory)) {
|
||||
// @codeCoverageIgnoreStart
|
||||
if (!is_dir($directory)) {
|
||||
throw new PathExistsButIsNotDirectoryException($directory);
|
||||
}
|
||||
|
||||
if (!is_writable($directory)) {
|
||||
throw new WriteOperationFailedException($directory);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
Filesystem::createDirectory($directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws XmlException
|
||||
*/
|
||||
private function processDirectory(DirectoryNode $directory, Node $context): void
|
||||
{
|
||||
$directoryName = $directory->name();
|
||||
|
||||
if ($this->project->projectSourceDirectory() === $directoryName) {
|
||||
$directoryName = '/';
|
||||
}
|
||||
|
||||
$writer = $this->project->getWriter();
|
||||
$writer->startElement('directory');
|
||||
$writer->writeAttribute('name', $directoryName);
|
||||
$directoryObject = $context->addDirectory();
|
||||
|
||||
$this->setTotals($directory, $directoryObject->totals());
|
||||
|
||||
foreach ($directory->directories() as $node) {
|
||||
$this->processDirectory($node, $directoryObject);
|
||||
}
|
||||
|
||||
foreach ($directory->files() as $node) {
|
||||
$this->processFile($node, $directoryObject);
|
||||
}
|
||||
$writer->endElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws XmlException
|
||||
*/
|
||||
private function processFile(FileNode $file, Directory $context): void
|
||||
{
|
||||
$context->getWriter()->startElement('file');
|
||||
$context->getWriter()->writeAttribute('name', $file->name());
|
||||
$context->getWriter()->writeAttribute('href', $file->id() . '.xml');
|
||||
$context->getWriter()->writeAttribute('hash', $file->sha1());
|
||||
|
||||
$fileObject = $context->addFile();
|
||||
|
||||
$this->setTotals($file, $fileObject->totals());
|
||||
|
||||
$context->getWriter()->endElement();
|
||||
|
||||
$path = substr(
|
||||
$file->pathAsString(),
|
||||
strlen($this->project->projectSourceDirectory()),
|
||||
);
|
||||
|
||||
$writer = new XMLWriter;
|
||||
$writer->openUri($this->targetFilePath($file->id()));
|
||||
$writer->setIndent(true);
|
||||
$writer->setIndentString(' ');
|
||||
$fileReport = new Report($writer, $path, $file->sha1());
|
||||
|
||||
$this->setTotals($file, $fileReport->totals());
|
||||
|
||||
foreach ($file->classesAndTraits() as $unit) {
|
||||
$this->processUnit($unit, $fileReport);
|
||||
}
|
||||
|
||||
foreach ($file->functions() as $function) {
|
||||
$this->processFunction($function, $fileReport);
|
||||
}
|
||||
|
||||
$fileReport->getWriter()->startElement('coverage');
|
||||
|
||||
foreach ($file->lineCoverageData() as $line => $tests) {
|
||||
if (!is_array($tests) || count($tests) === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$coverage = $fileReport->lineCoverage((string) $line);
|
||||
$coverage->finalize($tests);
|
||||
}
|
||||
$fileReport->getWriter()->endElement();
|
||||
|
||||
if ($this->includeSource) {
|
||||
$fileReport->source()->setSourceCode(
|
||||
file_get_contents($file->pathAsString()),
|
||||
);
|
||||
}
|
||||
|
||||
$fileReport->finalize();
|
||||
}
|
||||
|
||||
private function processUnit(ProcessedClassType|ProcessedTraitType $unit, Report $report): void
|
||||
{
|
||||
if ($unit instanceof ProcessedClassType) {
|
||||
$report->getWriter()->startElement('class');
|
||||
|
||||
$unitObject = $report->classObject(
|
||||
$unit->className,
|
||||
$unit->namespace,
|
||||
$unit->startLine,
|
||||
$unit->executableLines,
|
||||
$unit->executedLines,
|
||||
(float) $unit->crap,
|
||||
);
|
||||
} else {
|
||||
$report->getWriter()->startElement('trait');
|
||||
|
||||
$unitObject = $report->traitObject(
|
||||
$unit->traitName,
|
||||
$unit->namespace,
|
||||
$unit->startLine,
|
||||
$unit->executableLines,
|
||||
$unit->executedLines,
|
||||
(float) $unit->crap,
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($unit->methods as $method) {
|
||||
$report->getWriter()->startElement('method');
|
||||
|
||||
$unitObject->addMethod(
|
||||
$method->methodName,
|
||||
$method->signature,
|
||||
(string) $method->startLine,
|
||||
(string) $method->endLine,
|
||||
(string) $method->executableLines,
|
||||
(string) $method->executedLines,
|
||||
(string) $method->coverage,
|
||||
$method->crap,
|
||||
);
|
||||
|
||||
$report->getWriter()->endElement();
|
||||
}
|
||||
|
||||
$report->getWriter()->endElement();
|
||||
}
|
||||
|
||||
private function processFunction(ProcessedFunctionType $function, Report $report): void
|
||||
{
|
||||
$report->getWriter()->startElement('function');
|
||||
|
||||
$report->functionObject(
|
||||
$function->functionName,
|
||||
$function->signature,
|
||||
(string) $function->startLine,
|
||||
null,
|
||||
(string) $function->executableLines,
|
||||
(string) $function->executedLines,
|
||||
(string) $function->coverage,
|
||||
$function->crap,
|
||||
);
|
||||
|
||||
$report->getWriter()->endElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, TestType> $tests
|
||||
*/
|
||||
private function processTests(array $tests): void
|
||||
{
|
||||
$this->project->getWriter()->startElement('tests');
|
||||
|
||||
$testsObject = $this->project->tests();
|
||||
|
||||
foreach ($tests as $test => $result) {
|
||||
$testsObject->addTest($test, $result);
|
||||
}
|
||||
|
||||
$this->project->getWriter()->endElement();
|
||||
}
|
||||
|
||||
private function setTotals(AbstractNode $node, Totals $totals): void
|
||||
{
|
||||
$totals->getWriter()->startElement('totals');
|
||||
|
||||
$loc = $node->linesOfCode();
|
||||
|
||||
$totals->setNumLines(
|
||||
$loc->linesOfCode(),
|
||||
$loc->commentLinesOfCode(),
|
||||
$loc->nonCommentLinesOfCode(),
|
||||
$node->numberOfExecutableLines(),
|
||||
$node->numberOfExecutedLines(),
|
||||
);
|
||||
|
||||
$totals->setNumMethods(
|
||||
$node->numberOfMethods(),
|
||||
$node->numberOfTestedMethods(),
|
||||
);
|
||||
|
||||
$totals->setNumFunctions(
|
||||
$node->numberOfFunctions(),
|
||||
$node->numberOfTestedFunctions(),
|
||||
);
|
||||
|
||||
$totals->setNumClasses(
|
||||
$node->numberOfClasses(),
|
||||
$node->numberOfTestedClasses(),
|
||||
);
|
||||
|
||||
$totals->setNumTraits(
|
||||
$node->numberOfTraits(),
|
||||
$node->numberOfTestedTraits(),
|
||||
);
|
||||
|
||||
$totals->getWriter()->endElement();
|
||||
}
|
||||
|
||||
private function targetDirectory(): string
|
||||
{
|
||||
return $this->target;
|
||||
}
|
||||
|
||||
private function targetFilePath(string $name): string
|
||||
{
|
||||
$filename = sprintf('%s/%s.xml', $this->targetDirectory(), $name);
|
||||
|
||||
$this->initTargetDirectory(dirname($filename));
|
||||
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
class File
|
||||
{
|
||||
protected XMLWriter $xmlWriter;
|
||||
|
||||
public function __construct(XMLWriter $xmlWriter)
|
||||
{
|
||||
$this->xmlWriter = $xmlWriter;
|
||||
}
|
||||
|
||||
public function getWriter(): XMLWriter
|
||||
{
|
||||
return $this->xmlWriter;
|
||||
}
|
||||
|
||||
public function totals(): Totals
|
||||
{
|
||||
return new Totals($this->xmlWriter);
|
||||
}
|
||||
|
||||
public function lineCoverage(string $line): Coverage
|
||||
{
|
||||
return new Coverage($this->xmlWriter, $line);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final readonly class Method
|
||||
{
|
||||
private XMLWriter $xmlWriter;
|
||||
|
||||
public function __construct(
|
||||
XMLWriter $xmlWriter,
|
||||
string $name,
|
||||
string $signature,
|
||||
string $start,
|
||||
?string $end,
|
||||
string $executable,
|
||||
string $executed,
|
||||
string $coverage,
|
||||
string $crap
|
||||
) {
|
||||
$this->xmlWriter = $xmlWriter;
|
||||
|
||||
$this->xmlWriter->writeAttribute('name', $name);
|
||||
$this->xmlWriter->writeAttribute('signature', $signature);
|
||||
|
||||
$this->xmlWriter->writeAttribute('start', $start);
|
||||
|
||||
if ($end !== null) {
|
||||
$this->xmlWriter->writeAttribute('end', $end);
|
||||
}
|
||||
|
||||
$this->xmlWriter->writeAttribute('crap', $crap);
|
||||
|
||||
$this->xmlWriter->writeAttribute('executable', $executable);
|
||||
$this->xmlWriter->writeAttribute('executed', $executed);
|
||||
$this->xmlWriter->writeAttribute('coverage', $coverage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
abstract class Node
|
||||
{
|
||||
protected readonly XMLWriter $xmlWriter;
|
||||
|
||||
public function __construct(XMLWriter $xmlWriter)
|
||||
{
|
||||
$this->xmlWriter = $xmlWriter;
|
||||
}
|
||||
|
||||
public function totals(): Totals
|
||||
{
|
||||
return new Totals($this->xmlWriter);
|
||||
}
|
||||
|
||||
public function addDirectory(): Directory
|
||||
{
|
||||
return new Directory($this->xmlWriter);
|
||||
}
|
||||
|
||||
public function addFile(): File
|
||||
{
|
||||
return new File($this->xmlWriter);
|
||||
}
|
||||
|
||||
public function getWriter(): XMLWriter
|
||||
{
|
||||
return $this->xmlWriter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Project extends Node
|
||||
{
|
||||
private readonly string $directory;
|
||||
|
||||
public function __construct(XMLWriter $xmlWriter, string $directory)
|
||||
{
|
||||
$this->directory = $directory;
|
||||
|
||||
parent::__construct($xmlWriter);
|
||||
|
||||
$this->xmlWriter->startDocument();
|
||||
|
||||
$this->xmlWriter->startElement('phpunit');
|
||||
$this->xmlWriter->writeAttribute('xmlns', Facade::XML_NAMESPACE);
|
||||
}
|
||||
|
||||
public function projectSourceDirectory(): string
|
||||
{
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
public function buildInformation(
|
||||
Runtime $runtime,
|
||||
DateTimeImmutable $buildDate,
|
||||
string $phpUnitVersion,
|
||||
string $coverageVersion,
|
||||
string $driverExtensionName,
|
||||
string $driverExtensionVersion,
|
||||
): void {
|
||||
new BuildInformation(
|
||||
$this->xmlWriter,
|
||||
$runtime,
|
||||
$buildDate,
|
||||
$phpUnitVersion,
|
||||
$coverageVersion,
|
||||
$driverExtensionName,
|
||||
$driverExtensionVersion,
|
||||
);
|
||||
}
|
||||
|
||||
public function tests(): Tests
|
||||
{
|
||||
return new Tests($this->xmlWriter);
|
||||
}
|
||||
|
||||
public function getWriter(): XMLWriter
|
||||
{
|
||||
return $this->xmlWriter;
|
||||
}
|
||||
|
||||
public function startProject(): void
|
||||
{
|
||||
$this->xmlWriter->startElement('project');
|
||||
$this->xmlWriter->writeAttribute('source', $this->directory);
|
||||
}
|
||||
|
||||
public function finalize(): void
|
||||
{
|
||||
$this->xmlWriter->endElement();
|
||||
$this->xmlWriter->endDocument();
|
||||
$this->xmlWriter->flush();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use function basename;
|
||||
use function dirname;
|
||||
use DOMDocument;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Report extends File
|
||||
{
|
||||
private readonly string $name;
|
||||
private readonly string $sha1;
|
||||
|
||||
public function __construct(XMLWriter $xmlWriter, string $name, string $sha1)
|
||||
{
|
||||
/*
|
||||
$dom = new DOMDocument;
|
||||
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="https://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
|
||||
|
||||
$contextNode = $dom->getElementsByTagNameNS(
|
||||
Facade::XML_NAMESPACE,
|
||||
'file',
|
||||
)->item(0);
|
||||
*/
|
||||
parent::__construct($xmlWriter);
|
||||
|
||||
$this->name = $name;
|
||||
$this->sha1 = $sha1;
|
||||
|
||||
$xmlWriter->startDocument();
|
||||
$xmlWriter->startElement('phpunit');
|
||||
$xmlWriter->writeAttribute('xmlns', Facade::XML_NAMESPACE);
|
||||
$xmlWriter->startElement('file');
|
||||
$xmlWriter->writeAttribute('name', basename($this->name));
|
||||
$xmlWriter->writeAttribute('path', dirname($this->name));
|
||||
$xmlWriter->writeAttribute('hash', $this->sha1);
|
||||
}
|
||||
|
||||
public function finalize(): void
|
||||
{
|
||||
$this->xmlWriter->endElement();
|
||||
$this->xmlWriter->endElement();
|
||||
|
||||
$this->xmlWriter->endDocument();
|
||||
$this->xmlWriter->flush();
|
||||
}
|
||||
|
||||
public function functionObject(
|
||||
string $name,
|
||||
string $signature,
|
||||
string $start,
|
||||
?string $end,
|
||||
string $executable,
|
||||
string $executed,
|
||||
string $coverage,
|
||||
string $crap
|
||||
): void {
|
||||
new Method(
|
||||
$this->xmlWriter,
|
||||
$name,
|
||||
$signature,
|
||||
$start,
|
||||
$end,
|
||||
$executable,
|
||||
$executed,
|
||||
$coverage,
|
||||
$crap,
|
||||
);
|
||||
}
|
||||
|
||||
public function classObject(
|
||||
string $name,
|
||||
string $namespace,
|
||||
int $start,
|
||||
int $executable,
|
||||
int $executed,
|
||||
float $crap
|
||||
): Unit {
|
||||
return new Unit($this->xmlWriter, $name, $namespace, $start, $executable, $executed, $crap);
|
||||
}
|
||||
|
||||
public function traitObject(
|
||||
string $name,
|
||||
string $namespace,
|
||||
int $start,
|
||||
int $executable,
|
||||
int $executed,
|
||||
float $crap
|
||||
): Unit {
|
||||
return new Unit($this->xmlWriter, $name, $namespace, $start, $executable, $executed, $crap);
|
||||
}
|
||||
|
||||
public function source(): Source
|
||||
{
|
||||
return new Source($this->xmlWriter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use TheSeer\Tokenizer\NamespaceUri;
|
||||
use TheSeer\Tokenizer\Tokenizer;
|
||||
use TheSeer\Tokenizer\XMLSerializer;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final readonly class Source
|
||||
{
|
||||
private XMLWriter $xmlWriter;
|
||||
|
||||
public function __construct(XMLWriter $xmlWriter)
|
||||
{
|
||||
$this->xmlWriter = $xmlWriter;
|
||||
}
|
||||
|
||||
public function setSourceCode(string $source): void
|
||||
{
|
||||
$tokens = (new Tokenizer)->parse($source);
|
||||
(new XMLSerializer(new NamespaceUri(Facade::XML_NAMESPACE)))->appendToWriter($this->xmlWriter, $tokens);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use function sprintf;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*
|
||||
* @phpstan-import-type TestType from CodeCoverage
|
||||
*/
|
||||
final readonly class Tests
|
||||
{
|
||||
private readonly XMLWriter $xmlWriter;
|
||||
|
||||
public function __construct(XMLWriter $xmlWriter)
|
||||
{
|
||||
$this->xmlWriter = $xmlWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TestType $result
|
||||
*/
|
||||
public function addTest(string $test, array $result): void
|
||||
{
|
||||
$this->xmlWriter->startElement('test');
|
||||
|
||||
$this->xmlWriter->writeAttribute('name', $test);
|
||||
$this->xmlWriter->writeAttribute('size', $result['size']);
|
||||
$this->xmlWriter->writeAttribute('status', $result['status']);
|
||||
$this->xmlWriter->writeAttribute('time', sprintf('%F', $result['time']));
|
||||
|
||||
$this->xmlWriter->endElement();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use function sprintf;
|
||||
use SebastianBergmann\CodeCoverage\Util\Percentage;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final readonly class Totals
|
||||
{
|
||||
private XMLWriter $xmlWriter;
|
||||
|
||||
public function __construct(XMLWriter $xmlWriter)
|
||||
{
|
||||
$this->xmlWriter = $xmlWriter;
|
||||
}
|
||||
|
||||
public function setNumLines(int $loc, int $cloc, int $ncloc, int $executable, int $executed): void
|
||||
{
|
||||
$this->xmlWriter->startElement('lines');
|
||||
$this->xmlWriter->writeAttribute('total', (string) $loc);
|
||||
$this->xmlWriter->writeAttribute('comments', (string) $cloc);
|
||||
$this->xmlWriter->writeAttribute('code', (string) $ncloc);
|
||||
$this->xmlWriter->writeAttribute('executable', (string) $executable);
|
||||
$this->xmlWriter->writeAttribute('executed', (string) $executed);
|
||||
$this->xmlWriter->writeAttribute(
|
||||
'percent',
|
||||
$executable === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($executed, $executable)->asFloat()),
|
||||
);
|
||||
$this->xmlWriter->endElement();
|
||||
}
|
||||
|
||||
public function setNumClasses(int $count, int $tested): void
|
||||
{
|
||||
$this->xmlWriter->startElement('classes');
|
||||
$this->xmlWriter->writeAttribute('count', (string) $count);
|
||||
$this->xmlWriter->writeAttribute('tested', (string) $tested);
|
||||
$this->xmlWriter->writeAttribute(
|
||||
'percent',
|
||||
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()),
|
||||
);
|
||||
$this->xmlWriter->endElement();
|
||||
}
|
||||
|
||||
public function setNumTraits(int $count, int $tested): void
|
||||
{
|
||||
$this->xmlWriter->startElement('traits');
|
||||
$this->xmlWriter->writeAttribute('count', (string) $count);
|
||||
$this->xmlWriter->writeAttribute('tested', (string) $tested);
|
||||
$this->xmlWriter->writeAttribute(
|
||||
'percent',
|
||||
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()),
|
||||
);
|
||||
$this->xmlWriter->endElement();
|
||||
}
|
||||
|
||||
public function setNumMethods(int $count, int $tested): void
|
||||
{
|
||||
$this->xmlWriter->startElement('methods');
|
||||
$this->xmlWriter->writeAttribute('count', (string) $count);
|
||||
$this->xmlWriter->writeAttribute('tested', (string) $tested);
|
||||
$this->xmlWriter->writeAttribute(
|
||||
'percent',
|
||||
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()),
|
||||
);
|
||||
$this->xmlWriter->endElement();
|
||||
}
|
||||
|
||||
public function setNumFunctions(int $count, int $tested): void
|
||||
{
|
||||
$this->xmlWriter->startElement('functions');
|
||||
$this->xmlWriter->writeAttribute('count', (string) $count);
|
||||
$this->xmlWriter->writeAttribute('tested', (string) $tested);
|
||||
$this->xmlWriter->writeAttribute(
|
||||
'percent',
|
||||
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()),
|
||||
);
|
||||
$this->xmlWriter->endElement();
|
||||
}
|
||||
|
||||
public function getWriter(): XMLWriter
|
||||
{
|
||||
return $this->xmlWriter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?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 SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final readonly class Unit
|
||||
{
|
||||
private XMLWriter $xmlWriter;
|
||||
|
||||
public function __construct(
|
||||
XMLWriter $xmlWriter,
|
||||
string $name,
|
||||
string $namespace,
|
||||
int $start,
|
||||
int $executable,
|
||||
int $executed,
|
||||
float $crap
|
||||
) {
|
||||
$this->xmlWriter = $xmlWriter;
|
||||
|
||||
$this->xmlWriter->writeAttribute('name', $name);
|
||||
$this->xmlWriter->writeAttribute('start', (string) $start);
|
||||
$this->xmlWriter->writeAttribute('executable', (string) $executable);
|
||||
$this->xmlWriter->writeAttribute('executed', (string) $executed);
|
||||
$this->xmlWriter->writeAttribute('crap', (string) $crap);
|
||||
|
||||
$this->xmlWriter->startElement('namespace');
|
||||
$this->xmlWriter->writeAttribute('name', $namespace);
|
||||
$this->xmlWriter->endElement();
|
||||
}
|
||||
|
||||
public function addMethod(
|
||||
string $name,
|
||||
string $signature,
|
||||
string $start,
|
||||
?string $end,
|
||||
string $executable,
|
||||
string $executed,
|
||||
string $coverage,
|
||||
string $crap
|
||||
): void {
|
||||
new Method(
|
||||
$this->xmlWriter,
|
||||
$name,
|
||||
$signature,
|
||||
$start,
|
||||
$end,
|
||||
$executable,
|
||||
$executed,
|
||||
$coverage,
|
||||
$crap,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user