class PHP_CodeCoverage_Report_HTML_Renderer_File

Renders a PHP_CodeCoverage_Report_Node_File node.

@category PHP @package CodeCoverage @author Sebastian Bergmann <sebastian@phpunit.de> @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de> @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License @link http://github.com/sebastianbergmann/php-code-coverage @since Class available since Release 1.1.0

Hierarchy

Expanded class hierarchy of PHP_CodeCoverage_Report_HTML_Renderer_File

File

drupal/core/vendor/phpunit/php-code-coverage/PHP/CodeCoverage/Report/HTML/Renderer/File.php, line 71

View source
class PHP_CodeCoverage_Report_HTML_Renderer_File extends PHP_CodeCoverage_Report_HTML_Renderer {

  /**
   * @var boolean
   */
  protected $highlight;

  /**
   * Constructor.
   *
   * @param string  $templatePath
   * @param string  $charset
   * @param string  $generator
   * @param string  $date
   * @param integer $lowUpperBound
   * @param integer $highLowerBound
   * @param boolean $highlight
   */
  public function __construct($templatePath, $charset, $generator, $date, $lowUpperBound, $highLowerBound, $highlight) {
    parent::__construct($templatePath, $charset, $generator, $date, $lowUpperBound, $highLowerBound);
    $this->highlight = $highlight;
  }

  /**
   * @param PHP_CodeCoverage_Report_Node_File $node
   * @param string                            $file
   */
  public function render(PHP_CodeCoverage_Report_Node_File $node, $file) {
    $template = new Text_Template($this->templatePath . 'file.html');
    $template
      ->setVar(array(
      'items' => $this
        ->renderItems($node),
      'lines' => $this
        ->renderSource($node),
    ));
    $this
      ->setCommonTemplateVariables($template, $node);
    $template
      ->renderTo($file);
  }

  /**
   * @param  PHP_CodeCoverage_Report_Node_File $node
   * @return string
   */
  protected function renderItems(PHP_CodeCoverage_Report_Node_File $node) {
    $template = new Text_Template($this->templatePath . 'file_item.html');
    $methodItemTemplate = new Text_Template($this->templatePath . 'method_item.html');
    $items = $this
      ->renderItemTemplate($template, array(
      'name' => 'Total',
      'numClasses' => $node
        ->getNumClassesAndTraits(),
      'numTestedClasses' => $node
        ->getNumTestedClassesAndTraits(),
      'numMethods' => $node
        ->getNumMethods(),
      'numTestedMethods' => $node
        ->getNumTestedMethods(),
      'linesExecutedPercent' => $node
        ->getLineExecutedPercent(FALSE),
      'linesExecutedPercentAsString' => $node
        ->getLineExecutedPercent(),
      'numExecutedLines' => $node
        ->getNumExecutedLines(),
      'numExecutableLines' => $node
        ->getNumExecutableLines(),
      'testedMethodsPercent' => $node
        ->getTestedMethodsPercent(FALSE),
      'testedMethodsPercentAsString' => $node
        ->getTestedMethodsPercent(),
      'testedClassesPercent' => $node
        ->getTestedClassesAndTraitsPercent(FALSE),
      'testedClassesPercentAsString' => $node
        ->getTestedClassesAndTraitsPercent(),
      'crap' => '<acronym title="Change Risk Anti-Patterns (CRAP) Index">CRAP</acronym>',
    ));
    $items .= $this
      ->renderFunctionItems($node
      ->getFunctions(), $methodItemTemplate);
    $items .= $this
      ->renderTraitOrClassItems($node
      ->getTraits(), $template, $methodItemTemplate);
    $items .= $this
      ->renderTraitOrClassItems($node
      ->getClasses(), $template, $methodItemTemplate);
    return $items;
  }

  /**
   * @param  array         $items
   * @param  Text_Template $template
   * @return string
   */
  protected function renderTraitOrClassItems(array $items, Text_Template $template, Text_Template $methodItemTemplate) {
    if (empty($items)) {
      return '';
    }
    $buffer = '';
    foreach ($items as $name => $item) {
      $numMethods = count($item['methods']);
      $numTestedMethods = 0;
      foreach ($item['methods'] as $method) {
        if ($method['executedLines'] == $method['executableLines']) {
          $numTestedMethods++;
        }
      }
      $buffer .= $this
        ->renderItemTemplate($template, array(
        'name' => $name,
        'numClasses' => 1,
        'numTestedClasses' => $numTestedMethods == $numMethods ? 1 : 0,
        'numMethods' => $numMethods,
        'numTestedMethods' => $numTestedMethods,
        'linesExecutedPercent' => PHP_CodeCoverage_Util::percent($item['executedLines'], $item['executableLines'], FALSE),
        'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent($item['executedLines'], $item['executableLines'], TRUE),
        'numExecutedLines' => $item['executedLines'],
        'numExecutableLines' => $item['executableLines'],
        'testedMethodsPercent' => PHP_CodeCoverage_Util::percent($numTestedMethods, $numMethods, FALSE),
        'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent($numTestedMethods, $numMethods, TRUE),
        'testedClassesPercent' => PHP_CodeCoverage_Util::percent($numTestedMethods == $numMethods ? 1 : 0, 1, FALSE),
        'testedClassesPercentAsString' => PHP_CodeCoverage_Util::percent($numTestedMethods == $numMethods ? 1 : 0, 1, TRUE),
        'crap' => $item['crap'],
      ));
      foreach ($item['methods'] as $method) {
        $buffer .= $this
          ->renderFunctionOrMethodItem($methodItemTemplate, $method, '&nbsp;');
      }
    }
    return $buffer;
  }

  /**
   * @param  array         $functions
   * @param  Text_Template $template
   * @return string
   */
  protected function renderFunctionItems(array $functions, Text_Template $template) {
    if (empty($functions)) {
      return '';
    }
    $buffer = '';
    foreach ($functions as $function) {
      $buffer .= $this
        ->renderFunctionOrMethodItem($template, $function);
    }
    return $buffer;
  }

  /**
   * @param  Text_Template $template
   * @return string
   */
  protected function renderFunctionOrMethodItem(Text_Template $template, array $item, $indent = '') {
    $numTestedItems = $item['executedLines'] == $item['executableLines'] ? 1 : 0;
    return $this
      ->renderItemTemplate($template, array(
      'name' => sprintf('%s<a href="#%d">%s</a>', $indent, $item['startLine'], htmlspecialchars($item['signature'])),
      'numMethods' => 1,
      'numTestedMethods' => $numTestedItems,
      'linesExecutedPercent' => PHP_CodeCoverage_Util::percent($item['executedLines'], $item['executableLines'], FALSE),
      'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent($item['executedLines'], $item['executableLines'], TRUE),
      'numExecutedLines' => $item['executedLines'],
      'numExecutableLines' => $item['executableLines'],
      'testedMethodsPercent' => PHP_CodeCoverage_Util::percent($numTestedItems, 1, FALSE),
      'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent($numTestedItems, 1, TRUE),
      'crap' => $item['crap'],
    ));
  }

  /**
   * @param  PHP_CodeCoverage_Report_Node_File $node
   * @return string
   */
  protected function renderSource(PHP_CodeCoverage_Report_Node_File $node) {
    $coverageData = $node
      ->getCoverageData();
    $ignoredLines = $node
      ->getIgnoredLines();
    $testData = $node
      ->getTestData();
    $codeLines = $this
      ->loadFile($node
      ->getPath());
    $lines = '';
    $i = 1;
    foreach ($codeLines as $line) {
      $numTests = '';
      $trClass = '';
      $popoverContent = '';
      $popoverTitle = '';
      if (!isset($ignoredLines[$i]) && isset($coverageData[$i])) {
        $numTests = count($coverageData[$i]);
        if ($coverageData[$i] === NULL) {
          $trClass = ' class="warning"';
        }
        else {
          if ($numTests == 0) {
            $trClass = ' class="danger"';
          }
          else {
            $trClass = ' class="success popin"';
            $popoverContent = '<ul>';
            if ($numTests > 1) {
              $popoverTitle = $numTests . ' tests cover line ' . $i;
            }
            else {
              $popoverTitle = '1 test covers line ' . $i;
            }
            foreach ($coverageData[$i] as $test) {
              switch ($testData[$test]) {
                case 0:
                  $testCSS = ' class="success"';
                  break;
                case 1:
                case 2:
                  $testCSS = ' class="warning"';
                  break;
                case 3:
                  $testCSS = ' class="danger"';
                  break;
                case 4:
                  $testCSS = ' class="danger"';
                  break;
                default:
                  $testCSS = '';
              }
              $popoverContent .= sprintf('<li%s>%s</li>', $testCSS, htmlspecialchars($test));
            }
            $popoverContent .= '</ul>';
          }
        }
      }
      if (!empty($popoverTitle)) {
        $popover = sprintf(' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent));
      }
      else {
        $popover = '';
      }
      $lines .= sprintf('     <tr%s%s><td><div align="right"><a name="%d"></a><a href="#%d">%d</a></div></td><td class="codeLine">%s</td></tr>' . "\n", $trClass, $popover, $i, $i, $i, !$this->highlight ? htmlspecialchars($line) : $line);
      $i++;
    }
    return $lines;
  }

  /**
   * @param  string $file
   * @return array
   */
  protected function loadFile($file) {
    $buffer = file_get_contents($file);
    $lines = explode("\n", str_replace("\t", '    ', $buffer));
    $result = array();
    if (count($lines) == 0) {
      return $result;
    }
    $lines = array_map('rtrim', $lines);
    if (!$this->highlight) {
      unset($lines[count($lines) - 1]);
      return $lines;
    }
    $tokens = token_get_all($buffer);
    $stringFlag = FALSE;
    $i = 0;
    $result[$i] = '';
    foreach ($tokens as $j => $token) {
      if (is_string($token)) {
        if ($token === '"' && $tokens[$j - 1] !== '\\') {
          $result[$i] .= sprintf('<span class="string">%s</span>', htmlspecialchars($token));
          $stringFlag = !$stringFlag;
        }
        else {
          $result[$i] .= sprintf('<span class="keyword">%s</span>', htmlspecialchars($token));
        }
        continue;
      }
      list($token, $value) = $token;
      $value = str_replace(array(
        "\t",
        ' ',
      ), array(
        '&nbsp;&nbsp;&nbsp;&nbsp;',
        '&nbsp;',
      ), htmlspecialchars($value));
      if ($value === "\n") {
        $result[++$i] = '';
      }
      else {
        $lines = explode("\n", $value);
        foreach ($lines as $jj => $line) {
          $line = trim($line);
          if ($line !== '') {
            if ($stringFlag) {
              $colour = 'string';
            }
            else {
              switch ($token) {
                case T_INLINE_HTML:
                  $colour = 'html';
                  break;
                case T_COMMENT:
                case T_DOC_COMMENT:
                  $colour = 'comment';
                  break;
                case T_ABSTRACT:
                case T_ARRAY:
                case T_AS:
                case T_BREAK:
                case T_CALLABLE:
                case T_CASE:
                case T_CATCH:
                case T_CLASS:
                case T_CLONE:
                case T_CONTINUE:
                case T_DEFAULT:
                case T_ECHO:
                case T_ELSE:
                case T_ELSEIF:
                case T_EMPTY:
                case T_ENDDECLARE:
                case T_ENDFOR:
                case T_ENDFOREACH:
                case T_ENDIF:
                case T_ENDSWITCH:
                case T_ENDWHILE:
                case T_EXIT:
                case T_EXTENDS:
                case T_FINAL:
                case T_FOREACH:
                case T_FUNCTION:
                case T_GLOBAL:
                case T_IF:
                case T_IMPLEMENTS:
                case T_INCLUDE:
                case T_INCLUDE_ONCE:
                case T_INSTANCEOF:
                case T_INSTEADOF:
                case T_INTERFACE:
                case T_ISSET:
                case T_LOGICAL_AND:
                case T_LOGICAL_OR:
                case T_LOGICAL_XOR:
                case T_NAMESPACE:
                case T_NEW:
                case T_PRIVATE:
                case T_PROTECTED:
                case T_PUBLIC:
                case T_REQUIRE:
                case T_REQUIRE_ONCE:
                case T_RETURN:
                case T_STATIC:
                case T_THROW:
                case T_TRAIT:
                case T_TRY:
                case T_UNSET:
                case T_USE:
                case T_VAR:
                case T_WHILE:
                  $colour = 'keyword';
                  break;
                default:
                  $colour = 'default';
              }
            }
            $result[$i] .= sprintf('<span class="%s">%s</span>', $colour, $line);
          }
          if (isset($lines[$jj + 1])) {
            $result[++$i] = '';
          }
        }
      }
    }
    unset($result[count($result) - 1]);
    return $result;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
PHP_CodeCoverage_Report_HTML_Renderer::$charset protected property
PHP_CodeCoverage_Report_HTML_Renderer::$date protected property
PHP_CodeCoverage_Report_HTML_Renderer::$generator protected property
PHP_CodeCoverage_Report_HTML_Renderer::$highLowerBound protected property
PHP_CodeCoverage_Report_HTML_Renderer::$lowUpperBound protected property
PHP_CodeCoverage_Report_HTML_Renderer::$templatePath protected property
PHP_CodeCoverage_Report_HTML_Renderer::getActiveBreadcrumb protected function 1
PHP_CodeCoverage_Report_HTML_Renderer::getBreadcrumbs protected function
PHP_CodeCoverage_Report_HTML_Renderer::getColorLevel protected function
PHP_CodeCoverage_Report_HTML_Renderer::getCoverageBar protected function
PHP_CodeCoverage_Report_HTML_Renderer::getInactiveBreadcrumb protected function
PHP_CodeCoverage_Report_HTML_Renderer::renderItemTemplate protected function
PHP_CodeCoverage_Report_HTML_Renderer::setCommonTemplateVariables protected function
PHP_CodeCoverage_Report_HTML_Renderer_File::$highlight protected property
PHP_CodeCoverage_Report_HTML_Renderer_File::loadFile protected function
PHP_CodeCoverage_Report_HTML_Renderer_File::render public function
PHP_CodeCoverage_Report_HTML_Renderer_File::renderFunctionItems protected function
PHP_CodeCoverage_Report_HTML_Renderer_File::renderFunctionOrMethodItem protected function
PHP_CodeCoverage_Report_HTML_Renderer_File::renderItems protected function
PHP_CodeCoverage_Report_HTML_Renderer_File::renderSource protected function
PHP_CodeCoverage_Report_HTML_Renderer_File::renderTraitOrClassItems protected function
PHP_CodeCoverage_Report_HTML_Renderer_File::__construct public function Constructor. Overrides PHP_CodeCoverage_Report_HTML_Renderer::__construct