mirror of
https://github.com/Dannecron/coverage-merger.git
synced 2025-12-26 00:02:35 +03:00
create merge clover coverage command
This commit is contained in:
239
src/Clover/Renderer.php
Normal file
239
src/Clover/Renderer.php
Normal file
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dannecron\CoverageMerger\Clover;
|
||||
|
||||
use Dannecron\CoverageMerger\Clover\Dto\Accumulator;
|
||||
use Dannecron\CoverageMerger\Clover\Dto\ClassDto;
|
||||
use Dannecron\CoverageMerger\Clover\Dto\FileDto;
|
||||
use Dannecron\CoverageMerger\Clover\Dto\LineDto;
|
||||
use Dannecron\CoverageMerger\Clover\Dto\Metrics;
|
||||
|
||||
class Renderer
|
||||
{
|
||||
/**
|
||||
* @param Accumulator $accumulator
|
||||
* @return array
|
||||
* @throws \DOMException
|
||||
*/
|
||||
public function renderAccumulator(Accumulator $accumulator): array
|
||||
{
|
||||
$files = $accumulator->getFiles();
|
||||
\ksort($files);
|
||||
|
||||
$xmlDocument = new \DOMDocument('1.0', 'UTF-8');
|
||||
|
||||
$xmlCoverage = $xmlDocument->createElement('coverage');
|
||||
$xmlCoverage->setAttribute('generated', (string)\time());
|
||||
$xmlDocument->appendChild($xmlCoverage);
|
||||
|
||||
$xmlProject = $xmlDocument->createElement('project');
|
||||
$xmlProject->setAttribute('timestamp', (string)\time());
|
||||
$xmlCoverage->appendChild($xmlProject);
|
||||
|
||||
$projectMetrics = Metrics::makeEmpty();
|
||||
$packages = [];
|
||||
|
||||
foreach ($files as $name => $file) {
|
||||
[$xmlFile, $fileMetrics] = $this->renderFile($xmlDocument, $file, $name);
|
||||
$projectMetrics = $projectMetrics->merge($fileMetrics);
|
||||
$packageName = $file->packageName;
|
||||
if ($packageName === null) {
|
||||
$xmlProject->appendChild($xmlFile);
|
||||
continue;
|
||||
}
|
||||
|
||||
$existedPackage = $packages[$packageName] ?? null;
|
||||
if ($existedPackage !== null) {
|
||||
$existedPackage[0]->appendChild($xmlFile);
|
||||
$existedPackage[1] = $existedPackage[1]->merge($fileMetrics);
|
||||
$packages[$packageName] = $existedPackage;
|
||||
continue;
|
||||
}
|
||||
|
||||
$xmlPackage = $xmlDocument->createElement('package');
|
||||
$xmlPackage->setAttribute('name', $packageName);
|
||||
$xmlProject->appendChild($xmlPackage);
|
||||
$xmlPackage->appendChild($xmlFile);
|
||||
|
||||
$packageMetrics = Metrics::makeEmpty();
|
||||
$packageMetrics->packageCount = 1;
|
||||
$packageMetrics = $packageMetrics->merge($fileMetrics);
|
||||
$packages[$packageName] = [$xmlPackage, $packageMetrics];
|
||||
}
|
||||
|
||||
foreach ($packages as $package) {
|
||||
/** @var Metrics $packageMetrics */
|
||||
$packageMetrics = $package[1];
|
||||
$package[0]->appendChild($this->renderMetricsPackage($xmlDocument, $packageMetrics));
|
||||
}
|
||||
|
||||
$xmlProject->appendChild($this->renderMetricsProject($xmlDocument, $projectMetrics));
|
||||
|
||||
return [$xmlDocument->saveXML(), $projectMetrics];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an XML element to represent these metrics under a file.
|
||||
* @param \DOMDocument $xmlDocument The parent document
|
||||
* @param Metrics $metrics
|
||||
* @return \DOMElement
|
||||
* @throws \DOMException
|
||||
*/
|
||||
private function renderMetrics(\DOMDocument $xmlDocument, Metrics $metrics): \DOMElement
|
||||
{
|
||||
$xmlMetrics = $xmlDocument->createElement('metrics');
|
||||
// We can't know the complexity, just set 0
|
||||
// (attribute required by the clover xml schema)
|
||||
$xmlMetrics->setAttribute('complexity', '0');
|
||||
|
||||
$xmlMetrics->setAttribute('elements', (string) $metrics->getElementCount());
|
||||
$xmlMetrics->setAttribute('coveredelements', (string) $metrics->getCoveredElementCount());
|
||||
$xmlMetrics->setAttribute('conditionals', (string) $metrics->conditionalCount);
|
||||
$xmlMetrics->setAttribute('coveredconditionals', (string) $metrics->coveredConditionalCount);
|
||||
$xmlMetrics->setAttribute('statements', (string) $metrics->statementCount);
|
||||
$xmlMetrics->setAttribute('coveredstatements', (string) $metrics->coveredStatementCount);
|
||||
$xmlMetrics->setAttribute('methods', (string) $metrics->methodCount);
|
||||
$xmlMetrics->setAttribute('coveredmethods', (string) $metrics->coveredMethodCount);
|
||||
$xmlMetrics->setAttribute('classes', (string) $metrics->classCount);
|
||||
|
||||
return $xmlMetrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an XML element to represent these metrics under a package.
|
||||
* Contains all the attributes of the file context plus the number of files.
|
||||
* @param \DOMDocument $xmlDocument The parent document.
|
||||
* @param Metrics $metrics
|
||||
* @return \DOMElement
|
||||
* @throws \DOMException
|
||||
*/
|
||||
private function renderMetricsPackage(\DOMDocument $xmlDocument, Metrics $metrics): \DOMElement
|
||||
{
|
||||
$xmlMetrics = $this->renderMetrics($xmlDocument, $metrics);
|
||||
$xmlMetrics->setAttribute('files', (string) $metrics->fileCount);
|
||||
|
||||
return $xmlMetrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an XML element to represent these metrics under a project.
|
||||
* Contains all the attributes of the package context plus the number of packages.
|
||||
* @param \DOMDocument $xmlDocument The parent document.
|
||||
* @param Metrics $metrics
|
||||
* @return \DOMElement
|
||||
* @throws \DOMException
|
||||
*/
|
||||
private function renderMetricsProject(\DOMDocument $xmlDocument, Metrics $metrics): \DOMElement
|
||||
{
|
||||
$xmlMetrics = $this->renderMetricsPackage($xmlDocument, $metrics);
|
||||
$xmlMetrics->setAttribute('packages', (string) $metrics->packageCount);
|
||||
|
||||
return $xmlMetrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMDocument $document
|
||||
* @param FileDto $fileDto
|
||||
* @param string $name
|
||||
* @return array{0:\DOMElement,1:Metrics}
|
||||
* @throws \DOMException
|
||||
*/
|
||||
private function renderFile(\DOMDocument $document, FileDto $fileDto, string $name): array
|
||||
{
|
||||
$xmlFile = $document->createElement('file');
|
||||
$xmlFile->setAttribute('name', $name);
|
||||
|
||||
$classes = $fileDto->getClasses();
|
||||
$lines = $fileDto->getLines();
|
||||
|
||||
// Metric counts
|
||||
$statementCount = 0;
|
||||
$coveredStatementCount = 0;
|
||||
$conditionalCount = 0;
|
||||
$coveredConditionalCount = 0;
|
||||
$methodCount = 0;
|
||||
$coveredMethodCount = 0;
|
||||
$classCount = \count($classes);
|
||||
|
||||
foreach ($classes as $class) {
|
||||
$xmlFile->appendChild($this->renderClass($document, $class));
|
||||
}
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$xmlFile->appendChild($this->renderLine($document, $line));
|
||||
$properties = $line->getProperties();
|
||||
|
||||
$covered = $line->getCount() > 0;
|
||||
$type = $properties['type'] ?? 'stmt';
|
||||
|
||||
if ($type === 'method') {
|
||||
$methodCount++;
|
||||
if ($covered) {
|
||||
$coveredMethodCount++;
|
||||
}
|
||||
} elseif ($type === 'stmt') {
|
||||
$statementCount++;
|
||||
if ($covered) {
|
||||
$coveredStatementCount++;
|
||||
}
|
||||
} elseif ($type === 'cond') {
|
||||
$conditionalCount++;
|
||||
if ($covered) {
|
||||
$coveredConditionalCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$metrics = new Metrics(
|
||||
$statementCount,
|
||||
$coveredStatementCount,
|
||||
$conditionalCount,
|
||||
$coveredConditionalCount,
|
||||
$methodCount,
|
||||
$coveredMethodCount,
|
||||
$classCount,
|
||||
1
|
||||
);
|
||||
|
||||
$xmlFile->appendChild($this->renderMetrics($document, $metrics));
|
||||
|
||||
return [$xmlFile, $metrics];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMDocument $document
|
||||
* @param ClassDto $class
|
||||
* @return \DOMElement
|
||||
* @throws \DOMException
|
||||
*/
|
||||
private function renderClass(\DOMDocument $document, ClassDto $class): \DOMElement
|
||||
{
|
||||
$xmlClass = $document->createElement('class');
|
||||
|
||||
foreach ($class->getProperties() as $key => $value) {
|
||||
$xmlClass->setAttribute($key, $value);
|
||||
}
|
||||
|
||||
return $xmlClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMDocument $document
|
||||
* @param LineDto $line
|
||||
* @return \DOMElement
|
||||
* @throws \DOMException
|
||||
*/
|
||||
private function renderLine(\DOMDocument $document, LineDto $line): \DOMElement
|
||||
{
|
||||
$xmlLine = $document->createElement('line');
|
||||
foreach ($line->getProperties() as $key => $value) {
|
||||
$xmlLine->setAttribute($key, $value);
|
||||
}
|
||||
|
||||
$xmlLine->setAttribute('count', (string) $line->getCount());
|
||||
|
||||
return $xmlLine;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user