diff --git a/src/CodeCoverage.php b/src/CodeCoverage.php index 88326f0b7..e6127da52 100644 --- a/src/CodeCoverage.php +++ b/src/CodeCoverage.php @@ -54,6 +54,8 @@ class PHP_CodeCoverage /** * @var bool + * + * @deprecated */ private $processUncoveredFilesFromWhitelist = false; @@ -86,6 +88,13 @@ class PHP_CodeCoverage */ private $tests = array(); + /** + * Store all uncovered files + * + * @var array + */ + private $uncoveredFiles = array(); + /** * Constructor. * @@ -105,6 +114,8 @@ public function __construct(PHP_CodeCoverage_Driver $driver = null, PHP_CodeCove $this->driver = $driver; $this->filter = $filter; + + $this->initData(); } /** @@ -219,7 +230,7 @@ public function start($id, $clear = false) $this->currentId = $id; - $this->driver->start(); + $this->driver->start(false); } /** @@ -250,6 +261,12 @@ public function stop($append = true, $linesToBeCovered = array(), array $linesTo $data = $this->driver->stop(); $this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed); + foreach (array_keys($data) as $file) { + if (isset($this->uncoveredFiles[$file])) { + unset($this->uncoveredFiles[$file]); + } + } + $this->currentId = null; return $data; @@ -576,7 +593,7 @@ private function applyIgnoredLinesFilter(array &$data) private function initializeFilesThatAreSeenTheFirstTime(array $data) { foreach ($data as $file => $lines) { - if ($this->filter->isFile($file) && !isset($this->data[$file])) { + if ($this->filter->isFile($file) && !isset($this->data[$file]) && !$this->filter()->isFiltered($file)) { $this->data[$file] = array(); foreach ($lines as $k => $v) { @@ -591,62 +608,15 @@ private function initializeFilesThatAreSeenTheFirstTime(array $data) */ private function addUncoveredFilesFromWhitelist() { - $data = array(); - $uncoveredFiles = array_diff( - $this->filter->getWhitelist(), - array_keys($this->data) - ); + $data = []; - foreach ($uncoveredFiles as $uncoveredFile) { - if (!file_exists($uncoveredFile)) { - continue; - } - - if ($this->processUncoveredFilesFromWhitelist) { - $this->processUncoveredFileFromWhitelist( - $uncoveredFile, - $data, - $uncoveredFiles - ); - } else { - $data[$uncoveredFile] = array(); - - $lines = count(file($uncoveredFile)); - - for ($i = 1; $i <= $lines; $i++) { - $data[$uncoveredFile][$i] = PHP_CodeCoverage_Driver::LINE_NOT_EXECUTED; - } - } + foreach (array_keys($this->uncoveredFiles) as $file) { + $data[$file] = $this->data[$file]; } $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST'); } - /** - * @param string $uncoveredFile - * @param array $data - * @param array $uncoveredFiles - */ - private function processUncoveredFileFromWhitelist($uncoveredFile, array &$data, array $uncoveredFiles) - { - $this->driver->start(); - include_once $uncoveredFile; - $coverage = $this->driver->stop(); - - foreach ($coverage as $file => $fileCoverage) { - if (!isset($data[$file]) && - in_array($file, $uncoveredFiles)) { - foreach (array_keys($fileCoverage) as $key) { - if ($fileCoverage[$key] == PHP_CodeCoverage_Driver::LINE_EXECUTED) { - $fileCoverage[$key] = PHP_CodeCoverage_Driver::LINE_NOT_EXECUTED; - } - } - - $data[$file] = $fileCoverage; - } - } - } - /** * Returns the lines of a source file that should be ignored. * @@ -917,4 +887,22 @@ private function selectDriver() return new PHP_CodeCoverage_Driver_Xdebug; } } + + /** + * Initialise the data with the executable/dead lines from each file in the whitelist + */ + private function initData() + { + foreach ($this->filter()->getWhitelist() as $file) { + $this->driver->start(); + include_once($file); + $data = $this->driver->stop(); + + $this->initializeFilesThatAreSeenTheFirstTime($data); + } + + foreach (array_keys($this->data) as $file) { + $this->uncoveredFiles[$file] = 1; + } + } } diff --git a/src/CodeCoverage/Driver.php b/src/CodeCoverage/Driver.php index 8635acefe..4452ec02e 100644 --- a/src/CodeCoverage/Driver.php +++ b/src/CodeCoverage/Driver.php @@ -36,7 +36,7 @@ interface PHP_CodeCoverage_Driver /** * Start collection of code coverage information. */ - public function start(); + public function start($determineUnusedAndDead = true); /** * Stop collection of code coverage information. diff --git a/src/CodeCoverage/Driver/HHVM.php b/src/CodeCoverage/Driver/HHVM.php index a9d8f0cef..4250091a3 100644 --- a/src/CodeCoverage/Driver/HHVM.php +++ b/src/CodeCoverage/Driver/HHVM.php @@ -19,7 +19,7 @@ class PHP_CodeCoverage_Driver_HHVM extends PHP_CodeCoverage_Driver_Xdebug /** * Start collection of code coverage information. */ - public function start() + public function start($determineUnusedAndDead = true) { xdebug_start_code_coverage(); } diff --git a/src/CodeCoverage/Driver/PHPDBG.php b/src/CodeCoverage/Driver/PHPDBG.php index f3eb6214a..4b8f4afe3 100644 --- a/src/CodeCoverage/Driver/PHPDBG.php +++ b/src/CodeCoverage/Driver/PHPDBG.php @@ -37,7 +37,7 @@ public function __construct() /** * Start collection of code coverage information. */ - public function start() + public function start($determineUnusedAndDead = true) { phpdbg_start_oplog(); } diff --git a/src/CodeCoverage/Driver/Xdebug.php b/src/CodeCoverage/Driver/Xdebug.php index 0cd7b9adc..1461569d4 100644 --- a/src/CodeCoverage/Driver/Xdebug.php +++ b/src/CodeCoverage/Driver/Xdebug.php @@ -16,6 +16,13 @@ */ class PHP_CodeCoverage_Driver_Xdebug implements PHP_CodeCoverage_Driver { + /** + * Cache the number of lines for each file + * + * @var array + */ + private $cacheNumLines = []; + /** * Constructor. */ @@ -36,9 +43,13 @@ public function __construct() /** * Start collection of code coverage information. */ - public function start() + public function start($determineUnusedAndDead = true) { - xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); + if ($determineUnusedAndDead) { + xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); + } else { + xdebug_start_code_coverage(); + } } /** @@ -85,13 +96,17 @@ private function cleanup(array $data) */ private function getNumberOfLinesInFile($file) { - $buffer = file_get_contents($file); - $lines = substr_count($buffer, "\n"); + if (!isset($this->cacheNumLines[$file])) { + $buffer = file_get_contents($file); + $lines = substr_count($buffer, "\n"); + + if (substr($buffer, -1) !== "\n") { + $lines++; + } - if (substr($buffer, -1) !== "\n") { - $lines++; + $this->cacheNumLines[$file] = $lines; } - return $lines; + return $this->cacheNumLines[$file]; } }