/** * @param PHP_CodeCoverage $coverage * @param string $target */ public function process(PHP_CodeCoverage $coverage, $target) { $target = PHP_CodeCoverage_Util::getDirectory($target); $files = $coverage->getSummary(); $commonPath = PHP_CodeCoverage_Util::reducePaths($files); $items = PHP_CodeCoverage_Util::buildDirectoryStructure($files); $root = new PHP_CodeCoverage_Report_HTML_Node_Directory($commonPath, NULL); $this->addItems($root, $items, $files); $this->renderDashboard($root, $target . 'index.dashboard.html', $this->options['title']); foreach ($root as $node) { if ($node instanceof PHP_CodeCoverage_Report_HTML_Node_Directory) { $this->renderDashboard($node, $target . PHP_CodeCoverage_Util::getSafeFilename($node->getId()) . '.dashboard.html', $node->getName(TRUE)); } } $root->render($target, $this->options['title'], $this->options['charset'], $this->options['lowUpperBound'], $this->options['highLowerBound'], $this->options['generator']); $this->copyFiles($target); }
/** * Renders this node. * * @param string $target * @param string $title * @param string $charset * @param integer $lowUpperBound * @param integer $highLowerBound * @param string $generator */ public function render($target, $title, $charset = 'UTF-8', $lowUpperBound = 35, $highLowerBound = 70, $generator = '') { if ($this->yui) { $template = new Text_Template(PHP_CodeCoverage_Report_HTML::$templatePath . 'file.html'); $yuiTemplate = new Text_Template(PHP_CodeCoverage_Report_HTML::$templatePath . 'yui_item.js'); } else { $template = new Text_Template(PHP_CodeCoverage_Report_HTML::$templatePath . 'file_no_yui.html'); } $i = 1; $lines = ''; foreach ($this->codeLines as $line) { $css = ''; if (!isset($this->ignoredLines[$i]) && isset($this->executedLines[$i])) { $count = ''; // Array: Line is executable and was executed. // count(Array) = Number of tests that hit this line. if (is_array($this->executedLines[$i])) { $color = 'lineCov'; $numTests = count($this->executedLines[$i]); $count = sprintf('%8d', $numTests); if ($this->yui) { $buffer = ''; $testCSS = ''; foreach ($this->executedLines[$i] as $test) { switch ($test['status']) { case 0: $testCSS = ' class=\\"testPassed\\"'; break; case 1: case 2: $testCSS = ' class=\\"testIncomplete\\"'; break; case 3: $testCSS = ' class=\\"testFailure\\"'; break; case 4: $testCSS = ' class=\\"testError\\"'; break; default: $testCSS = ''; } $buffer .= sprintf('<li%s>%s</li>', $testCSS, addslashes(htmlspecialchars($test['id']))); } if ($numTests > 1) { $header = $numTests . ' tests cover'; } else { $header = '1 test covers'; } $header .= ' line ' . $i; $yuiTemplate->setVar(array('line' => $i, 'header' => $header, 'tests' => $buffer), FALSE); $this->yuiPanelJS .= $yuiTemplate->render(); } } else { if ($this->executedLines[$i] == -1) { $color = 'lineNoCov'; $count = sprintf('%8d', 0); } else { $color = 'lineDeadCode'; $count = ' '; } } $css = sprintf('<span class="%s"> %s : ', $color, $count); } $fillup = array_shift($this->codeLinesFillup); if ($fillup > 0) { $line .= str_repeat(' ', $fillup); } $lines .= sprintf('<span class="lineNum" id="container%d"><a name="%d"></a>' . '<a href="#%d" id="line%d">%8d</a> </span>%s%s%s' . "\n", $i, $i, $i, $i, $i, !empty($css) ? $css : ' : ', !$this->highlight ? htmlspecialchars($line) : $line, !empty($css) ? '</span>' : ''); $i++; } $items = ''; foreach ($this->classes as $className => $classData) { if ($classData['executedLines'] == $classData['executableLines']) { $numTestedClasses = 1; $testedClassesPercent = 100; } else { $numTestedClasses = 0; $testedClassesPercent = 0; } $numMethods = 0; $numTestedMethods = 0; foreach ($classData['methods'] as $method) { if ($method['executableLines'] > 0) { $numMethods++; if ($method['executedLines'] == $method['executableLines']) { $numTestedMethods++; } } } $items .= $this->doRenderItem(array('name' => sprintf('<b><a href="#%d">%s</a></b>', $classData['startLine'], $className), 'numClasses' => 1, 'numTestedClasses' => $numTestedClasses, 'testedClassesPercent' => sprintf('%01.2f', $testedClassesPercent), 'numMethods' => $numMethods, 'numTestedMethods' => $numTestedMethods, 'testedMethodsPercent' => PHP_CodeCoverage_Util::percent($numTestedMethods, $numMethods, TRUE), 'numExecutableLines' => $classData['executableLines'], 'numExecutedLines' => $classData['executedLines'], 'executedLinesPercent' => PHP_CodeCoverage_Util::percent($classData['executedLines'], $classData['executableLines'], TRUE)), $lowUpperBound, $highLowerBound); foreach ($classData['methods'] as $methodData) { if ($methodData['executableLines'] > 0) { if ($methodData['executedLines'] == $methodData['executableLines']) { $numTestedMethods = 1; $testedMethodsPercent = 100; } else { $numTestedMethods = 0; $testedMethodsPercent = 0; } $items .= $this->doRenderItem(array('name' => sprintf(' <a href="#%d">%s</a>', $methodData['startLine'], htmlspecialchars($methodData['signature'])), 'numClasses' => '', 'numTestedClasses' => '', 'testedClassesPercent' => '', 'numMethods' => 1, 'numTestedMethods' => $numTestedMethods, 'testedMethodsPercent' => sprintf('%01.2f', $testedMethodsPercent), 'numExecutableLines' => $methodData['executableLines'], 'numExecutedLines' => $methodData['executedLines'], 'executedLinesPercent' => PHP_CodeCoverage_Util::percent($methodData['executedLines'], $methodData['executableLines'], TRUE), 'crap' => PHP_CodeCoverage_Util::crap($methodData['ccn'], PHP_CodeCoverage_Util::percent($methodData['executedLines'], $methodData['executableLines']))), $lowUpperBound, $highLowerBound, 'method_item.html'); } } } $this->setTemplateVars($template, $title, $charset, $generator); $template->setVar(array('lines' => $lines, 'total_item' => $this->renderTotalItem($lowUpperBound, $highLowerBound, FALSE), 'items' => $items, 'yuiPanelJS' => $this->yuiPanelJS)); $cleanId = PHP_CodeCoverage_Util::getSafeFilename($this->getId()); $template->renderTo($target . $cleanId . '.html'); $this->yuiPanelJS = ''; $this->executedLines = array(); }
/** * @param Text_Template $template * @param string $title * @param string $charset * @param string $generator */ protected function setTemplateVars(Text_Template $template, $title, $charset, $generator) { $dashboard = ''; if ($this instanceof PHP_CodeCoverage_Report_HTML_Node_Directory) { $dashboard = sprintf('<a href="%s">dashboard</a>', PHP_CodeCoverage_Util::getSafeFilename($this->getId()) . '.dashboard.html'); } $template->setVar(array('title' => $title, 'charset' => $charset, 'link' => $this->getLink(TRUE), 'dashboard_link' => $dashboard, 'num_executable_lines' => $this->getNumExecutableLines(), 'num_executed_lines' => $this->getNumExecutedLines(), 'lines_executed_percent' => $this->getLineExecutedPercent(), 'date' => date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']), 'version' => '@package_version@', 'php_version' => PHP_VERSION, 'generator' => $generator)); }
/** * @param string $target * @param string $title * @param string $charset * @param integer $lowUpperBound * @param integer $highLowerBound * @param string $generator */ protected function doRender($target, $title, $charset, $lowUpperBound, $highLowerBound, $generator) { $cleanId = PHP_CodeCoverage_Util::getSafeFilename($this->getId()); $file = $target . $cleanId . '.html'; $template = new Text_Template(PHP_CodeCoverage_Report_HTML::$templatePath . 'directory.html'); $this->setTemplateVars($template, $title, $charset, $generator); $template->setVar(array('total_item' => $this->renderTotalItem($lowUpperBound, $highLowerBound), 'items' => $this->renderItems($lowUpperBound, $highLowerBound), 'low_upper_bound' => $lowUpperBound, 'high_lower_bound' => $highLowerBound)); $template->renderTo($file); $this->directories = array(); $this->files = array(); }
/** * @covers PHP_CodeCoverage_Util::getSafeFilename */ public function testGetSafeFilename() { $this->assertEquals('foo', PHP_CodeCoverage_Util::getSafeFilename('foo')); $this->assertEquals('foo_bar', PHP_CodeCoverage_Util::getSafeFilename('foo/bar')); }