|
26 | 26 | */
|
27 | 27 | final class RawCodeCoverageData
|
28 | 28 | {
|
| 29 | + /** |
| 30 | + * @var array<string, array<int>> |
| 31 | + */ |
| 32 | + private static $emptyLineCache = []; |
| 33 | + |
29 | 34 | /**
|
30 | 35 | * @var array
|
31 | 36 | *
|
@@ -94,6 +99,8 @@ private function __construct(array $lineCoverage, array $functionCoverage)
|
94 | 99 | {
|
95 | 100 | $this->lineCoverage = $lineCoverage;
|
96 | 101 | $this->functionCoverage = $functionCoverage;
|
| 102 | + |
| 103 | + $this->skipEmptyLines(); |
97 | 104 | }
|
98 | 105 |
|
99 | 106 | public function clear(): void
|
@@ -181,4 +188,40 @@ public function removeCoverageDataForLines(string $filename, array $lines): void
|
181 | 188 | }
|
182 | 189 | }
|
183 | 190 | }
|
| 191 | + |
| 192 | + /** |
| 193 | + * At the end of a file, the PHP interpreter always sees an implicit return. Where this occurs in a file that has |
| 194 | + * e.g. a class definition, that line cannot be invoked from a test and results in confusing coverage. This engine |
| 195 | + * implementation detail therefore needs to be masked which is done here by simply ensuring that all empty lines |
| 196 | + * are skipped over for coverage purposes. |
| 197 | + * |
| 198 | + * @see https://github.com/sebastianbergmann/php-code-coverage/issues/799 |
| 199 | + */ |
| 200 | + private function skipEmptyLines(): void |
| 201 | + { |
| 202 | + foreach ($this->lineCoverage as $filename => $coverage) { |
| 203 | + foreach ($this->getEmptyLinesForFile($filename) as $emptyLine) { |
| 204 | + unset($this->lineCoverage[$filename][$emptyLine]); |
| 205 | + } |
| 206 | + } |
| 207 | + } |
| 208 | + |
| 209 | + private function getEmptyLinesForFile(string $filename): array |
| 210 | + { |
| 211 | + if (!isset(self::$emptyLineCache[$filename])) { |
| 212 | + self::$emptyLineCache[$filename] = []; |
| 213 | + |
| 214 | + if (is_file($filename)) { |
| 215 | + $sourceLines = explode("\n", file_get_contents($filename)); |
| 216 | + |
| 217 | + foreach ($sourceLines as $line => $source) { |
| 218 | + if (trim($source) === '') { |
| 219 | + self::$emptyLineCache[$filename][] = ($line + 1); |
| 220 | + } |
| 221 | + } |
| 222 | + } |
| 223 | + } |
| 224 | + |
| 225 | + return self::$emptyLineCache[$filename]; |
| 226 | + } |
184 | 227 | }
|
0 commit comments