annotate vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Text.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
rev   line source
Chris@0 1 <?php
Chris@0 2 /*
Chris@0 3 * This file is part of the PHP_CodeCoverage package.
Chris@0 4 *
Chris@0 5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
Chris@0 6 *
Chris@0 7 * For the full copyright and license information, please view the LICENSE
Chris@0 8 * file that was distributed with this source code.
Chris@0 9 */
Chris@0 10
Chris@0 11 /**
Chris@0 12 * Generates human readable output from an PHP_CodeCoverage object.
Chris@0 13 *
Chris@0 14 * The output gets put into a text file our written to the CLI.
Chris@0 15 *
Chris@0 16 * @since Class available since Release 1.1.0
Chris@0 17 */
Chris@0 18 class PHP_CodeCoverage_Report_Text
Chris@0 19 {
Chris@0 20 protected $lowUpperBound;
Chris@0 21 protected $highLowerBound;
Chris@0 22 protected $showUncoveredFiles;
Chris@0 23 protected $showOnlySummary;
Chris@0 24
Chris@0 25 protected $colors = array(
Chris@0 26 'green' => "\x1b[30;42m",
Chris@0 27 'yellow' => "\x1b[30;43m",
Chris@0 28 'red' => "\x1b[37;41m",
Chris@0 29 'header' => "\x1b[1;37;40m",
Chris@0 30 'reset' => "\x1b[0m",
Chris@0 31 'eol' => "\x1b[2K",
Chris@0 32 );
Chris@0 33
Chris@0 34 public function __construct($lowUpperBound, $highLowerBound, $showUncoveredFiles, $showOnlySummary)
Chris@0 35 {
Chris@0 36 $this->lowUpperBound = $lowUpperBound;
Chris@0 37 $this->highLowerBound = $highLowerBound;
Chris@0 38 $this->showUncoveredFiles = $showUncoveredFiles;
Chris@0 39 $this->showOnlySummary = $showOnlySummary;
Chris@0 40 }
Chris@0 41
Chris@0 42 /**
Chris@0 43 * @param PHP_CodeCoverage $coverage
Chris@0 44 * @param bool $showColors
Chris@0 45 * @return string
Chris@0 46 */
Chris@0 47 public function process(PHP_CodeCoverage $coverage, $showColors = false)
Chris@0 48 {
Chris@0 49 $output = PHP_EOL . PHP_EOL;
Chris@0 50 $report = $coverage->getReport();
Chris@0 51 unset($coverage);
Chris@0 52
Chris@0 53 $colors = array(
Chris@0 54 'header' => '',
Chris@0 55 'classes' => '',
Chris@0 56 'methods' => '',
Chris@0 57 'lines' => '',
Chris@0 58 'reset' => '',
Chris@0 59 'eol' => ''
Chris@0 60 );
Chris@0 61
Chris@0 62 if ($showColors) {
Chris@0 63 $colors['classes'] = $this->getCoverageColor(
Chris@0 64 $report->getNumTestedClassesAndTraits(),
Chris@0 65 $report->getNumClassesAndTraits()
Chris@0 66 );
Chris@0 67 $colors['methods'] = $this->getCoverageColor(
Chris@0 68 $report->getNumTestedMethods(),
Chris@0 69 $report->getNumMethods()
Chris@0 70 );
Chris@0 71 $colors['lines'] = $this->getCoverageColor(
Chris@0 72 $report->getNumExecutedLines(),
Chris@0 73 $report->getNumExecutableLines()
Chris@0 74 );
Chris@0 75 $colors['reset'] = $this->colors['reset'];
Chris@0 76 $colors['header'] = $this->colors['header'];
Chris@0 77 $colors['eol'] = $this->colors['eol'];
Chris@0 78 }
Chris@0 79
Chris@0 80 $classes = sprintf(
Chris@0 81 ' Classes: %6s (%d/%d)',
Chris@0 82 PHP_CodeCoverage_Util::percent(
Chris@0 83 $report->getNumTestedClassesAndTraits(),
Chris@0 84 $report->getNumClassesAndTraits(),
Chris@0 85 true
Chris@0 86 ),
Chris@0 87 $report->getNumTestedClassesAndTraits(),
Chris@0 88 $report->getNumClassesAndTraits()
Chris@0 89 );
Chris@0 90
Chris@0 91 $methods = sprintf(
Chris@0 92 ' Methods: %6s (%d/%d)',
Chris@0 93 PHP_CodeCoverage_Util::percent(
Chris@0 94 $report->getNumTestedMethods(),
Chris@0 95 $report->getNumMethods(),
Chris@0 96 true
Chris@0 97 ),
Chris@0 98 $report->getNumTestedMethods(),
Chris@0 99 $report->getNumMethods()
Chris@0 100 );
Chris@0 101
Chris@0 102 $lines = sprintf(
Chris@0 103 ' Lines: %6s (%d/%d)',
Chris@0 104 PHP_CodeCoverage_Util::percent(
Chris@0 105 $report->getNumExecutedLines(),
Chris@0 106 $report->getNumExecutableLines(),
Chris@0 107 true
Chris@0 108 ),
Chris@0 109 $report->getNumExecutedLines(),
Chris@0 110 $report->getNumExecutableLines()
Chris@0 111 );
Chris@0 112
Chris@0 113 $padding = max(array_map('strlen', array($classes, $methods, $lines)));
Chris@0 114
Chris@0 115 if ($this->showOnlySummary) {
Chris@0 116 $title = 'Code Coverage Report Summary:';
Chris@0 117 $padding = max($padding, strlen($title));
Chris@0 118
Chris@0 119 $output .= $this->format($colors['header'], $padding, $title);
Chris@0 120 } else {
Chris@0 121 $date = date(' Y-m-d H:i:s', $_SERVER['REQUEST_TIME']);
Chris@0 122 $title = 'Code Coverage Report:';
Chris@0 123
Chris@0 124 $output .= $this->format($colors['header'], $padding, $title);
Chris@0 125 $output .= $this->format($colors['header'], $padding, $date);
Chris@0 126 $output .= $this->format($colors['header'], $padding, '');
Chris@0 127 $output .= $this->format($colors['header'], $padding, ' Summary:');
Chris@0 128 }
Chris@0 129
Chris@0 130 $output .= $this->format($colors['classes'], $padding, $classes);
Chris@0 131 $output .= $this->format($colors['methods'], $padding, $methods);
Chris@0 132 $output .= $this->format($colors['lines'], $padding, $lines);
Chris@0 133
Chris@0 134 if ($this->showOnlySummary) {
Chris@0 135 return $output . PHP_EOL;
Chris@0 136 }
Chris@0 137
Chris@0 138 $classCoverage = array();
Chris@0 139
Chris@0 140 foreach ($report as $item) {
Chris@0 141 if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
Chris@0 142 continue;
Chris@0 143 }
Chris@0 144
Chris@0 145 $classes = $item->getClassesAndTraits();
Chris@0 146
Chris@0 147 foreach ($classes as $className => $class) {
Chris@0 148 $classStatements = 0;
Chris@0 149 $coveredClassStatements = 0;
Chris@0 150 $coveredMethods = 0;
Chris@0 151 $classMethods = 0;
Chris@0 152
Chris@0 153 foreach ($class['methods'] as $method) {
Chris@0 154 if ($method['executableLines'] == 0) {
Chris@0 155 continue;
Chris@0 156 }
Chris@0 157
Chris@0 158 $classMethods++;
Chris@0 159 $classStatements += $method['executableLines'];
Chris@0 160 $coveredClassStatements += $method['executedLines'];
Chris@0 161 if ($method['coverage'] == 100) {
Chris@0 162 $coveredMethods++;
Chris@0 163 }
Chris@0 164 }
Chris@0 165
Chris@0 166 if (!empty($class['package']['namespace'])) {
Chris@0 167 $namespace = '\\' . $class['package']['namespace'] . '::';
Chris@0 168 } elseif (!empty($class['package']['fullPackage'])) {
Chris@0 169 $namespace = '@' . $class['package']['fullPackage'] . '::';
Chris@0 170 } else {
Chris@0 171 $namespace = '';
Chris@0 172 }
Chris@0 173
Chris@0 174 $classCoverage[$namespace . $className] = array(
Chris@0 175 'namespace' => $namespace,
Chris@0 176 'className ' => $className,
Chris@0 177 'methodsCovered' => $coveredMethods,
Chris@0 178 'methodCount' => $classMethods,
Chris@0 179 'statementsCovered' => $coveredClassStatements,
Chris@0 180 'statementCount' => $classStatements,
Chris@0 181 );
Chris@0 182 }
Chris@0 183 }
Chris@0 184
Chris@0 185 ksort($classCoverage);
Chris@0 186
Chris@0 187 $methodColor = '';
Chris@0 188 $linesColor = '';
Chris@0 189 $resetColor = '';
Chris@0 190
Chris@0 191 foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
Chris@0 192 if ($classInfo['statementsCovered'] != 0 ||
Chris@0 193 $this->showUncoveredFiles) {
Chris@0 194 if ($showColors) {
Chris@0 195 $methodColor = $this->getCoverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
Chris@0 196 $linesColor = $this->getCoverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
Chris@0 197 $resetColor = $colors['reset'];
Chris@0 198 }
Chris@0 199
Chris@0 200 $output .= PHP_EOL . $fullQualifiedPath . PHP_EOL
Chris@0 201 . ' ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' '
Chris@0 202 . ' ' . $linesColor . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor
Chris@0 203 ;
Chris@0 204 }
Chris@0 205 }
Chris@0 206
Chris@0 207 return $output . PHP_EOL;
Chris@0 208 }
Chris@0 209
Chris@0 210 protected function getCoverageColor($numberOfCoveredElements, $totalNumberOfElements)
Chris@0 211 {
Chris@0 212 $coverage = PHP_CodeCoverage_Util::percent(
Chris@0 213 $numberOfCoveredElements,
Chris@0 214 $totalNumberOfElements
Chris@0 215 );
Chris@0 216
Chris@0 217 if ($coverage >= $this->highLowerBound) {
Chris@0 218 return $this->colors['green'];
Chris@0 219 } elseif ($coverage > $this->lowUpperBound) {
Chris@0 220 return $this->colors['yellow'];
Chris@0 221 }
Chris@0 222
Chris@0 223 return $this->colors['red'];
Chris@0 224 }
Chris@0 225
Chris@0 226 protected function printCoverageCounts($numberOfCoveredElements, $totalNumberOfElements, $presicion)
Chris@0 227 {
Chris@0 228 $format = '%' . $presicion . 's';
Chris@0 229
Chris@0 230 return PHP_CodeCoverage_Util::percent(
Chris@0 231 $numberOfCoveredElements,
Chris@0 232 $totalNumberOfElements,
Chris@0 233 true,
Chris@0 234 true
Chris@0 235 ) .
Chris@0 236 ' (' . sprintf($format, $numberOfCoveredElements) . '/' .
Chris@0 237 sprintf($format, $totalNumberOfElements) . ')';
Chris@0 238 }
Chris@0 239
Chris@0 240 private function format($color, $padding, $string)
Chris@0 241 {
Chris@0 242 $reset = $color ? $this->colors['reset'] : '';
Chris@0 243
Chris@0 244 return $color . str_pad($string, $padding) . $reset . PHP_EOL;
Chris@0 245 }
Chris@0 246 }