diff vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php	Mon Apr 23 09:46:53 2018 +0100
@@ -0,0 +1,574 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Html;
+
+use SebastianBergmann\CodeCoverage\Node\File as FileNode;
+use SebastianBergmann\CodeCoverage\Util;
+
+/**
+ * Renders a file node.
+ */
+class File extends Renderer
+{
+    /**
+     * @var int
+     */
+    private $htmlspecialcharsFlags;
+
+    /**
+     * Constructor.
+     *
+     * @param string $templatePath
+     * @param string $generator
+     * @param string $date
+     * @param int    $lowUpperBound
+     * @param int    $highLowerBound
+     */
+    public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
+    {
+        parent::__construct(
+            $templatePath,
+            $generator,
+            $date,
+            $lowUpperBound,
+            $highLowerBound
+        );
+
+        $this->htmlspecialcharsFlags = ENT_COMPAT;
+
+        $this->htmlspecialcharsFlags = $this->htmlspecialcharsFlags | ENT_HTML401 | ENT_SUBSTITUTE;
+    }
+
+    /**
+     * @param FileNode $node
+     * @param string   $file
+     */
+    public function render(FileNode $node, $file)
+    {
+        $template = new \Text_Template($this->templatePath . 'file.html', '{{', '}}');
+
+        $template->setVar(
+            [
+                'items' => $this->renderItems($node),
+                'lines' => $this->renderSource($node)
+            ]
+        );
+
+        $this->setCommonTemplateVariables($template, $node);
+
+        $template->renderTo($file);
+    }
+
+    /**
+     * @param FileNode $node
+     *
+     * @return string
+     */
+    protected function renderItems(FileNode $node)
+    {
+        $template = new \Text_Template($this->templatePath . 'file_item.html', '{{', '}}');
+
+        $methodItemTemplate = new \Text_Template(
+            $this->templatePath . 'method_item.html',
+            '{{',
+            '}}'
+        );
+
+        $items = $this->renderItemTemplate(
+            $template,
+            [
+                'name'                         => 'Total',
+                'numClasses'                   => $node->getNumClassesAndTraits(),
+                'numTestedClasses'             => $node->getNumTestedClassesAndTraits(),
+                'numMethods'                   => $node->getNumFunctionsAndMethods(),
+                'numTestedMethods'             => $node->getNumTestedFunctionsAndMethods(),
+                'linesExecutedPercent'         => $node->getLineExecutedPercent(false),
+                'linesExecutedPercentAsString' => $node->getLineExecutedPercent(),
+                'numExecutedLines'             => $node->getNumExecutedLines(),
+                'numExecutableLines'           => $node->getNumExecutableLines(),
+                'testedMethodsPercent'         => $node->getTestedFunctionsAndMethodsPercent(false),
+                'testedMethodsPercentAsString' => $node->getTestedFunctionsAndMethodsPercent(),
+                'testedClassesPercent'         => $node->getTestedClassesAndTraitsPercent(false),
+                'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(),
+                'crap'                         => '<abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr>'
+            ]
+        );
+
+        $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
+     * @param \Text_Template $methodItemTemplate
+     *
+     * @return string
+     */
+    protected function renderTraitOrClassItems(array $items, \Text_Template $template, \Text_Template $methodItemTemplate)
+    {
+        $buffer = '';
+
+        if (empty($items)) {
+            return $buffer;
+        }
+
+        foreach ($items as $name => $item) {
+            $numMethods       = 0;
+            $numTestedMethods = 0;
+
+            foreach ($item['methods'] as $method) {
+                if ($method['executableLines'] > 0) {
+                    $numMethods++;
+
+                    if ($method['executedLines'] === $method['executableLines']) {
+                        $numTestedMethods++;
+                    }
+                }
+            }
+
+            if ($item['executableLines'] > 0) {
+                $numClasses                   = 1;
+                $numTestedClasses             = $numTestedMethods == $numMethods ? 1 : 0;
+                $linesExecutedPercentAsString = Util::percent(
+                    $item['executedLines'],
+                    $item['executableLines'],
+                    true
+                );
+            } else {
+                $numClasses                   = 'n/a';
+                $numTestedClasses             = 'n/a';
+                $linesExecutedPercentAsString = 'n/a';
+            }
+
+            $buffer .= $this->renderItemTemplate(
+                $template,
+                [
+                    'name'                         => $name,
+                    'numClasses'                   => $numClasses,
+                    'numTestedClasses'             => $numTestedClasses,
+                    'numMethods'                   => $numMethods,
+                    'numTestedMethods'             => $numTestedMethods,
+                    'linesExecutedPercent'         => Util::percent(
+                        $item['executedLines'],
+                        $item['executableLines'],
+                        false
+                    ),
+                    'linesExecutedPercentAsString' => $linesExecutedPercentAsString,
+                    'numExecutedLines'             => $item['executedLines'],
+                    'numExecutableLines'           => $item['executableLines'],
+                    'testedMethodsPercent'         => Util::percent(
+                        $numTestedMethods,
+                        $numMethods,
+                        false
+                    ),
+                    'testedMethodsPercentAsString' => Util::percent(
+                        $numTestedMethods,
+                        $numMethods,
+                        true
+                    ),
+                    'testedClassesPercent'         => Util::percent(
+                        $numTestedMethods == $numMethods ? 1 : 0,
+                        1,
+                        false
+                    ),
+                    'testedClassesPercentAsString' => 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 = '')
+    {
+        $numMethods       = 0;
+        $numTestedMethods = 0;
+
+        if ($item['executableLines'] > 0) {
+            $numMethods = 1;
+
+            if ($item['executedLines'] === $item['executableLines']) {
+                $numTestedMethods = 1;
+            }
+        }
+
+        return $this->renderItemTemplate(
+            $template,
+            [
+                'name'                         => \sprintf(
+                    '%s<a href="#%d"><abbr title="%s">%s</abbr></a>',
+                    $indent,
+                    $item['startLine'],
+                    \htmlspecialchars($item['signature']),
+                    isset($item['functionName']) ? $item['functionName'] : $item['methodName']
+                ),
+                'numMethods'                   => $numMethods,
+                'numTestedMethods'             => $numTestedMethods,
+                'linesExecutedPercent'         => Util::percent(
+                    $item['executedLines'],
+                    $item['executableLines'],
+                    false
+                ),
+                'linesExecutedPercentAsString' => Util::percent(
+                    $item['executedLines'],
+                    $item['executableLines'],
+                    true
+                ),
+                'numExecutedLines'             => $item['executedLines'],
+                'numExecutableLines'           => $item['executableLines'],
+                'testedMethodsPercent'         => Util::percent(
+                    $numTestedMethods,
+                    1,
+                    false
+                ),
+                'testedMethodsPercentAsString' => Util::percent(
+                    $numTestedMethods,
+                    1,
+                    true
+                ),
+                'crap'                         => $item['crap']
+            ]
+        );
+    }
+
+    /**
+     * @param FileNode $node
+     *
+     * @return string
+     */
+    protected function renderSource(FileNode $node)
+    {
+        $coverageData = $node->getCoverageData();
+        $testData     = $node->getTestData();
+        $codeLines    = $this->loadFile($node->getPath());
+        $lines        = '';
+        $i            = 1;
+
+        foreach ($codeLines as $line) {
+            $trClass        = '';
+            $popoverContent = '';
+            $popoverTitle   = '';
+
+            if (\array_key_exists($i, $coverageData)) {
+                $numTests = ($coverageData[$i] ? \count($coverageData[$i]) : 0);
+
+                if ($coverageData[$i] === null) {
+                    $trClass = ' class="warning"';
+                } elseif ($numTests == 0) {
+                    $trClass = ' class="danger"';
+                } else {
+                    $lineCss        = 'covered-by-large-tests';
+                    $popoverContent = '<ul>';
+
+                    if ($numTests > 1) {
+                        $popoverTitle = $numTests . ' tests cover line ' . $i;
+                    } else {
+                        $popoverTitle = '1 test covers line ' . $i;
+                    }
+
+                    foreach ($coverageData[$i] as $test) {
+                        if ($lineCss == 'covered-by-large-tests' && $testData[$test]['size'] == 'medium') {
+                            $lineCss = 'covered-by-medium-tests';
+                        } elseif ($testData[$test]['size'] == 'small') {
+                            $lineCss = 'covered-by-small-tests';
+                        }
+
+                        switch ($testData[$test]['status']) {
+                            case 0:
+                                switch ($testData[$test]['size']) {
+                                    case 'small':
+                                        $testCSS = ' class="covered-by-small-tests"';
+
+                                        break;
+
+                                    case 'medium':
+                                        $testCSS = ' class="covered-by-medium-tests"';
+
+                                        break;
+
+                                    default:
+                                        $testCSS = ' class="covered-by-large-tests"';
+
+                                        break;
+                                }
+
+                                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>';
+                    $trClass         = ' class="' . $lineCss . ' popin"';
+                }
+            }
+
+            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,
+                $line
+            );
+
+            $i++;
+        }
+
+        return $lines;
+    }
+
+    /**
+     * @param string $file
+     *
+     * @return array
+     */
+    protected function loadFile($file)
+    {
+        $buffer              = \file_get_contents($file);
+        $tokens              = \token_get_all($buffer);
+        $result              = [''];
+        $i                   = 0;
+        $stringFlag          = false;
+        $fileEndsWithNewLine = \substr($buffer, -1) == "\n";
+
+        unset($buffer);
+
+        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(
+                ["\t", ' '],
+                ['&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;'],
+                \htmlspecialchars($value, $this->htmlspecialcharsFlags)
+            );
+
+            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_FINALLY:
+                                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:
+                                case T_YIELD:
+                                    $colour = 'keyword';
+
+                                    break;
+
+                                default:
+                                    $colour = 'default';
+                            }
+                        }
+
+                        $result[$i] .= \sprintf(
+                            '<span class="%s">%s</span>',
+                            $colour,
+                            $line
+                        );
+                    }
+
+                    if (isset($lines[$jj + 1])) {
+                        $result[++$i] = '';
+                    }
+                }
+            }
+        }
+
+        if ($fileEndsWithNewLine) {
+            unset($result[\count($result) - 1]);
+        }
+
+        return $result;
+    }
+}