Server IP : 66.29.132.124 / Your IP : 3.145.179.30 Web Server : LiteSpeed System : Linux business141.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64 User : wavevlvu ( 1524) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/wavevlvu/book24.ng/vendor/phpunit/php-code-coverage/src/ |
Upload File : |
<?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_intersect; use function array_intersect_key; use function count; use function in_array; use function range; use SebastianBergmann\CodeCoverage\Driver\Driver; use SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage */ final class RawCodeCoverageData { /** * @var array<string, array<int>> */ private static $emptyLineCache = []; /** * @var array * * @see https://xdebug.org/docs/code_coverage for format */ private $lineCoverage; /** * @var array * * @see https://xdebug.org/docs/code_coverage for format */ private $functionCoverage; public static function fromXdebugWithoutPathCoverage(array $rawCoverage): self { return new self($rawCoverage, []); } public static function fromXdebugWithPathCoverage(array $rawCoverage): self { $lineCoverage = []; $functionCoverage = []; foreach ($rawCoverage as $file => $fileCoverageData) { $lineCoverage[$file] = $fileCoverageData['lines']; $functionCoverage[$file] = $fileCoverageData['functions']; } return new self($lineCoverage, $functionCoverage); } public static function fromXdebugWithMixedCoverage(array $rawCoverage): self { $lineCoverage = []; $functionCoverage = []; foreach ($rawCoverage as $file => $fileCoverageData) { if (!isset($fileCoverageData['functions'])) { // Current file does not have functions, so line coverage // is stored in $fileCoverageData, not in $fileCoverageData['lines'] $lineCoverage[$file] = $fileCoverageData; continue; } $lineCoverage[$file] = $fileCoverageData['lines']; $functionCoverage[$file] = $fileCoverageData['functions']; } return new self($lineCoverage, $functionCoverage); } public static function fromUncoveredFile(string $filename, FileAnalyser $analyser): self { $lineCoverage = []; foreach ($analyser->executableLinesIn($filename) as $line) { $lineCoverage[$line] = Driver::LINE_NOT_EXECUTED; } return new self([$filename => $lineCoverage], []); } private function __construct(array $lineCoverage, array $functionCoverage) { $this->lineCoverage = $lineCoverage; $this->functionCoverage = $functionCoverage; $this->skipEmptyLines(); } public function clear(): void { $this->lineCoverage = $this->functionCoverage = []; } public function lineCoverage(): array { return $this->lineCoverage; } public function functionCoverage(): array { return $this->functionCoverage; } public function removeCoverageDataForFile(string $filename): void { unset($this->lineCoverage[$filename], $this->functionCoverage[$filename]); } /** * @param int[] $lines */ public function keepLineCoverageDataOnlyForLines(string $filename, array $lines): void { if (!isset($this->lineCoverage[$filename])) { return; } $this->lineCoverage[$filename] = array_intersect_key( $this->lineCoverage[$filename], array_flip($lines) ); } /** * @param int[] $lines */ public function keepFunctionCoverageDataOnlyForLines(string $filename, array $lines): void { if (!isset($this->functionCoverage[$filename])) { return; } 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]); } } } } } } /** * @param int[] $lines */ public function removeCoverageDataForLines(string $filename, array $lines): void { if (empty($lines)) { return; } if (!isset($this->lineCoverage[$filename])) { return; } $this->lineCoverage[$filename] = array_diff_key( $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_intersect($lines, range($branch['line_start'], $branch['line_end']))) > 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]); } } } } } } } /** * At the end of a file, the PHP interpreter always sees an implicit return. Where this occurs in a file that has * e.g. a class definition, that line cannot be invoked from a test and results in confusing coverage. This engine * implementation detail therefore needs to be masked which is done here by simply ensuring that all empty lines * are skipped over for coverage purposes. * * @see https://github.com/sebastianbergmann/php-code-coverage/issues/799 */ private function skipEmptyLines(): void { foreach ($this->lineCoverage as $filename => $coverage) { foreach ($this->getEmptyLinesForFile($filename) as $emptyLine) { unset($this->lineCoverage[$filename][$emptyLine]); } } } private function getEmptyLinesForFile(string $filename): array { if (!isset(self::$emptyLineCache[$filename])) { self::$emptyLineCache[$filename] = []; if (is_file($filename)) { $sourceLines = explode("\n", file_get_contents($filename)); foreach ($sourceLines as $line => $source) { if (trim($source) === '') { self::$emptyLineCache[$filename][] = ($line + 1); } } } } return self::$emptyLineCache[$filename]; } }