Skip to content

Commit

Permalink
Tentatively implements #4288
Browse files Browse the repository at this point in the history
  • Loading branch information
theseer authored and sebastianbergmann committed Jul 27, 2020
1 parent 9640df0 commit 3f47a6a
Show file tree
Hide file tree
Showing 24 changed files with 579 additions and 7 deletions.
54 changes: 54 additions & 0 deletions src/TextUI/XmlConfiguration/Migration/MigrationBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?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 PHPUnit\TextUI\XmlConfiguration;

use function version_compare;

final class MigrationBuilder {

private const availableMigrations = [
'9.2' => [
IntroduceCoverageElement::class,
MoveAttributesFromRootToCoverage::class,
MoveAttributesFromFilterWhitelistToCoverage::class,
MoveWhitelistDirectoriesToCoverage::class,
MoveWhitelistExcludesToCoverage::class,
RemoveEmptyFilter::class,
CoverageCloverToReport::class,
CoverageCrap4jToReport::class,
CoverageHtmlToReport::class,
CoveragePhpToReport::class,
CoverageTextToReport::class,
CoverageXmlToReport::class,
ConvertLogTypes::class
]
];

public function build(string $fromVersion): array
{
if (version_compare($fromVersion, '9.2', '<')) {
throw new MigrationBuilderException('Versions before 9.2 are not supported.');
}

$stack = [];

foreach(self::availableMigrations as $version => $migrations) {
if (version_compare($version, $fromVersion, '<')) {
continue;
}

foreach($migrations as $migration) {
$stack[] = new $migration;
}
}

return $stack;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use RuntimeException;

class MigrationBuilderException extends RuntimeException implements \PHPUnit\Exception
{

}
9 changes: 9 additions & 0 deletions src/TextUI/XmlConfiguration/Migration/MigrationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use RuntimeException;

class MigrationException extends RuntimeException implements \PHPUnit\Exception
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMDocument;
use DOMElement;

class ConvertLogTypes implements Migration {

public function migrate(DOMDocument $document): void {

$logging = $document->getElementsByTagName('logging')->item(0);
if (!$logging instanceof DOMElement) {
return;
}
$types = [
'junit' => 'junit',
'teamcity' => 'teamcity',
'testdox-html' => 'testdoxHtml',
'testdox-text' => 'testdoxText',
'testdox-xml' => 'testdoxXml',
'plain' => 'text'
];

$logNodes = [];
foreach($logging->getElementsByTagName('log') as $logNode) {
if (!isset($types[$logNode->getAttribute('type')])) {
continue;
}

$logNodes[] = $logNode;
}

foreach($logNodes as $oldNode) {
$newLogNode = $document->createElement($types[$oldNode->getAttribute('type')]);
$newLogNode->setAttribute('outputFile', $oldNode->getAttribute('target'));

$logging->replaceChild($newLogNode, $oldNode);
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMElement;

class CoverageCloverToReport extends LogToReportMigration {

protected function forType(): string {
return 'coverage-clover';
}

protected function toReportFormat(DOMElement $logNode): DOMElement {
$clover = $logNode->ownerDocument->createElement('clover');
$clover->setAttribute('outputFile', $logNode->getAttribute('target'));

return $clover;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMElement;

class CoverageCrap4jToReport extends LogToReportMigration {

protected function forType(): string {
return 'coverage-crap4j';
}

protected function toReportFormat(DOMElement $logNode): DOMElement {
$crap4j = $logNode->ownerDocument->createElement('crap4j');
$crap4j->setAttribute('outputFile', $logNode->getAttribute('target'));

$this->migrateAttributes($logNode, $crap4j, ['threshold']);

return $crap4j;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMElement;

class CoverageHtmlToReport extends LogToReportMigration {

protected function forType(): string {
return 'coverage-html';
}

protected function toReportFormat(DOMElement $logNode): DOMElement {
$html = $logNode->ownerDocument->createElement('html');
$html->setAttribute('outputDirectory', $logNode->getAttribute('target'));

$this->migrateAttributes($logNode, $html, ['lowUpperBound', 'highLowerBound']);

return $html;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMElement;

class CoveragePhpToReport extends LogToReportMigration {

protected function forType(): string {
return 'coverage-php';
}

protected function toReportFormat(DOMElement $logNode): DOMElement {
$php = $logNode->ownerDocument->createElement('php');
$php->setAttribute('outputFile', $logNode->getAttribute('target'));

return $php;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMElement;

class CoverageTextToReport extends LogToReportMigration {

protected function forType(): string {
return 'coverage-text';
}

protected function toReportFormat(DOMElement $logNode): DOMElement {
$text = $logNode->ownerDocument->createElement('text');
$text->setAttribute('outputFile', $logNode->getAttribute('target'));

$this->migrateAttributes($logNode, $text, ['showUncoveredFiles', 'showOnlySummary']);

return $text;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMElement;

class CoverageXmlToReport extends LogToReportMigration {

protected function forType(): string {
return 'coverage-xml';
}

protected function toReportFormat(DOMElement $logNode): DOMElement {
$xml = $logNode->ownerDocument->createElement('xml');
$xml->setAttribute('outputDirectory', $logNode->getAttribute('target'));

return $xml;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMDocument;
use DOMElement;

class IntroduceCoverageElement implements Migration
{
/**
* @var DOMDocument
*/
private $document;

/**
* @var DOMElement
*/
private $coverage;

public function migrate(DOMDocument $document): void
{
$this->document = $document;
$this->coverage = $document->createElement('coverage');

$this->document->documentElement->insertBefore(
$this->coverage,
$this->document->documentElement->firstChild
);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMDocument;
use DOMElement;
use DOMXPath;

abstract class LogToReportMigration implements Migration {

public function migrate(DOMDocument $document): void {
/** @var ?DOMElement $coverage */
$coverage = $document->getElementsByTagName('coverage')->item(0);
if (!$coverage instanceof DOMElement) {
throw new MigrationException('Unexpected state - No coverage element');
}

$logNode = $this->findLogNode($document);
if ($logNode === null) {
return;
}

$reportChild = $this->toReportFormat($logNode);

$report = $coverage->getElementsByTagName('report')->item(0);
if ($report === null) {
$report = $coverage->appendChild($document->createElement('report'));
}

$report->appendChild($reportChild);
$logNode->parentNode->removeChild($logNode);
}

private function findLogNode($document): ?DOMElement {
$logNode = (new DOMXPath($document))->query(
sprintf('//logging/log[@type="%s"]', $this->forType())
)->item(0);

if (!$logNode instanceof DOMElement) {
return null;
}

return $logNode;
}

protected function migrateAttributes(DOMElement $src, DOMElement $dest, array $attributes): void {
foreach($attributes as $attr) {
if (!$src->hasAttribute($attr)) {
continue;
}

$dest->setAttribute($attr, $src->getAttribute($attr));
$src->removeAttribute($attr);
}
}

abstract protected function forType(): string;
abstract protected function toReportFormat(DOMElement $logNode): DOMElement;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMDocument;

interface Migration
{
public function migrate(DOMDocument $document): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php declare(strict_types = 1);
namespace PHPUnit\TextUI\XmlConfiguration;

use DOMDocument;
use DOMElement;

class MoveAttributesFromFilterWhitelistToCoverage implements Migration {
public function migrate(DOMDocument $document): void {
$whitelist = $document->getElementsByTagName('whitelist')->item(0);
if (!$whitelist) {
return;
}

/** @var ?DOMElement $coverage */
$coverage = $document->getElementsByTagName('coverage')->item(0);
if (!$coverage instanceof DOMElement) {
throw new MigrationException('Unexpected state - No coverage element');
}

$map = [
'addUncoveredFilesFromWhitelist' => 'includeUncoveredFiles',
'processUncoveredFilesFromWhitelist' => 'processUncoveredFiles'
];

foreach($map as $old => $new) {
if (!$whitelist->hasAttribute($old)) {
continue;
}

$coverage->setAttribute($new, $whitelist->getAttribute($old));
$whitelist->removeAttribute($old);
}
}

}
Loading

0 comments on commit 3f47a6a

Please sign in to comment.