Laravel 5.6 updates
Travis config update Removed HHVM script as Laravel no longer support HHVM after releasing 5.3
This commit is contained in:
@@ -12,8 +12,8 @@ namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Runner\PhptTestCase;
|
||||
use PHPUnit\Util\Test;
|
||||
use SebastianBergmann\CodeCoverage\Driver\Driver;
|
||||
use SebastianBergmann\CodeCoverage\Driver\HHVM;
|
||||
use SebastianBergmann\CodeCoverage\Driver\PHPDBG;
|
||||
use SebastianBergmann\CodeCoverage\Driver\Xdebug;
|
||||
use SebastianBergmann\CodeCoverage\Node\Builder;
|
||||
@@ -24,7 +24,7 @@ use SebastianBergmann\Environment\Runtime;
|
||||
/**
|
||||
* Provides collection functionality for PHP code coverage information.
|
||||
*/
|
||||
class CodeCoverage
|
||||
final class CodeCoverage
|
||||
{
|
||||
/**
|
||||
* @var Driver
|
||||
@@ -82,7 +82,7 @@ class CodeCoverage
|
||||
private $ignoreDeprecatedCode = false;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
* @var PhptTestCase|string|TestCase
|
||||
*/
|
||||
private $currentId;
|
||||
|
||||
@@ -135,11 +135,6 @@ class CodeCoverage
|
||||
private $report;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Driver $driver
|
||||
* @param Filter $filter
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct(Driver $driver = null, Filter $filter = null)
|
||||
@@ -160,10 +155,8 @@ class CodeCoverage
|
||||
|
||||
/**
|
||||
* Returns the code coverage information as a graph of node objects.
|
||||
*
|
||||
* @return Directory
|
||||
*/
|
||||
public function getReport()
|
||||
public function getReport(): Directory
|
||||
{
|
||||
if ($this->report === null) {
|
||||
$builder = new Builder;
|
||||
@@ -177,7 +170,7 @@ class CodeCoverage
|
||||
/**
|
||||
* Clears collected code coverage data.
|
||||
*/
|
||||
public function clear()
|
||||
public function clear(): void
|
||||
{
|
||||
$this->isInitialized = false;
|
||||
$this->currentId = null;
|
||||
@@ -188,10 +181,8 @@ class CodeCoverage
|
||||
|
||||
/**
|
||||
* Returns the filter object used.
|
||||
*
|
||||
* @return Filter
|
||||
*/
|
||||
public function filter()
|
||||
public function filter(): Filter
|
||||
{
|
||||
return $this->filter;
|
||||
}
|
||||
@@ -199,12 +190,8 @@ class CodeCoverage
|
||||
/**
|
||||
* Returns the collected code coverage data.
|
||||
* Set $raw = true to bypass all filters.
|
||||
*
|
||||
* @param bool $raw
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData($raw = false)
|
||||
public function getData(bool $raw = false): array
|
||||
{
|
||||
if (!$raw && $this->addUncoveredFilesFromWhitelist) {
|
||||
$this->addUncoveredFilesFromWhitelist();
|
||||
@@ -215,10 +202,8 @@ class CodeCoverage
|
||||
|
||||
/**
|
||||
* Sets the coverage data.
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data)
|
||||
public function setData(array $data): void
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->report = null;
|
||||
@@ -226,20 +211,16 @@ class CodeCoverage
|
||||
|
||||
/**
|
||||
* Returns the test data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTests()
|
||||
public function getTests(): array
|
||||
{
|
||||
return $this->tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test data.
|
||||
*
|
||||
* @param array $tests
|
||||
*/
|
||||
public function setTests(array $tests)
|
||||
public function setTests(array $tests): void
|
||||
{
|
||||
$this->tests = $tests;
|
||||
}
|
||||
@@ -247,20 +228,13 @@ class CodeCoverage
|
||||
/**
|
||||
* Start collection of code coverage information.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param bool $clear
|
||||
* @param PhptTestCase|string|TestCase $id
|
||||
* @param bool $clear
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function start($id, $clear = false)
|
||||
public function start($id, bool $clear = false): void
|
||||
{
|
||||
if (!\is_bool($clear)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
if ($clear) {
|
||||
$this->clear();
|
||||
}
|
||||
@@ -277,25 +251,16 @@ class CodeCoverage
|
||||
/**
|
||||
* Stop collection of code coverage information.
|
||||
*
|
||||
* @param bool $append
|
||||
* @param mixed $linesToBeCovered
|
||||
* @param array $linesToBeUsed
|
||||
* @param bool $ignoreForceCoversAnnotation
|
||||
* @param array|false $linesToBeCovered
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
|
||||
* @throws MissingCoversAnnotationException
|
||||
* @throws CoveredCodeNotExecutedException
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function stop($append = true, $linesToBeCovered = [], array $linesToBeUsed = [], $ignoreForceCoversAnnotation = false)
|
||||
public function stop(bool $append = true, $linesToBeCovered = [], array $linesToBeUsed = [], bool $ignoreForceCoversAnnotation = false): array
|
||||
{
|
||||
if (!\is_bool($append)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
if (!\is_array($linesToBeCovered) && $linesToBeCovered !== false) {
|
||||
throw InvalidArgumentException::create(
|
||||
2,
|
||||
@@ -314,12 +279,8 @@ class CodeCoverage
|
||||
/**
|
||||
* Appends code coverage data.
|
||||
*
|
||||
* @param array $data
|
||||
* @param mixed $id
|
||||
* @param bool $append
|
||||
* @param mixed $linesToBeCovered
|
||||
* @param array $linesToBeUsed
|
||||
* @param bool $ignoreForceCoversAnnotation
|
||||
* @param PhptTestCase|string|TestCase $id
|
||||
* @param array|false $linesToBeCovered
|
||||
*
|
||||
* @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException
|
||||
* @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException
|
||||
@@ -328,7 +289,7 @@ class CodeCoverage
|
||||
* @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function append(array $data, $id = null, $append = true, $linesToBeCovered = [], array $linesToBeUsed = [], $ignoreForceCoversAnnotation = false)
|
||||
public function append(array $data, $id = null, bool $append = true, $linesToBeCovered = [], array $linesToBeUsed = [], bool $ignoreForceCoversAnnotation = false): void
|
||||
{
|
||||
if ($id === null) {
|
||||
$id = $this->currentId;
|
||||
@@ -338,7 +299,7 @@ class CodeCoverage
|
||||
throw new RuntimeException;
|
||||
}
|
||||
|
||||
$this->applyListsFilter($data);
|
||||
$this->applyWhitelistFilter($data);
|
||||
$this->applyIgnoredLinesFilter($data);
|
||||
$this->initializeFilesThatAreSeenTheFirstTime($data);
|
||||
|
||||
@@ -360,16 +321,16 @@ class CodeCoverage
|
||||
}
|
||||
|
||||
$size = 'unknown';
|
||||
$status = null;
|
||||
$status = -1;
|
||||
|
||||
if ($id instanceof TestCase) {
|
||||
$_size = $id->getSize();
|
||||
|
||||
if ($_size === \PHPUnit\Util\Test::SMALL) {
|
||||
if ($_size === Test::SMALL) {
|
||||
$size = 'small';
|
||||
} elseif ($_size === \PHPUnit\Util\Test::MEDIUM) {
|
||||
} elseif ($_size === Test::MEDIUM) {
|
||||
$size = 'medium';
|
||||
} elseif ($_size === \PHPUnit\Util\Test::LARGE) {
|
||||
} elseif ($_size === Test::LARGE) {
|
||||
$size = 'large';
|
||||
}
|
||||
|
||||
@@ -404,7 +365,7 @@ class CodeCoverage
|
||||
*
|
||||
* @param CodeCoverage $that
|
||||
*/
|
||||
public function merge(self $that)
|
||||
public function merge(self $that): void
|
||||
{
|
||||
$this->filter->setWhitelistedFiles(
|
||||
\array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles())
|
||||
@@ -419,15 +380,24 @@ class CodeCoverage
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($lines as $line => $data) {
|
||||
if ($data !== null) {
|
||||
if (!isset($this->data[$file][$line])) {
|
||||
$this->data[$file][$line] = $data;
|
||||
} else {
|
||||
$this->data[$file][$line] = \array_unique(
|
||||
\array_merge($this->data[$file][$line], $data)
|
||||
);
|
||||
}
|
||||
// we should compare the lines if any of two contains data
|
||||
$compareLineNumbers = \array_unique(
|
||||
\array_merge(
|
||||
\array_keys($this->data[$file]),
|
||||
\array_keys($that->data[$file])
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($compareLineNumbers as $line) {
|
||||
$thatPriority = $this->getLinePriority($that->data[$file], $line);
|
||||
$thisPriority = $this->getLinePriority($this->data[$file], $line);
|
||||
|
||||
if ($thatPriority > $thisPriority) {
|
||||
$this->data[$file][$line] = $that->data[$file][$line];
|
||||
} elseif ($thatPriority === $thisPriority && \is_array($this->data[$file][$line])) {
|
||||
$this->data[$file][$line] = \array_unique(
|
||||
\array_merge($this->data[$file][$line], $that->data[$file][$line])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,200 +406,104 @@ class CodeCoverage
|
||||
$this->report = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setCacheTokens($flag)
|
||||
public function setCacheTokens(bool $flag): void
|
||||
{
|
||||
if (!\is_bool($flag)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
$this->cacheTokens = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getCacheTokens()
|
||||
public function getCacheTokens(): bool
|
||||
{
|
||||
return $this->cacheTokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setCheckForUnintentionallyCoveredCode($flag)
|
||||
public function setCheckForUnintentionallyCoveredCode(bool $flag): void
|
||||
{
|
||||
if (!\is_bool($flag)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
$this->checkForUnintentionallyCoveredCode = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setForceCoversAnnotation($flag)
|
||||
public function setForceCoversAnnotation(bool $flag): void
|
||||
{
|
||||
if (!\is_bool($flag)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
$this->forceCoversAnnotation = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setCheckForMissingCoversAnnotation($flag)
|
||||
public function setCheckForMissingCoversAnnotation(bool $flag): void
|
||||
{
|
||||
if (!\is_bool($flag)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
$this->checkForMissingCoversAnnotation = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setCheckForUnexecutedCoveredCode($flag)
|
||||
public function setCheckForUnexecutedCoveredCode(bool $flag): void
|
||||
{
|
||||
if (!\is_bool($flag)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
$this->checkForUnexecutedCoveredCode = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setMapTestClassNameToCoveredClassName($flag)
|
||||
public function setAddUncoveredFilesFromWhitelist(bool $flag): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setAddUncoveredFilesFromWhitelist($flag)
|
||||
{
|
||||
if (!\is_bool($flag)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addUncoveredFilesFromWhitelist = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setProcessUncoveredFilesFromWhitelist($flag)
|
||||
public function setProcessUncoveredFilesFromWhitelist(bool $flag): void
|
||||
{
|
||||
if (!\is_bool($flag)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
$this->processUncoveredFilesFromWhitelist = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setDisableIgnoredLines($flag)
|
||||
public function setDisableIgnoredLines(bool $flag): void
|
||||
{
|
||||
if (!\is_bool($flag)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
$this->disableIgnoredLines = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setIgnoreDeprecatedCode($flag)
|
||||
public function setIgnoreDeprecatedCode(bool $flag): void
|
||||
{
|
||||
if (!\is_bool($flag)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
|
||||
$this->ignoreDeprecatedCode = $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $whitelist
|
||||
*/
|
||||
public function setUnintentionallyCoveredSubclassesWhitelist(array $whitelist)
|
||||
public function setUnintentionallyCoveredSubclassesWhitelist(array $whitelist): void
|
||||
{
|
||||
$this->unintentionallyCoveredSubclassesWhitelist = $whitelist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the @covers annotation filtering.
|
||||
* Determine the priority for a line
|
||||
*
|
||||
* 1 = the line is not set
|
||||
* 2 = the line has not been tested
|
||||
* 3 = the line is dead code
|
||||
* 4 = the line has been tested
|
||||
*
|
||||
* During a merge, a higher number is better.
|
||||
*
|
||||
* @param array $data
|
||||
* @param mixed $linesToBeCovered
|
||||
* @param array $linesToBeUsed
|
||||
* @param bool $ignoreForceCoversAnnotation
|
||||
* @param int $line
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getLinePriority($data, $line)
|
||||
{
|
||||
if (!\array_key_exists($line, $data)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (\is_array($data[$line]) && \count($data[$line]) === 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if ($data[$line] === null) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the @covers annotation filtering.
|
||||
*
|
||||
* @param array|false $linesToBeCovered
|
||||
*
|
||||
* @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
|
||||
* @throws \ReflectionException
|
||||
* @throws MissingCoversAnnotationException
|
||||
* @throws UnintentionallyCoveredCodeException
|
||||
*/
|
||||
private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed, $ignoreForceCoversAnnotation)
|
||||
private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed, bool $ignoreForceCoversAnnotation): void
|
||||
{
|
||||
if ($linesToBeCovered === false ||
|
||||
($this->forceCoversAnnotation && empty($linesToBeCovered) && !$ignoreForceCoversAnnotation)) {
|
||||
@@ -664,12 +538,7 @@ class CodeCoverage
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the whitelist filtering.
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
private function applyListsFilter(array &$data)
|
||||
private function applyWhitelistFilter(array &$data): void
|
||||
{
|
||||
foreach (\array_keys($data) as $filename) {
|
||||
if ($this->filter->isFiltered($filename)) {
|
||||
@@ -679,13 +548,9 @@ class CodeCoverage
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the "ignored lines" filtering.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
|
||||
*/
|
||||
private function applyIgnoredLinesFilter(array &$data)
|
||||
private function applyIgnoredLinesFilter(array &$data): void
|
||||
{
|
||||
foreach (\array_keys($data) as $filename) {
|
||||
if (!$this->filter->isFile($filename)) {
|
||||
@@ -698,10 +563,7 @@ class CodeCoverage
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
private function initializeFilesThatAreSeenTheFirstTime(array $data)
|
||||
private function initializeFilesThatAreSeenTheFirstTime(array $data): void
|
||||
{
|
||||
foreach ($data as $file => $lines) {
|
||||
if (!isset($this->data[$file]) && $this->filter->isFile($file)) {
|
||||
@@ -715,9 +577,14 @@ class CodeCoverage
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes whitelisted files that are not covered.
|
||||
* @throws CoveredCodeNotExecutedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws MissingCoversAnnotationException
|
||||
* @throws RuntimeException
|
||||
* @throws UnintentionallyCoveredCodeException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
private function addUncoveredFilesFromWhitelist()
|
||||
private function addUncoveredFilesFromWhitelist(): void
|
||||
{
|
||||
$data = [];
|
||||
$uncoveredFiles = \array_diff(
|
||||
@@ -742,42 +609,26 @@ class CodeCoverage
|
||||
$this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lines of a source file that should be ignored.
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function getLinesToBeIgnored($filename)
|
||||
private function getLinesToBeIgnored(string $fileName): array
|
||||
{
|
||||
if (!\is_string($filename)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'string'
|
||||
);
|
||||
if (isset($this->ignoredLines[$fileName])) {
|
||||
return $this->ignoredLines[$fileName];
|
||||
}
|
||||
|
||||
if (isset($this->ignoredLines[$filename])) {
|
||||
return $this->ignoredLines[$filename];
|
||||
}
|
||||
$this->ignoredLines[$fileName] = [];
|
||||
|
||||
$this->ignoredLines[$filename] = [];
|
||||
|
||||
$lines = \file($filename);
|
||||
$lines = \file($fileName);
|
||||
|
||||
foreach ($lines as $index => $line) {
|
||||
if (!\trim($line)) {
|
||||
$this->ignoredLines[$filename][] = $index + 1;
|
||||
$this->ignoredLines[$fileName][] = $index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->cacheTokens) {
|
||||
$tokens = \PHP_Token_Stream_CachingFactory::get($filename);
|
||||
$tokens = \PHP_Token_Stream_CachingFactory::get($fileName);
|
||||
} else {
|
||||
$tokens = new \PHP_Token_Stream($filename);
|
||||
$tokens = new \PHP_Token_Stream($fileName);
|
||||
}
|
||||
|
||||
foreach ($tokens->getInterfaces() as $interface) {
|
||||
@@ -785,7 +636,7 @@ class CodeCoverage
|
||||
$interfaceEndLine = $interface['endLine'];
|
||||
|
||||
foreach (\range($interfaceStartLine, $interfaceEndLine) as $line) {
|
||||
$this->ignoredLines[$filename][] = $line;
|
||||
$this->ignoredLines[$fileName][] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -795,7 +646,7 @@ class CodeCoverage
|
||||
|
||||
if (empty($classOrTrait['methods'])) {
|
||||
foreach (\range($classOrTraitStartLine, $classOrTraitEndLine) as $line) {
|
||||
$this->ignoredLines[$filename][] = $line;
|
||||
$this->ignoredLines[$fileName][] = $line;
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -815,19 +666,19 @@ class CodeCoverage
|
||||
}
|
||||
|
||||
foreach (\range($classOrTraitStartLine, $firstMethodStartLine) as $line) {
|
||||
$this->ignoredLines[$filename][] = $line;
|
||||
$this->ignoredLines[$fileName][] = $line;
|
||||
}
|
||||
|
||||
foreach (\range($lastMethodEndLine + 1, $classOrTraitEndLine) as $line) {
|
||||
$this->ignoredLines[$filename][] = $line;
|
||||
$this->ignoredLines[$fileName][] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->disableIgnoredLines) {
|
||||
$this->ignoredLines[$filename] = array_unique($this->ignoredLines[$filename]);
|
||||
\sort($this->ignoredLines[$filename]);
|
||||
$this->ignoredLines[$fileName] = \array_unique($this->ignoredLines[$fileName]);
|
||||
\sort($this->ignoredLines[$fileName]);
|
||||
|
||||
return $this->ignoredLines[$filename];
|
||||
return $this->ignoredLines[$fileName];
|
||||
}
|
||||
|
||||
$ignore = false;
|
||||
@@ -863,13 +714,13 @@ class CodeCoverage
|
||||
}
|
||||
|
||||
for ($i = $start; $i < $end; $i++) {
|
||||
$this->ignoredLines[$filename][] = $i;
|
||||
$this->ignoredLines[$fileName][] = $i;
|
||||
}
|
||||
|
||||
// A DOC_COMMENT token or a COMMENT token starting with "/*"
|
||||
// does not contain the final \n character in its text
|
||||
if (isset($lines[$i - 1]) && 0 === \strpos($_token, '/*') && '*/' === \substr(\trim($lines[$i - 1]), -2)) {
|
||||
$this->ignoredLines[$filename][] = $i;
|
||||
$this->ignoredLines[$fileName][] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,38 +734,34 @@ class CodeCoverage
|
||||
|
||||
$docblock = $token->getDocblock();
|
||||
|
||||
$this->ignoredLines[$filename][] = $token->getLine();
|
||||
$this->ignoredLines[$fileName][] = $token->getLine();
|
||||
|
||||
if (\strpos($docblock, '@codeCoverageIgnore') || ($this->ignoreDeprecatedCode && \strpos($docblock, '@deprecated'))) {
|
||||
$endLine = $token->getEndLine();
|
||||
|
||||
for ($i = $token->getLine(); $i <= $endLine; $i++) {
|
||||
$this->ignoredLines[$filename][] = $i;
|
||||
$this->ignoredLines[$fileName][] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case \PHP_Token_ENUM::class:
|
||||
$this->ignoredLines[$filename][] = $token->getLine();
|
||||
|
||||
break;
|
||||
|
||||
/* @noinspection PhpMissingBreakStatementInspection */
|
||||
case \PHP_Token_NAMESPACE::class:
|
||||
$this->ignoredLines[$filename][] = $token->getEndLine();
|
||||
$this->ignoredLines[$fileName][] = $token->getEndLine();
|
||||
|
||||
// Intentional fallthrough
|
||||
case \PHP_Token_DECLARE::class:
|
||||
case \PHP_Token_OPEN_TAG::class:
|
||||
case \PHP_Token_CLOSE_TAG::class:
|
||||
case \PHP_Token_USE::class:
|
||||
$this->ignoredLines[$filename][] = $token->getLine();
|
||||
$this->ignoredLines[$fileName][] = $token->getLine();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($ignore) {
|
||||
$this->ignoredLines[$filename][] = $token->getLine();
|
||||
$this->ignoredLines[$fileName][] = $token->getLine();
|
||||
|
||||
if ($stop) {
|
||||
$ignore = false;
|
||||
@@ -923,27 +770,23 @@ class CodeCoverage
|
||||
}
|
||||
}
|
||||
|
||||
$this->ignoredLines[$filename][] = \count($lines) + 1;
|
||||
$this->ignoredLines[$fileName][] = \count($lines) + 1;
|
||||
|
||||
$this->ignoredLines[$filename] = \array_unique(
|
||||
$this->ignoredLines[$filename]
|
||||
$this->ignoredLines[$fileName] = \array_unique(
|
||||
$this->ignoredLines[$fileName]
|
||||
);
|
||||
|
||||
$this->ignoredLines[$filename] = array_unique($this->ignoredLines[$filename]);
|
||||
\sort($this->ignoredLines[$filename]);
|
||||
$this->ignoredLines[$fileName] = \array_unique($this->ignoredLines[$fileName]);
|
||||
\sort($this->ignoredLines[$fileName]);
|
||||
|
||||
return $this->ignoredLines[$filename];
|
||||
return $this->ignoredLines[$fileName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $linesToBeCovered
|
||||
* @param array $linesToBeUsed
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
* @throws UnintentionallyCoveredCodeException
|
||||
*/
|
||||
private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed)
|
||||
private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed): void
|
||||
{
|
||||
$allowedLines = $this->getAllowedLines(
|
||||
$linesToBeCovered,
|
||||
@@ -970,13 +813,9 @@ class CodeCoverage
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $linesToBeCovered
|
||||
* @param array $linesToBeUsed
|
||||
*
|
||||
* @throws CoveredCodeNotExecutedException
|
||||
*/
|
||||
private function performUnexecutedCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed)
|
||||
private function performUnexecutedCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed): void
|
||||
{
|
||||
$executedCodeUnits = $this->coverageToCodeUnits($data);
|
||||
$message = '';
|
||||
@@ -1004,13 +843,7 @@ class CodeCoverage
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $linesToBeCovered
|
||||
* @param array $linesToBeUsed
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed)
|
||||
private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed): array
|
||||
{
|
||||
$allowedLines = [];
|
||||
|
||||
@@ -1046,11 +879,9 @@ class CodeCoverage
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Driver
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function selectDriver()
|
||||
private function selectDriver(): Driver
|
||||
{
|
||||
$runtime = new Runtime;
|
||||
|
||||
@@ -1058,25 +889,18 @@ class CodeCoverage
|
||||
throw new RuntimeException('No code coverage driver available');
|
||||
}
|
||||
|
||||
if ($runtime->isHHVM()) {
|
||||
return new HHVM;
|
||||
}
|
||||
|
||||
if ($runtime->isPHPDBG()) {
|
||||
return new PHPDBG;
|
||||
}
|
||||
|
||||
return new Xdebug;
|
||||
if ($runtime->hasXdebug()) {
|
||||
return new Xdebug;
|
||||
}
|
||||
|
||||
throw new RuntimeException('No code coverage driver available');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $unintentionallyCoveredUnits
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits)
|
||||
private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits): array
|
||||
{
|
||||
$unintentionallyCoveredUnits = \array_unique($unintentionallyCoveredUnits);
|
||||
\sort($unintentionallyCoveredUnits);
|
||||
@@ -1103,23 +927,25 @@ class CodeCoverage
|
||||
}
|
||||
|
||||
/**
|
||||
* If we are processing uncovered files from whitelist,
|
||||
* we can initialize the data before we start to speed up the tests
|
||||
*
|
||||
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
|
||||
* @throws CoveredCodeNotExecutedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws MissingCoversAnnotationException
|
||||
* @throws RuntimeException
|
||||
* @throws UnintentionallyCoveredCodeException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
protected function initializeData()
|
||||
private function initializeData(): void
|
||||
{
|
||||
$this->isInitialized = true;
|
||||
|
||||
if ($this->processUncoveredFilesFromWhitelist) {
|
||||
$this->shouldCheckForDeadAndUnused = false;
|
||||
|
||||
$this->driver->start(true);
|
||||
$this->driver->start();
|
||||
|
||||
foreach ($this->filter->getWhitelist() as $file) {
|
||||
if ($this->filter->isFile($file)) {
|
||||
include_once($file);
|
||||
include_once $file;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1144,12 +970,7 @@ class CodeCoverage
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function coverageToCodeUnits(array $data)
|
||||
private function coverageToCodeUnits(array $data): array
|
||||
{
|
||||
$codeUnits = [];
|
||||
|
||||
@@ -1164,12 +985,7 @@ class CodeCoverage
|
||||
return \array_unique($codeUnits);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function linesToCodeUnits(array $data)
|
||||
private function linesToCodeUnits(array $data): array
|
||||
{
|
||||
$codeUnits = [];
|
||||
|
||||
|
@@ -20,33 +20,29 @@ interface Driver
|
||||
*
|
||||
* @see http://xdebug.org/docs/code_coverage
|
||||
*/
|
||||
const LINE_EXECUTED = 1;
|
||||
public const LINE_EXECUTED = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @see http://xdebug.org/docs/code_coverage
|
||||
*/
|
||||
const LINE_NOT_EXECUTED = -1;
|
||||
public const LINE_NOT_EXECUTED = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @see http://xdebug.org/docs/code_coverage
|
||||
*/
|
||||
const LINE_NOT_EXECUTABLE = -2;
|
||||
public const LINE_NOT_EXECUTABLE = -2;
|
||||
|
||||
/**
|
||||
* Start collection of code coverage information.
|
||||
*
|
||||
* @param bool $determineUnusedAndDead
|
||||
*/
|
||||
public function start($determineUnusedAndDead = true);
|
||||
public function start(bool $determineUnusedAndDead = true): void;
|
||||
|
||||
/**
|
||||
* Stop collection of code coverage information.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stop();
|
||||
public function stop(): array;
|
||||
}
|
||||
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of the php-code-coverage package.
|
||||
*
|
||||
* (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\Driver;
|
||||
|
||||
/**
|
||||
* Driver for HHVM's code coverage functionality.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class HHVM extends Xdebug
|
||||
{
|
||||
/**
|
||||
* Start collection of code coverage information.
|
||||
*
|
||||
* @param bool $determineUnusedAndDead
|
||||
*/
|
||||
public function start($determineUnusedAndDead = true)
|
||||
{
|
||||
\xdebug_start_code_coverage();
|
||||
}
|
||||
}
|
@@ -17,10 +17,10 @@ use SebastianBergmann\CodeCoverage\RuntimeException;
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class PHPDBG implements Driver
|
||||
final class PHPDBG implements Driver
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -39,39 +39,30 @@ class PHPDBG implements Driver
|
||||
|
||||
/**
|
||||
* Start collection of code coverage information.
|
||||
*
|
||||
* @param bool $determineUnusedAndDead
|
||||
*/
|
||||
public function start($determineUnusedAndDead = true)
|
||||
public function start(bool $determineUnusedAndDead = true): void
|
||||
{
|
||||
phpdbg_start_oplog();
|
||||
\phpdbg_start_oplog();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop collection of code coverage information.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stop()
|
||||
public function stop(): array
|
||||
{
|
||||
static $fetchedLines = [];
|
||||
|
||||
$dbgData = phpdbg_end_oplog();
|
||||
$dbgData = \phpdbg_end_oplog();
|
||||
|
||||
if ($fetchedLines == []) {
|
||||
$sourceLines = phpdbg_get_executable();
|
||||
$sourceLines = \phpdbg_get_executable();
|
||||
} else {
|
||||
$newFiles = \array_diff(
|
||||
\get_included_files(),
|
||||
\array_keys($fetchedLines)
|
||||
);
|
||||
$newFiles = \array_diff(\get_included_files(), \array_keys($fetchedLines));
|
||||
|
||||
$sourceLines = [];
|
||||
|
||||
if ($newFiles) {
|
||||
$sourceLines = phpdbg_get_executable(
|
||||
['files' => $newFiles]
|
||||
);
|
||||
} else {
|
||||
$sourceLines = [];
|
||||
$sourceLines = phpdbg_get_executable(['files' => $newFiles]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,13 +79,8 @@ class PHPDBG implements Driver
|
||||
|
||||
/**
|
||||
* Convert phpdbg based data into the format CodeCoverage expects
|
||||
*
|
||||
* @param array $sourceLines
|
||||
* @param array $dbgData
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function detectExecutedLines(array $sourceLines, array $dbgData)
|
||||
private function detectExecutedLines(array $sourceLines, array $dbgData): array
|
||||
{
|
||||
foreach ($dbgData as $file => $coveredLines) {
|
||||
foreach ($coveredLines as $lineNo => $numExecuted) {
|
||||
|
@@ -17,17 +17,15 @@ use SebastianBergmann\CodeCoverage\RuntimeException;
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Xdebug implements Driver
|
||||
final class Xdebug implements Driver
|
||||
{
|
||||
/**
|
||||
* Cache the number of lines for each file
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $cacheNumLines = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -35,20 +33,15 @@ class Xdebug implements Driver
|
||||
throw new RuntimeException('This driver requires Xdebug');
|
||||
}
|
||||
|
||||
if (\version_compare(\phpversion('xdebug'), '2.2.1', '>=') &&
|
||||
!\ini_get('xdebug.coverage_enable')) {
|
||||
throw new RuntimeException(
|
||||
'xdebug.coverage_enable=On has to be set in php.ini'
|
||||
);
|
||||
if (!\ini_get('xdebug.coverage_enable')) {
|
||||
throw new RuntimeException('xdebug.coverage_enable=On has to be set in php.ini');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start collection of code coverage information.
|
||||
*
|
||||
* @param bool $determineUnusedAndDead
|
||||
*/
|
||||
public function start($determineUnusedAndDead = true)
|
||||
public function start(bool $determineUnusedAndDead = true): void
|
||||
{
|
||||
if ($determineUnusedAndDead) {
|
||||
\xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
|
||||
@@ -59,23 +52,17 @@ class Xdebug implements Driver
|
||||
|
||||
/**
|
||||
* Stop collection of code coverage information.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stop()
|
||||
public function stop(): array
|
||||
{
|
||||
$data = \xdebug_get_code_coverage();
|
||||
|
||||
\xdebug_stop_code_coverage();
|
||||
|
||||
return $this->cleanup($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function cleanup(array $data)
|
||||
private function cleanup(array $data): array
|
||||
{
|
||||
foreach (\array_keys($data) as $file) {
|
||||
unset($data[$file][0]);
|
||||
@@ -94,24 +81,19 @@ class Xdebug implements Driver
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getNumberOfLinesInFile($file)
|
||||
private function getNumberOfLinesInFile(string $fileName): int
|
||||
{
|
||||
if (!isset($this->cacheNumLines[$file])) {
|
||||
$buffer = \file_get_contents($file);
|
||||
if (!isset($this->cacheNumLines[$fileName])) {
|
||||
$buffer = \file_get_contents($fileName);
|
||||
$lines = \substr_count($buffer, "\n");
|
||||
|
||||
if (\substr($buffer, -1) !== "\n") {
|
||||
$lines++;
|
||||
}
|
||||
|
||||
$this->cacheNumLines[$file] = $lines;
|
||||
$this->cacheNumLines[$fileName] = $lines;
|
||||
}
|
||||
|
||||
return $this->cacheNumLines[$file];
|
||||
return $this->cacheNumLines[$fileName];
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,6 @@ namespace SebastianBergmann\CodeCoverage;
|
||||
/**
|
||||
* Exception that is raised when covered code is not executed.
|
||||
*/
|
||||
class CoveredCodeNotExecutedException extends RuntimeException
|
||||
final class CoveredCodeNotExecutedException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements Exception
|
||||
final class InvalidArgumentException extends \InvalidArgumentException implements Exception
|
||||
{
|
||||
/**
|
||||
* @param int $argument
|
||||
@@ -19,7 +19,7 @@ class InvalidArgumentException extends \InvalidArgumentException implements Exce
|
||||
*
|
||||
* @return InvalidArgumentException
|
||||
*/
|
||||
public static function create($argument, $type, $value = null)
|
||||
public static function create($argument, $type, $value = null): self
|
||||
{
|
||||
$stack = \debug_backtrace(0);
|
||||
|
||||
|
@@ -13,6 +13,6 @@ namespace SebastianBergmann\CodeCoverage;
|
||||
/**
|
||||
* Exception that is raised when @covers must be used but is not.
|
||||
*/
|
||||
class MissingCoversAnnotationException extends RuntimeException
|
||||
final class MissingCoversAnnotationException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ namespace SebastianBergmann\CodeCoverage;
|
||||
/**
|
||||
* Exception that is raised when code is unintentionally covered.
|
||||
*/
|
||||
class UnintentionallyCoveredCodeException extends RuntimeException
|
||||
final class UnintentionallyCoveredCodeException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
@@ -33,7 +33,7 @@ class UnintentionallyCoveredCodeException extends RuntimeException
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getUnintentionallyCoveredUnits()
|
||||
public function getUnintentionallyCoveredUnits(): array
|
||||
{
|
||||
return $this->unintentionallyCoveredUnits;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ class UnintentionallyCoveredCodeException extends RuntimeException
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function toString()
|
||||
private function toString(): string
|
||||
{
|
||||
$message = '';
|
||||
|
||||
|
62
vendor/phpunit/php-code-coverage/src/Filter.php
vendored
62
vendor/phpunit/php-code-coverage/src/Filter.php
vendored
@@ -10,10 +10,12 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
|
||||
|
||||
/**
|
||||
* Filter for whitelisting of code coverage information.
|
||||
*/
|
||||
class Filter
|
||||
final class Filter
|
||||
{
|
||||
/**
|
||||
* Source files that are whitelisted.
|
||||
@@ -24,14 +26,10 @@ class Filter
|
||||
|
||||
/**
|
||||
* Adds a directory to the whitelist (recursively).
|
||||
*
|
||||
* @param string $directory
|
||||
* @param string $suffix
|
||||
* @param string $prefix
|
||||
*/
|
||||
public function addDirectoryToWhitelist($directory, $suffix = '.php', $prefix = '')
|
||||
public function addDirectoryToWhitelist(string $directory, string $suffix = '.php', string $prefix = ''): void
|
||||
{
|
||||
$facade = new \File_Iterator_Facade;
|
||||
$facade = new FileIteratorFacade;
|
||||
$files = $facade->getFilesAsArray($directory, $suffix, $prefix);
|
||||
|
||||
foreach ($files as $file) {
|
||||
@@ -41,10 +39,8 @@ class Filter
|
||||
|
||||
/**
|
||||
* Adds a file to the whitelist.
|
||||
*
|
||||
* @param string $filename
|
||||
*/
|
||||
public function addFileToWhitelist($filename)
|
||||
public function addFileToWhitelist(string $filename): void
|
||||
{
|
||||
$this->whitelistedFiles[\realpath($filename)] = true;
|
||||
}
|
||||
@@ -52,9 +48,9 @@ class Filter
|
||||
/**
|
||||
* Adds files to the whitelist.
|
||||
*
|
||||
* @param array $files
|
||||
* @param string[] $files
|
||||
*/
|
||||
public function addFilesToWhitelist(array $files)
|
||||
public function addFilesToWhitelist(array $files): void
|
||||
{
|
||||
foreach ($files as $file) {
|
||||
$this->addFileToWhitelist($file);
|
||||
@@ -63,14 +59,10 @@ class Filter
|
||||
|
||||
/**
|
||||
* Removes a directory from the whitelist (recursively).
|
||||
*
|
||||
* @param string $directory
|
||||
* @param string $suffix
|
||||
* @param string $prefix
|
||||
*/
|
||||
public function removeDirectoryFromWhitelist($directory, $suffix = '.php', $prefix = '')
|
||||
public function removeDirectoryFromWhitelist(string $directory, string $suffix = '.php', string $prefix = ''): void
|
||||
{
|
||||
$facade = new \File_Iterator_Facade;
|
||||
$facade = new FileIteratorFacade;
|
||||
$files = $facade->getFilesAsArray($directory, $suffix, $prefix);
|
||||
|
||||
foreach ($files as $file) {
|
||||
@@ -80,10 +72,8 @@ class Filter
|
||||
|
||||
/**
|
||||
* Removes a file from the whitelist.
|
||||
*
|
||||
* @param string $filename
|
||||
*/
|
||||
public function removeFileFromWhitelist($filename)
|
||||
public function removeFileFromWhitelist(string $filename): void
|
||||
{
|
||||
$filename = \realpath($filename);
|
||||
|
||||
@@ -92,14 +82,10 @@ class Filter
|
||||
|
||||
/**
|
||||
* Checks whether a filename is a real filename.
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFile($filename)
|
||||
public function isFile(string $filename): bool
|
||||
{
|
||||
if ($filename == '-' ||
|
||||
if ($filename === '-' ||
|
||||
\strpos($filename, 'vfs://') === 0 ||
|
||||
\strpos($filename, 'xdebug://debug-eval') !== false ||
|
||||
\strpos($filename, 'eval()\'d code') !== false ||
|
||||
@@ -115,12 +101,8 @@ class Filter
|
||||
|
||||
/**
|
||||
* Checks whether or not a file is filtered.
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFiltered($filename)
|
||||
public function isFiltered(string $filename): bool
|
||||
{
|
||||
if (!$this->isFile($filename)) {
|
||||
return true;
|
||||
@@ -134,19 +116,17 @@ class Filter
|
||||
/**
|
||||
* Returns the list of whitelisted files.
|
||||
*
|
||||
* @return array
|
||||
* @return string[]
|
||||
*/
|
||||
public function getWhitelist()
|
||||
public function getWhitelist(): array
|
||||
{
|
||||
return \array_keys($this->whitelistedFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this filter has a whitelist.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasWhitelist()
|
||||
public function hasWhitelist(): bool
|
||||
{
|
||||
return !empty($this->whitelistedFiles);
|
||||
}
|
||||
@@ -154,19 +134,17 @@ class Filter
|
||||
/**
|
||||
* Returns the whitelisted files.
|
||||
*
|
||||
* @return array
|
||||
* @return string[]
|
||||
*/
|
||||
public function getWhitelistedFiles()
|
||||
public function getWhitelistedFiles(): array
|
||||
{
|
||||
return $this->whitelistedFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the whitelisted files.
|
||||
*
|
||||
* @param array $whitelistedFiles
|
||||
*/
|
||||
public function setWhitelistedFiles($whitelistedFiles)
|
||||
public function setWhitelistedFiles(array $whitelistedFiles): void
|
||||
{
|
||||
$this->whitelistedFiles = $whitelistedFiles;
|
||||
}
|
||||
|
@@ -42,13 +42,7 @@ abstract class AbstractNode implements \Countable
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name
|
||||
* @param AbstractNode $parent
|
||||
*/
|
||||
public function __construct($name, self $parent = null)
|
||||
public function __construct(string $name, self $parent = null)
|
||||
{
|
||||
if (\substr($name, -1) == '/') {
|
||||
$name = \substr($name, 0, -1);
|
||||
@@ -58,18 +52,12 @@ abstract class AbstractNode implements \Countable
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
public function getId(): string
|
||||
{
|
||||
if ($this->id === null) {
|
||||
$parent = $this->getParent();
|
||||
@@ -79,7 +67,7 @@ abstract class AbstractNode implements \Countable
|
||||
} else {
|
||||
$parentId = $parent->getId();
|
||||
|
||||
if ($parentId == 'index') {
|
||||
if ($parentId === 'index') {
|
||||
$this->id = \str_replace(':', '_', $this->name);
|
||||
} else {
|
||||
$this->id = $parentId . '/' . $this->name;
|
||||
@@ -90,10 +78,7 @@ abstract class AbstractNode implements \Countable
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
public function getPath(): string
|
||||
{
|
||||
if ($this->path === null) {
|
||||
if ($this->parent === null || $this->parent->getPath() === null || $this->parent->getPath() === false) {
|
||||
@@ -106,10 +91,7 @@ abstract class AbstractNode implements \Countable
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPathAsArray()
|
||||
public function getPathAsArray(): array
|
||||
{
|
||||
if ($this->pathArray === null) {
|
||||
if ($this->parent === null) {
|
||||
@@ -124,10 +106,7 @@ abstract class AbstractNode implements \Countable
|
||||
return $this->pathArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractNode
|
||||
*/
|
||||
public function getParent()
|
||||
public function getParent(): ?self
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
@@ -135,11 +114,9 @@ abstract class AbstractNode implements \Countable
|
||||
/**
|
||||
* Returns the percentage of classes that has been tested.
|
||||
*
|
||||
* @param bool $asString
|
||||
*
|
||||
* @return int
|
||||
* @return int|string
|
||||
*/
|
||||
public function getTestedClassesPercent($asString = true)
|
||||
public function getTestedClassesPercent(bool $asString = true)
|
||||
{
|
||||
return Util::percent(
|
||||
$this->getNumTestedClasses(),
|
||||
@@ -151,11 +128,9 @@ abstract class AbstractNode implements \Countable
|
||||
/**
|
||||
* Returns the percentage of traits that has been tested.
|
||||
*
|
||||
* @param bool $asString
|
||||
*
|
||||
* @return int
|
||||
* @return int|string
|
||||
*/
|
||||
public function getTestedTraitsPercent($asString = true)
|
||||
public function getTestedTraitsPercent(bool $asString = true)
|
||||
{
|
||||
return Util::percent(
|
||||
$this->getNumTestedTraits(),
|
||||
@@ -167,11 +142,9 @@ abstract class AbstractNode implements \Countable
|
||||
/**
|
||||
* Returns the percentage of classes and traits that has been tested.
|
||||
*
|
||||
* @param bool $asString
|
||||
*
|
||||
* @return int
|
||||
* @return int|string
|
||||
*/
|
||||
public function getTestedClassesAndTraitsPercent($asString = true)
|
||||
public function getTestedClassesAndTraitsPercent(bool $asString = true)
|
||||
{
|
||||
return Util::percent(
|
||||
$this->getNumTestedClassesAndTraits(),
|
||||
@@ -183,11 +156,9 @@ abstract class AbstractNode implements \Countable
|
||||
/**
|
||||
* Returns the percentage of functions that has been tested.
|
||||
*
|
||||
* @param bool $asString
|
||||
*
|
||||
* @return int
|
||||
* @return int|string
|
||||
*/
|
||||
public function getTestedFunctionsPercent($asString = true)
|
||||
public function getTestedFunctionsPercent(bool $asString = true)
|
||||
{
|
||||
return Util::percent(
|
||||
$this->getNumTestedFunctions(),
|
||||
@@ -199,11 +170,9 @@ abstract class AbstractNode implements \Countable
|
||||
/**
|
||||
* Returns the percentage of methods that has been tested.
|
||||
*
|
||||
* @param bool $asString
|
||||
*
|
||||
* @return int
|
||||
* @return int|string
|
||||
*/
|
||||
public function getTestedMethodsPercent($asString = true)
|
||||
public function getTestedMethodsPercent(bool $asString = true)
|
||||
{
|
||||
return Util::percent(
|
||||
$this->getNumTestedMethods(),
|
||||
@@ -215,11 +184,9 @@ abstract class AbstractNode implements \Countable
|
||||
/**
|
||||
* Returns the percentage of functions and methods that has been tested.
|
||||
*
|
||||
* @param bool $asString
|
||||
*
|
||||
* @return int
|
||||
* @return int|string
|
||||
*/
|
||||
public function getTestedFunctionsAndMethodsPercent($asString = true)
|
||||
public function getTestedFunctionsAndMethodsPercent(bool $asString = true)
|
||||
{
|
||||
return Util::percent(
|
||||
$this->getNumTestedFunctionsAndMethods(),
|
||||
@@ -231,11 +198,9 @@ abstract class AbstractNode implements \Countable
|
||||
/**
|
||||
* Returns the percentage of executed lines.
|
||||
*
|
||||
* @param bool $asString
|
||||
*
|
||||
* @return int
|
||||
* @return int|string
|
||||
*/
|
||||
public function getLineExecutedPercent($asString = true)
|
||||
public function getLineExecutedPercent(bool $asString = true)
|
||||
{
|
||||
return Util::percent(
|
||||
$this->getNumExecutedLines(),
|
||||
@@ -246,159 +211,119 @@ abstract class AbstractNode implements \Countable
|
||||
|
||||
/**
|
||||
* Returns the number of classes and traits.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumClassesAndTraits()
|
||||
public function getNumClassesAndTraits(): int
|
||||
{
|
||||
return $this->getNumClasses() + $this->getNumTraits();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of tested classes and traits.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedClassesAndTraits()
|
||||
public function getNumTestedClassesAndTraits(): int
|
||||
{
|
||||
return $this->getNumTestedClasses() + $this->getNumTestedTraits();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the classes and traits of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getClassesAndTraits()
|
||||
public function getClassesAndTraits(): array
|
||||
{
|
||||
return \array_merge($this->getClasses(), $this->getTraits());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of functions and methods.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumFunctionsAndMethods()
|
||||
public function getNumFunctionsAndMethods(): int
|
||||
{
|
||||
return $this->getNumFunctions() + $this->getNumMethods();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of tested functions and methods.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedFunctionsAndMethods()
|
||||
public function getNumTestedFunctionsAndMethods(): int
|
||||
{
|
||||
return $this->getNumTestedFunctions() + $this->getNumTestedMethods();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the functions and methods of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctionsAndMethods()
|
||||
public function getFunctionsAndMethods(): array
|
||||
{
|
||||
return \array_merge($this->getFunctions(), $this->getMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the classes of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getClasses();
|
||||
abstract public function getClasses(): array;
|
||||
|
||||
/**
|
||||
* Returns the traits of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getTraits();
|
||||
abstract public function getTraits(): array;
|
||||
|
||||
/**
|
||||
* Returns the functions of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getFunctions();
|
||||
abstract public function getFunctions(): array;
|
||||
|
||||
/**
|
||||
* Returns the LOC/CLOC/NCLOC of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getLinesOfCode();
|
||||
abstract public function getLinesOfCode(): array;
|
||||
|
||||
/**
|
||||
* Returns the number of executable lines.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumExecutableLines();
|
||||
abstract public function getNumExecutableLines(): int;
|
||||
|
||||
/**
|
||||
* Returns the number of executed lines.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumExecutedLines();
|
||||
abstract public function getNumExecutedLines(): int;
|
||||
|
||||
/**
|
||||
* Returns the number of classes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumClasses();
|
||||
abstract public function getNumClasses(): int;
|
||||
|
||||
/**
|
||||
* Returns the number of tested classes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumTestedClasses();
|
||||
abstract public function getNumTestedClasses(): int;
|
||||
|
||||
/**
|
||||
* Returns the number of traits.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumTraits();
|
||||
abstract public function getNumTraits(): int;
|
||||
|
||||
/**
|
||||
* Returns the number of tested traits.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumTestedTraits();
|
||||
abstract public function getNumTestedTraits(): int;
|
||||
|
||||
/**
|
||||
* Returns the number of methods.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumMethods();
|
||||
abstract public function getNumMethods(): int;
|
||||
|
||||
/**
|
||||
* Returns the number of tested methods.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumTestedMethods();
|
||||
abstract public function getNumTestedMethods(): int;
|
||||
|
||||
/**
|
||||
* Returns the number of functions.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumFunctions();
|
||||
abstract public function getNumFunctions(): int;
|
||||
|
||||
/**
|
||||
* Returns the number of tested functions.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNumTestedFunctions();
|
||||
abstract public function getNumTestedFunctions(): int;
|
||||
}
|
||||
|
@@ -12,14 +12,9 @@ namespace SebastianBergmann\CodeCoverage\Node;
|
||||
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
|
||||
class Builder
|
||||
final class Builder
|
||||
{
|
||||
/**
|
||||
* @param CodeCoverage $coverage
|
||||
*
|
||||
* @return Directory
|
||||
*/
|
||||
public function build(CodeCoverage $coverage)
|
||||
public function build(CodeCoverage $coverage): Directory
|
||||
{
|
||||
$files = $coverage->getData();
|
||||
$commonPath = $this->reducePaths($files);
|
||||
@@ -38,13 +33,7 @@ class Builder
|
||||
return $root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Directory $root
|
||||
* @param array $items
|
||||
* @param array $tests
|
||||
* @param bool $cacheTokens
|
||||
*/
|
||||
private function addItems(Directory $root, array $items, array $tests, $cacheTokens)
|
||||
private function addItems(Directory $root, array $items, array $tests, bool $cacheTokens): void
|
||||
{
|
||||
foreach ($items as $key => $value) {
|
||||
if (\substr($key, -2) == '/f') {
|
||||
@@ -99,12 +88,8 @@ class Builder
|
||||
* )
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @param array $files
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function buildDirectoryStructure($files)
|
||||
private function buildDirectoryStructure(array $files): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
@@ -114,10 +99,10 @@ class Builder
|
||||
$max = \count($path);
|
||||
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
$type = '';
|
||||
|
||||
if ($i == ($max - 1)) {
|
||||
$type = '/f';
|
||||
} else {
|
||||
$type = '';
|
||||
}
|
||||
|
||||
$pointer = &$pointer[$path[$i] . $type];
|
||||
@@ -165,12 +150,8 @@ class Builder
|
||||
* )
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @param array $files
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function reducePaths(&$files)
|
||||
private function reducePaths(array &$files): string
|
||||
{
|
||||
if (empty($files)) {
|
||||
return '.';
|
||||
@@ -179,7 +160,7 @@ class Builder
|
||||
$commonPath = '';
|
||||
$paths = \array_keys($files);
|
||||
|
||||
if (\count($files) == 1) {
|
||||
if (\count($files) === 1) {
|
||||
$commonPath = \dirname($paths[0]) . '/';
|
||||
$files[\basename($paths[0])] = $files[$paths[0]];
|
||||
|
||||
@@ -194,7 +175,7 @@ class Builder
|
||||
// strip phar:// prefixes
|
||||
if (\strpos($paths[$i], 'phar://') === 0) {
|
||||
$paths[$i] = \substr($paths[$i], 7);
|
||||
$paths[$i] = \strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
|
||||
$paths[$i] = \str_replace('/', DIRECTORY_SEPARATOR, $paths[$i]);
|
||||
}
|
||||
$paths[$i] = \explode(DIRECTORY_SEPARATOR, $paths[$i]);
|
||||
|
||||
|
@@ -15,7 +15,7 @@ use SebastianBergmann\CodeCoverage\InvalidArgumentException;
|
||||
/**
|
||||
* Represents a directory in the code coverage information tree.
|
||||
*/
|
||||
class Directory extends AbstractNode implements \IteratorAggregate
|
||||
final class Directory extends AbstractNode implements \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var AbstractNode[]
|
||||
@@ -50,7 +50,7 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $linesOfCode = null;
|
||||
private $linesOfCode;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
@@ -109,12 +109,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of files in/under this node.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
if ($this->numFiles == -1) {
|
||||
if ($this->numFiles === -1) {
|
||||
$this->numFiles = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -127,10 +125,8 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns an iterator for this node.
|
||||
*
|
||||
* @return \RecursiveIteratorIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
public function getIterator(): \RecursiveIteratorIterator
|
||||
{
|
||||
return new \RecursiveIteratorIterator(
|
||||
new Iterator($this),
|
||||
@@ -140,12 +136,8 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Adds a new directory.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Directory
|
||||
*/
|
||||
public function addDirectory($name)
|
||||
public function addDirectory(string $name): self
|
||||
{
|
||||
$directory = new self($name, $this);
|
||||
|
||||
@@ -158,24 +150,11 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
/**
|
||||
* Adds a new file.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $coverageData
|
||||
* @param array $testData
|
||||
* @param bool $cacheTokens
|
||||
*
|
||||
* @return File
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function addFile($name, array $coverageData, array $testData, $cacheTokens)
|
||||
public function addFile(string $name, array $coverageData, array $testData, bool $cacheTokens): File
|
||||
{
|
||||
$file = new File(
|
||||
$name,
|
||||
$this,
|
||||
$coverageData,
|
||||
$testData,
|
||||
$cacheTokens
|
||||
);
|
||||
$file = new File($name, $this, $coverageData, $testData, $cacheTokens);
|
||||
|
||||
$this->children[] = $file;
|
||||
$this->files[] = &$this->children[\count($this->children) - 1];
|
||||
@@ -188,40 +167,32 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the directories in this directory.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDirectories()
|
||||
public function getDirectories(): array
|
||||
{
|
||||
return $this->directories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the files in this directory.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFiles()
|
||||
public function getFiles(): array
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the child nodes of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChildNodes()
|
||||
public function getChildNodes(): array
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the classes of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getClasses()
|
||||
public function getClasses(): array
|
||||
{
|
||||
if ($this->classes === null) {
|
||||
$this->classes = [];
|
||||
@@ -239,10 +210,8 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the traits of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTraits()
|
||||
public function getTraits(): array
|
||||
{
|
||||
if ($this->traits === null) {
|
||||
$this->traits = [];
|
||||
@@ -260,10 +229,8 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the functions of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
public function getFunctions(): array
|
||||
{
|
||||
if ($this->functions === null) {
|
||||
$this->functions = [];
|
||||
@@ -281,10 +248,8 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the LOC/CLOC/NCLOC of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLinesOfCode()
|
||||
public function getLinesOfCode(): array
|
||||
{
|
||||
if ($this->linesOfCode === null) {
|
||||
$this->linesOfCode = ['loc' => 0, 'cloc' => 0, 'ncloc' => 0];
|
||||
@@ -303,12 +268,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of executable lines.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumExecutableLines()
|
||||
public function getNumExecutableLines(): int
|
||||
{
|
||||
if ($this->numExecutableLines == -1) {
|
||||
if ($this->numExecutableLines === -1) {
|
||||
$this->numExecutableLines = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -321,12 +284,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of executed lines.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumExecutedLines()
|
||||
public function getNumExecutedLines(): int
|
||||
{
|
||||
if ($this->numExecutedLines == -1) {
|
||||
if ($this->numExecutedLines === -1) {
|
||||
$this->numExecutedLines = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -339,12 +300,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of classes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumClasses()
|
||||
public function getNumClasses(): int
|
||||
{
|
||||
if ($this->numClasses == -1) {
|
||||
if ($this->numClasses === -1) {
|
||||
$this->numClasses = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -357,12 +316,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of tested classes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedClasses()
|
||||
public function getNumTestedClasses(): int
|
||||
{
|
||||
if ($this->numTestedClasses == -1) {
|
||||
if ($this->numTestedClasses === -1) {
|
||||
$this->numTestedClasses = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -375,12 +332,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of traits.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTraits()
|
||||
public function getNumTraits(): int
|
||||
{
|
||||
if ($this->numTraits == -1) {
|
||||
if ($this->numTraits === -1) {
|
||||
$this->numTraits = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -393,12 +348,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of tested traits.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedTraits()
|
||||
public function getNumTestedTraits(): int
|
||||
{
|
||||
if ($this->numTestedTraits == -1) {
|
||||
if ($this->numTestedTraits === -1) {
|
||||
$this->numTestedTraits = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -411,12 +364,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of methods.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumMethods()
|
||||
public function getNumMethods(): int
|
||||
{
|
||||
if ($this->numMethods == -1) {
|
||||
if ($this->numMethods === -1) {
|
||||
$this->numMethods = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -429,12 +380,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of tested methods.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedMethods()
|
||||
public function getNumTestedMethods(): int
|
||||
{
|
||||
if ($this->numTestedMethods == -1) {
|
||||
if ($this->numTestedMethods === -1) {
|
||||
$this->numTestedMethods = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -447,12 +396,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of functions.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumFunctions()
|
||||
public function getNumFunctions(): int
|
||||
{
|
||||
if ($this->numFunctions == -1) {
|
||||
if ($this->numFunctions === -1) {
|
||||
$this->numFunctions = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
@@ -465,12 +412,10 @@ class Directory extends AbstractNode implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the number of tested functions.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedFunctions()
|
||||
public function getNumTestedFunctions(): int
|
||||
{
|
||||
if ($this->numTestedFunctions == -1) {
|
||||
if ($this->numTestedFunctions === -1) {
|
||||
$this->numTestedFunctions = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
|
331
vendor/phpunit/php-code-coverage/src/Node/File.php
vendored
331
vendor/phpunit/php-code-coverage/src/Node/File.php
vendored
@@ -10,12 +10,10 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage\Node;
|
||||
|
||||
use SebastianBergmann\CodeCoverage\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Represents a file in the code coverage information tree.
|
||||
*/
|
||||
class File extends AbstractNode
|
||||
final class File extends AbstractNode
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
@@ -60,7 +58,7 @@ class File extends AbstractNode
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numClasses = null;
|
||||
private $numClasses;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
@@ -70,7 +68,7 @@ class File extends AbstractNode
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTraits = null;
|
||||
private $numTraits;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
@@ -80,27 +78,17 @@ class File extends AbstractNode
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numMethods = null;
|
||||
private $numMethods;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedMethods = null;
|
||||
private $numTestedMethods;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedFunctions = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $startLines = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $endLines = [];
|
||||
private $numTestedFunctions;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
@@ -108,25 +96,12 @@ class File extends AbstractNode
|
||||
private $cacheTokens;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name
|
||||
* @param AbstractNode $parent
|
||||
* @param array $coverageData
|
||||
* @param array $testData
|
||||
* @param bool $cacheTokens
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @var array
|
||||
*/
|
||||
public function __construct($name, AbstractNode $parent, array $coverageData, array $testData, $cacheTokens)
|
||||
{
|
||||
if (!\is_bool($cacheTokens)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'boolean'
|
||||
);
|
||||
}
|
||||
private $codeUnitsByLine = [];
|
||||
|
||||
public function __construct(string $name, AbstractNode $parent, array $coverageData, array $testData, bool $cacheTokens)
|
||||
{
|
||||
parent::__construct($name, $parent);
|
||||
|
||||
$this->coverageData = $coverageData;
|
||||
@@ -138,100 +113,80 @@ class File extends AbstractNode
|
||||
|
||||
/**
|
||||
* Returns the number of files in/under this node.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code coverage data of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCoverageData()
|
||||
public function getCoverageData(): array
|
||||
{
|
||||
return $this->coverageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the test data of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTestData()
|
||||
public function getTestData(): array
|
||||
{
|
||||
return $this->testData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the classes of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getClasses()
|
||||
public function getClasses(): array
|
||||
{
|
||||
return $this->classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the traits of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTraits()
|
||||
public function getTraits(): array
|
||||
{
|
||||
return $this->traits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the functions of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the LOC/CLOC/NCLOC of this node.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLinesOfCode()
|
||||
public function getLinesOfCode(): array
|
||||
{
|
||||
return $this->linesOfCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of executable lines.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumExecutableLines()
|
||||
public function getNumExecutableLines(): int
|
||||
{
|
||||
return $this->numExecutableLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of executed lines.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumExecutedLines()
|
||||
public function getNumExecutedLines(): int
|
||||
{
|
||||
return $this->numExecutedLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of classes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumClasses()
|
||||
public function getNumClasses(): int
|
||||
{
|
||||
if ($this->numClasses === null) {
|
||||
$this->numClasses = 0;
|
||||
@@ -252,20 +207,16 @@ class File extends AbstractNode
|
||||
|
||||
/**
|
||||
* Returns the number of tested classes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedClasses()
|
||||
public function getNumTestedClasses(): int
|
||||
{
|
||||
return $this->numTestedClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of traits.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTraits()
|
||||
public function getNumTraits(): int
|
||||
{
|
||||
if ($this->numTraits === null) {
|
||||
$this->numTraits = 0;
|
||||
@@ -286,20 +237,16 @@ class File extends AbstractNode
|
||||
|
||||
/**
|
||||
* Returns the number of tested traits.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedTraits()
|
||||
public function getNumTestedTraits(): int
|
||||
{
|
||||
return $this->numTestedTraits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of methods.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumMethods()
|
||||
public function getNumMethods(): int
|
||||
{
|
||||
if ($this->numMethods === null) {
|
||||
$this->numMethods = 0;
|
||||
@@ -326,10 +273,8 @@ class File extends AbstractNode
|
||||
|
||||
/**
|
||||
* Returns the number of tested methods.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedMethods()
|
||||
public function getNumTestedMethods(): int
|
||||
{
|
||||
if ($this->numTestedMethods === null) {
|
||||
$this->numTestedMethods = 0;
|
||||
@@ -337,7 +282,7 @@ class File extends AbstractNode
|
||||
foreach ($this->classes as $class) {
|
||||
foreach ($class['methods'] as $method) {
|
||||
if ($method['executableLines'] > 0 &&
|
||||
$method['coverage'] == 100) {
|
||||
$method['coverage'] === 100) {
|
||||
$this->numTestedMethods++;
|
||||
}
|
||||
}
|
||||
@@ -346,7 +291,7 @@ class File extends AbstractNode
|
||||
foreach ($this->traits as $trait) {
|
||||
foreach ($trait['methods'] as $method) {
|
||||
if ($method['executableLines'] > 0 &&
|
||||
$method['coverage'] == 100) {
|
||||
$method['coverage'] === 100) {
|
||||
$this->numTestedMethods++;
|
||||
}
|
||||
}
|
||||
@@ -358,27 +303,23 @@ class File extends AbstractNode
|
||||
|
||||
/**
|
||||
* Returns the number of functions.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumFunctions()
|
||||
public function getNumFunctions(): int
|
||||
{
|
||||
return \count($this->functions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of tested functions.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumTestedFunctions()
|
||||
public function getNumTestedFunctions(): int
|
||||
{
|
||||
if ($this->numTestedFunctions === null) {
|
||||
$this->numTestedFunctions = 0;
|
||||
|
||||
foreach ($this->functions as $function) {
|
||||
if ($function['executableLines'] > 0 &&
|
||||
$function['coverage'] == 100) {
|
||||
$function['coverage'] === 100) {
|
||||
$this->numTestedFunctions++;
|
||||
}
|
||||
}
|
||||
@@ -387,119 +328,45 @@ class File extends AbstractNode
|
||||
return $this->numTestedFunctions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates coverage statistics for the file.
|
||||
*/
|
||||
protected function calculateStatistics()
|
||||
private function calculateStatistics(): void
|
||||
{
|
||||
$classStack = $functionStack = [];
|
||||
|
||||
if ($this->cacheTokens) {
|
||||
$tokens = \PHP_Token_Stream_CachingFactory::get($this->getPath());
|
||||
} else {
|
||||
$tokens = new \PHP_Token_Stream($this->getPath());
|
||||
}
|
||||
|
||||
$this->linesOfCode = $tokens->getLinesOfCode();
|
||||
|
||||
foreach (\range(1, $this->linesOfCode['loc']) as $lineNumber) {
|
||||
$this->codeUnitsByLine[$lineNumber] = [];
|
||||
}
|
||||
|
||||
$this->processClasses($tokens);
|
||||
$this->processTraits($tokens);
|
||||
$this->processFunctions($tokens);
|
||||
$this->linesOfCode = $tokens->getLinesOfCode();
|
||||
unset($tokens);
|
||||
|
||||
for ($lineNumber = 1; $lineNumber <= $this->linesOfCode['loc']; $lineNumber++) {
|
||||
if (isset($this->startLines[$lineNumber])) {
|
||||
// Start line of a class.
|
||||
if (isset($this->startLines[$lineNumber]['className'])) {
|
||||
if (isset($currentClass)) {
|
||||
$classStack[] = &$currentClass;
|
||||
}
|
||||
|
||||
$currentClass = &$this->startLines[$lineNumber];
|
||||
} // Start line of a trait.
|
||||
elseif (isset($this->startLines[$lineNumber]['traitName'])) {
|
||||
$currentTrait = &$this->startLines[$lineNumber];
|
||||
} // Start line of a method.
|
||||
elseif (isset($this->startLines[$lineNumber]['methodName'])) {
|
||||
$currentMethod = &$this->startLines[$lineNumber];
|
||||
} // Start line of a function.
|
||||
elseif (isset($this->startLines[$lineNumber]['functionName'])) {
|
||||
if (isset($currentFunction)) {
|
||||
$functionStack[] = &$currentFunction;
|
||||
}
|
||||
|
||||
$currentFunction = &$this->startLines[$lineNumber];
|
||||
}
|
||||
}
|
||||
|
||||
foreach (\range(1, $this->linesOfCode['loc']) as $lineNumber) {
|
||||
if (isset($this->coverageData[$lineNumber])) {
|
||||
if (isset($currentClass)) {
|
||||
$currentClass['executableLines']++;
|
||||
foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) {
|
||||
$codeUnit['executableLines']++;
|
||||
}
|
||||
|
||||
if (isset($currentTrait)) {
|
||||
$currentTrait['executableLines']++;
|
||||
}
|
||||
|
||||
if (isset($currentMethod)) {
|
||||
$currentMethod['executableLines']++;
|
||||
}
|
||||
|
||||
if (isset($currentFunction)) {
|
||||
$currentFunction['executableLines']++;
|
||||
}
|
||||
unset($codeUnit);
|
||||
|
||||
$this->numExecutableLines++;
|
||||
|
||||
if (\count($this->coverageData[$lineNumber]) > 0) {
|
||||
if (isset($currentClass)) {
|
||||
$currentClass['executedLines']++;
|
||||
foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) {
|
||||
$codeUnit['executedLines']++;
|
||||
}
|
||||
|
||||
if (isset($currentTrait)) {
|
||||
$currentTrait['executedLines']++;
|
||||
}
|
||||
|
||||
if (isset($currentMethod)) {
|
||||
$currentMethod['executedLines']++;
|
||||
}
|
||||
|
||||
if (isset($currentFunction)) {
|
||||
$currentFunction['executedLines']++;
|
||||
}
|
||||
unset($codeUnit);
|
||||
|
||||
$this->numExecutedLines++;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->endLines[$lineNumber])) {
|
||||
// End line of a class.
|
||||
if (isset($this->endLines[$lineNumber]['className'])) {
|
||||
unset($currentClass);
|
||||
|
||||
if ($classStack) {
|
||||
\end($classStack);
|
||||
$key = \key($classStack);
|
||||
$currentClass = &$classStack[$key];
|
||||
unset($classStack[$key]);
|
||||
}
|
||||
} // End line of a trait.
|
||||
elseif (isset($this->endLines[$lineNumber]['traitName'])) {
|
||||
unset($currentTrait);
|
||||
} // End line of a method.
|
||||
elseif (isset($this->endLines[$lineNumber]['methodName'])) {
|
||||
unset($currentMethod);
|
||||
} // End line of a function.
|
||||
elseif (isset($this->endLines[$lineNumber]['functionName'])) {
|
||||
unset($currentFunction);
|
||||
|
||||
if ($functionStack) {
|
||||
\end($functionStack);
|
||||
$key = \key($functionStack);
|
||||
$currentFunction = &$functionStack[$key];
|
||||
unset($functionStack[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->traits as &$trait) {
|
||||
@@ -519,11 +386,13 @@ class File extends AbstractNode
|
||||
$trait['ccn'] += $method['ccn'];
|
||||
}
|
||||
|
||||
unset($method);
|
||||
|
||||
if ($trait['executableLines'] > 0) {
|
||||
$trait['coverage'] = ($trait['executedLines'] /
|
||||
$trait['executableLines']) * 100;
|
||||
|
||||
if ($trait['coverage'] == 100) {
|
||||
if ($trait['coverage'] === 100) {
|
||||
$this->numTestedClasses++;
|
||||
}
|
||||
} else {
|
||||
@@ -536,6 +405,8 @@ class File extends AbstractNode
|
||||
);
|
||||
}
|
||||
|
||||
unset($trait);
|
||||
|
||||
foreach ($this->classes as &$class) {
|
||||
foreach ($class['methods'] as &$method) {
|
||||
if ($method['executableLines'] > 0) {
|
||||
@@ -553,11 +424,13 @@ class File extends AbstractNode
|
||||
$class['ccn'] += $method['ccn'];
|
||||
}
|
||||
|
||||
unset($method);
|
||||
|
||||
if ($class['executableLines'] > 0) {
|
||||
$class['coverage'] = ($class['executedLines'] /
|
||||
$class['executableLines']) * 100;
|
||||
|
||||
if ($class['coverage'] == 100) {
|
||||
if ($class['coverage'] === 100) {
|
||||
$this->numTestedClasses++;
|
||||
}
|
||||
} else {
|
||||
@@ -570,6 +443,8 @@ class File extends AbstractNode
|
||||
);
|
||||
}
|
||||
|
||||
unset($class);
|
||||
|
||||
foreach ($this->functions as &$function) {
|
||||
if ($function['executableLines'] > 0) {
|
||||
$function['coverage'] = ($function['executedLines'] /
|
||||
@@ -578,7 +453,7 @@ class File extends AbstractNode
|
||||
$function['coverage'] = 100;
|
||||
}
|
||||
|
||||
if ($function['coverage'] == 100) {
|
||||
if ($function['coverage'] === 100) {
|
||||
$this->numTestedFunctions++;
|
||||
}
|
||||
|
||||
@@ -589,17 +464,16 @@ class File extends AbstractNode
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \PHP_Token_Stream $tokens
|
||||
*/
|
||||
protected function processClasses(\PHP_Token_Stream $tokens)
|
||||
private function processClasses(\PHP_Token_Stream $tokens): void
|
||||
{
|
||||
$classes = $tokens->getClasses();
|
||||
unset($tokens);
|
||||
|
||||
$link = $this->getId() . '.html#';
|
||||
$link = $this->getId() . '.html#';
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
if (\strpos($className, 'anonymous') === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($class['package']['namespace'])) {
|
||||
$className = $class['package']['namespace'] . '\\' . $className;
|
||||
}
|
||||
@@ -617,27 +491,27 @@ class File extends AbstractNode
|
||||
'link' => $link . $class['startLine']
|
||||
];
|
||||
|
||||
$this->startLines[$class['startLine']] = &$this->classes[$className];
|
||||
$this->endLines[$class['endLine']] = &$this->classes[$className];
|
||||
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
if (\strpos($methodName, 'anonymous') === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->classes[$className]['methods'][$methodName] = $this->newMethod($methodName, $method, $link);
|
||||
|
||||
$this->startLines[$method['startLine']] = &$this->classes[$className]['methods'][$methodName];
|
||||
$this->endLines[$method['endLine']] = &$this->classes[$className]['methods'][$methodName];
|
||||
foreach (\range($method['startLine'], $method['endLine']) as $lineNumber) {
|
||||
$this->codeUnitsByLine[$lineNumber] = [
|
||||
&$this->classes[$className],
|
||||
&$this->classes[$className]['methods'][$methodName]
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \PHP_Token_Stream $tokens
|
||||
*/
|
||||
protected function processTraits(\PHP_Token_Stream $tokens)
|
||||
private function processTraits(\PHP_Token_Stream $tokens): void
|
||||
{
|
||||
$traits = $tokens->getTraits();
|
||||
unset($tokens);
|
||||
|
||||
$link = $this->getId() . '.html#';
|
||||
$link = $this->getId() . '.html#';
|
||||
|
||||
foreach ($traits as $traitName => $trait) {
|
||||
$this->traits[$traitName] = [
|
||||
@@ -653,29 +527,33 @@ class File extends AbstractNode
|
||||
'link' => $link . $trait['startLine']
|
||||
];
|
||||
|
||||
$this->startLines[$trait['startLine']] = &$this->traits[$traitName];
|
||||
$this->endLines[$trait['endLine']] = &$this->traits[$traitName];
|
||||
|
||||
foreach ($trait['methods'] as $methodName => $method) {
|
||||
if (\strpos($methodName, 'anonymous') === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->traits[$traitName]['methods'][$methodName] = $this->newMethod($methodName, $method, $link);
|
||||
|
||||
$this->startLines[$method['startLine']] = &$this->traits[$traitName]['methods'][$methodName];
|
||||
$this->endLines[$method['endLine']] = &$this->traits[$traitName]['methods'][$methodName];
|
||||
foreach (\range($method['startLine'], $method['endLine']) as $lineNumber) {
|
||||
$this->codeUnitsByLine[$lineNumber] = [
|
||||
&$this->traits[$traitName],
|
||||
&$this->traits[$traitName]['methods'][$methodName]
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \PHP_Token_Stream $tokens
|
||||
*/
|
||||
protected function processFunctions(\PHP_Token_Stream $tokens)
|
||||
private function processFunctions(\PHP_Token_Stream $tokens): void
|
||||
{
|
||||
$functions = $tokens->getFunctions();
|
||||
unset($tokens);
|
||||
|
||||
$link = $this->getId() . '.html#';
|
||||
$link = $this->getId() . '.html#';
|
||||
|
||||
foreach ($functions as $functionName => $function) {
|
||||
if (\strpos($functionName, 'anonymous') === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->functions[$functionName] = [
|
||||
'functionName' => $functionName,
|
||||
'signature' => $function['signature'],
|
||||
@@ -688,24 +566,16 @@ class File extends AbstractNode
|
||||
'link' => $link . $function['startLine']
|
||||
];
|
||||
|
||||
$this->startLines[$function['startLine']] = &$this->functions[$functionName];
|
||||
$this->endLines[$function['endLine']] = &$this->functions[$functionName];
|
||||
foreach (\range($function['startLine'], $function['endLine']) as $lineNumber) {
|
||||
$this->codeUnitsByLine[$lineNumber] = [&$this->functions[$functionName]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the Change Risk Anti-Patterns (CRAP) index for a unit of code
|
||||
* based on its cyclomatic complexity and percentage of code coverage.
|
||||
*
|
||||
* @param int $ccn
|
||||
* @param float $coverage
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function crap($ccn, $coverage)
|
||||
private function crap(int $ccn, float $coverage): string
|
||||
{
|
||||
if ($coverage == 0) {
|
||||
return (string) (\pow($ccn, 2) + $ccn);
|
||||
if ($coverage === 0) {
|
||||
return (string) ($ccn ** 2 + $ccn);
|
||||
}
|
||||
|
||||
if ($coverage >= 95) {
|
||||
@@ -714,18 +584,11 @@ class File extends AbstractNode
|
||||
|
||||
return \sprintf(
|
||||
'%01.2F',
|
||||
\pow($ccn, 2) * \pow(1 - $coverage / 100, 3) + $ccn
|
||||
$ccn ** 2 * (1 - $coverage / 100) ** 3 + $ccn
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $methodName
|
||||
* @param array $method
|
||||
* @param string $link
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function newMethod($methodName, array $method, $link)
|
||||
private function newMethod(string $methodName, array $method, string $link): array
|
||||
{
|
||||
return [
|
||||
'methodName' => $methodName,
|
||||
|
@@ -13,7 +13,7 @@ namespace SebastianBergmann\CodeCoverage\Node;
|
||||
/**
|
||||
* Recursive iterator for node object graphs.
|
||||
*/
|
||||
class Iterator implements \RecursiveIterator
|
||||
final class Iterator implements \RecursiveIterator
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
@@ -25,9 +25,6 @@ class Iterator implements \RecursiveIterator
|
||||
*/
|
||||
private $nodes;
|
||||
|
||||
/**
|
||||
* @param Directory $node
|
||||
*/
|
||||
public function __construct(Directory $node)
|
||||
{
|
||||
$this->nodes = $node->getChildNodes();
|
||||
@@ -36,37 +33,31 @@ class Iterator implements \RecursiveIterator
|
||||
/**
|
||||
* Rewinds the Iterator to the first element.
|
||||
*/
|
||||
public function rewind()
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a current element after calls to rewind() or next().
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
public function valid(): bool
|
||||
{
|
||||
return $this->position < \count($this->nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key of the current element.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function key()
|
||||
public function key(): int
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current element.
|
||||
*
|
||||
* @return \PHPUnit_Framework_Test
|
||||
*/
|
||||
public function current()
|
||||
public function current(): AbstractNode
|
||||
{
|
||||
return $this->valid() ? $this->nodes[$this->position] : null;
|
||||
}
|
||||
@@ -74,7 +65,7 @@ class Iterator implements \RecursiveIterator
|
||||
/**
|
||||
* Moves forward to next element.
|
||||
*/
|
||||
public function next()
|
||||
public function next(): void
|
||||
{
|
||||
$this->position++;
|
||||
}
|
||||
@@ -84,11 +75,9 @@ class Iterator implements \RecursiveIterator
|
||||
*
|
||||
* @return Iterator
|
||||
*/
|
||||
public function getChildren()
|
||||
public function getChildren(): self
|
||||
{
|
||||
return new self(
|
||||
$this->nodes[$this->position]
|
||||
);
|
||||
return new self($this->nodes[$this->position]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,7 +85,7 @@ class Iterator implements \RecursiveIterator
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasChildren()
|
||||
public function hasChildren(): bool
|
||||
{
|
||||
return $this->nodes[$this->position] instanceof Directory;
|
||||
}
|
||||
|
@@ -17,18 +17,12 @@ use SebastianBergmann\CodeCoverage\RuntimeException;
|
||||
/**
|
||||
* Generates a Clover XML logfile from a code coverage object.
|
||||
*/
|
||||
class Clover
|
||||
final class Clover
|
||||
{
|
||||
/**
|
||||
* @param CodeCoverage $coverage
|
||||
* @param string $target
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, $target = null, $name = null)
|
||||
public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
|
||||
{
|
||||
$xmlDocument = new \DOMDocument('1.0', 'UTF-8');
|
||||
$xmlDocument->formatOutput = true;
|
||||
@@ -48,7 +42,6 @@ class Clover
|
||||
|
||||
$packages = [];
|
||||
$report = $coverage->getReport();
|
||||
unset($coverage);
|
||||
|
||||
foreach ($report as $item) {
|
||||
if (!$item instanceof File) {
|
||||
@@ -60,10 +53,10 @@ class Clover
|
||||
$xmlFile = $xmlDocument->createElement('file');
|
||||
$xmlFile->setAttribute('name', $item->getPath());
|
||||
|
||||
$classes = $item->getClassesAndTraits();
|
||||
$coverage = $item->getCoverageData();
|
||||
$lines = [];
|
||||
$namespace = 'global';
|
||||
$classes = $item->getClassesAndTraits();
|
||||
$coverageData = $item->getCoverageData();
|
||||
$lines = [];
|
||||
$namespace = 'global';
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
$classStatements = 0;
|
||||
@@ -87,8 +80,8 @@ class Clover
|
||||
$methodCount = 0;
|
||||
|
||||
foreach (\range($method['startLine'], $method['endLine']) as $line) {
|
||||
if (isset($coverage[$line]) && ($coverage[$line] !== null)) {
|
||||
$methodCount = \max($methodCount, \count($coverage[$line]));
|
||||
if (isset($coverageData[$line]) && ($coverageData[$line] !== null)) {
|
||||
$methodCount = \max($methodCount, \count($coverageData[$line]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +146,7 @@ class Clover
|
||||
$xmlClass->appendChild($xmlMetrics);
|
||||
}
|
||||
|
||||
foreach ($coverage as $line => $data) {
|
||||
foreach ($coverageData as $line => $data) {
|
||||
if ($data === null || isset($lines[$line])) {
|
||||
continue;
|
||||
}
|
||||
@@ -206,7 +199,7 @@ class Clover
|
||||
$xmlMetrics->setAttribute('coveredelements', $item->getNumTestedMethods() + $item->getNumExecutedLines() /* + coveredconditionals */);
|
||||
$xmlFile->appendChild($xmlMetrics);
|
||||
|
||||
if ($namespace == 'global') {
|
||||
if ($namespace === 'global') {
|
||||
$xmlProject->appendChild($xmlFile);
|
||||
} else {
|
||||
if (!isset($packages[$namespace])) {
|
||||
@@ -242,8 +235,8 @@ class Clover
|
||||
$buffer = $xmlDocument->saveXML();
|
||||
|
||||
if ($target !== null) {
|
||||
if (!\is_dir(\dirname($target))) {
|
||||
\mkdir(\dirname($target), 0777, true);
|
||||
if (!$this->createDirectory(\dirname($target))) {
|
||||
throw new \RuntimeException(\sprintf('Directory "%s" was not created', \dirname($target)));
|
||||
}
|
||||
|
||||
if (@\file_put_contents($target, $buffer) === false) {
|
||||
@@ -258,4 +251,9 @@ class Clover
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
private function createDirectory(string $directory): bool
|
||||
{
|
||||
return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory));
|
||||
}
|
||||
}
|
||||
|
@@ -11,42 +11,25 @@
|
||||
namespace SebastianBergmann\CodeCoverage\Report;
|
||||
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\InvalidArgumentException;
|
||||
use SebastianBergmann\CodeCoverage\Node\File;
|
||||
use SebastianBergmann\CodeCoverage\RuntimeException;
|
||||
|
||||
class Crap4j
|
||||
final class Crap4j
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $threshold;
|
||||
|
||||
/**
|
||||
* @param int $threshold
|
||||
*/
|
||||
public function __construct($threshold = 30)
|
||||
public function __construct(int $threshold = 30)
|
||||
{
|
||||
if (!\is_int($threshold)) {
|
||||
throw InvalidArgumentException::create(
|
||||
1,
|
||||
'integer'
|
||||
);
|
||||
}
|
||||
|
||||
$this->threshold = $threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CodeCoverage $coverage
|
||||
* @param string $target
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, $target = null, $name = null)
|
||||
public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
|
||||
{
|
||||
$document = new \DOMDocument('1.0', 'UTF-8');
|
||||
$document->formatOutput = true;
|
||||
@@ -120,10 +103,10 @@ class Crap4j
|
||||
$stats->appendChild($document->createElement('crapLoad', \round($fullCrapLoad)));
|
||||
$stats->appendChild($document->createElement('totalCrap', $fullCrap));
|
||||
|
||||
$crapMethodPercent = 0;
|
||||
|
||||
if ($fullMethodCount > 0) {
|
||||
$crapMethodPercent = $this->roundValue((100 * $fullCrapMethodCount) / $fullMethodCount);
|
||||
} else {
|
||||
$crapMethodPercent = 0;
|
||||
}
|
||||
|
||||
$stats->appendChild($document->createElement('crapMethodPercent', $crapMethodPercent));
|
||||
@@ -134,8 +117,8 @@ class Crap4j
|
||||
$buffer = $document->saveXML();
|
||||
|
||||
if ($target !== null) {
|
||||
if (!\is_dir(\dirname($target))) {
|
||||
\mkdir(\dirname($target), 0777, true);
|
||||
if (!$this->createDirectory(\dirname($target))) {
|
||||
throw new \RuntimeException(\sprintf('Directory "%s" was not created', \dirname($target)));
|
||||
}
|
||||
|
||||
if (@\file_put_contents($target, $buffer) === false) {
|
||||
@@ -158,7 +141,7 @@ class Crap4j
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent)
|
||||
private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent): float
|
||||
{
|
||||
$crapLoad = 0;
|
||||
|
||||
@@ -175,8 +158,13 @@ class Crap4j
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
private function roundValue($value)
|
||||
private function roundValue($value): float
|
||||
{
|
||||
return \round($value, 2);
|
||||
}
|
||||
|
||||
private function createDirectory(string $directory): bool
|
||||
{
|
||||
return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory));
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ use SebastianBergmann\CodeCoverage\RuntimeException;
|
||||
/**
|
||||
* Generates an HTML report from a code coverage object.
|
||||
*/
|
||||
class Facade
|
||||
final class Facade
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
@@ -39,14 +39,7 @@ class Facade
|
||||
*/
|
||||
private $highLowerBound;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $lowUpperBound
|
||||
* @param int $highLowerBound
|
||||
* @param string $generator
|
||||
*/
|
||||
public function __construct($lowUpperBound = 50, $highLowerBound = 90, $generator = '')
|
||||
public function __construct(int $lowUpperBound = 50, int $highLowerBound = 90, string $generator = '')
|
||||
{
|
||||
$this->generator = $generator;
|
||||
$this->highLowerBound = $highLowerBound;
|
||||
@@ -55,14 +48,14 @@ class Facade
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CodeCoverage $coverage
|
||||
* @param string $target
|
||||
* @throws RuntimeException
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, $target)
|
||||
public function process(CodeCoverage $coverage, string $target): void
|
||||
{
|
||||
$target = $this->getDirectory($target);
|
||||
$report = $coverage->getReport();
|
||||
unset($coverage);
|
||||
|
||||
if (!isset($_SERVER['REQUEST_TIME'])) {
|
||||
$_SERVER['REQUEST_TIME'] = \time();
|
||||
@@ -101,8 +94,8 @@ class Facade
|
||||
$id = $node->getId();
|
||||
|
||||
if ($node instanceof DirectoryNode) {
|
||||
if (!\file_exists($target . $id)) {
|
||||
\mkdir($target . $id, 0777, true);
|
||||
if (!$this->createDirectory($target . $id)) {
|
||||
throw new \RuntimeException(\sprintf('Directory "%s" was not created', $target . $id));
|
||||
}
|
||||
|
||||
$directory->render($node, $target . $id . '/index.html');
|
||||
@@ -110,8 +103,8 @@ class Facade
|
||||
} else {
|
||||
$dir = \dirname($target . $id);
|
||||
|
||||
if (!\file_exists($dir)) {
|
||||
\mkdir($dir, 0777, true);
|
||||
if (!$this->createDirectory($dir)) {
|
||||
throw new \RuntimeException(\sprintf('Directory "%s" was not created', $dir));
|
||||
}
|
||||
|
||||
$file->render($node, $target . $id . '.html');
|
||||
@@ -122,9 +115,9 @@ class Facade
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $target
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function copyFiles($target)
|
||||
private function copyFiles(string $target): void
|
||||
{
|
||||
$dir = $this->getDirectory($target . '.css');
|
||||
|
||||
@@ -140,6 +133,7 @@ class Facade
|
||||
|
||||
\copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css');
|
||||
\copy($this->templatePath . 'css/style.css', $dir . 'style.css');
|
||||
\copy($this->templatePath . 'css/custom.css', $dir . 'custom.css');
|
||||
|
||||
$dir = $this->getDirectory($target . '.fonts');
|
||||
\copy($this->templatePath . 'fonts/glyphicons-halflings-regular.eot', $dir . 'glyphicons-halflings-regular.eot');
|
||||
@@ -160,31 +154,28 @@ class Facade
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $directory
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function getDirectory($directory)
|
||||
private function getDirectory(string $directory): string
|
||||
{
|
||||
if (\substr($directory, -1, 1) != DIRECTORY_SEPARATOR) {
|
||||
$directory .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
if (\is_dir($directory)) {
|
||||
return $directory;
|
||||
if (!$this->createDirectory($directory)) {
|
||||
throw new RuntimeException(
|
||||
\sprintf(
|
||||
'Directory "%s" does not exist.',
|
||||
$directory
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (@\mkdir($directory, 0777, true)) {
|
||||
return $directory;
|
||||
}
|
||||
return $directory;
|
||||
}
|
||||
|
||||
throw new RuntimeException(
|
||||
\sprintf(
|
||||
'Directory "%s" does not exist.',
|
||||
$directory
|
||||
)
|
||||
);
|
||||
private function createDirectory(string $directory): bool
|
||||
{
|
||||
return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory));
|
||||
}
|
||||
}
|
||||
|
@@ -51,16 +51,7 @@ abstract class Renderer
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $templatePath
|
||||
* @param string $generator
|
||||
* @param string $date
|
||||
* @param int $lowUpperBound
|
||||
* @param int $highLowerBound
|
||||
*/
|
||||
public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
|
||||
public function __construct(string $templatePath, string $generator, string $date, int $lowUpperBound, int $highLowerBound)
|
||||
{
|
||||
$this->templatePath = $templatePath;
|
||||
$this->generator = $generator;
|
||||
@@ -70,13 +61,7 @@ abstract class Renderer
|
||||
$this->version = Version::id();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Text_Template $template
|
||||
* @param array $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderItemTemplate(\Text_Template $template, array $data)
|
||||
protected function renderItemTemplate(\Text_Template $template, array $data): string
|
||||
{
|
||||
$numSeparator = ' / ';
|
||||
|
||||
@@ -130,8 +115,8 @@ abstract class Renderer
|
||||
|
||||
$template->setVar(
|
||||
[
|
||||
'icon' => isset($data['icon']) ? $data['icon'] : '',
|
||||
'crap' => isset($data['crap']) ? $data['crap'] : '',
|
||||
'icon' => $data['icon'] ?? '',
|
||||
'crap' => $data['crap'] ?? '',
|
||||
'name' => $data['name'],
|
||||
'lines_bar' => $linesBar,
|
||||
'lines_executed_percent' => $data['linesExecutedPercentAsString'],
|
||||
@@ -142,7 +127,7 @@ abstract class Renderer
|
||||
'methods_level' => $methodsLevel,
|
||||
'methods_number' => $methodsNumber,
|
||||
'classes_bar' => $classesBar,
|
||||
'classes_tested_percent' => isset($data['testedClassesPercentAsString']) ? $data['testedClassesPercentAsString'] : '',
|
||||
'classes_tested_percent' => $data['testedClassesPercentAsString'] ?? '',
|
||||
'classes_level' => $classesLevel,
|
||||
'classes_number' => $classesNumber
|
||||
]
|
||||
@@ -151,11 +136,7 @@ abstract class Renderer
|
||||
return $template->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Text_Template $template
|
||||
* @param AbstractNode $node
|
||||
*/
|
||||
protected function setCommonTemplateVariables(\Text_Template $template, AbstractNode $node)
|
||||
protected function setCommonTemplateVariables(\Text_Template $template, AbstractNode $node): void
|
||||
{
|
||||
$template->setVar(
|
||||
[
|
||||
@@ -173,7 +154,7 @@ abstract class Renderer
|
||||
);
|
||||
}
|
||||
|
||||
protected function getBreadcrumbs(AbstractNode $node)
|
||||
protected function getBreadcrumbs(AbstractNode $node): string
|
||||
{
|
||||
$breadcrumbs = '';
|
||||
$path = $node->getPathAsArray();
|
||||
@@ -202,7 +183,7 @@ abstract class Renderer
|
||||
return $breadcrumbs;
|
||||
}
|
||||
|
||||
protected function getActiveBreadcrumb(AbstractNode $node)
|
||||
protected function getActiveBreadcrumb(AbstractNode $node): string
|
||||
{
|
||||
$buffer = \sprintf(
|
||||
' <li class="active">%s</li>' . "\n",
|
||||
@@ -216,7 +197,7 @@ abstract class Renderer
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
protected function getInactiveBreadcrumb(AbstractNode $node, $pathToRoot)
|
||||
protected function getInactiveBreadcrumb(AbstractNode $node, string $pathToRoot): string
|
||||
{
|
||||
return \sprintf(
|
||||
' <li><a href="%sindex.html">%s</a></li>' . "\n",
|
||||
@@ -225,12 +206,12 @@ abstract class Renderer
|
||||
);
|
||||
}
|
||||
|
||||
protected function getPathToRoot(AbstractNode $node)
|
||||
protected function getPathToRoot(AbstractNode $node): string
|
||||
{
|
||||
$id = $node->getId();
|
||||
$depth = \substr_count($id, '/');
|
||||
|
||||
if ($id != 'index' &&
|
||||
if ($id !== 'index' &&
|
||||
$node instanceof DirectoryNode) {
|
||||
$depth++;
|
||||
}
|
||||
@@ -238,7 +219,7 @@ abstract class Renderer
|
||||
return \str_repeat('../', $depth);
|
||||
}
|
||||
|
||||
protected function getCoverageBar($percent)
|
||||
protected function getCoverageBar(float $percent): string
|
||||
{
|
||||
$level = $this->getColorLevel($percent);
|
||||
|
||||
@@ -253,27 +234,21 @@ abstract class Renderer
|
||||
return $template->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $percent
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getColorLevel($percent)
|
||||
protected function getColorLevel(float $percent): string
|
||||
{
|
||||
if ($percent <= $this->lowUpperBound) {
|
||||
return 'danger';
|
||||
} elseif ($percent > $this->lowUpperBound &&
|
||||
}
|
||||
|
||||
if ($percent > $this->lowUpperBound &&
|
||||
$percent < $this->highLowerBound) {
|
||||
return 'warning';
|
||||
} else {
|
||||
return 'success';
|
||||
}
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getRuntimeString()
|
||||
private function getRuntimeString(): string
|
||||
{
|
||||
$runtime = new Runtime;
|
||||
|
||||
|
@@ -16,15 +16,13 @@ use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
/**
|
||||
* Renders the dashboard for a directory node.
|
||||
*/
|
||||
class Dashboard extends Renderer
|
||||
final class Dashboard extends Renderer
|
||||
{
|
||||
/**
|
||||
* @param DirectoryNode $node
|
||||
* @param string $file
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function render(DirectoryNode $node, $file)
|
||||
public function render(DirectoryNode $node, string $file)
|
||||
{
|
||||
$classes = $node->getClassesAndTraits();
|
||||
$template = new \Text_Template(
|
||||
@@ -59,13 +57,8 @@ class Dashboard extends Renderer
|
||||
|
||||
/**
|
||||
* Returns the data for the Class/Method Complexity charts.
|
||||
*
|
||||
* @param array $classes
|
||||
* @param string $baseLink
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function complexity(array $classes, $baseLink)
|
||||
protected function complexity(array $classes, string $baseLink): array
|
||||
{
|
||||
$result = ['class' => [], 'method' => []];
|
||||
|
||||
@@ -105,12 +98,8 @@ class Dashboard extends Renderer
|
||||
|
||||
/**
|
||||
* Returns the data for the Class / Method Coverage Distribution chart.
|
||||
*
|
||||
* @param array $classes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function coverageDistribution(array $classes)
|
||||
protected function coverageDistribution(array $classes): array
|
||||
{
|
||||
$result = [
|
||||
'class' => [
|
||||
@@ -175,13 +164,8 @@ class Dashboard extends Renderer
|
||||
|
||||
/**
|
||||
* Returns the classes / methods with insufficient coverage.
|
||||
*
|
||||
* @param array $classes
|
||||
* @param string $baseLink
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function insufficientCoverage(array $classes, $baseLink)
|
||||
protected function insufficientCoverage(array $classes, string $baseLink): array
|
||||
{
|
||||
$leastTestedClasses = [];
|
||||
$leastTestedMethods = [];
|
||||
@@ -218,7 +202,7 @@ class Dashboard extends Renderer
|
||||
}
|
||||
|
||||
foreach ($leastTestedMethods as $methodName => $coverage) {
|
||||
list($class, $method) = \explode('::', $methodName);
|
||||
[$class, $method] = \explode('::', $methodName);
|
||||
|
||||
$result['method'] .= \sprintf(
|
||||
' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d%%</td></tr>' . "\n",
|
||||
@@ -234,13 +218,8 @@ class Dashboard extends Renderer
|
||||
|
||||
/**
|
||||
* Returns the project risks according to the CRAP index.
|
||||
*
|
||||
* @param array $classes
|
||||
* @param string $baseLink
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function projectRisks(array $classes, $baseLink)
|
||||
protected function projectRisks(array $classes, string $baseLink): array
|
||||
{
|
||||
$classRisks = [];
|
||||
$methodRisks = [];
|
||||
@@ -248,12 +227,11 @@ class Dashboard extends Renderer
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
if ($method['coverage'] < $this->highLowerBound &&
|
||||
$method['ccn'] > 1) {
|
||||
if ($method['coverage'] < $this->highLowerBound && $method['ccn'] > 1) {
|
||||
$key = $methodName;
|
||||
|
||||
if ($className !== '*') {
|
||||
$key = $className . '::' . $methodName;
|
||||
} else {
|
||||
$key = $methodName;
|
||||
}
|
||||
|
||||
$methodRisks[$key] = $method['crap'];
|
||||
@@ -279,7 +257,7 @@ class Dashboard extends Renderer
|
||||
}
|
||||
|
||||
foreach ($methodRisks as $methodName => $crap) {
|
||||
list($class, $method) = \explode('::', $methodName);
|
||||
[$class, $method] = \explode('::', $methodName);
|
||||
|
||||
$result['method'] .= \sprintf(
|
||||
' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d</td></tr>' . "\n",
|
||||
@@ -293,7 +271,7 @@ class Dashboard extends Renderer
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getActiveBreadcrumb(AbstractNode $node)
|
||||
protected function getActiveBreadcrumb(AbstractNode $node): string
|
||||
{
|
||||
return \sprintf(
|
||||
' <li><a href="index.html">%s</a></li>' . "\n" .
|
||||
|
@@ -16,13 +16,13 @@ use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
/**
|
||||
* Renders a directory node.
|
||||
*/
|
||||
class Directory extends Renderer
|
||||
final class Directory extends Renderer
|
||||
{
|
||||
/**
|
||||
* @param DirectoryNode $node
|
||||
* @param string $file
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function render(DirectoryNode $node, $file)
|
||||
public function render(DirectoryNode $node, string $file): void
|
||||
{
|
||||
$template = new \Text_Template($this->templatePath . 'directory.html', '{{', '}}');
|
||||
|
||||
@@ -48,13 +48,7 @@ class Directory extends Renderer
|
||||
$template->renderTo($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $node
|
||||
* @param bool $total
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderItem(Node $node, $total = false)
|
||||
protected function renderItem(Node $node, bool $total = false): string
|
||||
{
|
||||
$data = [
|
||||
'numClasses' => $node->getNumClassesAndTraits(),
|
||||
|
@@ -16,42 +16,17 @@ use SebastianBergmann\CodeCoverage\Util;
|
||||
/**
|
||||
* Renders a file node.
|
||||
*/
|
||||
class File extends Renderer
|
||||
final class File extends Renderer
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $htmlspecialcharsFlags;
|
||||
private $htmlSpecialCharsFlags = ENT_COMPAT | ENT_HTML401 | ENT_SUBSTITUTE;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $templatePath
|
||||
* @param string $generator
|
||||
* @param string $date
|
||||
* @param int $lowUpperBound
|
||||
* @param int $highLowerBound
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
|
||||
{
|
||||
parent::__construct(
|
||||
$templatePath,
|
||||
$generator,
|
||||
$date,
|
||||
$lowUpperBound,
|
||||
$highLowerBound
|
||||
);
|
||||
|
||||
$this->htmlspecialcharsFlags = ENT_COMPAT;
|
||||
|
||||
$this->htmlspecialcharsFlags = $this->htmlspecialcharsFlags | ENT_HTML401 | ENT_SUBSTITUTE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FileNode $node
|
||||
* @param string $file
|
||||
*/
|
||||
public function render(FileNode $node, $file)
|
||||
public function render(FileNode $node, string $file): void
|
||||
{
|
||||
$template = new \Text_Template($this->templatePath . 'file.html', '{{', '}}');
|
||||
|
||||
@@ -67,12 +42,7 @@ class File extends Renderer
|
||||
$template->renderTo($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FileNode $node
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderItems(FileNode $node)
|
||||
protected function renderItems(FileNode $node): string
|
||||
{
|
||||
$template = new \Text_Template($this->templatePath . 'file_item.html', '{{', '}}');
|
||||
|
||||
@@ -122,14 +92,7 @@ class File extends Renderer
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
* @param \Text_Template $template
|
||||
* @param \Text_Template $methodItemTemplate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderTraitOrClassItems(array $items, \Text_Template $template, \Text_Template $methodItemTemplate)
|
||||
protected function renderTraitOrClassItems(array $items, \Text_Template $template, \Text_Template $methodItemTemplate): string
|
||||
{
|
||||
$buffer = '';
|
||||
|
||||
@@ -183,8 +146,7 @@ class File extends Renderer
|
||||
'numExecutableLines' => $item['executableLines'],
|
||||
'testedMethodsPercent' => Util::percent(
|
||||
$numTestedMethods,
|
||||
$numMethods,
|
||||
false
|
||||
$numMethods
|
||||
),
|
||||
'testedMethodsPercentAsString' => Util::percent(
|
||||
$numTestedMethods,
|
||||
@@ -193,8 +155,7 @@ class File extends Renderer
|
||||
),
|
||||
'testedClassesPercent' => Util::percent(
|
||||
$numTestedMethods == $numMethods ? 1 : 0,
|
||||
1,
|
||||
false
|
||||
1
|
||||
),
|
||||
'testedClassesPercentAsString' => Util::percent(
|
||||
$numTestedMethods == $numMethods ? 1 : 0,
|
||||
@@ -217,13 +178,7 @@ class File extends Renderer
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $functions
|
||||
* @param \Text_Template $template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderFunctionItems(array $functions, \Text_Template $template)
|
||||
protected function renderFunctionItems(array $functions, \Text_Template $template): string
|
||||
{
|
||||
if (empty($functions)) {
|
||||
return '';
|
||||
@@ -241,12 +196,7 @@ class File extends Renderer
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Text_Template $template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderFunctionOrMethodItem(\Text_Template $template, array $item, $indent = '')
|
||||
protected function renderFunctionOrMethodItem(\Text_Template $template, array $item, string $indent = ''): string
|
||||
{
|
||||
$numMethods = 0;
|
||||
$numTestedMethods = 0;
|
||||
@@ -266,15 +216,14 @@ class File extends Renderer
|
||||
'%s<a href="#%d"><abbr title="%s">%s</abbr></a>',
|
||||
$indent,
|
||||
$item['startLine'],
|
||||
\htmlspecialchars($item['signature']),
|
||||
isset($item['functionName']) ? $item['functionName'] : $item['methodName']
|
||||
\htmlspecialchars($item['signature'], $this->htmlSpecialCharsFlags),
|
||||
$item['functionName'] ?? $item['methodName']
|
||||
),
|
||||
'numMethods' => $numMethods,
|
||||
'numTestedMethods' => $numTestedMethods,
|
||||
'linesExecutedPercent' => Util::percent(
|
||||
$item['executedLines'],
|
||||
$item['executableLines'],
|
||||
false
|
||||
$item['executableLines']
|
||||
),
|
||||
'linesExecutedPercentAsString' => Util::percent(
|
||||
$item['executedLines'],
|
||||
@@ -285,8 +234,7 @@ class File extends Renderer
|
||||
'numExecutableLines' => $item['executableLines'],
|
||||
'testedMethodsPercent' => Util::percent(
|
||||
$numTestedMethods,
|
||||
1,
|
||||
false
|
||||
1
|
||||
),
|
||||
'testedMethodsPercentAsString' => Util::percent(
|
||||
$numTestedMethods,
|
||||
@@ -303,7 +251,7 @@ class File extends Renderer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderSource(FileNode $node)
|
||||
protected function renderSource(FileNode $node): string
|
||||
{
|
||||
$coverageData = $node->getCoverageData();
|
||||
$testData = $node->getTestData();
|
||||
@@ -384,7 +332,7 @@ class File extends Renderer
|
||||
$popoverContent .= \sprintf(
|
||||
'<li%s>%s</li>',
|
||||
$testCSS,
|
||||
\htmlspecialchars($test)
|
||||
\htmlspecialchars($test, $this->htmlSpecialCharsFlags)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -393,14 +341,14 @@ class File extends Renderer
|
||||
}
|
||||
}
|
||||
|
||||
$popover = '';
|
||||
|
||||
if (!empty($popoverTitle)) {
|
||||
$popover = \sprintf(
|
||||
' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"',
|
||||
$popoverTitle,
|
||||
\htmlspecialchars($popoverContent)
|
||||
\htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags)
|
||||
);
|
||||
} else {
|
||||
$popover = '';
|
||||
}
|
||||
|
||||
$lines .= \sprintf(
|
||||
@@ -424,7 +372,7 @@ class File extends Renderer
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function loadFile($file)
|
||||
protected function loadFile($file): array
|
||||
{
|
||||
$buffer = \file_get_contents($file);
|
||||
$tokens = \token_get_all($buffer);
|
||||
@@ -440,26 +388,26 @@ class File extends Renderer
|
||||
if ($token === '"' && $tokens[$j - 1] !== '\\') {
|
||||
$result[$i] .= \sprintf(
|
||||
'<span class="string">%s</span>',
|
||||
\htmlspecialchars($token)
|
||||
\htmlspecialchars($token, $this->htmlSpecialCharsFlags)
|
||||
);
|
||||
|
||||
$stringFlag = !$stringFlag;
|
||||
} else {
|
||||
$result[$i] .= \sprintf(
|
||||
'<span class="keyword">%s</span>',
|
||||
\htmlspecialchars($token)
|
||||
\htmlspecialchars($token, $this->htmlSpecialCharsFlags)
|
||||
);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
list($token, $value) = $token;
|
||||
[$token, $value] = $token;
|
||||
|
||||
$value = \str_replace(
|
||||
["\t", ' '],
|
||||
[' ', ' '],
|
||||
\htmlspecialchars($value, $this->htmlspecialcharsFlags)
|
||||
\htmlspecialchars($value, $this->htmlSpecialCharsFlags)
|
||||
);
|
||||
|
||||
if ($value === "\n") {
|
||||
|
0
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/custom.css
vendored
Normal file
0
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/custom.css
vendored
Normal file
@@ -7,6 +7,7 @@
|
||||
<link href="{{path_to_root}}.css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}.css/nv.d3.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}.css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}.css/custom.css" rel="stylesheet" type="text/css">
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{{path_to_root}}.js/html5shiv.min.js"></script>
|
||||
<script src="{{path_to_root}}.js/respond.min.js"></script>
|
||||
|
@@ -6,6 +6,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}.css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}.css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}.css/custom.css" rel="stylesheet" type="text/css">
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{{path_to_root}}.js/html5shiv.min.js"></script>
|
||||
<script src="{{path_to_root}}.js/respond.min.js"></script>
|
||||
|
@@ -6,6 +6,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}.css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}.css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}.css/custom.css" rel="stylesheet" type="text/css">
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{{path_to_root}}.js/html5shiv.min.js"></script>
|
||||
<script src="{{path_to_root}}.js/respond.min.js"></script>
|
||||
|
@@ -16,15 +16,17 @@ use SebastianBergmann\CodeCoverage\RuntimeException;
|
||||
/**
|
||||
* Uses var_export() to write a SebastianBergmann\CodeCoverage\CodeCoverage object to a file.
|
||||
*/
|
||||
class PHP
|
||||
final class PHP
|
||||
{
|
||||
/**
|
||||
* @param CodeCoverage $coverage
|
||||
* @param string $target
|
||||
* @param null|string $target
|
||||
*
|
||||
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, $target = null)
|
||||
public function process(CodeCoverage $coverage, ?string $target = null): string
|
||||
{
|
||||
$filter = $coverage->filter();
|
||||
|
||||
|
112
vendor/phpunit/php-code-coverage/src/Report/Text.php
vendored
112
vendor/phpunit/php-code-coverage/src/Report/Text.php
vendored
@@ -19,29 +19,59 @@ use SebastianBergmann\CodeCoverage\Util;
|
||||
*
|
||||
* The output gets put into a text file our written to the CLI.
|
||||
*/
|
||||
class Text
|
||||
final class Text
|
||||
{
|
||||
private $lowUpperBound;
|
||||
private $highLowerBound;
|
||||
private $showUncoveredFiles;
|
||||
private $showOnlySummary;
|
||||
|
||||
private $colors = [
|
||||
'green' => "\x1b[30;42m",
|
||||
'yellow' => "\x1b[30;43m",
|
||||
'red' => "\x1b[37;41m",
|
||||
'header' => "\x1b[1;37;40m",
|
||||
'reset' => "\x1b[0m",
|
||||
'eol' => "\x1b[2K",
|
||||
];
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_GREEN = "\x1b[30;42m";
|
||||
|
||||
/**
|
||||
* @param int $lowUpperBound
|
||||
* @param int $highLowerBound
|
||||
* @param bool $showUncoveredFiles
|
||||
* @param bool $showOnlySummary
|
||||
* @var string
|
||||
*/
|
||||
public function __construct($lowUpperBound = 50, $highLowerBound = 90, $showUncoveredFiles = false, $showOnlySummary = false)
|
||||
private const COLOR_YELLOW = "\x1b[30;43m";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_RED = "\x1b[37;41m";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_HEADER = "\x1b[1;37;40m";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_RESET = "\x1b[0m";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_EOL = "\x1b[2K";
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $lowUpperBound;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $highLowerBound;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $showUncoveredFiles;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $showOnlySummary;
|
||||
|
||||
public function __construct(int $lowUpperBound = 50, int $highLowerBound = 90, bool $showUncoveredFiles = false, bool $showOnlySummary = false)
|
||||
{
|
||||
$this->lowUpperBound = $lowUpperBound;
|
||||
$this->highLowerBound = $highLowerBound;
|
||||
@@ -49,17 +79,10 @@ class Text
|
||||
$this->showOnlySummary = $showOnlySummary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CodeCoverage $coverage
|
||||
* @param bool $showColors
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, $showColors = false)
|
||||
public function process(CodeCoverage $coverage, bool $showColors = false): string
|
||||
{
|
||||
$output = PHP_EOL . PHP_EOL;
|
||||
$report = $coverage->getReport();
|
||||
unset($coverage);
|
||||
|
||||
$colors = [
|
||||
'header' => '',
|
||||
@@ -75,17 +98,20 @@ class Text
|
||||
$report->getNumTestedClassesAndTraits(),
|
||||
$report->getNumClassesAndTraits()
|
||||
);
|
||||
|
||||
$colors['methods'] = $this->getCoverageColor(
|
||||
$report->getNumTestedMethods(),
|
||||
$report->getNumMethods()
|
||||
);
|
||||
|
||||
$colors['lines'] = $this->getCoverageColor(
|
||||
$report->getNumExecutedLines(),
|
||||
$report->getNumExecutableLines()
|
||||
);
|
||||
$colors['reset'] = $this->colors['reset'];
|
||||
$colors['header'] = $this->colors['header'];
|
||||
$colors['eol'] = $this->colors['eol'];
|
||||
|
||||
$colors['reset'] = self::COLOR_RESET;
|
||||
$colors['header'] = self::COLOR_HEADER;
|
||||
$colors['eol'] = self::COLOR_EOL;
|
||||
}
|
||||
|
||||
$classes = \sprintf(
|
||||
@@ -169,17 +195,18 @@ class Text
|
||||
$classMethods++;
|
||||
$classStatements += $method['executableLines'];
|
||||
$coveredClassStatements += $method['executedLines'];
|
||||
|
||||
if ($method['coverage'] == 100) {
|
||||
$coveredMethods++;
|
||||
}
|
||||
}
|
||||
|
||||
$namespace = '';
|
||||
|
||||
if (!empty($class['package']['namespace'])) {
|
||||
$namespace = '\\' . $class['package']['namespace'] . '::';
|
||||
} elseif (!empty($class['package']['fullPackage'])) {
|
||||
$namespace = '@' . $class['package']['fullPackage'] . '::';
|
||||
} else {
|
||||
$namespace = '';
|
||||
}
|
||||
|
||||
$classCoverage[$namespace . $className] = [
|
||||
@@ -200,8 +227,7 @@ class Text
|
||||
$resetColor = '';
|
||||
|
||||
foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
|
||||
if ($classInfo['statementsCovered'] != 0 ||
|
||||
$this->showUncoveredFiles) {
|
||||
if ($this->showUncoveredFiles || $classInfo['statementsCovered'] != 0) {
|
||||
if ($showColors) {
|
||||
$methodColor = $this->getCoverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
|
||||
$linesColor = $this->getCoverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
|
||||
@@ -218,7 +244,7 @@ class Text
|
||||
return $output . PHP_EOL;
|
||||
}
|
||||
|
||||
protected function getCoverageColor($numberOfCoveredElements, $totalNumberOfElements)
|
||||
private function getCoverageColor(int $numberOfCoveredElements, int $totalNumberOfElements): string
|
||||
{
|
||||
$coverage = Util::percent(
|
||||
$numberOfCoveredElements,
|
||||
@@ -226,15 +252,17 @@ class Text
|
||||
);
|
||||
|
||||
if ($coverage >= $this->highLowerBound) {
|
||||
return $this->colors['green'];
|
||||
} elseif ($coverage > $this->lowUpperBound) {
|
||||
return $this->colors['yellow'];
|
||||
return self::COLOR_GREEN;
|
||||
}
|
||||
|
||||
return $this->colors['red'];
|
||||
if ($coverage > $this->lowUpperBound) {
|
||||
return self::COLOR_YELLOW;
|
||||
}
|
||||
|
||||
return self::COLOR_RED;
|
||||
}
|
||||
|
||||
protected function printCoverageCounts($numberOfCoveredElements, $totalNumberOfElements, $precision)
|
||||
private function printCoverageCounts(int $numberOfCoveredElements, int $totalNumberOfElements, int $precision): string
|
||||
{
|
||||
$format = '%' . $precision . 's';
|
||||
|
||||
@@ -248,9 +276,9 @@ class Text
|
||||
\sprintf($format, $totalNumberOfElements) . ')';
|
||||
}
|
||||
|
||||
private function format($color, $padding, $string)
|
||||
private function format($color, $padding, $string): string
|
||||
{
|
||||
$reset = $color ? $this->colors['reset'] : '';
|
||||
$reset = $color ? self::COLOR_RESET : '';
|
||||
|
||||
return $color . \str_pad($string, $padding) . $reset . PHP_EOL;
|
||||
}
|
||||
|
@@ -12,25 +12,19 @@ namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
|
||||
class BuildInformation
|
||||
final class BuildInformation
|
||||
{
|
||||
/**
|
||||
* @var \DOMElement
|
||||
*/
|
||||
private $contextNode;
|
||||
|
||||
/**
|
||||
* @param \DOMElement $contextNode
|
||||
*/
|
||||
public function __construct(\DOMElement $contextNode)
|
||||
{
|
||||
$this->contextNode = $contextNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Runtime $runtime
|
||||
*/
|
||||
public function setRuntimeInformation(Runtime $runtime)
|
||||
public function setRuntimeInformation(Runtime $runtime): void
|
||||
{
|
||||
$runtimeNode = $this->getNodeByName('runtime');
|
||||
|
||||
@@ -39,12 +33,6 @@ class BuildInformation
|
||||
$runtimeNode->setAttribute('url', $runtime->getVendorUrl());
|
||||
|
||||
$driverNode = $this->getNodeByName('driver');
|
||||
if ($runtime->isHHVM()) {
|
||||
$driverNode->setAttribute('name', 'hhvm');
|
||||
$driverNode->setAttribute('version', \constant('HHVM_VERSION'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($runtime->hasPHPDBGCodeCoverage()) {
|
||||
$driverNode->setAttribute('name', 'phpdbg');
|
||||
@@ -57,22 +45,28 @@ class BuildInformation
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @return \DOMElement
|
||||
*/
|
||||
private function getNodeByName($name)
|
||||
public function setBuildTime(\DateTime $date): void
|
||||
{
|
||||
$this->contextNode->setAttribute('time', $date->format('D M j G:i:s T Y'));
|
||||
}
|
||||
|
||||
public function setGeneratorVersions(string $phpUnitVersion, string $coverageVersion): void
|
||||
{
|
||||
$this->contextNode->setAttribute('phpunit', $phpUnitVersion);
|
||||
$this->contextNode->setAttribute('coverage', $coverageVersion);
|
||||
}
|
||||
|
||||
private function getNodeByName(string $name): \DOMElement
|
||||
{
|
||||
$node = $this->contextNode->getElementsByTagNameNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
$name
|
||||
)->item(0);
|
||||
|
||||
if (!$node) {
|
||||
$node = $this->contextNode->appendChild(
|
||||
$this->contextNode->ownerDocument->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
$name
|
||||
)
|
||||
);
|
||||
@@ -80,22 +74,4 @@ class BuildInformation
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $date
|
||||
*/
|
||||
public function setBuildTime(\DateTime $date)
|
||||
{
|
||||
$this->contextNode->setAttribute('time', $date->format('D M j G:i:s T Y'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $phpUnitVersion
|
||||
* @param string $coverageVersion
|
||||
*/
|
||||
public function setGeneratorVersions($phpUnitVersion, $coverageVersion)
|
||||
{
|
||||
$this->contextNode->setAttribute('phpunit', $phpUnitVersion);
|
||||
$this->contextNode->setAttribute('coverage', $coverageVersion);
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use SebastianBergmann\CodeCoverage\RuntimeException;
|
||||
|
||||
class Coverage
|
||||
final class Coverage
|
||||
{
|
||||
/**
|
||||
* @var \XMLWriter
|
||||
@@ -29,17 +29,20 @@ class Coverage
|
||||
*/
|
||||
private $finalized = false;
|
||||
|
||||
public function __construct(\DOMElement $context, $line)
|
||||
public function __construct(\DOMElement $context, string $line)
|
||||
{
|
||||
$this->contextNode = $context;
|
||||
|
||||
$this->writer = new \XMLWriter();
|
||||
$this->writer->openMemory();
|
||||
$this->writer->startElementNs(null, $context->nodeName, 'http://schema.phpunit.de/coverage/1.0');
|
||||
$this->writer->startElementNS(null, $context->nodeName, 'https://schema.phpunit.de/coverage/1.0');
|
||||
$this->writer->writeAttribute('nr', $line);
|
||||
}
|
||||
|
||||
public function addTest($test)
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function addTest(string $test): void
|
||||
{
|
||||
if ($this->finalized) {
|
||||
throw new RuntimeException('Coverage Report already finalized');
|
||||
@@ -50,7 +53,7 @@ class Coverage
|
||||
$this->writer->endElement();
|
||||
}
|
||||
|
||||
public function finalize()
|
||||
public function finalize(): void
|
||||
{
|
||||
$this->writer->endElement();
|
||||
|
||||
|
@@ -10,6 +10,6 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
class Directory extends Node
|
||||
final class Directory extends Node
|
||||
{
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ use SebastianBergmann\CodeCoverage\RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Version;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
|
||||
class Facade
|
||||
final class Facade
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
@@ -35,23 +35,17 @@ class Facade
|
||||
*/
|
||||
private $phpUnitVersion;
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*/
|
||||
public function __construct($version)
|
||||
public function __construct(string $version)
|
||||
{
|
||||
$this->phpUnitVersion = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CodeCoverage $coverage
|
||||
* @param string $target
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, $target)
|
||||
public function process(CodeCoverage $coverage, string $target): void
|
||||
{
|
||||
if (\substr($target, -1, 1) != DIRECTORY_SEPARATOR) {
|
||||
if (\substr($target, -1, 1) !== DIRECTORY_SEPARATOR) {
|
||||
$target .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
@@ -71,7 +65,7 @@ class Facade
|
||||
$this->saveDocument($this->project->asDom(), 'index');
|
||||
}
|
||||
|
||||
private function setBuildInformation()
|
||||
private function setBuildInformation(): void
|
||||
{
|
||||
$buildNode = $this->project->getBuildInformation();
|
||||
$buildNode->setRuntimeInformation(new Runtime());
|
||||
@@ -80,9 +74,9 @@ class Facade
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $directory
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function initTargetDirectory($directory)
|
||||
private function initTargetDirectory(string $directory): void
|
||||
{
|
||||
if (\file_exists($directory)) {
|
||||
if (!\is_dir($directory)) {
|
||||
@@ -96,33 +90,38 @@ class Facade
|
||||
"'$directory' exists but is not writable."
|
||||
);
|
||||
}
|
||||
} elseif (!@\mkdir($directory, 0777, true)) {
|
||||
} elseif (!$this->createDirectory($directory)) {
|
||||
throw new RuntimeException(
|
||||
"'$directory' could not be created."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function processDirectory(DirectoryNode $directory, Node $context)
|
||||
private function processDirectory(DirectoryNode $directory, Node $context): void
|
||||
{
|
||||
$dirname = $directory->getName();
|
||||
if ($this->project->getProjectSourceDirectory() === $dirname) {
|
||||
$dirname = '/';
|
||||
}
|
||||
$dirObject = $context->addDirectory($dirname);
|
||||
$directoryName = $directory->getName();
|
||||
|
||||
$this->setTotals($directory, $dirObject->getTotals());
|
||||
if ($this->project->getProjectSourceDirectory() === $directoryName) {
|
||||
$directoryName = '/';
|
||||
}
|
||||
|
||||
$directoryObject = $context->addDirectory($directoryName);
|
||||
|
||||
$this->setTotals($directory, $directoryObject->getTotals());
|
||||
|
||||
foreach ($directory->getDirectories() as $node) {
|
||||
$this->processDirectory($node, $dirObject);
|
||||
$this->processDirectory($node, $directoryObject);
|
||||
}
|
||||
|
||||
foreach ($directory->getFiles() as $node) {
|
||||
$this->processFile($node, $dirObject);
|
||||
$this->processFile($node, $directoryObject);
|
||||
}
|
||||
}
|
||||
|
||||
private function processFile(FileNode $file, Directory $context)
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function processFile(FileNode $file, Directory $context): void
|
||||
{
|
||||
$fileObject = $context->addFile(
|
||||
$file->getName(),
|
||||
@@ -135,6 +134,7 @@ class Facade
|
||||
$file->getPath(),
|
||||
\strlen($this->project->getProjectSourceDirectory())
|
||||
);
|
||||
|
||||
$fileReport = new Report($path);
|
||||
|
||||
$this->setTotals($file, $fileReport->getTotals());
|
||||
@@ -168,7 +168,7 @@ class Facade
|
||||
$this->saveDocument($fileReport->asDom(), $file->getId());
|
||||
}
|
||||
|
||||
private function processUnit($unit, Report $report)
|
||||
private function processUnit(array $unit, Report $report): void
|
||||
{
|
||||
if (isset($unit['className'])) {
|
||||
$unitObject = $report->getClassObject($unit['className']);
|
||||
@@ -206,7 +206,7 @@ class Facade
|
||||
}
|
||||
}
|
||||
|
||||
private function processFunction($function, Report $report)
|
||||
private function processFunction(array $function, Report $report): void
|
||||
{
|
||||
$functionObject = $report->getFunctionObject($function['functionName']);
|
||||
|
||||
@@ -216,12 +216,12 @@ class Facade
|
||||
$functionObject->setTotals($function['executableLines'], $function['executedLines'], $function['coverage']);
|
||||
}
|
||||
|
||||
private function processTests(array $tests)
|
||||
private function processTests(array $tests): void
|
||||
{
|
||||
$testsObject = $this->project->getTests();
|
||||
|
||||
foreach ($tests as $test => $result) {
|
||||
if ($test == 'UNCOVERED_FILES_FROM_WHITELIST') {
|
||||
if ($test === 'UNCOVERED_FILES_FROM_WHITELIST') {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ class Facade
|
||||
}
|
||||
}
|
||||
|
||||
private function setTotals(AbstractNode $node, Totals $totals)
|
||||
private function setTotals(AbstractNode $node, Totals $totals): void
|
||||
{
|
||||
$loc = $node->getLinesOfCode();
|
||||
|
||||
@@ -262,15 +262,15 @@ class Facade
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getTargetDirectory()
|
||||
private function getTargetDirectory(): string
|
||||
{
|
||||
return $this->target;
|
||||
}
|
||||
|
||||
protected function saveDocument(\DOMDocument $document, $name)
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function saveDocument(\DOMDocument $document, string $name): void
|
||||
{
|
||||
$filename = \sprintf('%s/%s.xml', $this->getTargetDirectory(), $name);
|
||||
|
||||
@@ -280,4 +280,9 @@ class Facade
|
||||
|
||||
$document->save($filename);
|
||||
}
|
||||
|
||||
private function createDirectory(string $directory): bool
|
||||
{
|
||||
return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory));
|
||||
}
|
||||
}
|
||||
|
@@ -28,30 +28,14 @@ class File
|
||||
$this->contextNode = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DOMElement
|
||||
*/
|
||||
protected function getContextNode()
|
||||
{
|
||||
return $this->contextNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DOMDocument
|
||||
*/
|
||||
protected function getDomDocument()
|
||||
{
|
||||
return $this->dom;
|
||||
}
|
||||
|
||||
public function getTotals()
|
||||
public function getTotals(): Totals
|
||||
{
|
||||
$totalsContainer = $this->contextNode->firstChild;
|
||||
|
||||
if (!$totalsContainer) {
|
||||
$totalsContainer = $this->contextNode->appendChild(
|
||||
$this->dom->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'totals'
|
||||
)
|
||||
);
|
||||
@@ -60,17 +44,17 @@ class File
|
||||
return new Totals($totalsContainer);
|
||||
}
|
||||
|
||||
public function getLineCoverage($line)
|
||||
public function getLineCoverage(string $line): Coverage
|
||||
{
|
||||
$coverage = $this->contextNode->getElementsByTagNameNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'coverage'
|
||||
)->item(0);
|
||||
|
||||
if (!$coverage) {
|
||||
$coverage = $this->contextNode->appendChild(
|
||||
$this->dom->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'coverage'
|
||||
)
|
||||
);
|
||||
@@ -78,11 +62,21 @@ class File
|
||||
|
||||
$lineNode = $coverage->appendChild(
|
||||
$this->dom->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'line'
|
||||
)
|
||||
);
|
||||
|
||||
return new Coverage($lineNode, $line);
|
||||
}
|
||||
|
||||
protected function getContextNode(): \DOMElement
|
||||
{
|
||||
return $this->contextNode;
|
||||
}
|
||||
|
||||
protected function getDomDocument(): \DOMDocument
|
||||
{
|
||||
return $this->dom;
|
||||
}
|
||||
}
|
||||
|
@@ -10,31 +10,26 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
class Method
|
||||
final class Method
|
||||
{
|
||||
/**
|
||||
* @var \DOMElement
|
||||
*/
|
||||
private $contextNode;
|
||||
|
||||
public function __construct(\DOMElement $context, $name)
|
||||
public function __construct(\DOMElement $context, string $name)
|
||||
{
|
||||
$this->contextNode = $context;
|
||||
|
||||
$this->setName($name);
|
||||
}
|
||||
|
||||
private function setName($name)
|
||||
{
|
||||
$this->contextNode->setAttribute('name', $name);
|
||||
}
|
||||
|
||||
public function setSignature($signature)
|
||||
public function setSignature(string $signature): void
|
||||
{
|
||||
$this->contextNode->setAttribute('signature', $signature);
|
||||
}
|
||||
|
||||
public function setLines($start, $end = null)
|
||||
public function setLines(string $start, ?string $end = null): void
|
||||
{
|
||||
$this->contextNode->setAttribute('start', $start);
|
||||
|
||||
@@ -43,15 +38,20 @@ class Method
|
||||
}
|
||||
}
|
||||
|
||||
public function setTotals($executable, $executed, $coverage)
|
||||
public function setTotals(string $executable, string $executed, string $coverage): void
|
||||
{
|
||||
$this->contextNode->setAttribute('executable', $executable);
|
||||
$this->contextNode->setAttribute('executed', $executed);
|
||||
$this->contextNode->setAttribute('coverage', $coverage);
|
||||
}
|
||||
|
||||
public function setCrap($crap)
|
||||
public function setCrap(string $crap): void
|
||||
{
|
||||
$this->contextNode->setAttribute('crap', $crap);
|
||||
}
|
||||
|
||||
private function setName(string $name): void
|
||||
{
|
||||
$this->contextNode->setAttribute('name', $name);
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
class Node
|
||||
abstract class Node
|
||||
{
|
||||
/**
|
||||
* @var \DOMDocument
|
||||
@@ -27,30 +27,19 @@ class Node
|
||||
$this->setContextNode($context);
|
||||
}
|
||||
|
||||
protected function setContextNode(\DOMElement $context)
|
||||
{
|
||||
$this->dom = $context->ownerDocument;
|
||||
$this->contextNode = $context;
|
||||
}
|
||||
|
||||
public function getDom()
|
||||
public function getDom(): \DOMDocument
|
||||
{
|
||||
return $this->dom;
|
||||
}
|
||||
|
||||
protected function getContextNode()
|
||||
{
|
||||
return $this->contextNode;
|
||||
}
|
||||
|
||||
public function getTotals()
|
||||
public function getTotals(): Totals
|
||||
{
|
||||
$totalsContainer = $this->getContextNode()->firstChild;
|
||||
|
||||
if (!$totalsContainer) {
|
||||
$totalsContainer = $this->getContextNode()->appendChild(
|
||||
$this->dom->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'totals'
|
||||
)
|
||||
);
|
||||
@@ -59,10 +48,10 @@ class Node
|
||||
return new Totals($totalsContainer);
|
||||
}
|
||||
|
||||
public function addDirectory($name)
|
||||
public function addDirectory(string $name): Directory
|
||||
{
|
||||
$dirNode = $this->getDom()->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'directory'
|
||||
);
|
||||
|
||||
@@ -72,10 +61,10 @@ class Node
|
||||
return new Directory($dirNode);
|
||||
}
|
||||
|
||||
public function addFile($name, $href)
|
||||
public function addFile(string $name, string $href): File
|
||||
{
|
||||
$fileNode = $this->getDom()->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'file'
|
||||
);
|
||||
|
||||
@@ -85,4 +74,15 @@ class Node
|
||||
|
||||
return new File($fileNode);
|
||||
}
|
||||
|
||||
protected function setContextNode(\DOMElement $context): void
|
||||
{
|
||||
$this->dom = $context->ownerDocument;
|
||||
$this->contextNode = $context;
|
||||
}
|
||||
|
||||
protected function getContextNode(): \DOMElement
|
||||
{
|
||||
return $this->contextNode;
|
||||
}
|
||||
}
|
||||
|
@@ -10,57 +10,30 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
class Project extends Node
|
||||
final class Project extends Node
|
||||
{
|
||||
/**
|
||||
* @param string $directory
|
||||
*/
|
||||
public function __construct($directory)
|
||||
public function __construct(string $directory)
|
||||
{
|
||||
$this->init();
|
||||
$this->setProjectSourceDirectory($directory);
|
||||
}
|
||||
|
||||
private function init()
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><build/><project/></phpunit>');
|
||||
|
||||
$this->setContextNode(
|
||||
$dom->getElementsByTagNameNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'project'
|
||||
)->item(0)
|
||||
);
|
||||
}
|
||||
|
||||
private function setProjectSourceDirectory($name)
|
||||
{
|
||||
$this->getContextNode()->setAttribute('source', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProjectSourceDirectory()
|
||||
public function getProjectSourceDirectory(): string
|
||||
{
|
||||
return $this->getContextNode()->getAttribute('source');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BuildInformation
|
||||
*/
|
||||
public function getBuildInformation()
|
||||
public function getBuildInformation(): BuildInformation
|
||||
{
|
||||
$buildNode = $this->getDom()->getElementsByTagNameNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'build'
|
||||
)->item(0);
|
||||
|
||||
if (!$buildNode) {
|
||||
$buildNode = $this->getDom()->documentElement->appendChild(
|
||||
$this->getDom()->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'build'
|
||||
)
|
||||
);
|
||||
@@ -69,17 +42,17 @@ class Project extends Node
|
||||
return new BuildInformation($buildNode);
|
||||
}
|
||||
|
||||
public function getTests()
|
||||
public function getTests(): Tests
|
||||
{
|
||||
$testsNode = $this->getContextNode()->getElementsByTagNameNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'tests'
|
||||
)->item(0);
|
||||
|
||||
if (!$testsNode) {
|
||||
$testsNode = $this->getContextNode()->appendChild(
|
||||
$this->getDom()->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'tests'
|
||||
)
|
||||
);
|
||||
@@ -88,8 +61,26 @@ class Project extends Node
|
||||
return new Tests($testsNode);
|
||||
}
|
||||
|
||||
public function asDom()
|
||||
public function asDom(): \DOMDocument
|
||||
{
|
||||
return $this->getDom();
|
||||
}
|
||||
|
||||
private function init(): void
|
||||
{
|
||||
$dom = new \DOMDocument;
|
||||
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="https://schema.phpunit.de/coverage/1.0"><build/><project/></phpunit>');
|
||||
|
||||
$this->setContextNode(
|
||||
$dom->getElementsByTagNameNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'project'
|
||||
)->item(0)
|
||||
);
|
||||
}
|
||||
|
||||
private function setProjectSourceDirectory(string $name): void
|
||||
{
|
||||
$this->getContextNode()->setAttribute('source', $name);
|
||||
}
|
||||
}
|
||||
|
@@ -10,38 +10,33 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
class Report extends File
|
||||
final class Report extends File
|
||||
{
|
||||
public function __construct($name)
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
|
||||
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="https://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
|
||||
|
||||
$contextNode = $dom->getElementsByTagNameNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'file'
|
||||
)->item(0);
|
||||
|
||||
parent::__construct($contextNode);
|
||||
|
||||
$this->setName($name);
|
||||
}
|
||||
|
||||
private function setName($name)
|
||||
{
|
||||
$this->getContextNode()->setAttribute('name', \basename($name));
|
||||
$this->getContextNode()->setAttribute('path', \dirname($name));
|
||||
}
|
||||
|
||||
public function asDom()
|
||||
public function asDom(): \DOMDocument
|
||||
{
|
||||
return $this->getDomDocument();
|
||||
}
|
||||
|
||||
public function getFunctionObject($name)
|
||||
public function getFunctionObject($name): Method
|
||||
{
|
||||
$node = $this->getContextNode()->appendChild(
|
||||
$this->getDomDocument()->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'function'
|
||||
)
|
||||
);
|
||||
@@ -49,39 +44,27 @@ class Report extends File
|
||||
return new Method($node, $name);
|
||||
}
|
||||
|
||||
public function getClassObject($name)
|
||||
public function getClassObject($name): Unit
|
||||
{
|
||||
return $this->getUnitObject('class', $name);
|
||||
}
|
||||
|
||||
public function getTraitObject($name)
|
||||
public function getTraitObject($name): Unit
|
||||
{
|
||||
return $this->getUnitObject('trait', $name);
|
||||
}
|
||||
|
||||
private function getUnitObject($tagName, $name)
|
||||
{
|
||||
$node = $this->getContextNode()->appendChild(
|
||||
$this->getDomDocument()->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
$tagName
|
||||
)
|
||||
);
|
||||
|
||||
return new Unit($node, $name);
|
||||
}
|
||||
|
||||
public function getSource()
|
||||
public function getSource(): Source
|
||||
{
|
||||
$source = $this->getContextNode()->getElementsByTagNameNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'source'
|
||||
)->item(0);
|
||||
|
||||
if (!$source) {
|
||||
$source = $this->getContextNode()->appendChild(
|
||||
$this->getDomDocument()->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'source'
|
||||
)
|
||||
);
|
||||
@@ -89,4 +72,22 @@ class Report extends File
|
||||
|
||||
return new Source($source);
|
||||
}
|
||||
|
||||
private function setName($name): void
|
||||
{
|
||||
$this->getContextNode()->setAttribute('name', \basename($name));
|
||||
$this->getContextNode()->setAttribute('path', \dirname($name));
|
||||
}
|
||||
|
||||
private function getUnitObject($tagName, $name): Unit
|
||||
{
|
||||
$node = $this->getContextNode()->appendChild(
|
||||
$this->getDomDocument()->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
$tagName
|
||||
)
|
||||
);
|
||||
|
||||
return new Unit($node, $name);
|
||||
}
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ use TheSeer\Tokenizer\NamespaceUri;
|
||||
use TheSeer\Tokenizer\Tokenizer;
|
||||
use TheSeer\Tokenizer\XMLSerializer;
|
||||
|
||||
class Source
|
||||
final class Source
|
||||
{
|
||||
/** @var \DOMElement */
|
||||
private $context;
|
||||
@@ -27,10 +27,7 @@ class Source
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
*/
|
||||
public function setSourceCode(string $source)
|
||||
public function setSourceCode(string $source): void
|
||||
{
|
||||
$context = $this->context;
|
||||
|
||||
|
@@ -10,18 +10,19 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
class Tests
|
||||
final class Tests
|
||||
{
|
||||
private $contextNode;
|
||||
|
||||
private $codeMap = [
|
||||
0 => 'PASSED', // PHPUnit_Runner_BaseTestRunner::STATUS_PASSED
|
||||
1 => 'SKIPPED', // PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED
|
||||
2 => 'INCOMPLETE', // PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE
|
||||
3 => 'FAILURE', // PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE
|
||||
4 => 'ERROR', // PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
|
||||
5 => 'RISKY', // PHPUnit_Runner_BaseTestRunner::STATUS_RISKY
|
||||
6 => 'WARNING' // PHPUnit_Runner_BaseTestRunner::STATUS_WARNING
|
||||
-1 => 'UNKNOWN', // PHPUnit_Runner_BaseTestRunner::STATUS_UNKNOWN
|
||||
0 => 'PASSED', // PHPUnit_Runner_BaseTestRunner::STATUS_PASSED
|
||||
1 => 'SKIPPED', // PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED
|
||||
2 => 'INCOMPLETE', // PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE
|
||||
3 => 'FAILURE', // PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE
|
||||
4 => 'ERROR', // PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
|
||||
5 => 'RISKY', // PHPUnit_Runner_BaseTestRunner::STATUS_RISKY
|
||||
6 => 'WARNING' // PHPUnit_Runner_BaseTestRunner::STATUS_WARNING
|
||||
];
|
||||
|
||||
public function __construct(\DOMElement $context)
|
||||
@@ -29,11 +30,11 @@ class Tests
|
||||
$this->contextNode = $context;
|
||||
}
|
||||
|
||||
public function addTest($test, array $result)
|
||||
public function addTest(string $test, array $result): void
|
||||
{
|
||||
$node = $this->contextNode->appendChild(
|
||||
$this->contextNode->ownerDocument->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'test'
|
||||
)
|
||||
);
|
||||
|
@@ -12,7 +12,7 @@ namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use SebastianBergmann\CodeCoverage\Util;
|
||||
|
||||
class Totals
|
||||
final class Totals
|
||||
{
|
||||
/**
|
||||
* @var \DOMNode
|
||||
@@ -50,27 +50,27 @@ class Totals
|
||||
$dom = $container->ownerDocument;
|
||||
|
||||
$this->linesNode = $dom->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'lines'
|
||||
);
|
||||
|
||||
$this->methodsNode = $dom->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'methods'
|
||||
);
|
||||
|
||||
$this->functionsNode = $dom->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'functions'
|
||||
);
|
||||
|
||||
$this->classesNode = $dom->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'classes'
|
||||
);
|
||||
|
||||
$this->traitsNode = $dom->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'traits'
|
||||
);
|
||||
|
||||
@@ -81,12 +81,12 @@ class Totals
|
||||
$container->appendChild($this->traitsNode);
|
||||
}
|
||||
|
||||
public function getContainer()
|
||||
public function getContainer(): \DOMNode
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
public function setNumLines($loc, $cloc, $ncloc, $executable, $executed)
|
||||
public function setNumLines(int $loc, int $cloc, int $ncloc, int $executable, int $executed): void
|
||||
{
|
||||
$this->linesNode->setAttribute('total', $loc);
|
||||
$this->linesNode->setAttribute('comments', $cloc);
|
||||
@@ -95,47 +95,47 @@ class Totals
|
||||
$this->linesNode->setAttribute('executed', $executed);
|
||||
$this->linesNode->setAttribute(
|
||||
'percent',
|
||||
$executable === 0 ? 0 : \sprintf('%01.2F', Util::percent($executed, $executable, false))
|
||||
$executable === 0 ? 0 : \sprintf('%01.2F', Util::percent($executed, $executable))
|
||||
);
|
||||
}
|
||||
|
||||
public function setNumClasses($count, $tested)
|
||||
public function setNumClasses(int $count, int $tested): void
|
||||
{
|
||||
$this->classesNode->setAttribute('count', $count);
|
||||
$this->classesNode->setAttribute('tested', $tested);
|
||||
$this->classesNode->setAttribute(
|
||||
'percent',
|
||||
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count, false))
|
||||
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count))
|
||||
);
|
||||
}
|
||||
|
||||
public function setNumTraits($count, $tested)
|
||||
public function setNumTraits(int $count, int $tested): void
|
||||
{
|
||||
$this->traitsNode->setAttribute('count', $count);
|
||||
$this->traitsNode->setAttribute('tested', $tested);
|
||||
$this->traitsNode->setAttribute(
|
||||
'percent',
|
||||
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count, false))
|
||||
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count))
|
||||
);
|
||||
}
|
||||
|
||||
public function setNumMethods($count, $tested)
|
||||
public function setNumMethods(int $count, int $tested): void
|
||||
{
|
||||
$this->methodsNode->setAttribute('count', $count);
|
||||
$this->methodsNode->setAttribute('tested', $tested);
|
||||
$this->methodsNode->setAttribute(
|
||||
'percent',
|
||||
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count, false))
|
||||
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count))
|
||||
);
|
||||
}
|
||||
|
||||
public function setNumFunctions($count, $tested)
|
||||
public function setNumFunctions(int $count, int $tested): void
|
||||
{
|
||||
$this->functionsNode->setAttribute('count', $count);
|
||||
$this->functionsNode->setAttribute('tested', $tested);
|
||||
$this->functionsNode->setAttribute(
|
||||
'percent',
|
||||
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count, false))
|
||||
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -10,48 +10,43 @@
|
||||
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
class Unit
|
||||
final class Unit
|
||||
{
|
||||
/**
|
||||
* @var \DOMElement
|
||||
*/
|
||||
private $contextNode;
|
||||
|
||||
public function __construct(\DOMElement $context, $name)
|
||||
public function __construct(\DOMElement $context, string $name)
|
||||
{
|
||||
$this->contextNode = $context;
|
||||
|
||||
$this->setName($name);
|
||||
}
|
||||
|
||||
private function setName($name)
|
||||
{
|
||||
$this->contextNode->setAttribute('name', $name);
|
||||
}
|
||||
|
||||
public function setLines($start, $executable, $executed)
|
||||
public function setLines(int $start, int $executable, int $executed): void
|
||||
{
|
||||
$this->contextNode->setAttribute('start', $start);
|
||||
$this->contextNode->setAttribute('executable', $executable);
|
||||
$this->contextNode->setAttribute('executed', $executed);
|
||||
}
|
||||
|
||||
public function setCrap($crap)
|
||||
public function setCrap(float $crap): void
|
||||
{
|
||||
$this->contextNode->setAttribute('crap', $crap);
|
||||
}
|
||||
|
||||
public function setPackage($full, $package, $sub, $category)
|
||||
public function setPackage(string $full, string $package, string $sub, string $category): void
|
||||
{
|
||||
$node = $this->contextNode->getElementsByTagNameNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'package'
|
||||
)->item(0);
|
||||
|
||||
if (!$node) {
|
||||
$node = $this->contextNode->appendChild(
|
||||
$this->contextNode->ownerDocument->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'package'
|
||||
)
|
||||
);
|
||||
@@ -63,17 +58,17 @@ class Unit
|
||||
$node->setAttribute('category', $category);
|
||||
}
|
||||
|
||||
public function setNamespace($namespace)
|
||||
public function setNamespace(string $namespace): void
|
||||
{
|
||||
$node = $this->contextNode->getElementsByTagNameNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'namespace'
|
||||
)->item(0);
|
||||
|
||||
if (!$node) {
|
||||
$node = $this->contextNode->appendChild(
|
||||
$this->contextNode->ownerDocument->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'namespace'
|
||||
)
|
||||
);
|
||||
@@ -82,15 +77,20 @@ class Unit
|
||||
$node->setAttribute('name', $namespace);
|
||||
}
|
||||
|
||||
public function addMethod($name)
|
||||
public function addMethod(string $name): Method
|
||||
{
|
||||
$node = $this->contextNode->appendChild(
|
||||
$this->contextNode->ownerDocument->createElementNS(
|
||||
'http://schema.phpunit.de/coverage/1.0',
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'method'
|
||||
)
|
||||
);
|
||||
|
||||
return new Method($node, $name);
|
||||
}
|
||||
|
||||
private function setName(string $name): void
|
||||
{
|
||||
$this->contextNode->setAttribute('name', $name);
|
||||
}
|
||||
}
|
||||
|
@@ -13,17 +13,12 @@ namespace SebastianBergmann\CodeCoverage;
|
||||
/**
|
||||
* Utility methods.
|
||||
*/
|
||||
class Util
|
||||
final class Util
|
||||
{
|
||||
/**
|
||||
* @param float $a
|
||||
* @param float $b
|
||||
* @param bool $asString
|
||||
* @param bool $fixedWidth
|
||||
*
|
||||
* @return float|int|string
|
||||
*/
|
||||
public static function percent($a, $b, $asString = false, $fixedWidth = false)
|
||||
public static function percent(float $a, float $b, bool $asString = false, bool $fixedWidth = false)
|
||||
{
|
||||
if ($asString && $b == 0) {
|
||||
return '';
|
||||
|
12
vendor/phpunit/php-code-coverage/src/Version.php
vendored
12
vendor/phpunit/php-code-coverage/src/Version.php
vendored
@@ -12,17 +12,17 @@ namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use SebastianBergmann\Version as VersionId;
|
||||
|
||||
class Version
|
||||
final class Version
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $version;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function id()
|
||||
public static function id(): string
|
||||
{
|
||||
if (self::$version === null) {
|
||||
$version = new VersionId('5.3.2', \dirname(__DIR__));
|
||||
$version = new VersionId('6.0.7', \dirname(__DIR__));
|
||||
self::$version = $version->getVersion();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user