/** * Mark a source code file based on the coverage data gathered * * @param $phpFile Name of the actual source file * @param $fileLink Link to the html mark-up file for the $phpFile * @param &$coverageLines Coverage recording for $phpFile * @return boolean FALSE on failure * @access protected */ protected function markFile($phpFile, $fileLink, &$coverageLines) { global $util; $fileLink = $util->replaceBackslashes($fileLink); $parentDir = $util->replaceBackslashes(dirname($fileLink)); if (!file_exists($parentDir)) { //echo "\nCreating dir: $parentDir\n"; $util->makeDirRecursive($parentDir, 0755); } $writer = fopen($fileLink, "w"); if (empty($writer)) { $this->logger->error("Could not open file for writing: {$fileLink}", __FILE__, __LINE__); return false; } // Get the header for file $filestr = $this->writePhpFileHeader(basename($phpFile), $fileLink); // Add header for table $filestr .= '<table width="100%" border="0" cellpadding="2" cellspacing="0">'; $filestr .= $this->writeFileTableHead(); $lineCnt = $coveredCnt = $uncoveredCnt = 0; $parser = new PHPParser(); $parser->parse($phpFile); $lastLineType = "non-exec"; $fileLines = array(); while (($line = $parser->getLine()) !== false) { if (substr($line, -1) == "\n") { $line = substr($line, 0, -1); } $lineCnt++; $coverageLineNumbers = array_keys($coverageLines); if (in_array($lineCnt, $coverageLineNumbers)) { $lineType = $parser->getLineType(); if ($lineType == LINE_TYPE_EXEC) { $coveredCnt++; $type = "covered"; } else { if ($lineType == LINE_TYPE_CONT) { // XDebug might return this as covered - when it is // actually merely a continuation of previous line if ($lastLineType == "covered" || $lastLineType == "covered_cont") { unset($coverageLines[$lineCnt]); $type = "covered_cont"; $coveredCnt++; } else { $ft = "uncovered_cont"; for ($il = $lineCnt - 1; $il >= 0 && isset($fileLines[$lineCnt - 1]["type"]) && $ft == "uncovered_cont"; $il--) { $ft = $fileLines[$il]["type"]; $uncoveredCnt--; $coveredCnt++; if ($ft == "uncovered") { $fileLines[$il]["type"] = "covered"; } else { $fileLines[$il]["type"] = "covered_cont"; } } $coveredCnt++; $type = "covered_cont"; } } else { $type = "non-exec"; $coverageLines[$lineCnt] = 0; } } } else { if ($parser->getLineType() == LINE_TYPE_EXEC) { $uncoveredCnt++; $type = "uncovered"; } else { if ($parser->getLineType() == LINE_TYPE_CONT) { if ($lastLineType == "uncovered" || $lastLineType == "uncovered_cont") { $uncoveredCnt++; $type = "uncovered_cont"; } else { if ($lastLineType == "covered" || $lastLineType == "covered_cont") { $coveredCnt++; $type = "covered_cont"; } else { $type = $lastLineType; $this->logger->debug("LINE_TYPE_CONT with lastLineType={$lastLineType}", __FILE__, __LINE__); } } } else { $type = "non-exec"; } } } // Save line type $lastLineType = $type; //echo $line . "\t[" . $type . "]\n"; if (!isset($coverageLines[$lineCnt])) { $coverageLines[$lineCnt] = 0; } $fileLines[$lineCnt] = array("type" => $type, "lineCnt" => $lineCnt, "line" => $line, "coverageLines" => $coverageLines[$lineCnt]); } $this->logger->debug("File lines: " . print_r($fileLines, true), __FILE__, __LINE__); for ($i = 1; $i <= count($fileLines); $i++) { $filestr .= $this->writeFileTableRow($fileLines[$i]["type"], $fileLines[$i]["lineCnt"], $fileLines[$i]["line"], $fileLines[$i]["coverageLines"]); } $filestr .= "</table>"; $filestr .= $this->writePhpFileFooter(); fwrite($writer, $filestr); fclose($writer); return array('filename' => $phpFile, 'covered' => $coveredCnt, 'uncovered' => $uncoveredCnt, 'total' => $lineCnt); }
protected function markFile($phpFile, $fileLink, &$coverageLines) { global $util; $fileLink = $util->replaceBackslashes($fileLink); $parentDir = $util->replaceBackslashes(dirname($fileLink)); $lineCnt = $coveredCnt = $uncoveredCnt = 0; $parser = new PHPParser(); $parser->parse($phpFile); $lastLineType = "non-exec"; $fileLines = array(); while (($line = $parser->getLine()) !== false) { $line = substr($line, 0, strlen($line) - 1); $lineCnt++; $coverageLineNumbers = array_keys($coverageLines); if (in_array($lineCnt, $coverageLineNumbers)) { $lineType = $parser->getLineType(); if ($lineType == LINE_TYPE_EXEC) { $coveredCnt++; $type = "covered"; } else { if ($lineType == LINE_TYPE_CONT) { // XDebug might return this as covered - when it is // actually merely a continuation of previous line if ($lastLineType == "covered") { unset($coverageLines[$lineCnt]); $type = $lastLineType; } else { if ($lineCnt - 1 >= 0 && isset($fileLines[$lineCnt - 1]["type"])) { if ($fileLines[$lineCnt - 1]["type"] == "uncovered") { $uncoveredCnt--; } $fileLines[$lineCnt - 1]["type"] = $lastLineType = "covered"; } $coveredCnt++; $type = "covered"; } } else { $type = "non-exec"; $coverageLines[$lineCnt] = 0; } } } else { if ($parser->getLineType() == LINE_TYPE_EXEC) { $uncoveredCnt++; $type = "uncovered"; } else { if ($parser->getLineType() == LINE_TYPE_CONT) { $type = $lastLineType; } else { $type = "non-exec"; } } } // Save line type $lastLineType = $type; if (!isset($coverageLines[$lineCnt])) { $coverageLines[$lineCnt] = 0; } $fileLines[$lineCnt] = array("type" => $type, "lineCnt" => $lineCnt, "line" => $line, "coverageLines" => $coverageLines[$lineCnt]); } return array('filename' => $phpFile, 'covered' => $coveredCnt, 'uncovered' => $uncoveredCnt, 'total' => $lineCnt); }