summaryrefslogtreecommitdiff
path: root/vendor/phpunit/php-code-coverage/src/CodeCoverage.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/phpunit/php-code-coverage/src/CodeCoverage.php')
-rw-r--r--vendor/phpunit/php-code-coverage/src/CodeCoverage.php682
1 files changed, 0 insertions, 682 deletions
diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage.php
deleted file mode 100644
index c35f27c8c..000000000
--- a/vendor/phpunit/php-code-coverage/src/CodeCoverage.php
+++ /dev/null
@@ -1,682 +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;
-
-use function array_diff;
-use function array_diff_key;
-use function array_flip;
-use function array_keys;
-use function array_merge;
-use function array_unique;
-use function array_values;
-use function count;
-use function explode;
-use function get_class;
-use function is_array;
-use function sort;
-use PHPUnit\Framework\TestCase;
-use PHPUnit\Runner\PhptTestCase;
-use PHPUnit\Util\Test;
-use ReflectionClass;
-use SebastianBergmann\CodeCoverage\Driver\Driver;
-use SebastianBergmann\CodeCoverage\Node\Builder;
-use SebastianBergmann\CodeCoverage\Node\Directory;
-use SebastianBergmann\CodeCoverage\StaticAnalysis\CachingFileAnalyser;
-use SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
-use SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingFileAnalyser;
-use SebastianBergmann\CodeUnitReverseLookup\Wizard;
-
-/**
- * Provides collection functionality for PHP code coverage information.
- */
-final class CodeCoverage
-{
- private const UNCOVERED_FILES = 'UNCOVERED_FILES';
-
- /**
- * @var Driver
- */
- private $driver;
-
- /**
- * @var Filter
- */
- private $filter;
-
- /**
- * @var Wizard
- */
- private $wizard;
-
- /**
- * @var bool
- */
- private $checkForUnintentionallyCoveredCode = false;
-
- /**
- * @var bool
- */
- private $includeUncoveredFiles = true;
-
- /**
- * @var bool
- */
- private $processUncoveredFiles = false;
-
- /**
- * @var bool
- */
- private $ignoreDeprecatedCode = false;
-
- /**
- * @var null|PhptTestCase|string|TestCase
- */
- private $currentId;
-
- /**
- * Code coverage data.
- *
- * @var ProcessedCodeCoverageData
- */
- private $data;
-
- /**
- * @var bool
- */
- private $useAnnotationsForIgnoringCode = true;
-
- /**
- * Test data.
- *
- * @var array
- */
- private $tests = [];
-
- /**
- * @psalm-var list<class-string>
- */
- private $parentClassesExcludedFromUnintentionallyCoveredCodeCheck = [];
-
- /**
- * @var ?FileAnalyser
- */
- private $analyser;
-
- /**
- * @var ?string
- */
- private $cacheDirectory;
-
- public function __construct(Driver $driver, Filter $filter)
- {
- $this->driver = $driver;
- $this->filter = $filter;
- $this->data = new ProcessedCodeCoverageData;
- $this->wizard = new Wizard;
- }
-
- /**
- * Returns the code coverage information as a graph of node objects.
- */
- public function getReport(): Directory
- {
- return (new Builder($this->analyser()))->build($this);
- }
-
- /**
- * Clears collected code coverage data.
- */
- public function clear(): void
- {
- $this->currentId = null;
- $this->data = new ProcessedCodeCoverageData;
- $this->tests = [];
- }
-
- /**
- * Returns the filter object used.
- */
- public function filter(): Filter
- {
- return $this->filter;
- }
-
- /**
- * Returns the collected code coverage data.
- */
- public function getData(bool $raw = false): ProcessedCodeCoverageData
- {
- if (!$raw) {
- if ($this->processUncoveredFiles) {
- $this->processUncoveredFilesFromFilter();
- } elseif ($this->includeUncoveredFiles) {
- $this->addUncoveredFilesFromFilter();
- }
- }
-
- return $this->data;
- }
-
- /**
- * Sets the coverage data.
- */
- public function setData(ProcessedCodeCoverageData $data): void
- {
- $this->data = $data;
- }
-
- /**
- * Returns the test data.
- */
- public function getTests(): array
- {
- return $this->tests;
- }
-
- /**
- * Sets the test data.
- */
- public function setTests(array $tests): void
- {
- $this->tests = $tests;
- }
-
- /**
- * Start collection of code coverage information.
- *
- * @param PhptTestCase|string|TestCase $id
- */
- public function start($id, bool $clear = false): void
- {
- if ($clear) {
- $this->clear();
- }
-
- $this->currentId = $id;
-
- $this->driver->start();
- }
-
- /**
- * Stop collection of code coverage information.
- *
- * @param array|false $linesToBeCovered
- */
- public function stop(bool $append = true, $linesToBeCovered = [], array $linesToBeUsed = []): RawCodeCoverageData
- {
- if (!is_array($linesToBeCovered) && $linesToBeCovered !== false) {
- throw new InvalidArgumentException(
- '$linesToBeCovered must be an array or false'
- );
- }
-
- $data = $this->driver->stop();
- $this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed);
-
- $this->currentId = null;
-
- return $data;
- }
-
- /**
- * Appends code coverage data.
- *
- * @param PhptTestCase|string|TestCase $id
- * @param array|false $linesToBeCovered
- *
- * @throws ReflectionException
- * @throws TestIdMissingException
- * @throws UnintentionallyCoveredCodeException
- */
- public function append(RawCodeCoverageData $rawData, $id = null, bool $append = true, $linesToBeCovered = [], array $linesToBeUsed = []): void
- {
- if ($id === null) {
- $id = $this->currentId;
- }
-
- if ($id === null) {
- throw new TestIdMissingException;
- }
-
- $this->applyFilter($rawData);
-
- $this->applyExecutableLinesFilter($rawData);
-
- if ($this->useAnnotationsForIgnoringCode) {
- $this->applyIgnoredLinesFilter($rawData);
- }
-
- $this->data->initializeUnseenData($rawData);
-
- if (!$append) {
- return;
- }
-
- if ($id !== self::UNCOVERED_FILES) {
- $this->applyCoversAnnotationFilter(
- $rawData,
- $linesToBeCovered,
- $linesToBeUsed
- );
-
- if (empty($rawData->lineCoverage())) {
- return;
- }
-
- $size = 'unknown';
- $status = -1;
- $fromTestcase = false;
-
- if ($id instanceof TestCase) {
- $fromTestcase = true;
- $_size = $id->getSize();
-
- if ($_size === Test::SMALL) {
- $size = 'small';
- } elseif ($_size === Test::MEDIUM) {
- $size = 'medium';
- } elseif ($_size === Test::LARGE) {
- $size = 'large';
- }
-
- $status = $id->getStatus();
- $id = get_class($id) . '::' . $id->getName();
- } elseif ($id instanceof PhptTestCase) {
- $fromTestcase = true;
- $size = 'large';
- $id = $id->getName();
- }
-
- $this->tests[$id] = ['size' => $size, 'status' => $status, 'fromTestcase' => $fromTestcase];
-
- $this->data->markCodeAsExecutedByTestCase($id, $rawData);
- }
- }
-
- /**
- * Merges the data from another instance.
- */
- public function merge(self $that): void
- {
- $this->filter->includeFiles(
- $that->filter()->files()
- );
-
- $this->data->merge($that->data);
-
- $this->tests = array_merge($this->tests, $that->getTests());
- }
-
- public function enableCheckForUnintentionallyCoveredCode(): void
- {
- $this->checkForUnintentionallyCoveredCode = true;
- }
-
- public function disableCheckForUnintentionallyCoveredCode(): void
- {
- $this->checkForUnintentionallyCoveredCode = false;
- }
-
- public function includeUncoveredFiles(): void
- {
- $this->includeUncoveredFiles = true;
- }
-
- public function excludeUncoveredFiles(): void
- {
- $this->includeUncoveredFiles = false;
- }
-
- public function processUncoveredFiles(): void
- {
- $this->processUncoveredFiles = true;
- }
-
- public function doNotProcessUncoveredFiles(): void
- {
- $this->processUncoveredFiles = false;
- }
-
- public function enableAnnotationsForIgnoringCode(): void
- {
- $this->useAnnotationsForIgnoringCode = true;
- }
-
- public function disableAnnotationsForIgnoringCode(): void
- {
- $this->useAnnotationsForIgnoringCode = false;
- }
-
- public function ignoreDeprecatedCode(): void
- {
- $this->ignoreDeprecatedCode = true;
- }
-
- public function doNotIgnoreDeprecatedCode(): void
- {
- $this->ignoreDeprecatedCode = false;
- }
-
- /**
- * @psalm-assert-if-true !null $this->cacheDirectory
- */
- public function cachesStaticAnalysis(): bool
- {
- return $this->cacheDirectory !== null;
- }
-
- public function cacheStaticAnalysis(string $directory): void
- {
- $this->cacheDirectory = $directory;
- }
-
- public function doNotCacheStaticAnalysis(): void
- {
- $this->cacheDirectory = null;
- }
-
- /**
- * @throws StaticAnalysisCacheNotConfiguredException
- */
- public function cacheDirectory(): string
- {
- if (!$this->cachesStaticAnalysis()) {
- throw new StaticAnalysisCacheNotConfiguredException(
- 'The static analysis cache is not configured'
- );
- }
-
- return $this->cacheDirectory;
- }
-
- /**
- * @psalm-param class-string $className
- */
- public function excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck(string $className): void
- {
- $this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck[] = $className;
- }
-
- public function enableBranchAndPathCoverage(): void
- {
- $this->driver->enableBranchAndPathCoverage();
- }
-
- public function disableBranchAndPathCoverage(): void
- {
- $this->driver->disableBranchAndPathCoverage();
- }
-
- public function collectsBranchAndPathCoverage(): bool
- {
- return $this->driver->collectsBranchAndPathCoverage();
- }
-
- public function detectsDeadCode(): bool
- {
- return $this->driver->detectsDeadCode();
- }
-
- /**
- * Applies the @covers annotation filtering.
- *
- * @param array|false $linesToBeCovered
- *
- * @throws ReflectionException
- * @throws UnintentionallyCoveredCodeException
- */
- private function applyCoversAnnotationFilter(RawCodeCoverageData $rawData, $linesToBeCovered, array $linesToBeUsed): void
- {
- if ($linesToBeCovered === false) {
- $rawData->clear();
-
- return;
- }
-
- if (empty($linesToBeCovered)) {
- return;
- }
-
- if ($this->checkForUnintentionallyCoveredCode &&
- (!$this->currentId instanceof TestCase ||
- (!$this->currentId->isMedium() && !$this->currentId->isLarge()))) {
- $this->performUnintentionallyCoveredCodeCheck($rawData, $linesToBeCovered, $linesToBeUsed);
- }
-
- $rawLineData = $rawData->lineCoverage();
- $filesWithNoCoverage = array_diff_key($rawLineData, $linesToBeCovered);
-
- foreach (array_keys($filesWithNoCoverage) as $fileWithNoCoverage) {
- $rawData->removeCoverageDataForFile($fileWithNoCoverage);
- }
-
- if (is_array($linesToBeCovered)) {
- foreach ($linesToBeCovered as $fileToBeCovered => $includedLines) {
- $rawData->keepLineCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
- $rawData->keepFunctionCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
- }
- }
- }
-
- private function applyFilter(RawCodeCoverageData $data): void
- {
- if ($this->filter->isEmpty()) {
- return;
- }
-
- foreach (array_keys($data->lineCoverage()) as $filename) {
- if ($this->filter->isExcluded($filename)) {
- $data->removeCoverageDataForFile($filename);
- }
- }
- }
-
- private function applyExecutableLinesFilter(RawCodeCoverageData $data): void
- {
- foreach (array_keys($data->lineCoverage()) as $filename) {
- if (!$this->filter->isFile($filename)) {
- continue;
- }
-
- $linesToBranchMap = $this->analyser()->executableLinesIn($filename);
-
- $data->keepLineCoverageDataOnlyForLines(
- $filename,
- array_keys($linesToBranchMap)
- );
-
- $data->markExecutableLineByBranch(
- $filename,
- $linesToBranchMap
- );
- }
- }
-
- private function applyIgnoredLinesFilter(RawCodeCoverageData $data): void
- {
- foreach (array_keys($data->lineCoverage()) as $filename) {
- if (!$this->filter->isFile($filename)) {
- continue;
- }
-
- $data->removeCoverageDataForLines(
- $filename,
- $this->analyser()->ignoredLinesFor($filename)
- );
- }
- }
-
- /**
- * @throws UnintentionallyCoveredCodeException
- */
- private function addUncoveredFilesFromFilter(): void
- {
- $uncoveredFiles = array_diff(
- $this->filter->files(),
- $this->data->coveredFiles()
- );
-
- foreach ($uncoveredFiles as $uncoveredFile) {
- if ($this->filter->isFile($uncoveredFile)) {
- $this->append(
- RawCodeCoverageData::fromUncoveredFile(
- $uncoveredFile,
- $this->analyser()
- ),
- self::UNCOVERED_FILES
- );
- }
- }
- }
-
- /**
- * @throws UnintentionallyCoveredCodeException
- */
- private function processUncoveredFilesFromFilter(): void
- {
- $uncoveredFiles = array_diff(
- $this->filter->files(),
- $this->data->coveredFiles()
- );
-
- $this->driver->start();
-
- foreach ($uncoveredFiles as $uncoveredFile) {
- if ($this->filter->isFile($uncoveredFile)) {
- include_once $uncoveredFile;
- }
- }
-
- $this->append($this->driver->stop(), self::UNCOVERED_FILES);
- }
-
- /**
- * @throws ReflectionException
- * @throws UnintentionallyCoveredCodeException
- */
- private function performUnintentionallyCoveredCodeCheck(RawCodeCoverageData $data, array $linesToBeCovered, array $linesToBeUsed): void
- {
- $allowedLines = $this->getAllowedLines(
- $linesToBeCovered,
- $linesToBeUsed
- );
-
- $unintentionallyCoveredUnits = [];
-
- foreach ($data->lineCoverage() as $file => $_data) {
- foreach ($_data as $line => $flag) {
- if ($flag === 1 && !isset($allowedLines[$file][$line])) {
- $unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line);
- }
- }
- }
-
- $unintentionallyCoveredUnits = $this->processUnintentionallyCoveredUnits($unintentionallyCoveredUnits);
-
- if (!empty($unintentionallyCoveredUnits)) {
- throw new UnintentionallyCoveredCodeException(
- $unintentionallyCoveredUnits
- );
- }
- }
-
- private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed): array
- {
- $allowedLines = [];
-
- foreach (array_keys($linesToBeCovered) as $file) {
- if (!isset($allowedLines[$file])) {
- $allowedLines[$file] = [];
- }
-
- $allowedLines[$file] = array_merge(
- $allowedLines[$file],
- $linesToBeCovered[$file]
- );
- }
-
- foreach (array_keys($linesToBeUsed) as $file) {
- if (!isset($allowedLines[$file])) {
- $allowedLines[$file] = [];
- }
-
- $allowedLines[$file] = array_merge(
- $allowedLines[$file],
- $linesToBeUsed[$file]
- );
- }
-
- foreach (array_keys($allowedLines) as $file) {
- $allowedLines[$file] = array_flip(
- array_unique($allowedLines[$file])
- );
- }
-
- return $allowedLines;
- }
-
- /**
- * @throws ReflectionException
- */
- private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits): array
- {
- $unintentionallyCoveredUnits = array_unique($unintentionallyCoveredUnits);
- sort($unintentionallyCoveredUnits);
-
- foreach (array_keys($unintentionallyCoveredUnits) as $k => $v) {
- $unit = explode('::', $unintentionallyCoveredUnits[$k]);
-
- if (count($unit) !== 2) {
- continue;
- }
-
- try {
- $class = new ReflectionClass($unit[0]);
-
- foreach ($this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck as $parentClass) {
- if ($class->isSubclassOf($parentClass)) {
- unset($unintentionallyCoveredUnits[$k]);
-
- break;
- }
- }
- } catch (\ReflectionException $e) {
- throw new ReflectionException(
- $e->getMessage(),
- $e->getCode(),
- $e
- );
- }
- }
-
- return array_values($unintentionallyCoveredUnits);
- }
-
- private function analyser(): FileAnalyser
- {
- if ($this->analyser !== null) {
- return $this->analyser;
- }
-
- $this->analyser = new ParsingFileAnalyser(
- $this->useAnnotationsForIgnoringCode,
- $this->ignoreDeprecatedCode
- );
-
- if ($this->cachesStaticAnalysis()) {
- $this->analyser = new CachingFileAnalyser(
- $this->cacheDirectory,
- $this->analyser
- );
- }
-
- return $this->analyser;
- }
-}