Composer upgrade
This commit is contained in:
+41
-3
@@ -2,6 +2,41 @@
|
||||
|
||||
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
|
||||
|
||||
## [9.2.13] - 2022-02-23
|
||||
|
||||
### Changed
|
||||
|
||||
* The contents of the static analysis sourcecode files is now used to generate the static analysis cache version identifier
|
||||
|
||||
### Fixed
|
||||
|
||||
* Reverted rename of `SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData` to `SebastianBergmann\CodeCoverage\Data\ProcessedCodeCoverageData` (this class is marked as `@internal` and not covered by the backward compatibility promise, but it is (still) used directly by PHPUnit)
|
||||
* Reverted rename of `SebastianBergmann\CodeCoverage\RawCodeCoverageData` to `SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData` (this class is marked as `@internal` and not covered by the backward compatibility promise, but it is (still) used directly by PHPUnit)
|
||||
* The `ArrayDim`, `Cast`, and `MethodCall` nodes are now considered when determining whether a line of code is executable or not
|
||||
|
||||
## [9.2.12] - 2022-02-23 [YANKED]
|
||||
|
||||
### Changed
|
||||
|
||||
* [#898](https://github.com/sebastianbergmann/php-code-coverage/pull/898): Use content hash instead of `filemtime()` to determine cache hit/miss
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#736](https://github.com/sebastianbergmann/php-code-coverage/issues/736): HTML report generator allows invalid values for low upper bound and high lower bound
|
||||
* [#854](https://github.com/sebastianbergmann/php-code-coverage/issues/854): "Class Coverage Distribution" and "Class Complexity" graphs are not displayed at full width
|
||||
* [#897](https://github.com/sebastianbergmann/php-code-coverage/issues/897): `declare(strict_types=1)` marked as uncovered
|
||||
|
||||
## [9.2.11] - 2022-02-18
|
||||
|
||||
### Changed
|
||||
|
||||
* `CoveredFileAnalyser` and `UncoveredFileAnalyser` have been combined to `FileAnalyser`
|
||||
* Updated bundled CSS/JavaScript components used for HTML report: Bootstrap 4.6.1, jQuery 3.6.0, and popper.js 1.16.1
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#889](https://github.com/sebastianbergmann/php-code-coverage/issues/889): Code Coverage depends on autoload order
|
||||
|
||||
## [9.2.10] - 2021-12-05
|
||||
|
||||
### Fixed
|
||||
@@ -88,7 +123,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#810](https://github.com/sebastianbergmann/php-code-coverage/issues/810): `SebastianBergmann\CodeCoverage\Driver\Driver::forLineCoverage()` and `SebastianBergmann\CodeCoverage\Driver\Driver::forLineAndPathCoverage()` are marked as internal
|
||||
* [#810](https://github.com/sebastianbergmann/php-code-coverage/issues/810): `SebastianBergmann\CodeCoverage\Driver\Driver::forLineCoverage()` and `SebastianBergmann\CodeCoverage\Driver\Driver::forLineAndPathCoverage()` are marked as internal
|
||||
|
||||
### Removed
|
||||
|
||||
@@ -286,7 +321,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
|
||||
|
||||
### Changed
|
||||
|
||||
* Update HTML report Bootstrap 4.3.1, jQuery 3.4.1, and popper.js 1.15.0
|
||||
* Updated bundled CSS/JavaScript components used for HTML report: Bootstrap 4.3.1, jQuery 3.4.1, and popper.js 1.15.0
|
||||
|
||||
## [7.0.7] - 2019-07-25
|
||||
|
||||
@@ -322,7 +357,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
|
||||
|
||||
### Changed
|
||||
|
||||
* Updated HTML report to Bootstrap 4.3.0
|
||||
* Updated bundled CSS/JavaScript components used for HTML report: Bootstrap 4.3.0
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -349,6 +384,9 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
|
||||
|
||||
* This component is no longer supported on PHP 7.1
|
||||
|
||||
[9.2.13]: https://github.com/sebastianbergmann/php-code-coverage/compare/c011a0b6aaa4acd2f39b7f51fb4ad4442b6ec631...9.2.13
|
||||
[9.2.12]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.11...c011a0b6aaa4acd2f39b7f51fb4ad4442b6ec631
|
||||
[9.2.11]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.10...9.2.11
|
||||
[9.2.10]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.9...9.2.10
|
||||
[9.2.9]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.8...9.2.9
|
||||
[9.2.8]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.7...9.2.8
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
php-code-coverage
|
||||
|
||||
Copyright (c) 2009-2021, Sebastian Bergmann <sebastian@phpunit.de>.
|
||||
Copyright (c) 2009-2022, Sebastian Bergmann <sebastian@phpunit.de>.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
+33
-44
@@ -29,12 +29,9 @@ use ReflectionClass;
|
||||
use SebastianBergmann\CodeCoverage\Driver\Driver;
|
||||
use SebastianBergmann\CodeCoverage\Node\Builder;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\CachingCoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\CachingUncoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\CoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingCoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingUncoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\UncoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\CachingFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingFileAnalyser;
|
||||
use SebastianBergmann\CodeUnitReverseLookup\Wizard;
|
||||
|
||||
/**
|
||||
@@ -109,14 +106,9 @@ final class CodeCoverage
|
||||
private $parentClassesExcludedFromUnintentionallyCoveredCodeCheck = [];
|
||||
|
||||
/**
|
||||
* @var ?CoveredFileAnalyser
|
||||
* @var ?FileAnalyser
|
||||
*/
|
||||
private $coveredFileAnalyser;
|
||||
|
||||
/**
|
||||
* @var ?UncoveredFileAnalyser
|
||||
*/
|
||||
private $uncoveredFileAnalyser;
|
||||
private $analyser;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
@@ -136,7 +128,7 @@ final class CodeCoverage
|
||||
*/
|
||||
public function getReport(): Directory
|
||||
{
|
||||
return (new Builder($this->coveredFileAnalyser()))->build($this);
|
||||
return (new Builder($this->analyser()))->build($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,8 +159,6 @@ final class CodeCoverage
|
||||
$this->processUncoveredFilesFromFilter();
|
||||
} elseif ($this->includeUncoveredFiles) {
|
||||
$this->addUncoveredFilesFromFilter();
|
||||
} else {
|
||||
$this->data->removeFilesWithNoCoverage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +248,8 @@ final class CodeCoverage
|
||||
|
||||
$this->applyFilter($rawData);
|
||||
|
||||
$this->applyExecutableLinesFilter($rawData);
|
||||
|
||||
if ($this->useAnnotationsForIgnoringCode) {
|
||||
$this->applyIgnoredLinesFilter($rawData);
|
||||
}
|
||||
@@ -468,7 +460,8 @@ final class CodeCoverage
|
||||
|
||||
if (is_array($linesToBeCovered)) {
|
||||
foreach ($linesToBeCovered as $fileToBeCovered => $includedLines) {
|
||||
$rawData->keepCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
|
||||
$rawData->keepLineCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
|
||||
$rawData->keepFunctionCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -486,6 +479,20 @@ final class CodeCoverage
|
||||
}
|
||||
}
|
||||
|
||||
private function applyExecutableLinesFilter(RawCodeCoverageData $data): void
|
||||
{
|
||||
foreach (array_keys($data->lineCoverage()) as $filename) {
|
||||
if (!$this->filter->isFile($filename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data->keepLineCoverageDataOnlyForLines(
|
||||
$filename,
|
||||
$this->analyser()->executableLinesIn($filename)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function applyIgnoredLinesFilter(RawCodeCoverageData $data): void
|
||||
{
|
||||
foreach (array_keys($data->lineCoverage()) as $filename) {
|
||||
@@ -495,7 +502,7 @@ final class CodeCoverage
|
||||
|
||||
$data->removeCoverageDataForLines(
|
||||
$filename,
|
||||
$this->coveredFileAnalyser()->ignoredLinesFor($filename)
|
||||
$this->analyser()->ignoredLinesFor($filename)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -515,7 +522,7 @@ final class CodeCoverage
|
||||
$this->append(
|
||||
RawCodeCoverageData::fromUncoveredFile(
|
||||
$uncoveredFile,
|
||||
$this->uncoveredFileAnalyser()
|
||||
$this->analyser()
|
||||
),
|
||||
self::UNCOVERED_FILES
|
||||
);
|
||||
@@ -646,42 +653,24 @@ final class CodeCoverage
|
||||
return array_values($unintentionallyCoveredUnits);
|
||||
}
|
||||
|
||||
private function coveredFileAnalyser(): CoveredFileAnalyser
|
||||
private function analyser(): FileAnalyser
|
||||
{
|
||||
if ($this->coveredFileAnalyser !== null) {
|
||||
return $this->coveredFileAnalyser;
|
||||
if ($this->analyser !== null) {
|
||||
return $this->analyser;
|
||||
}
|
||||
|
||||
$this->coveredFileAnalyser = new ParsingCoveredFileAnalyser(
|
||||
$this->analyser = new ParsingFileAnalyser(
|
||||
$this->useAnnotationsForIgnoringCode,
|
||||
$this->ignoreDeprecatedCode
|
||||
);
|
||||
|
||||
if ($this->cachesStaticAnalysis()) {
|
||||
$this->coveredFileAnalyser = new CachingCoveredFileAnalyser(
|
||||
$this->analyser = new CachingFileAnalyser(
|
||||
$this->cacheDirectory,
|
||||
$this->coveredFileAnalyser
|
||||
$this->analyser
|
||||
);
|
||||
}
|
||||
|
||||
return $this->coveredFileAnalyser;
|
||||
}
|
||||
|
||||
private function uncoveredFileAnalyser(): UncoveredFileAnalyser
|
||||
{
|
||||
if ($this->uncoveredFileAnalyser !== null) {
|
||||
return $this->uncoveredFileAnalyser;
|
||||
}
|
||||
|
||||
$this->uncoveredFileAnalyser = new ParsingUncoveredFileAnalyser;
|
||||
|
||||
if ($this->cachesStaticAnalysis()) {
|
||||
$this->uncoveredFileAnalyser = new CachingUncoveredFileAnalyser(
|
||||
$this->cacheDirectory,
|
||||
$this->uncoveredFileAnalyser
|
||||
);
|
||||
}
|
||||
|
||||
return $this->uncoveredFileAnalyser;
|
||||
return $this->analyser;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -7,9 +7,10 @@
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
namespace SebastianBergmann\CodeCoverage\Util;
|
||||
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Exception;
|
||||
|
||||
final class DirectoryCouldNotBeCreatedException extends RuntimeException implements Exception
|
||||
{
|
||||
|
||||
@@ -14,8 +14,7 @@ use function array_merge;
|
||||
use function str_replace;
|
||||
use function substr;
|
||||
use Countable;
|
||||
use SebastianBergmann\CodeCoverage\Percentage;
|
||||
use SebastianBergmann\LinesOfCode\LinesOfCode;
|
||||
use SebastianBergmann\CodeCoverage\Util\Percentage;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
@@ -219,7 +218,10 @@ abstract class AbstractNode implements Countable
|
||||
|
||||
abstract public function functions(): array;
|
||||
|
||||
abstract public function linesOfCode(): LinesOfCode;
|
||||
/**
|
||||
* @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int}
|
||||
*/
|
||||
abstract public function linesOfCode(): array;
|
||||
|
||||
abstract public function numberOfExecutableLines(): int;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ use function strpos;
|
||||
use function substr;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\CoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
@@ -30,13 +30,13 @@ use SebastianBergmann\CodeCoverage\StaticAnalysis\CoveredFileAnalyser;
|
||||
final class Builder
|
||||
{
|
||||
/**
|
||||
* @var CoveredFileAnalyser
|
||||
* @var FileAnalyser
|
||||
*/
|
||||
private $coveredFileAnalyser;
|
||||
private $analyser;
|
||||
|
||||
public function __construct(CoveredFileAnalyser $coveredFileAnalyser)
|
||||
public function __construct(FileAnalyser $analyser)
|
||||
{
|
||||
$this->coveredFileAnalyser = $coveredFileAnalyser;
|
||||
$this->analyser = $analyser;
|
||||
}
|
||||
|
||||
public function build(CodeCoverage $coverage): Directory
|
||||
@@ -74,10 +74,10 @@ final class Builder
|
||||
$value['lineCoverage'],
|
||||
$value['functionCoverage'],
|
||||
$tests,
|
||||
$this->coveredFileAnalyser->classesIn($filename),
|
||||
$this->coveredFileAnalyser->traitsIn($filename),
|
||||
$this->coveredFileAnalyser->functionsIn($filename),
|
||||
$this->coveredFileAnalyser->linesOfCodeFor($filename)
|
||||
$this->analyser->classesIn($filename),
|
||||
$this->analyser->traitsIn($filename),
|
||||
$this->analyser->functionsIn($filename),
|
||||
$this->analyser->linesOfCodeFor($filename)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
+1
-6
@@ -7,7 +7,7 @@
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
namespace SebastianBergmann\CodeCoverage\Node;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
@@ -26,11 +26,6 @@ final class CrapIndex
|
||||
*/
|
||||
private $codeCoverage;
|
||||
|
||||
public static function fromCyclomaticComplexityAndCoveragePercentage(int $cyclomaticComplexity, float $codeCoverage): self
|
||||
{
|
||||
return new self($cyclomaticComplexity, $codeCoverage);
|
||||
}
|
||||
|
||||
public function __construct(int $cyclomaticComplexity, float $codeCoverage)
|
||||
{
|
||||
$this->cyclomaticComplexity = $cyclomaticComplexity;
|
||||
+15
-5
@@ -13,7 +13,6 @@ use function array_merge;
|
||||
use function count;
|
||||
use IteratorAggregate;
|
||||
use RecursiveIteratorIterator;
|
||||
use SebastianBergmann\LinesOfCode\LinesOfCode;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
@@ -51,7 +50,7 @@ final class Directory extends AbstractNode implements IteratorAggregate
|
||||
private $functions;
|
||||
|
||||
/**
|
||||
* @var LinesOfCode
|
||||
* @psalm-var null|array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int}
|
||||
*/
|
||||
private $linesOfCode;
|
||||
|
||||
@@ -233,13 +232,24 @@ final class Directory extends AbstractNode implements IteratorAggregate
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
public function linesOfCode(): LinesOfCode
|
||||
/**
|
||||
* @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int}
|
||||
*/
|
||||
public function linesOfCode(): array
|
||||
{
|
||||
if ($this->linesOfCode === null) {
|
||||
$this->linesOfCode = new LinesOfCode(0, 0, 0, 0);
|
||||
$this->linesOfCode = [
|
||||
'linesOfCode' => 0,
|
||||
'commentLinesOfCode' => 0,
|
||||
'nonCommentLinesOfCode' => 0,
|
||||
];
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->linesOfCode = $this->linesOfCode->plus($child->linesOfCode());
|
||||
$childLinesOfCode = $child->linesOfCode();
|
||||
|
||||
$this->linesOfCode['linesOfCode'] += $childLinesOfCode['linesOfCode'];
|
||||
$this->linesOfCode['commentLinesOfCode'] += $childLinesOfCode['commentLinesOfCode'];
|
||||
$this->linesOfCode['nonCommentLinesOfCode'] += $childLinesOfCode['nonCommentLinesOfCode'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-11
@@ -12,8 +12,6 @@ namespace SebastianBergmann\CodeCoverage\Node;
|
||||
use function array_filter;
|
||||
use function count;
|
||||
use function range;
|
||||
use SebastianBergmann\CodeCoverage\CrapIndex;
|
||||
use SebastianBergmann\LinesOfCode\LinesOfCode;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
@@ -81,7 +79,7 @@ final class File extends AbstractNode
|
||||
private $functions = [];
|
||||
|
||||
/**
|
||||
* @var LinesOfCode
|
||||
* @psalm-var array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int}
|
||||
*/
|
||||
private $linesOfCode;
|
||||
|
||||
@@ -125,7 +123,10 @@ final class File extends AbstractNode
|
||||
*/
|
||||
private $codeUnitsByLine = [];
|
||||
|
||||
public function __construct(string $name, AbstractNode $parent, array $lineCoverageData, array $functionCoverageData, array $testData, array $classes, array $traits, array $functions, LinesOfCode $linesOfCode)
|
||||
/**
|
||||
* @psalm-param array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} $linesOfCode
|
||||
*/
|
||||
public function __construct(string $name, AbstractNode $parent, array $lineCoverageData, array $functionCoverageData, array $testData, array $classes, array $traits, array $functions, array $linesOfCode)
|
||||
{
|
||||
parent::__construct($name, $parent);
|
||||
|
||||
@@ -172,7 +173,10 @@ final class File extends AbstractNode
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
public function linesOfCode(): LinesOfCode
|
||||
/**
|
||||
* @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int}
|
||||
*/
|
||||
public function linesOfCode(): array
|
||||
{
|
||||
return $this->linesOfCode;
|
||||
}
|
||||
@@ -330,7 +334,7 @@ final class File extends AbstractNode
|
||||
|
||||
private function calculateStatistics(array $classes, array $traits, array $functions): void
|
||||
{
|
||||
foreach (range(1, $this->linesOfCode->linesOfCode()) as $lineNumber) {
|
||||
foreach (range(1, $this->linesOfCode['linesOfCode']) as $lineNumber) {
|
||||
$this->codeUnitsByLine[$lineNumber] = [];
|
||||
}
|
||||
|
||||
@@ -338,7 +342,7 @@ final class File extends AbstractNode
|
||||
$this->processTraits($traits);
|
||||
$this->processFunctions($functions);
|
||||
|
||||
foreach (range(1, $this->linesOfCode->linesOfCode()) as $lineNumber) {
|
||||
foreach (range(1, $this->linesOfCode['linesOfCode']) as $lineNumber) {
|
||||
if (isset($this->lineCoverageData[$lineNumber])) {
|
||||
foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) {
|
||||
$codeUnit['executableLines']++;
|
||||
@@ -557,7 +561,8 @@ final class File extends AbstractNode
|
||||
$this->functions[$functionName]['executedBranches'] = count(
|
||||
array_filter(
|
||||
$this->functionCoverageData[$functionName]['branches'],
|
||||
static function (array $branch) {
|
||||
static function (array $branch)
|
||||
{
|
||||
return (bool) $branch['hit'];
|
||||
}
|
||||
)
|
||||
@@ -572,7 +577,8 @@ final class File extends AbstractNode
|
||||
$this->functions[$functionName]['executedPaths'] = count(
|
||||
array_filter(
|
||||
$this->functionCoverageData[$functionName]['paths'],
|
||||
static function (array $path) {
|
||||
static function (array $path)
|
||||
{
|
||||
return (bool) $path['hit'];
|
||||
}
|
||||
)
|
||||
@@ -616,7 +622,8 @@ final class File extends AbstractNode
|
||||
$methodData['executedBranches'] = count(
|
||||
array_filter(
|
||||
$this->functionCoverageData[$key]['branches'],
|
||||
static function (array $branch) {
|
||||
static function (array $branch)
|
||||
{
|
||||
return (bool) $branch['hit'];
|
||||
}
|
||||
)
|
||||
@@ -631,7 +638,8 @@ final class File extends AbstractNode
|
||||
$methodData['executedPaths'] = count(
|
||||
array_filter(
|
||||
$this->functionCoverageData[$key]['paths'],
|
||||
static function (array $path) {
|
||||
static function (array $path)
|
||||
{
|
||||
return (bool) $path['hit'];
|
||||
}
|
||||
)
|
||||
|
||||
@@ -132,18 +132,6 @@ final class ProcessedCodeCoverageData
|
||||
unset($this->lineCoverage[$oldFile], $this->functionCoverage[$oldFile]);
|
||||
}
|
||||
|
||||
public function removeFilesWithNoCoverage(): void
|
||||
{
|
||||
foreach ($this->lineCoverage as $file => $lines) {
|
||||
foreach ($lines as $line) {
|
||||
if (is_array($line) && !empty($line)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
unset($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function merge(self $newData): void
|
||||
{
|
||||
foreach ($newData->lineCoverage as $file => $lines) {
|
||||
|
||||
@@ -15,11 +15,10 @@ use function array_flip;
|
||||
use function array_intersect;
|
||||
use function array_intersect_key;
|
||||
use function count;
|
||||
use function file;
|
||||
use function in_array;
|
||||
use function range;
|
||||
use SebastianBergmann\CodeCoverage\Driver\Driver;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\UncoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
@@ -84,11 +83,11 @@ final class RawCodeCoverageData
|
||||
return new self($lineCoverage, $functionCoverage);
|
||||
}
|
||||
|
||||
public static function fromUncoveredFile(string $filename, UncoveredFileAnalyser $uncoveredFileAnalyser): self
|
||||
public static function fromUncoveredFile(string $filename, FileAnalyser $analyser): self
|
||||
{
|
||||
$lineCoverage = [];
|
||||
|
||||
foreach ($uncoveredFileAnalyser->executableLinesIn($filename) as $line) {
|
||||
foreach ($analyser->executableLinesIn($filename) as $line) {
|
||||
$lineCoverage[$line] = Driver::LINE_NOT_EXECUTED;
|
||||
}
|
||||
|
||||
@@ -126,7 +125,7 @@ final class RawCodeCoverageData
|
||||
/**
|
||||
* @param int[] $lines
|
||||
*/
|
||||
public function keepCoverageDataOnlyForLines(string $filename, array $lines): void
|
||||
public function keepLineCoverageDataOnlyForLines(string $filename, array $lines): void
|
||||
{
|
||||
if (!isset($this->lineCoverage[$filename])) {
|
||||
return;
|
||||
@@ -136,17 +135,25 @@ final class RawCodeCoverageData
|
||||
$this->lineCoverage[$filename],
|
||||
array_flip($lines)
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($this->functionCoverage[$filename])) {
|
||||
foreach ($this->functionCoverage[$filename] as $functionName => $functionData) {
|
||||
foreach ($functionData['branches'] as $branchId => $branch) {
|
||||
if (count(array_diff(range($branch['line_start'], $branch['line_end']), $lines)) > 0) {
|
||||
unset($this->functionCoverage[$filename][$functionName]['branches'][$branchId]);
|
||||
/**
|
||||
* @param int[] $lines
|
||||
*/
|
||||
public function keepFunctionCoverageDataOnlyForLines(string $filename, array $lines): void
|
||||
{
|
||||
if (!isset($this->functionCoverage[$filename])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($functionData['paths'] as $pathId => $path) {
|
||||
if (in_array($branchId, $path['path'], true)) {
|
||||
unset($this->functionCoverage[$filename][$functionName]['paths'][$pathId]);
|
||||
}
|
||||
foreach ($this->functionCoverage[$filename] as $functionName => $functionData) {
|
||||
foreach ($functionData['branches'] as $branchId => $branch) {
|
||||
if (count(array_diff(range($branch['line_start'], $branch['line_end']), $lines)) > 0) {
|
||||
unset($this->functionCoverage[$filename][$functionName]['branches'][$branchId]);
|
||||
|
||||
foreach ($functionData['paths'] as $pathId => $path) {
|
||||
if (in_array($branchId, $path['path'], true)) {
|
||||
unset($this->functionCoverage[$filename][$functionName]['paths'][$pathId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ use function range;
|
||||
use function time;
|
||||
use DOMDocument;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\Node\File;
|
||||
use SebastianBergmann\CodeCoverage\Util\Filesystem;
|
||||
|
||||
final class Clover
|
||||
{
|
||||
@@ -194,8 +194,8 @@ final class Clover
|
||||
$linesOfCode = $item->linesOfCode();
|
||||
|
||||
$xmlMetrics = $xmlDocument->createElement('metrics');
|
||||
$xmlMetrics->setAttribute('loc', (string) $linesOfCode->linesOfCode());
|
||||
$xmlMetrics->setAttribute('ncloc', (string) $linesOfCode->nonCommentLinesOfCode());
|
||||
$xmlMetrics->setAttribute('loc', (string) $linesOfCode['linesOfCode']);
|
||||
$xmlMetrics->setAttribute('ncloc', (string) $linesOfCode['nonCommentLinesOfCode']);
|
||||
$xmlMetrics->setAttribute('classes', (string) $item->numberOfClassesAndTraits());
|
||||
$xmlMetrics->setAttribute('methods', (string) $item->numberOfMethods());
|
||||
$xmlMetrics->setAttribute('coveredmethods', (string) $item->numberOfTestedMethods());
|
||||
@@ -227,8 +227,8 @@ final class Clover
|
||||
|
||||
$xmlMetrics = $xmlDocument->createElement('metrics');
|
||||
$xmlMetrics->setAttribute('files', (string) count($report));
|
||||
$xmlMetrics->setAttribute('loc', (string) $linesOfCode->linesOfCode());
|
||||
$xmlMetrics->setAttribute('ncloc', (string) $linesOfCode->nonCommentLinesOfCode());
|
||||
$xmlMetrics->setAttribute('loc', (string) $linesOfCode['linesOfCode']);
|
||||
$xmlMetrics->setAttribute('ncloc', (string) $linesOfCode['nonCommentLinesOfCode']);
|
||||
$xmlMetrics->setAttribute('classes', (string) $report->numberOfClassesAndTraits());
|
||||
$xmlMetrics->setAttribute('methods', (string) $report->numberOfMethods());
|
||||
$xmlMetrics->setAttribute('coveredmethods', (string) $report->numberOfTestedMethods());
|
||||
@@ -243,7 +243,7 @@ final class Clover
|
||||
$buffer = $xmlDocument->saveXML();
|
||||
|
||||
if ($target !== null) {
|
||||
Directory::create(dirname($target));
|
||||
Filesystem::createDirectory(dirname($target));
|
||||
|
||||
if (@file_put_contents($target, $buffer) === false) {
|
||||
throw new WriteOperationFailedException($target);
|
||||
|
||||
@@ -16,9 +16,9 @@ use function range;
|
||||
use function time;
|
||||
use DOMImplementation;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\Node\File;
|
||||
use SebastianBergmann\CodeCoverage\Util\Filesystem;
|
||||
|
||||
final class Cobertura
|
||||
{
|
||||
@@ -292,7 +292,7 @@ final class Cobertura
|
||||
$buffer = $document->saveXML();
|
||||
|
||||
if ($target !== null) {
|
||||
Directory::create(dirname($target));
|
||||
Filesystem::createDirectory(dirname($target));
|
||||
|
||||
if (@file_put_contents($target, $buffer) === false) {
|
||||
throw new WriteOperationFailedException($target);
|
||||
|
||||
@@ -17,9 +17,9 @@ use function is_string;
|
||||
use function round;
|
||||
use DOMDocument;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\Node\File;
|
||||
use SebastianBergmann\CodeCoverage\Util\Filesystem;
|
||||
|
||||
final class Crap4j
|
||||
{
|
||||
@@ -124,7 +124,7 @@ final class Crap4j
|
||||
$buffer = $document->saveXML();
|
||||
|
||||
if ($target !== null) {
|
||||
Directory::create(dirname($target));
|
||||
Filesystem::createDirectory(dirname($target));
|
||||
|
||||
if (@file_put_contents($target, $buffer) === false) {
|
||||
throw new WriteOperationFailedException($target);
|
||||
|
||||
@@ -15,8 +15,9 @@ use function date;
|
||||
use function dirname;
|
||||
use function substr;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory as DirectoryUtil;
|
||||
use SebastianBergmann\CodeCoverage\InvalidArgumentException;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\CodeCoverage\Util\Filesystem;
|
||||
|
||||
final class Facade
|
||||
{
|
||||
@@ -42,6 +43,12 @@ final class Facade
|
||||
|
||||
public function __construct(int $lowUpperBound = 50, int $highLowerBound = 90, string $generator = '')
|
||||
{
|
||||
if ($lowUpperBound > $highLowerBound) {
|
||||
throw new InvalidArgumentException(
|
||||
'$lowUpperBound must not be larger than $highLowerBound'
|
||||
);
|
||||
}
|
||||
|
||||
$this->generator = $generator;
|
||||
$this->highLowerBound = $highLowerBound;
|
||||
$this->lowUpperBound = $lowUpperBound;
|
||||
@@ -88,14 +95,14 @@ final class Facade
|
||||
$id = $node->id();
|
||||
|
||||
if ($node instanceof DirectoryNode) {
|
||||
DirectoryUtil::create($target . $id);
|
||||
Filesystem::createDirectory($target . $id);
|
||||
|
||||
$directory->render($node, $target . $id . '/index.html');
|
||||
$dashboard->render($node, $target . $id . '/dashboard.html');
|
||||
} else {
|
||||
$dir = dirname($target . $id);
|
||||
|
||||
DirectoryUtil::create($dir);
|
||||
Filesystem::createDirectory($dir);
|
||||
|
||||
$file->render($node, $target . $id);
|
||||
}
|
||||
@@ -133,7 +140,7 @@ final class Facade
|
||||
$directory .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
DirectoryUtil::create($directory);
|
||||
Filesystem::createDirectory($directory);
|
||||
|
||||
return $directory;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ use function token_get_all;
|
||||
use function trim;
|
||||
use PHPUnit\Runner\BaseTestRunner;
|
||||
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
|
||||
use SebastianBergmann\CodeCoverage\Percentage;
|
||||
use SebastianBergmann\CodeCoverage\Util\Percentage;
|
||||
use SebastianBergmann\Template\Template;
|
||||
|
||||
/**
|
||||
|
||||
Vendored
+5
-5
File diff suppressed because one or more lines are too long
-5
@@ -96,11 +96,6 @@ span.success, span.warning, span.danger {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#classCoverageDistribution, #classComplexity {
|
||||
height: 200px;
|
||||
width: 475px;
|
||||
}
|
||||
|
||||
#toplink {
|
||||
position: fixed;
|
||||
left: 5px;
|
||||
|
||||
+2
-2
@@ -33,9 +33,9 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
<td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
<td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
Vendored
+4
-4
@@ -33,11 +33,11 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
<td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Paths</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Branches</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Branches</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Paths</strong></div></td>
|
||||
<td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
+6
-6
@@ -1,14 +1,14 @@
|
||||
<tr>
|
||||
<td class="{{classes_level}}">{{name}}</td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
</tr>
|
||||
|
||||
|
||||
Vendored
+12
-12
@@ -1,20 +1,20 @@
|
||||
<tr>
|
||||
<td class="{{classes_level}}">{{name}}</td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
</tr>
|
||||
|
||||
|
||||
+4
-4
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+5
-4
@@ -1,11 +1,12 @@
|
||||
<tr>
|
||||
<td class="{{methods_level}}" colspan="4">{{name}}</td>
|
||||
<td class="{{methods_level}}">{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{methods_level}}" colspan="3"></td>
|
||||
</tr>
|
||||
|
||||
|
||||
Vendored
+11
-10
@@ -1,17 +1,18 @@
|
||||
<tr>
|
||||
<td class="{{methods_level}}" colspan="4">{{name}}</td>
|
||||
<td class="{{methods_level}}">{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{methods_level}}" colspan="3"></td>
|
||||
</tr>
|
||||
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ use function file_put_contents;
|
||||
use function serialize;
|
||||
use function sprintf;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\Util\Filesystem;
|
||||
|
||||
final class PHP
|
||||
{
|
||||
@@ -31,7 +31,7 @@ return \unserialize(<<<'END_OF_COVERAGE_SERIALIZATION'%s%s%sEND_OF_COVERAGE_SERI
|
||||
);
|
||||
|
||||
if ($target !== null) {
|
||||
Directory::create(dirname($target));
|
||||
Filesystem::createDirectory(dirname($target));
|
||||
|
||||
if (@file_put_contents($target, $buffer) === false) {
|
||||
throw new WriteOperationFailedException($target);
|
||||
|
||||
@@ -19,7 +19,7 @@ use function str_pad;
|
||||
use function strlen;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Node\File;
|
||||
use SebastianBergmann\CodeCoverage\Percentage;
|
||||
use SebastianBergmann\CodeCoverage\Util\Percentage;
|
||||
|
||||
final class Text
|
||||
{
|
||||
|
||||
@@ -28,12 +28,12 @@ use function substr;
|
||||
use DateTimeImmutable;
|
||||
use DOMDocument;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory as DirectoryUtil;
|
||||
use SebastianBergmann\CodeCoverage\Driver\PathExistsButIsNotDirectoryException;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
|
||||
use SebastianBergmann\CodeCoverage\Util\Filesystem as DirectoryUtil;
|
||||
use SebastianBergmann\CodeCoverage\Version;
|
||||
use SebastianBergmann\CodeCoverage\XmlException;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
@@ -109,7 +109,7 @@ final class Facade
|
||||
}
|
||||
}
|
||||
|
||||
DirectoryUtil::create($directory);
|
||||
DirectoryUtil::createDirectory($directory);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,9 +240,9 @@ final class Facade
|
||||
$loc = $node->linesOfCode();
|
||||
|
||||
$totals->setNumLines(
|
||||
$loc->linesOfCode(),
|
||||
$loc->commentLinesOfCode(),
|
||||
$loc->nonCommentLinesOfCode(),
|
||||
$loc['linesOfCode'],
|
||||
$loc['commentLinesOfCode'],
|
||||
$loc['nonCommentLinesOfCode'],
|
||||
$node->numberOfExecutableLines(),
|
||||
$node->numberOfExecutedLines()
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
use function sprintf;
|
||||
use DOMElement;
|
||||
use DOMNode;
|
||||
use SebastianBergmann\CodeCoverage\Percentage;
|
||||
use SebastianBergmann\CodeCoverage\Util\Percentage;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use function file_get_contents;
|
||||
use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function hash;
|
||||
use function is_file;
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
abstract class Cache
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $directory;
|
||||
|
||||
public function __construct(string $directory)
|
||||
{
|
||||
Directory::create($directory);
|
||||
|
||||
$this->directory = $directory;
|
||||
}
|
||||
|
||||
protected function has(string $filename, string $key): bool
|
||||
{
|
||||
$cacheFile = $this->cacheFile($filename, $key);
|
||||
|
||||
if (!is_file($cacheFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filemtime($cacheFile) < filemtime($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param list<class-string> $allowedClasses
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function read(string $filename, string $key, array $allowedClasses = [])
|
||||
{
|
||||
$options = ['allowed_classes' => false];
|
||||
|
||||
if (!empty($allowedClasses)) {
|
||||
$options = ['allowed_classes' => $allowedClasses];
|
||||
}
|
||||
|
||||
return unserialize(
|
||||
file_get_contents(
|
||||
$this->cacheFile($filename, $key)
|
||||
),
|
||||
$options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
protected function write(string $filename, string $key, $data): void
|
||||
{
|
||||
file_put_contents(
|
||||
$this->cacheFile($filename, $key),
|
||||
serialize($data)
|
||||
);
|
||||
}
|
||||
|
||||
private function cacheFile(string $filename, string $key): string
|
||||
{
|
||||
return $this->directory . DIRECTORY_SEPARATOR . hash('sha256', $filename . $key);
|
||||
}
|
||||
}
|
||||
@@ -15,24 +15,16 @@ final class CacheWarmer
|
||||
{
|
||||
public function warmCache(string $cacheDirectory, bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode, Filter $filter): void
|
||||
{
|
||||
$coveredFileAnalyser = new CachingCoveredFileAnalyser(
|
||||
$analyser = new CachingFileAnalyser(
|
||||
$cacheDirectory,
|
||||
new ParsingCoveredFileAnalyser(
|
||||
new ParsingFileAnalyser(
|
||||
$useAnnotationsForIgnoringCode,
|
||||
$ignoreDeprecatedCode
|
||||
)
|
||||
);
|
||||
|
||||
$uncoveredFileAnalyser = new CachingUncoveredFileAnalyser(
|
||||
$cacheDirectory,
|
||||
new ParsingUncoveredFileAnalyser
|
||||
);
|
||||
|
||||
foreach ($filter->files() as $file) {
|
||||
$coveredFileAnalyser->process($file);
|
||||
|
||||
/* @noinspection UnusedFunctionResultInspection */
|
||||
$uncoveredFileAnalyser->executableLinesIn($file);
|
||||
$analyser->process($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
use SebastianBergmann\LinesOfCode\LinesOfCode;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class CachingCoveredFileAnalyser extends Cache implements CoveredFileAnalyser
|
||||
{
|
||||
/**
|
||||
* @var CoveredFileAnalyser
|
||||
*/
|
||||
private $coveredFileAnalyser;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $cache = [];
|
||||
|
||||
public function __construct(string $directory, CoveredFileAnalyser $coveredFileAnalyser)
|
||||
{
|
||||
parent::__construct($directory);
|
||||
|
||||
$this->coveredFileAnalyser = $coveredFileAnalyser;
|
||||
}
|
||||
|
||||
public function classesIn(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['classesIn'];
|
||||
}
|
||||
|
||||
public function traitsIn(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['traitsIn'];
|
||||
}
|
||||
|
||||
public function functionsIn(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['functionsIn'];
|
||||
}
|
||||
|
||||
public function linesOfCodeFor(string $filename): LinesOfCode
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['linesOfCodeFor'];
|
||||
}
|
||||
|
||||
public function ignoredLinesFor(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['ignoredLinesFor'];
|
||||
}
|
||||
|
||||
public function process(string $filename): void
|
||||
{
|
||||
if ($this->has($filename, __CLASS__)) {
|
||||
$this->cache[$filename] = $this->read($filename, __CLASS__, [LinesOfCode::class]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cache[$filename] = [
|
||||
'classesIn' => $this->coveredFileAnalyser->classesIn($filename),
|
||||
'traitsIn' => $this->coveredFileAnalyser->traitsIn($filename),
|
||||
'functionsIn' => $this->coveredFileAnalyser->functionsIn($filename),
|
||||
'linesOfCodeFor' => $this->coveredFileAnalyser->linesOfCodeFor($filename),
|
||||
'ignoredLinesFor' => $this->coveredFileAnalyser->ignoredLinesFor($filename),
|
||||
];
|
||||
|
||||
$this->write($filename, __CLASS__, $this->cache[$filename]);
|
||||
}
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
use function assert;
|
||||
use function crc32;
|
||||
use function file_get_contents;
|
||||
use function file_put_contents;
|
||||
use function is_file;
|
||||
use function serialize;
|
||||
use GlobIterator;
|
||||
use SebastianBergmann\CodeCoverage\Util\Filesystem;
|
||||
use SplFileInfo;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class CachingFileAnalyser implements FileAnalyser
|
||||
{
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
private static $cacheVersion;
|
||||
|
||||
/**
|
||||
* @var FileAnalyser
|
||||
*/
|
||||
private $analyser;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $cache = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $directory;
|
||||
|
||||
public function __construct(string $directory, FileAnalyser $analyser)
|
||||
{
|
||||
Filesystem::createDirectory($directory);
|
||||
|
||||
$this->analyser = $analyser;
|
||||
$this->directory = $directory;
|
||||
|
||||
if (self::$cacheVersion === null) {
|
||||
$this->calculateCacheVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public function classesIn(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['classesIn'];
|
||||
}
|
||||
|
||||
public function traitsIn(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['traitsIn'];
|
||||
}
|
||||
|
||||
public function functionsIn(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['functionsIn'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int}
|
||||
*/
|
||||
public function linesOfCodeFor(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['linesOfCodeFor'];
|
||||
}
|
||||
|
||||
public function executableLinesIn(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['executableLinesIn'];
|
||||
}
|
||||
|
||||
public function ignoredLinesFor(string $filename): array
|
||||
{
|
||||
if (!isset($this->cache[$filename])) {
|
||||
$this->process($filename);
|
||||
}
|
||||
|
||||
return $this->cache[$filename]['ignoredLinesFor'];
|
||||
}
|
||||
|
||||
public function process(string $filename): void
|
||||
{
|
||||
$cache = $this->read($filename);
|
||||
|
||||
if ($cache !== false) {
|
||||
$this->cache[$filename] = $cache;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cache[$filename] = [
|
||||
'classesIn' => $this->analyser->classesIn($filename),
|
||||
'traitsIn' => $this->analyser->traitsIn($filename),
|
||||
'functionsIn' => $this->analyser->functionsIn($filename),
|
||||
'linesOfCodeFor' => $this->analyser->linesOfCodeFor($filename),
|
||||
'ignoredLinesFor' => $this->analyser->ignoredLinesFor($filename),
|
||||
'executableLinesIn' => $this->analyser->executableLinesIn($filename),
|
||||
];
|
||||
|
||||
$this->write($filename, $this->cache[$filename]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
private function read(string $filename)
|
||||
{
|
||||
$cacheFile = $this->cacheFile($filename);
|
||||
|
||||
if (!is_file($cacheFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return unserialize(
|
||||
file_get_contents($cacheFile),
|
||||
['allowed_classes' => false]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
private function write(string $filename, $data): void
|
||||
{
|
||||
file_put_contents(
|
||||
$this->cacheFile($filename),
|
||||
serialize($data)
|
||||
);
|
||||
}
|
||||
|
||||
private function cacheFile(string $filename): string
|
||||
{
|
||||
return $this->directory . DIRECTORY_SEPARATOR . hash('sha256', $filename . crc32(file_get_contents($filename)) . self::$cacheVersion);
|
||||
}
|
||||
|
||||
private function calculateCacheVersion(): void
|
||||
{
|
||||
$buffer = '';
|
||||
|
||||
foreach (new GlobIterator(__DIR__ . '/*.php') as $file) {
|
||||
assert($file instanceof SplFileInfo);
|
||||
|
||||
$buffer .= file_get_contents($file->getPathname());
|
||||
}
|
||||
|
||||
self::$cacheVersion = (string) crc32($buffer);
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class CachingUncoveredFileAnalyser extends Cache implements UncoveredFileAnalyser
|
||||
{
|
||||
/**
|
||||
* @var UncoveredFileAnalyser
|
||||
*/
|
||||
private $uncoveredFileAnalyser;
|
||||
|
||||
public function __construct(string $directory, UncoveredFileAnalyser $uncoveredFileAnalyser)
|
||||
{
|
||||
parent::__construct($directory);
|
||||
|
||||
$this->uncoveredFileAnalyser = $uncoveredFileAnalyser;
|
||||
}
|
||||
|
||||
public function executableLinesIn(string $filename): array
|
||||
{
|
||||
if ($this->has($filename, __METHOD__)) {
|
||||
return $this->read($filename, __METHOD__);
|
||||
}
|
||||
|
||||
$data = $this->uncoveredFileAnalyser->executableLinesIn($filename);
|
||||
|
||||
$this->write($filename, __METHOD__, $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -206,7 +206,7 @@ final class CodeUnitFindingVisitor extends NodeVisitorAbstract
|
||||
|
||||
$this->classes[$namespacedName] = [
|
||||
'name' => $name,
|
||||
'namespacedName' => (string) $namespacedName,
|
||||
'namespacedName' => $namespacedName,
|
||||
'namespace' => $this->namespace($namespacedName, $name),
|
||||
'startLine' => $node->getStartLine(),
|
||||
'endLine' => $node->getEndLine(),
|
||||
@@ -221,7 +221,7 @@ final class CodeUnitFindingVisitor extends NodeVisitorAbstract
|
||||
|
||||
$this->traits[$namespacedName] = [
|
||||
'name' => $name,
|
||||
'namespacedName' => (string) $namespacedName,
|
||||
'namespacedName' => $namespacedName,
|
||||
'namespace' => $this->namespace($namespacedName, $name),
|
||||
'startLine' => $node->getStartLine(),
|
||||
'endLine' => $node->getEndLine(),
|
||||
|
||||
+94
-10
@@ -9,9 +9,19 @@
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
use function array_unique;
|
||||
use function sort;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\BinaryOp;
|
||||
use PhpParser\Node\Expr\CallLike;
|
||||
use PhpParser\Node\Expr\Cast;
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\NullsafePropertyFetch;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticPropertyFetch;
|
||||
use PhpParser\Node\Expr\Ternary;
|
||||
use PhpParser\Node\Scalar\Encapsed;
|
||||
use PhpParser\Node\Stmt\Break_;
|
||||
use PhpParser\Node\Stmt\Case_;
|
||||
use PhpParser\Node\Stmt\Catch_;
|
||||
@@ -26,6 +36,7 @@ use PhpParser\Node\Stmt\For_;
|
||||
use PhpParser\Node\Stmt\Foreach_;
|
||||
use PhpParser\Node\Stmt\Goto_;
|
||||
use PhpParser\Node\Stmt\If_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PhpParser\Node\Stmt\Switch_;
|
||||
use PhpParser\Node\Stmt\Throw_;
|
||||
@@ -40,49 +51,122 @@ use PhpParser\NodeVisitorAbstract;
|
||||
final class ExecutableLinesFindingVisitor extends NodeVisitorAbstract
|
||||
{
|
||||
/**
|
||||
* @psalm-var list<int>
|
||||
* @psalm-var array<int, int>
|
||||
*/
|
||||
private $executableLines = [];
|
||||
|
||||
/**
|
||||
* @psalm-var array<int, int>
|
||||
*/
|
||||
private $propertyLines = [];
|
||||
|
||||
public function enterNode(Node $node): void
|
||||
{
|
||||
$this->savePropertyLines($node);
|
||||
|
||||
if (!$this->isExecutable($node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->executableLines[] = $node->getStartLine();
|
||||
foreach ($this->getLines($node) as $line) {
|
||||
if (isset($this->propertyLines[$line])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->executableLines[$line] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return list<int>
|
||||
* @psalm-return array<int, int>
|
||||
*/
|
||||
public function executableLines(): array
|
||||
{
|
||||
$executableLines = array_unique($this->executableLines);
|
||||
sort($this->executableLines);
|
||||
|
||||
sort($executableLines);
|
||||
return $this->executableLines;
|
||||
}
|
||||
|
||||
return $executableLines;
|
||||
private function savePropertyLines(Node $node): void
|
||||
{
|
||||
if (!$node instanceof Property && !$node instanceof Node\Stmt\ClassConst) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (range($node->getStartLine(), $node->getEndLine()) as $index) {
|
||||
$this->propertyLines[$index] = $index;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
private function getLines(Node $node): array
|
||||
{
|
||||
if ($node instanceof Cast ||
|
||||
$node instanceof PropertyFetch ||
|
||||
$node instanceof NullsafePropertyFetch ||
|
||||
$node instanceof StaticPropertyFetch) {
|
||||
return [$node->getEndLine()];
|
||||
}
|
||||
|
||||
if ($node instanceof ArrayDimFetch) {
|
||||
if (null === $node->dim) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [$node->dim->getStartLine()];
|
||||
}
|
||||
|
||||
if ($node instanceof MethodCall) {
|
||||
return [$node->name->getStartLine()];
|
||||
}
|
||||
|
||||
if ($node instanceof Ternary) {
|
||||
$lines = [$node->cond->getStartLine()];
|
||||
|
||||
if (null !== $node->if) {
|
||||
$lines[] = $node->if->getStartLine();
|
||||
}
|
||||
|
||||
$lines[] = $node->else->getStartLine();
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
return [$node->getStartLine()];
|
||||
}
|
||||
|
||||
private function isExecutable(Node $node): bool
|
||||
{
|
||||
return $node instanceof Break_ ||
|
||||
return $node instanceof Assign ||
|
||||
$node instanceof ArrayDimFetch ||
|
||||
$node instanceof BinaryOp ||
|
||||
$node instanceof Break_ ||
|
||||
$node instanceof CallLike ||
|
||||
$node instanceof Case_ ||
|
||||
$node instanceof Cast ||
|
||||
$node instanceof Catch_ ||
|
||||
$node instanceof Closure ||
|
||||
$node instanceof Continue_ ||
|
||||
$node instanceof Do_ ||
|
||||
$node instanceof Echo_ ||
|
||||
$node instanceof ElseIf_ ||
|
||||
$node instanceof Else_ ||
|
||||
$node instanceof Encapsed ||
|
||||
$node instanceof Expression ||
|
||||
$node instanceof Finally_ ||
|
||||
$node instanceof Foreach_ ||
|
||||
$node instanceof For_ ||
|
||||
$node instanceof Foreach_ ||
|
||||
$node instanceof Goto_ ||
|
||||
$node instanceof If_ ||
|
||||
$node instanceof MethodCall ||
|
||||
$node instanceof NullsafePropertyFetch ||
|
||||
$node instanceof PropertyFetch ||
|
||||
$node instanceof Return_ ||
|
||||
$node instanceof StaticPropertyFetch ||
|
||||
$node instanceof Switch_ ||
|
||||
$node instanceof Ternary ||
|
||||
$node instanceof Throw_ ||
|
||||
$node instanceof TryCatch ||
|
||||
$node instanceof Unset_ ||
|
||||
|
||||
+7
-4
@@ -9,12 +9,10 @@
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
use SebastianBergmann\LinesOfCode\LinesOfCode;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
interface CoveredFileAnalyser
|
||||
interface FileAnalyser
|
||||
{
|
||||
public function classesIn(string $filename): array;
|
||||
|
||||
@@ -22,7 +20,12 @@ interface CoveredFileAnalyser
|
||||
|
||||
public function functionsIn(string $filename): array;
|
||||
|
||||
public function linesOfCodeFor(string $filename): LinesOfCode;
|
||||
/**
|
||||
* @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int}
|
||||
*/
|
||||
public function linesOfCodeFor(string $filename): array;
|
||||
|
||||
public function executableLinesIn(string $filename): array;
|
||||
|
||||
public function ignoredLinesFor(string $filename): array;
|
||||
}
|
||||
+6
-13
@@ -18,7 +18,6 @@ use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use PhpParser\NodeTraverser;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
|
||||
/**
|
||||
@@ -47,18 +46,18 @@ final class IgnoredLinesFindingVisitor extends NodeVisitorAbstract
|
||||
$this->ignoreDeprecated = $ignoreDeprecated;
|
||||
}
|
||||
|
||||
public function enterNode(Node $node): ?int
|
||||
public function enterNode(Node $node): void
|
||||
{
|
||||
if (!$node instanceof Class_ &&
|
||||
!$node instanceof Trait_ &&
|
||||
!$node instanceof Interface_ &&
|
||||
!$node instanceof ClassMethod &&
|
||||
!$node instanceof Function_) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof Class_ && $node->isAnonymous()) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Workaround for https://bugs.xdebug.org/view.php?id=1798
|
||||
@@ -69,17 +68,17 @@ final class IgnoredLinesFindingVisitor extends NodeVisitorAbstract
|
||||
}
|
||||
|
||||
if (!$this->useAnnotationsForIgnoringCode) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof Interface_) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
$docComment = $node->getDocComment();
|
||||
|
||||
if ($docComment === null) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strpos($docComment->getText(), '@codeCoverageIgnore') !== false) {
|
||||
@@ -95,12 +94,6 @@ final class IgnoredLinesFindingVisitor extends NodeVisitorAbstract
|
||||
range($node->getStartLine(), $node->getEndLine())
|
||||
);
|
||||
}
|
||||
|
||||
if ($node instanceof ClassMethod || $node instanceof Function_) {
|
||||
return NodeTraverser::DONT_TRAVERSE_CHILDREN;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+37
-13
@@ -25,12 +25,11 @@ use PhpParser\NodeVisitor\ParentConnectingVisitor;
|
||||
use PhpParser\ParserFactory;
|
||||
use SebastianBergmann\CodeCoverage\ParserException;
|
||||
use SebastianBergmann\LinesOfCode\LineCountingVisitor;
|
||||
use SebastianBergmann\LinesOfCode\LinesOfCode;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class ParsingCoveredFileAnalyser implements CoveredFileAnalyser
|
||||
final class ParsingFileAnalyser implements FileAnalyser
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
@@ -48,7 +47,7 @@ final class ParsingCoveredFileAnalyser implements CoveredFileAnalyser
|
||||
private $functions = [];
|
||||
|
||||
/**
|
||||
* @var LinesOfCode[]
|
||||
* @var array<string,array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int}>
|
||||
*/
|
||||
private $linesOfCode = [];
|
||||
|
||||
@@ -57,6 +56,11 @@ final class ParsingCoveredFileAnalyser implements CoveredFileAnalyser
|
||||
*/
|
||||
private $ignoredLines = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $executableLines = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
@@ -94,13 +98,23 @@ final class ParsingCoveredFileAnalyser implements CoveredFileAnalyser
|
||||
return $this->functions[$filename];
|
||||
}
|
||||
|
||||
public function linesOfCodeFor(string $filename): LinesOfCode
|
||||
/**
|
||||
* @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int}
|
||||
*/
|
||||
public function linesOfCodeFor(string $filename): array
|
||||
{
|
||||
$this->analyse($filename);
|
||||
|
||||
return $this->linesOfCode[$filename];
|
||||
}
|
||||
|
||||
public function executableLinesIn(string $filename): array
|
||||
{
|
||||
$this->analyse($filename);
|
||||
|
||||
return $this->executableLines[$filename];
|
||||
}
|
||||
|
||||
public function ignoredLinesFor(string $filename): array
|
||||
{
|
||||
$this->analyse($filename);
|
||||
@@ -134,16 +148,18 @@ final class ParsingCoveredFileAnalyser implements CoveredFileAnalyser
|
||||
|
||||
assert($nodes !== null);
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$codeUnitFindingVisitor = new CodeUnitFindingVisitor;
|
||||
$lineCountingVisitor = new LineCountingVisitor($linesOfCode);
|
||||
$ignoredLinesFindingVisitor = new IgnoredLinesFindingVisitor($this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode);
|
||||
$traverser = new NodeTraverser;
|
||||
$codeUnitFindingVisitor = new CodeUnitFindingVisitor;
|
||||
$lineCountingVisitor = new LineCountingVisitor($linesOfCode);
|
||||
$ignoredLinesFindingVisitor = new IgnoredLinesFindingVisitor($this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode);
|
||||
$executableLinesFindingVisitor = new ExecutableLinesFindingVisitor;
|
||||
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
$traverser->addVisitor(new ParentConnectingVisitor);
|
||||
$traverser->addVisitor($codeUnitFindingVisitor);
|
||||
$traverser->addVisitor($lineCountingVisitor);
|
||||
$traverser->addVisitor($ignoredLinesFindingVisitor);
|
||||
$traverser->addVisitor($executableLinesFindingVisitor);
|
||||
|
||||
/* @noinspection UnusedFunctionResultInspection */
|
||||
$traverser->traverse($nodes);
|
||||
@@ -161,11 +177,11 @@ final class ParsingCoveredFileAnalyser implements CoveredFileAnalyser
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$this->classes[$filename] = $codeUnitFindingVisitor->classes();
|
||||
$this->traits[$filename] = $codeUnitFindingVisitor->traits();
|
||||
$this->functions[$filename] = $codeUnitFindingVisitor->functions();
|
||||
$this->linesOfCode[$filename] = $lineCountingVisitor->result();
|
||||
$this->ignoredLines[$filename] = [];
|
||||
$this->classes[$filename] = $codeUnitFindingVisitor->classes();
|
||||
$this->traits[$filename] = $codeUnitFindingVisitor->traits();
|
||||
$this->functions[$filename] = $codeUnitFindingVisitor->functions();
|
||||
$this->executableLines[$filename] = $executableLinesFindingVisitor->executableLines();
|
||||
$this->ignoredLines[$filename] = [];
|
||||
|
||||
$this->findLinesIgnoredByLineBasedAnnotations($filename, $source, $this->useAnnotationsForIgnoringCode);
|
||||
|
||||
@@ -177,6 +193,14 @@ final class ParsingCoveredFileAnalyser implements CoveredFileAnalyser
|
||||
);
|
||||
|
||||
sort($this->ignoredLines[$filename]);
|
||||
|
||||
$result = $lineCountingVisitor->result();
|
||||
|
||||
$this->linesOfCode[$filename] = [
|
||||
'linesOfCode' => $result->linesOfCode(),
|
||||
'commentLinesOfCode' => $result->commentLinesOfCode(),
|
||||
'nonCommentLinesOfCode' => $result->nonCommentLinesOfCode(),
|
||||
];
|
||||
}
|
||||
|
||||
private function findLinesIgnoredByLineBasedAnnotations(string $filename, string $source, bool $useAnnotationsForIgnoringCode): void
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
use PhpParser\Error;
|
||||
use PhpParser\Lexer;
|
||||
use PhpParser\NodeTraverser;
|
||||
use PhpParser\ParserFactory;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class ParsingUncoveredFileAnalyser implements UncoveredFileAnalyser
|
||||
{
|
||||
public function executableLinesIn(string $filename): array
|
||||
{
|
||||
$parser = (new ParserFactory)->create(
|
||||
ParserFactory::PREFER_PHP7,
|
||||
new Lexer
|
||||
);
|
||||
|
||||
try {
|
||||
$nodes = $parser->parse(file_get_contents($filename));
|
||||
|
||||
assert($nodes !== null);
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$visitor = new ExecutableLinesFindingVisitor;
|
||||
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
/* @noinspection UnusedFunctionResultInspection */
|
||||
$traverser->traverse($nodes);
|
||||
|
||||
return $visitor->executableLines();
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Error $error) {
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
interface UncoveredFileAnalyser
|
||||
{
|
||||
public function executableLinesIn(string $filename): array;
|
||||
}
|
||||
+3
-3
@@ -7,7 +7,7 @@
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
namespace SebastianBergmann\CodeCoverage\Util;
|
||||
|
||||
use function is_dir;
|
||||
use function mkdir;
|
||||
@@ -16,12 +16,12 @@ use function sprintf;
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Directory
|
||||
final class Filesystem
|
||||
{
|
||||
/**
|
||||
* @throws DirectoryCouldNotBeCreatedException
|
||||
*/
|
||||
public static function create(string $directory): void
|
||||
public static function createDirectory(string $directory): void
|
||||
{
|
||||
$success = !(!is_dir($directory) && !@mkdir($directory, 0777, true) && !is_dir($directory));
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
namespace SebastianBergmann\CodeCoverage\Util;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ final class Version
|
||||
public static function id(): string
|
||||
{
|
||||
if (self::$version === null) {
|
||||
self::$version = (new VersionId('9.2.10', dirname(__DIR__)))->getVersion();
|
||||
self::$version = (new VersionId('9.2.13', dirname(__DIR__)))->getVersion();
|
||||
}
|
||||
|
||||
return self::$version;
|
||||
|
||||
+19
@@ -2,6 +2,23 @@
|
||||
|
||||
All notable changes of the PHPUnit 8.5 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
|
||||
|
||||
## [8.5.24] - 2022-MM-DD
|
||||
|
||||
### Changed
|
||||
|
||||
* [#4874](https://github.com/sebastianbergmann/phpunit/pull/4874): `PHP_FLOAT_EPSILON` is now used instead of hardcoded `0.0000000001` in `PHPUnit\Framework\Constraint\IsIdentical`
|
||||
|
||||
### Fixed
|
||||
|
||||
* When the HTML code coverage report's configured low upper bound is larger than the high lower bound then the default values are used instead
|
||||
|
||||
## [8.5.23] - 2022-01-21
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#4799](https://github.com/sebastianbergmann/phpunit/pull/4799): Memory leaks in `PHPUnit\Framework\TestSuite` class
|
||||
* [#4857](https://github.com/sebastianbergmann/phpunit/pull/4857): Result of `debug_backtrace()` is not used correctly
|
||||
|
||||
## [8.5.22] - 2021-12-25
|
||||
|
||||
### Changed
|
||||
@@ -190,6 +207,8 @@ All notable changes of the PHPUnit 8.5 release series are documented in this fil
|
||||
* [#3967](https://github.com/sebastianbergmann/phpunit/issues/3967): Cannot double interface that extends interface that extends `\Throwable`
|
||||
* [#3968](https://github.com/sebastianbergmann/phpunit/pull/3968): Test class run in a separate PHP process are passing when `exit` called inside
|
||||
|
||||
[8.5.24]: https://github.com/sebastianbergmann/phpunit/compare/8.5.23...8.5
|
||||
[8.5.23]: https://github.com/sebastianbergmann/phpunit/compare/8.5.22...8.5.23
|
||||
[8.5.22]: https://github.com/sebastianbergmann/phpunit/compare/8.5.21...8.5.22
|
||||
[8.5.21]: https://github.com/sebastianbergmann/phpunit/compare/8.5.20...8.5.21
|
||||
[8.5.20]: https://github.com/sebastianbergmann/phpunit/compare/8.5.19...8.5.20
|
||||
|
||||
+36
@@ -2,6 +2,37 @@
|
||||
|
||||
All notable changes of the PHPUnit 9.5 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
|
||||
|
||||
## [9.5.16] - 2022-02-23
|
||||
|
||||
### Changed
|
||||
|
||||
* Reverted sync with API change in (now yanked) phpunit/php-code-coverage 9.2.12
|
||||
|
||||
## [9.5.15] - 2022-02-23 [YANKED]
|
||||
|
||||
### Fixed
|
||||
|
||||
* When the HTML code coverage report's configured low upper bound is larger than the high lower bound then the default values are used instead
|
||||
|
||||
## [9.5.14] - 2022-02-18
|
||||
|
||||
### Changed
|
||||
|
||||
* [#4874](https://github.com/sebastianbergmann/phpunit/pull/4874): `PHP_FLOAT_EPSILON` is now used instead of hardcoded `0.0000000001` in `PHPUnit\Framework\Constraint\IsIdentical`
|
||||
|
||||
## [9.5.13] - 2022-01-24
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#4871](https://github.com/sebastianbergmann/phpunit/issues/4871): Class `SebastianBergmann\CodeCoverage\Filter` is not found during PHPT tests when PHPUnit is used from PHAR
|
||||
|
||||
## [9.5.12] - 2022-01-21
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#4799](https://github.com/sebastianbergmann/phpunit/pull/4799): Memory leaks in `PHPUnit\Framework\TestSuite` class
|
||||
* [#4857](https://github.com/sebastianbergmann/phpunit/pull/4857): Result of `debug_backtrace()` is not used correctly
|
||||
|
||||
## [9.5.11] - 2021-12-25
|
||||
|
||||
### Changed
|
||||
@@ -103,6 +134,11 @@ All notable changes of the PHPUnit 9.5 release series are documented in this fil
|
||||
|
||||
* [#4535](https://github.com/sebastianbergmann/phpunit/issues/4535): `getMockFromWsdl()` does not handle methods that do not have parameters correctly
|
||||
|
||||
[9.5.16]: https://github.com/sebastianbergmann/phpunit/compare/dc738383c519243b0a967f63943a848d3fd861aa...9.5.16
|
||||
[9.5.15]: https://github.com/sebastianbergmann/phpunit/compare/9.5.14...dc738383c519243b0a967f63943a848d3fd861aa
|
||||
[9.5.14]: https://github.com/sebastianbergmann/phpunit/compare/9.5.13...9.5.14
|
||||
[9.5.13]: https://github.com/sebastianbergmann/phpunit/compare/9.5.12...9.5.13
|
||||
[9.5.12]: https://github.com/sebastianbergmann/phpunit/compare/9.5.11...9.5.12
|
||||
[9.5.11]: https://github.com/sebastianbergmann/phpunit/compare/9.5.10...9.5.11
|
||||
[9.5.10]: https://github.com/sebastianbergmann/phpunit/compare/9.5.9...9.5.10
|
||||
[9.5.9]: https://github.com/sebastianbergmann/phpunit/compare/9.5.8...9.5.9
|
||||
|
||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
PHPUnit
|
||||
|
||||
Copyright (c) 2001-2021, Sebastian Bergmann <sebastian@phpunit.de>.
|
||||
Copyright (c) 2001-2022, Sebastian Bergmann <sebastian@phpunit.de>.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@
|
||||
"phar-io/manifest": "^2.0.3",
|
||||
"phar-io/version": "^3.0.2",
|
||||
"phpspec/prophecy": "^1.12.1",
|
||||
"phpunit/php-code-coverage": "^9.2.7",
|
||||
"phpunit/php-code-coverage": "^9.2.13",
|
||||
"phpunit/php-file-iterator": "^3.0.5",
|
||||
"phpunit/php-invoker": "^3.1.1",
|
||||
"phpunit/php-text-template": "^2.0.3",
|
||||
|
||||
@@ -179,7 +179,7 @@ abstract class Constraint implements Countable, SelfDescribing
|
||||
* Returns the description of the failure when this constraint appears in
|
||||
* context of an $operator expression.
|
||||
*
|
||||
* The purpose of this method is to provide meaningful failue description
|
||||
* The purpose of this method is to provide meaningful failure description
|
||||
* in context of operators such as LogicalNot. Native PHPUnit constraints
|
||||
* are supported out of the box by LogicalNot, but externally developed
|
||||
* ones had no way to provide correct messages in this context.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
namespace PHPUnit\Framework\Constraint;
|
||||
|
||||
use const PHP_FLOAT_EPSILON;
|
||||
use function abs;
|
||||
use function get_class;
|
||||
use function is_array;
|
||||
@@ -26,11 +27,6 @@ use SebastianBergmann\Comparator\ComparisonFailure;
|
||||
*/
|
||||
final class IsIdentical extends Constraint
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private const EPSILON = 0.0000000001;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
@@ -59,7 +55,7 @@ final class IsIdentical extends Constraint
|
||||
if (is_float($this->value) && is_float($other) &&
|
||||
!is_infinite($this->value) && !is_infinite($other) &&
|
||||
!is_nan($this->value) && !is_nan($other)) {
|
||||
$success = abs($this->value - $other) < self::EPSILON;
|
||||
$success = abs($this->value - $other) < PHP_FLOAT_EPSILON;
|
||||
} else {
|
||||
$success = $this->value === $other;
|
||||
}
|
||||
|
||||
+8
-4
@@ -21,14 +21,18 @@ final class InvalidArgumentException extends Exception
|
||||
{
|
||||
public static function create(int $argument, string $type): self
|
||||
{
|
||||
$stack = debug_backtrace();
|
||||
$stack = debug_backtrace();
|
||||
$function = $stack[1]['function'];
|
||||
|
||||
if (isset($stack[1]['class'])) {
|
||||
$function = sprintf('%s::%s', $stack[1]['class'], $stack[1]['function']);
|
||||
}
|
||||
|
||||
return new self(
|
||||
sprintf(
|
||||
'Argument #%d of %s::%s() must be %s %s',
|
||||
'Argument #%d of %s() must be %s %s',
|
||||
$argument,
|
||||
$stack[1]['class'],
|
||||
$stack[1]['function'],
|
||||
$function,
|
||||
in_array(lcfirst($type)[0], ['a', 'e', 'i', 'o', 'u'], true) ? 'an' : 'a',
|
||||
$type
|
||||
)
|
||||
|
||||
+7
-47
@@ -12,74 +12,34 @@ namespace PHPUnit\Framework;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* @deprecated Use the `TestHook` interfaces instead
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @deprecated
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface TestListener
|
||||
{
|
||||
/**
|
||||
* An error occurred.
|
||||
*
|
||||
* @deprecated Use `AfterTestErrorHook::executeAfterTestError` instead
|
||||
*/
|
||||
public function addError(Test $test, Throwable $t, float $time): void;
|
||||
|
||||
/**
|
||||
* A warning occurred.
|
||||
*
|
||||
* @deprecated Use `AfterTestWarningHook::executeAfterTestWarning` instead
|
||||
*/
|
||||
public function addWarning(Test $test, Warning $e, float $time): void;
|
||||
|
||||
/**
|
||||
* A failure occurred.
|
||||
*
|
||||
* @deprecated Use `AfterTestFailureHook::executeAfterTestFailure` instead
|
||||
*/
|
||||
public function addFailure(Test $test, AssertionFailedError $e, float $time): void;
|
||||
|
||||
/**
|
||||
* Incomplete test.
|
||||
*
|
||||
* @deprecated Use `AfterIncompleteTestHook::executeAfterIncompleteTest` instead
|
||||
*/
|
||||
public function addIncompleteTest(Test $test, Throwable $t, float $time): void;
|
||||
|
||||
/**
|
||||
* Risky test.
|
||||
*
|
||||
* @deprecated Use `AfterRiskyTestHook::executeAfterRiskyTest` instead
|
||||
*/
|
||||
public function addRiskyTest(Test $test, Throwable $t, float $time): void;
|
||||
|
||||
/**
|
||||
* Skipped test.
|
||||
*
|
||||
* @deprecated Use `AfterSkippedTestHook::executeAfterSkippedTest` instead
|
||||
*/
|
||||
public function addSkippedTest(Test $test, Throwable $t, float $time): void;
|
||||
|
||||
/**
|
||||
* A test suite started.
|
||||
*/
|
||||
public function startTestSuite(TestSuite $suite): void;
|
||||
|
||||
/**
|
||||
* A test suite ended.
|
||||
*/
|
||||
public function endTestSuite(TestSuite $suite): void;
|
||||
|
||||
/**
|
||||
* A test started.
|
||||
*
|
||||
* @deprecated Use `BeforeTestHook::executeBeforeTest` instead
|
||||
*/
|
||||
public function startTest(Test $test): void;
|
||||
|
||||
/**
|
||||
* A test ended.
|
||||
*
|
||||
* @deprecated Use `AfterTestHook::executeAfterTest` instead
|
||||
*/
|
||||
public function endTest(Test $test, float $time): void;
|
||||
}
|
||||
|
||||
+2
-2
@@ -755,8 +755,8 @@ final class TestResult implements Countable
|
||||
sprintf(
|
||||
'%s in %s:%s',
|
||||
$e->getMessage(),
|
||||
$frame['file'],
|
||||
$frame['line']
|
||||
$frame['file'] ?? $e->getFile(),
|
||||
$frame['line'] ?? $e->getLine()
|
||||
)
|
||||
);
|
||||
} catch (Warning $e) {
|
||||
|
||||
+7
-8
@@ -10,7 +10,6 @@
|
||||
namespace PHPUnit\Framework;
|
||||
|
||||
use const PHP_EOL;
|
||||
use function array_diff;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function array_merge;
|
||||
@@ -128,9 +127,9 @@ class TestSuite implements IteratorAggregate, Reorderable, SelfDescribing, Test
|
||||
private $iteratorFilter;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @var int
|
||||
*/
|
||||
private $declaredClasses;
|
||||
private $declaredClassesPointer;
|
||||
|
||||
/**
|
||||
* @psalm-var array<int,string>
|
||||
@@ -167,7 +166,7 @@ class TestSuite implements IteratorAggregate, Reorderable, SelfDescribing, Test
|
||||
);
|
||||
}
|
||||
|
||||
$this->declaredClasses = get_declared_classes();
|
||||
$this->declaredClassesPointer = count(get_declared_classes());
|
||||
|
||||
if (!$theClass instanceof ReflectionClass) {
|
||||
if (class_exists($theClass, true)) {
|
||||
@@ -390,7 +389,7 @@ class TestSuite implements IteratorAggregate, Reorderable, SelfDescribing, Test
|
||||
if (is_file($filename) && substr($filename, -5) === '.phpt') {
|
||||
$this->addTest(new PhptTestCase($filename));
|
||||
|
||||
$this->declaredClasses = get_declared_classes();
|
||||
$this->declaredClassesPointer = count(get_declared_classes());
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -400,7 +399,7 @@ class TestSuite implements IteratorAggregate, Reorderable, SelfDescribing, Test
|
||||
// The given file may contain further stub classes in addition to the
|
||||
// test class itself. Figure out the actual test class.
|
||||
$filename = FileLoader::checkAndLoad($filename);
|
||||
$newClasses = array_diff(get_declared_classes(), $this->declaredClasses);
|
||||
$newClasses = array_slice(get_declared_classes(), $this->declaredClassesPointer);
|
||||
|
||||
// The diff is empty in case a parent class (with test methods) is added
|
||||
// AFTER a child class that inherited from it. To account for that case,
|
||||
@@ -410,8 +409,8 @@ class TestSuite implements IteratorAggregate, Reorderable, SelfDescribing, Test
|
||||
// On the assumption that test classes are defined first in files,
|
||||
// process discovered classes in approximate LIFO order, so as to
|
||||
// avoid unnecessary reflection.
|
||||
$this->foundClasses = array_merge($newClasses, $this->foundClasses);
|
||||
$this->declaredClasses = get_declared_classes();
|
||||
$this->foundClasses = array_merge($newClasses, $this->foundClasses);
|
||||
$this->declaredClassesPointer = count(get_declared_classes());
|
||||
}
|
||||
|
||||
// The test class's name must match the filename, either in full, or as
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface AfterIncompleteTestHook extends TestHook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface AfterLastTestHook extends Hook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface AfterRiskyTestHook extends TestHook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface AfterSkippedTestHook extends TestHook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface AfterSuccessfulTestHook extends TestHook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface AfterTestErrorHook extends TestHook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface AfterTestFailureHook extends TestHook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface AfterTestHook extends TestHook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface AfterTestWarningHook extends TestHook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface BeforeFirstTestHook extends Hook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface BeforeTestHook extends TestHook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface Hook
|
||||
{
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
/**
|
||||
* This interface, as well as the associated mechanism for extending PHPUnit,
|
||||
* will be removed in PHPUnit 10. There is no alternative available in this
|
||||
* version of PHPUnit.
|
||||
*
|
||||
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/4676
|
||||
*/
|
||||
interface TestHook extends Hook
|
||||
{
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ final class Version
|
||||
}
|
||||
|
||||
if (self::$version === '') {
|
||||
self::$version = (new VersionId('9.5.11', dirname(__DIR__, 2)))->getVersion();
|
||||
self::$version = (new VersionId('9.5.16', dirname(__DIR__, 2)))->getVersion();
|
||||
}
|
||||
|
||||
return self::$version;
|
||||
|
||||
+5
-7
@@ -93,11 +93,6 @@ final class TestRunner extends BaseTestRunner
|
||||
|
||||
public const EXCEPTION_EXIT = 2;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $versionStringPrinted = false;
|
||||
|
||||
/**
|
||||
* @var CodeCoverageFilter
|
||||
*/
|
||||
@@ -334,8 +329,6 @@ final class TestRunner extends BaseTestRunner
|
||||
Version::getVersionString() . "\n"
|
||||
);
|
||||
|
||||
self::$versionStringPrinted = true;
|
||||
|
||||
foreach ($arguments['listeners'] as $listener) {
|
||||
$result->addListener($listener);
|
||||
}
|
||||
@@ -1142,6 +1135,11 @@ final class TestRunner extends BaseTestRunner
|
||||
$arguments['timeoutForMediumTests'] = $arguments['timeoutForMediumTests'] ?? 10;
|
||||
$arguments['timeoutForSmallTests'] = $arguments['timeoutForSmallTests'] ?? 1;
|
||||
$arguments['verbose'] = $arguments['verbose'] ?? false;
|
||||
|
||||
if ($arguments['reportLowUpperBound'] > $arguments['reportHighLowerBound']) {
|
||||
$arguments['reportLowUpperBound'] = 50;
|
||||
$arguments['reportHighLowerBound'] = 90;
|
||||
}
|
||||
}
|
||||
|
||||
private function processSuiteFilters(TestSuite $suite, array $arguments): void
|
||||
|
||||
Reference in New Issue
Block a user