芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/xmintal-back/vendor/phpunit/php-code-coverage/src/Node/File.php
* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace SebastianBergmann\CodeCoverage\Node; /** * Represents a file in the code coverage information tree. */ final class File extends AbstractNode { /** * @var array */ private $coverageData; /** * @var array */ private $testData; /** * @var int */ private $numExecutableLines = 0; /** * @var int */ private $numExecutedLines = 0; /** * @var array */ private $classes = []; /** * @var array */ private $traits = []; /** * @var array */ private $functions = []; /** * @var array */ private $linesOfCode = []; /** * @var int */ private $numClasses; /** * @var int */ private $numTestedClasses = 0; /** * @var int */ private $numTraits; /** * @var int */ private $numTestedTraits = 0; /** * @var int */ private $numMethods; /** * @var int */ private $numTestedMethods; /** * @var int */ private $numTestedFunctions; /** * @var bool */ private $cacheTokens; /** * @var array */ private $codeUnitsByLine = []; public function __construct(string $name, AbstractNode $parent, array $coverageData, array $testData, bool $cacheTokens) { parent::__construct($name, $parent); $this->coverageData = $coverageData; $this->testData = $testData; $this->cacheTokens = $cacheTokens; $this->calculateStatistics(); } /** * Returns the number of files in/under this node. */ public function count(): int { return 1; } /** * Returns the code coverage data of this node. */ public function getCoverageData(): array { return $this->coverageData; } /** * Returns the test data of this node. */ public function getTestData(): array { return $this->testData; } /** * Returns the classes of this node. */ public function getClasses(): array { return $this->classes; } /** * Returns the traits of this node. */ public function getTraits(): array { return $this->traits; } /** * Returns the functions of this node. */ public function getFunctions(): array { return $this->functions; } /** * Returns the LOC/CLOC/NCLOC of this node. */ public function getLinesOfCode(): array { return $this->linesOfCode; } /** * Returns the number of executable lines. */ public function getNumExecutableLines(): int { return $this->numExecutableLines; } /** * Returns the number of executed lines. */ public function getNumExecutedLines(): int { return $this->numExecutedLines; } /** * Returns the number of classes. */ public function getNumClasses(): int { if ($this->numClasses === null) { $this->numClasses = 0; foreach ($this->classes as $class) { foreach ($class['methods'] as $method) { if ($method['executableLines'] > 0) { $this->numClasses++; continue 2; } } } } return $this->numClasses; } /** * Returns the number of tested classes. */ public function getNumTestedClasses(): int { return $this->numTestedClasses; } /** * Returns the number of traits. */ public function getNumTraits(): int { if ($this->numTraits === null) { $this->numTraits = 0; foreach ($this->traits as $trait) { foreach ($trait['methods'] as $method) { if ($method['executableLines'] > 0) { $this->numTraits++; continue 2; } } } } return $this->numTraits; } /** * Returns the number of tested traits. */ public function getNumTestedTraits(): int { return $this->numTestedTraits; } /** * Returns the number of methods. */ public function getNumMethods(): int { if ($this->numMethods === null) { $this->numMethods = 0; foreach ($this->classes as $class) { foreach ($class['methods'] as $method) { if ($method['executableLines'] > 0) { $this->numMethods++; } } } foreach ($this->traits as $trait) { foreach ($trait['methods'] as $method) { if ($method['executableLines'] > 0) { $this->numMethods++; } } } } return $this->numMethods; } /** * Returns the number of tested methods. */ public function getNumTestedMethods(): int { if ($this->numTestedMethods === null) { $this->numTestedMethods = 0; foreach ($this->classes as $class) { foreach ($class['methods'] as $method) { if ($method['executableLines'] > 0 && $method['coverage'] === 100) { $this->numTestedMethods++; } } } foreach ($this->traits as $trait) { foreach ($trait['methods'] as $method) { if ($method['executableLines'] > 0 && $method['coverage'] === 100) { $this->numTestedMethods++; } } } } return $this->numTestedMethods; } /** * Returns the number of functions. */ public function getNumFunctions(): int { return \count($this->functions); } /** * Returns the number of tested functions. */ public function getNumTestedFunctions(): int { if ($this->numTestedFunctions === null) { $this->numTestedFunctions = 0; foreach ($this->functions as $function) { if ($function['executableLines'] > 0 && $function['coverage'] === 100) { $this->numTestedFunctions++; } } } return $this->numTestedFunctions; } private function calculateStatistics(): void { if ($this->cacheTokens) { $tokens = \PHP_Token_Stream_CachingFactory::get($this->getPath()); } else { $tokens = new \PHP_Token_Stream($this->getPath()); } $this->linesOfCode = $tokens->getLinesOfCode(); foreach (\range(1, $this->linesOfCode['loc']) as $lineNumber) { $this->codeUnitsByLine[$lineNumber] = []; } try { $this->processClasses($tokens); $this->processTraits($tokens); $this->processFunctions($tokens); } catch (\OutOfBoundsException $e) { // This can happen with PHP_Token_Stream if the file is syntactically invalid, // and probably affects a file that wasn't executed. } unset($tokens); foreach (\range(1, $this->linesOfCode['loc']) as $lineNumber) { if (isset($this->coverageData[$lineNumber])) { foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { $codeUnit['executableLines']++; } unset($codeUnit); $this->numExecutableLines++; if (\count($this->coverageData[$lineNumber]) > 0) { foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { $codeUnit['executedLines']++; } unset($codeUnit); $this->numExecutedLines++; } } } foreach ($this->traits as &$trait) { foreach ($trait['methods'] as &$method) { if ($method['executableLines'] > 0) { $method['coverage'] = ($method['executedLines'] / $method['executableLines']) * 100; } else { $method['coverage'] = 100; } $method['crap'] = $this->crap( $method['ccn'], $method['coverage'] ); $trait['ccn'] += $method['ccn']; } unset($method); if ($trait['executableLines'] > 0) { $trait['coverage'] = ($trait['executedLines'] / $trait['executableLines']) * 100; if ($trait['coverage'] === 100) { $this->numTestedClasses++; } } else { $trait['coverage'] = 100; } $trait['crap'] = $this->crap( $trait['ccn'], $trait['coverage'] ); } unset($trait); foreach ($this->classes as &$class) { foreach ($class['methods'] as &$method) { if ($method['executableLines'] > 0) { $method['coverage'] = ($method['executedLines'] / $method['executableLines']) * 100; } else { $method['coverage'] = 100; } $method['crap'] = $this->crap( $method['ccn'], $method['coverage'] ); $class['ccn'] += $method['ccn']; } unset($method); if ($class['executableLines'] > 0) { $class['coverage'] = ($class['executedLines'] / $class['executableLines']) * 100; if ($class['coverage'] === 100) { $this->numTestedClasses++; } } else { $class['coverage'] = 100; } $class['crap'] = $this->crap( $class['ccn'], $class['coverage'] ); } unset($class); foreach ($this->functions as &$function) { if ($function['executableLines'] > 0) { $function['coverage'] = ($function['executedLines'] / $function['executableLines']) * 100; } else { $function['coverage'] = 100; } if ($function['coverage'] === 100) { $this->numTestedFunctions++; } $function['crap'] = $this->crap( $function['ccn'], $function['coverage'] ); } } private function processClasses(\PHP_Token_Stream $tokens): void { $classes = $tokens->getClasses(); $link = $this->getId() . '.html#'; foreach ($classes as $className => $class) { if (\strpos($className, 'anonymous') === 0) { continue; } if (!empty($class['package']['namespace'])) { $className = $class['package']['namespace'] . '\\' . $className; } $this->classes[$className] = [ 'className' => $className, 'methods' => [], 'startLine' => $class['startLine'], 'executableLines' => 0, 'executedLines' => 0, 'ccn' => 0, 'coverage' => 0, 'crap' => 0, 'package' => $class['package'], 'link' => $link . $class['startLine'], ]; foreach ($class['methods'] as $methodName => $method) { if (\strpos($methodName, 'anonymous') === 0) { continue; } $this->classes[$className]['methods'][$methodName] = $this->newMethod($methodName, $method, $link); foreach (\range($method['startLine'], $method['endLine']) as $lineNumber) { $this->codeUnitsByLine[$lineNumber] = [ &$this->classes[$className], &$this->classes[$className]['methods'][$methodName], ]; } } } } private function processTraits(\PHP_Token_Stream $tokens): void { $traits = $tokens->getTraits(); $link = $this->getId() . '.html#'; foreach ($traits as $traitName => $trait) { $this->traits[$traitName] = [ 'traitName' => $traitName, 'methods' => [], 'startLine' => $trait['startLine'], 'executableLines' => 0, 'executedLines' => 0, 'ccn' => 0, 'coverage' => 0, 'crap' => 0, 'package' => $trait['package'], 'link' => $link . $trait['startLine'], ]; foreach ($trait['methods'] as $methodName => $method) { if (\strpos($methodName, 'anonymous') === 0) { continue; } $this->traits[$traitName]['methods'][$methodName] = $this->newMethod($methodName, $method, $link); foreach (\range($method['startLine'], $method['endLine']) as $lineNumber) { $this->codeUnitsByLine[$lineNumber] = [ &$this->traits[$traitName], &$this->traits[$traitName]['methods'][$methodName], ]; } } } } private function processFunctions(\PHP_Token_Stream $tokens): void { $functions = $tokens->getFunctions(); $link = $this->getId() . '.html#'; foreach ($functions as $functionName => $function) { if (\strpos($functionName, 'anonymous') === 0) { continue; } $this->functions[$functionName] = [ 'functionName' => $functionName, 'signature' => $function['signature'], 'startLine' => $function['startLine'], 'executableLines' => 0, 'executedLines' => 0, 'ccn' => $function['ccn'], 'coverage' => 0, 'crap' => 0, 'link' => $link . $function['startLine'], ]; foreach (\range($function['startLine'], $function['endLine']) as $lineNumber) { $this->codeUnitsByLine[$lineNumber] = [&$this->functions[$functionName]]; } } } private function crap(int $ccn, float $coverage): string { if ($coverage === 0.0) { return (string) ($ccn ** 2 + $ccn); } if ($coverage >= 95) { return (string) $ccn; } return \sprintf( '%01.2F', $ccn ** 2 * (1 - $coverage / 100) ** 3 + $ccn ); } private function newMethod(string $methodName, array $method, string $link): array { return [ 'methodName' => $methodName, 'visibility' => $method['visibility'], 'signature' => $method['signature'], 'startLine' => $method['startLine'], 'endLine' => $method['endLine'], 'executableLines' => 0, 'executedLines' => 0, 'ccn' => $method['ccn'], 'coverage' => 0, 'crap' => 0, 'link' => $link . $method['startLine'], ]; } }