cancellazione modifiche dopo step before oauth
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (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;
|
||||
|
||||
/**
|
||||
* @immutable
|
||||
*/
|
||||
final readonly class Colors
|
||||
{
|
||||
private string $successLow;
|
||||
private string $successMedium;
|
||||
private string $successHigh;
|
||||
private string $warning;
|
||||
private string $danger;
|
||||
|
||||
public static function default(): self
|
||||
{
|
||||
return new self('#dff0d8', '#c3e3b5', '#99cb84', '#fcf8e3', '#f2dede');
|
||||
}
|
||||
|
||||
public static function from(string $successLow, string $successMedium, string $successHigh, string $warning, string $danger): self
|
||||
{
|
||||
return new self($successLow, $successMedium, $successHigh, $warning, $danger);
|
||||
}
|
||||
|
||||
private function __construct(string $successLow, string $successMedium, string $successHigh, string $warning, string $danger)
|
||||
{
|
||||
$this->successLow = $successLow;
|
||||
$this->successMedium = $successMedium;
|
||||
$this->successHigh = $successHigh;
|
||||
$this->warning = $warning;
|
||||
$this->danger = $danger;
|
||||
}
|
||||
|
||||
public function successLow(): string
|
||||
{
|
||||
return $this->successLow;
|
||||
}
|
||||
|
||||
public function successMedium(): string
|
||||
{
|
||||
return $this->successMedium;
|
||||
}
|
||||
|
||||
public function successHigh(): string
|
||||
{
|
||||
return $this->successHigh;
|
||||
}
|
||||
|
||||
public function warning(): string
|
||||
{
|
||||
return $this->warning;
|
||||
}
|
||||
|
||||
public function danger(): string
|
||||
{
|
||||
return $this->danger;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (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 function is_file;
|
||||
use SebastianBergmann\CodeCoverage\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @immutable
|
||||
*/
|
||||
final readonly class CustomCssFile
|
||||
{
|
||||
private string $path;
|
||||
|
||||
public static function default(): self
|
||||
{
|
||||
return new self(__DIR__ . '/Renderer/Template/css/custom.css');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function from(string $path): self
|
||||
{
|
||||
if (!is_file($path)) {
|
||||
throw new InvalidArgumentException(
|
||||
'$path does not exist',
|
||||
);
|
||||
}
|
||||
|
||||
return new self($path);
|
||||
}
|
||||
|
||||
private function __construct(string $path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
public function path(): string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (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 const DIRECTORY_SEPARATOR;
|
||||
use function copy;
|
||||
use function date;
|
||||
use function dirname;
|
||||
use function str_ends_with;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\CodeCoverage\Report\Thresholds;
|
||||
use SebastianBergmann\CodeCoverage\Util\Filesystem;
|
||||
use SebastianBergmann\Template\Exception;
|
||||
use SebastianBergmann\Template\Template;
|
||||
|
||||
final readonly class Facade
|
||||
{
|
||||
private string $templatePath;
|
||||
private string $generator;
|
||||
private Colors $colors;
|
||||
private Thresholds $thresholds;
|
||||
private CustomCssFile $customCssFile;
|
||||
|
||||
public function __construct(string $generator = '', ?Colors $colors = null, ?Thresholds $thresholds = null, ?CustomCssFile $customCssFile = null)
|
||||
{
|
||||
$this->generator = $generator;
|
||||
$this->colors = $colors ?? Colors::default();
|
||||
$this->thresholds = $thresholds ?? Thresholds::default();
|
||||
$this->customCssFile = $customCssFile ?? CustomCssFile::default();
|
||||
$this->templatePath = __DIR__ . '/Renderer/Template/';
|
||||
}
|
||||
|
||||
public function process(CodeCoverage $coverage, string $target): void
|
||||
{
|
||||
$target = $this->directory($target);
|
||||
$report = $coverage->getReport();
|
||||
$date = date('D M j G:i:s T Y');
|
||||
$hasBranchCoverage = $coverage->getData(true)->functionCoverage() !== [];
|
||||
|
||||
$dashboard = new Dashboard(
|
||||
$this->templatePath,
|
||||
$this->generator,
|
||||
$date,
|
||||
$this->thresholds,
|
||||
$hasBranchCoverage,
|
||||
);
|
||||
|
||||
$directory = new Directory(
|
||||
$this->templatePath,
|
||||
$this->generator,
|
||||
$date,
|
||||
$this->thresholds,
|
||||
$hasBranchCoverage,
|
||||
);
|
||||
|
||||
$file = new File(
|
||||
$this->templatePath,
|
||||
$this->generator,
|
||||
$date,
|
||||
$this->thresholds,
|
||||
$hasBranchCoverage,
|
||||
);
|
||||
|
||||
$directory->render($report, $target . 'index.html');
|
||||
$dashboard->render($report, $target . 'dashboard.html');
|
||||
|
||||
foreach ($report as $node) {
|
||||
$id = $node->id();
|
||||
|
||||
if ($node instanceof DirectoryNode) {
|
||||
Filesystem::createDirectory($target . $id);
|
||||
|
||||
$directory->render($node, $target . $id . '/index.html');
|
||||
$dashboard->render($node, $target . $id . '/dashboard.html');
|
||||
} else {
|
||||
$dir = dirname($target . $id);
|
||||
|
||||
Filesystem::createDirectory($dir);
|
||||
|
||||
$file->render($node, $target . $id);
|
||||
}
|
||||
}
|
||||
|
||||
$this->copyFiles($target);
|
||||
$this->renderCss($target);
|
||||
}
|
||||
|
||||
private function copyFiles(string $target): void
|
||||
{
|
||||
$dir = $this->directory($target . '_css');
|
||||
|
||||
copy($this->templatePath . 'css/billboard.min.css', $dir . 'billboard.min.css');
|
||||
copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css');
|
||||
copy($this->customCssFile->path(), $dir . 'custom.css');
|
||||
copy($this->templatePath . 'css/octicons.css', $dir . 'octicons.css');
|
||||
|
||||
$dir = $this->directory($target . '_icons');
|
||||
copy($this->templatePath . 'icons/file-code.svg', $dir . 'file-code.svg');
|
||||
copy($this->templatePath . 'icons/file-directory.svg', $dir . 'file-directory.svg');
|
||||
|
||||
$dir = $this->directory($target . '_js');
|
||||
copy($this->templatePath . 'js/billboard.pkgd.min.js', $dir . 'billboard.pkgd.min.js');
|
||||
copy($this->templatePath . 'js/bootstrap.bundle.min.js', $dir . 'bootstrap.bundle.min.js');
|
||||
copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js');
|
||||
copy($this->templatePath . 'js/file.js', $dir . 'file.js');
|
||||
}
|
||||
|
||||
private function renderCss(string $target): void
|
||||
{
|
||||
$template = new Template($this->templatePath . 'css/style.css', '{{', '}}');
|
||||
|
||||
$template->setVar(
|
||||
[
|
||||
'success-low' => $this->colors->successLow(),
|
||||
'success-medium' => $this->colors->successMedium(),
|
||||
'success-high' => $this->colors->successHigh(),
|
||||
'warning' => $this->colors->warning(),
|
||||
'danger' => $this->colors->danger(),
|
||||
],
|
||||
);
|
||||
|
||||
try {
|
||||
$template->renderTo($this->directory($target . '_css') . 'style.css');
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
throw new FileCouldNotBeWrittenException(
|
||||
$e->getMessage(),
|
||||
$e->getCode(),
|
||||
$e,
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
private function directory(string $directory): string
|
||||
{
|
||||
if (!str_ends_with($directory, DIRECTORY_SEPARATOR)) {
|
||||
$directory .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
Filesystem::createDirectory($directory);
|
||||
|
||||
return $directory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (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 function array_pop;
|
||||
use function count;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
use function substr_count;
|
||||
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
|
||||
use SebastianBergmann\CodeCoverage\Report\Thresholds;
|
||||
use SebastianBergmann\CodeCoverage\Version;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
use SebastianBergmann\Template\Template;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
abstract class Renderer
|
||||
{
|
||||
protected string $templatePath;
|
||||
protected string $generator;
|
||||
protected string $date;
|
||||
protected Thresholds $thresholds;
|
||||
protected bool $hasBranchCoverage;
|
||||
protected string $version;
|
||||
|
||||
public function __construct(string $templatePath, string $generator, string $date, Thresholds $thresholds, bool $hasBranchCoverage)
|
||||
{
|
||||
$this->templatePath = $templatePath;
|
||||
$this->generator = $generator;
|
||||
$this->date = $date;
|
||||
$this->thresholds = $thresholds;
|
||||
$this->version = Version::id();
|
||||
$this->hasBranchCoverage = $hasBranchCoverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<non-empty-string, float|int|string> $data
|
||||
*/
|
||||
protected function renderItemTemplate(Template $template, array $data): string
|
||||
{
|
||||
$numSeparator = ' / ';
|
||||
|
||||
if (isset($data['numClasses']) && $data['numClasses'] > 0) {
|
||||
$classesLevel = $this->colorLevel($data['testedClassesPercent']);
|
||||
|
||||
$classesNumber = $data['numTestedClasses'] . $numSeparator .
|
||||
$data['numClasses'];
|
||||
|
||||
$classesBar = $this->coverageBar(
|
||||
$data['testedClassesPercent'],
|
||||
);
|
||||
} else {
|
||||
$classesLevel = '';
|
||||
$classesNumber = '0' . $numSeparator . '0';
|
||||
$classesBar = '';
|
||||
$data['testedClassesPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
if ($data['numMethods'] > 0) {
|
||||
$methodsLevel = $this->colorLevel($data['testedMethodsPercent']);
|
||||
|
||||
$methodsNumber = $data['numTestedMethods'] . $numSeparator .
|
||||
$data['numMethods'];
|
||||
|
||||
$methodsBar = $this->coverageBar(
|
||||
$data['testedMethodsPercent'],
|
||||
);
|
||||
} else {
|
||||
$methodsLevel = '';
|
||||
$methodsNumber = '0' . $numSeparator . '0';
|
||||
$methodsBar = '';
|
||||
$data['testedMethodsPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
if ($data['numExecutableLines'] > 0) {
|
||||
$linesLevel = $this->colorLevel($data['linesExecutedPercent']);
|
||||
|
||||
$linesNumber = $data['numExecutedLines'] . $numSeparator .
|
||||
$data['numExecutableLines'];
|
||||
|
||||
$linesBar = $this->coverageBar(
|
||||
$data['linesExecutedPercent'],
|
||||
);
|
||||
} else {
|
||||
$linesLevel = '';
|
||||
$linesNumber = '0' . $numSeparator . '0';
|
||||
$linesBar = '';
|
||||
$data['linesExecutedPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
if ($data['numExecutablePaths'] > 0) {
|
||||
$pathsLevel = $this->colorLevel($data['pathsExecutedPercent']);
|
||||
|
||||
$pathsNumber = $data['numExecutedPaths'] . $numSeparator .
|
||||
$data['numExecutablePaths'];
|
||||
|
||||
$pathsBar = $this->coverageBar(
|
||||
$data['pathsExecutedPercent'],
|
||||
);
|
||||
} else {
|
||||
$pathsLevel = '';
|
||||
$pathsNumber = '0' . $numSeparator . '0';
|
||||
$pathsBar = '';
|
||||
$data['pathsExecutedPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
if ($data['numExecutableBranches'] > 0) {
|
||||
$branchesLevel = $this->colorLevel($data['branchesExecutedPercent']);
|
||||
|
||||
$branchesNumber = $data['numExecutedBranches'] . $numSeparator .
|
||||
$data['numExecutableBranches'];
|
||||
|
||||
$branchesBar = $this->coverageBar(
|
||||
$data['branchesExecutedPercent'],
|
||||
);
|
||||
} else {
|
||||
$branchesLevel = '';
|
||||
$branchesNumber = '0' . $numSeparator . '0';
|
||||
$branchesBar = '';
|
||||
$data['branchesExecutedPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
$template->setVar(
|
||||
[
|
||||
'icon' => $data['icon'] ?? '',
|
||||
'crap' => $data['crap'] ?? '',
|
||||
'name' => $data['name'],
|
||||
'lines_bar' => $linesBar,
|
||||
'lines_executed_percent' => $data['linesExecutedPercentAsString'],
|
||||
'lines_level' => $linesLevel,
|
||||
'lines_number' => $linesNumber,
|
||||
'paths_bar' => $pathsBar,
|
||||
'paths_executed_percent' => $data['pathsExecutedPercentAsString'],
|
||||
'paths_level' => $pathsLevel,
|
||||
'paths_number' => $pathsNumber,
|
||||
'branches_bar' => $branchesBar,
|
||||
'branches_executed_percent' => $data['branchesExecutedPercentAsString'],
|
||||
'branches_level' => $branchesLevel,
|
||||
'branches_number' => $branchesNumber,
|
||||
'methods_bar' => $methodsBar,
|
||||
'methods_tested_percent' => $data['testedMethodsPercentAsString'],
|
||||
'methods_level' => $methodsLevel,
|
||||
'methods_number' => $methodsNumber,
|
||||
'classes_bar' => $classesBar,
|
||||
'classes_tested_percent' => $data['testedClassesPercentAsString'] ?? '',
|
||||
'classes_level' => $classesLevel,
|
||||
'classes_number' => $classesNumber,
|
||||
],
|
||||
);
|
||||
|
||||
return $template->render();
|
||||
}
|
||||
|
||||
protected function setCommonTemplateVariables(Template $template, AbstractNode $node): void
|
||||
{
|
||||
$template->setVar(
|
||||
[
|
||||
'id' => $node->id(),
|
||||
'full_path' => $node->pathAsString(),
|
||||
'path_to_root' => $this->pathToRoot($node),
|
||||
'breadcrumbs' => $this->breadcrumbs($node),
|
||||
'date' => $this->date,
|
||||
'version' => $this->version,
|
||||
'runtime' => $this->runtimeString(),
|
||||
'generator' => $this->generator,
|
||||
'low_upper_bound' => (string) $this->thresholds->lowUpperBound(),
|
||||
'high_lower_bound' => (string) $this->thresholds->highLowerBound(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
protected function breadcrumbs(AbstractNode $node): string
|
||||
{
|
||||
$breadcrumbs = '';
|
||||
$path = $node->pathAsArray();
|
||||
$pathToRoot = [];
|
||||
$max = count($path);
|
||||
|
||||
if ($node instanceof FileNode) {
|
||||
$max--;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
$pathToRoot[] = str_repeat('../', $i);
|
||||
}
|
||||
|
||||
foreach ($path as $step) {
|
||||
if ($step !== $node) {
|
||||
$breadcrumbs .= $this->inactiveBreadcrumb(
|
||||
$step,
|
||||
array_pop($pathToRoot),
|
||||
);
|
||||
} else {
|
||||
$breadcrumbs .= $this->activeBreadcrumb($step);
|
||||
}
|
||||
}
|
||||
|
||||
return $breadcrumbs;
|
||||
}
|
||||
|
||||
protected function activeBreadcrumb(AbstractNode $node): string
|
||||
{
|
||||
$buffer = sprintf(
|
||||
' <li class="breadcrumb-item active">%s</li>' . "\n",
|
||||
$node->name(),
|
||||
);
|
||||
|
||||
if ($node instanceof DirectoryNode) {
|
||||
$buffer .= ' <li class="breadcrumb-item">(<a href="dashboard.html">Dashboard</a>)</li>' . "\n";
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
protected function inactiveBreadcrumb(AbstractNode $node, string $pathToRoot): string
|
||||
{
|
||||
return sprintf(
|
||||
' <li class="breadcrumb-item"><a href="%sindex.html">%s</a></li>' . "\n",
|
||||
$pathToRoot,
|
||||
$node->name(),
|
||||
);
|
||||
}
|
||||
|
||||
protected function pathToRoot(AbstractNode $node): string
|
||||
{
|
||||
$id = $node->id();
|
||||
$depth = substr_count($id, '/');
|
||||
|
||||
if ($id !== 'index' &&
|
||||
$node instanceof DirectoryNode) {
|
||||
$depth++;
|
||||
}
|
||||
|
||||
return str_repeat('../', $depth);
|
||||
}
|
||||
|
||||
protected function coverageBar(float $percent): string
|
||||
{
|
||||
$level = $this->colorLevel($percent);
|
||||
|
||||
$templateName = $this->templatePath . ($this->hasBranchCoverage ? 'coverage_bar_branch.html' : 'coverage_bar.html');
|
||||
$template = new Template(
|
||||
$templateName,
|
||||
'{{',
|
||||
'}}',
|
||||
);
|
||||
|
||||
$template->setVar(['level' => $level, 'percent' => sprintf('%.2F', $percent)]);
|
||||
|
||||
return $template->render();
|
||||
}
|
||||
|
||||
protected function colorLevel(float $percent): string
|
||||
{
|
||||
if ($percent <= $this->thresholds->lowUpperBound()) {
|
||||
return 'danger';
|
||||
}
|
||||
|
||||
if ($percent > $this->thresholds->lowUpperBound() &&
|
||||
$percent < $this->thresholds->highLowerBound()) {
|
||||
return 'warning';
|
||||
}
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
private function runtimeString(): string
|
||||
{
|
||||
$runtime = new Runtime;
|
||||
|
||||
return sprintf(
|
||||
'<a href="%s" target="_top">%s %s</a>',
|
||||
$runtime->getVendorUrl(),
|
||||
$runtime->getName(),
|
||||
$runtime->getVersion(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (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 function array_values;
|
||||
use function asort;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function floor;
|
||||
use function json_encode;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
use function uasort;
|
||||
use function usort;
|
||||
use SebastianBergmann\CodeCoverage\Data\ProcessedClassType;
|
||||
use SebastianBergmann\CodeCoverage\Data\ProcessedMethodType;
|
||||
use SebastianBergmann\CodeCoverage\Data\ProcessedTraitType;
|
||||
use SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
|
||||
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\Template\Exception;
|
||||
use SebastianBergmann\Template\Template;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Dashboard extends Renderer
|
||||
{
|
||||
public function render(DirectoryNode $node, string $file): void
|
||||
{
|
||||
$classes = $node->classesAndTraits();
|
||||
$templateName = $this->templatePath . ($this->hasBranchCoverage ? 'dashboard_branch.html' : 'dashboard.html');
|
||||
$template = new Template(
|
||||
$templateName,
|
||||
'{{',
|
||||
'}}',
|
||||
);
|
||||
|
||||
$this->setCommonTemplateVariables($template, $node);
|
||||
|
||||
$baseLink = $node->id() . '/';
|
||||
$complexity = $this->complexity($classes, $baseLink);
|
||||
$coverageDistribution = $this->coverageDistribution($classes);
|
||||
$insufficientCoverage = $this->insufficientCoverage($classes, $baseLink);
|
||||
$projectRisks = $this->projectRisks($classes, $baseLink);
|
||||
|
||||
$template->setVar(
|
||||
[
|
||||
'insufficient_coverage_classes' => $insufficientCoverage['class'],
|
||||
'insufficient_coverage_methods' => $insufficientCoverage['method'],
|
||||
'project_risks_classes' => $projectRisks['class'],
|
||||
'project_risks_methods' => $projectRisks['method'],
|
||||
'complexity_class' => $complexity['class'],
|
||||
'complexity_method' => $complexity['method'],
|
||||
'class_coverage_distribution' => $coverageDistribution['class'],
|
||||
'method_coverage_distribution' => $coverageDistribution['method'],
|
||||
],
|
||||
);
|
||||
|
||||
try {
|
||||
$template->renderTo($file);
|
||||
} catch (Exception $e) {
|
||||
throw new FileCouldNotBeWrittenException(
|
||||
$e->getMessage(),
|
||||
$e->getCode(),
|
||||
$e,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function activeBreadcrumb(AbstractNode $node): string
|
||||
{
|
||||
return sprintf(
|
||||
' <li class="breadcrumb-item"><a href="index.html">%s</a></li>' . "\n" .
|
||||
' <li class="breadcrumb-item active">(Dashboard)</li>' . "\n",
|
||||
$node->name(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, ProcessedClassType|ProcessedTraitType> $classes
|
||||
*
|
||||
* @return array{class: non-empty-string, method: non-empty-string}
|
||||
*/
|
||||
private function complexity(array $classes, string $baseLink): array
|
||||
{
|
||||
$result = ['class' => [], 'method' => []];
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
foreach ($class->methods as $methodName => $method) {
|
||||
if ($className !== '*') {
|
||||
$methodName = $className . '::' . $methodName;
|
||||
}
|
||||
|
||||
$result['method'][] = [
|
||||
$method->coverage,
|
||||
$method->ccn,
|
||||
str_replace($baseLink, '', $method->link),
|
||||
$methodName,
|
||||
$method->crap,
|
||||
];
|
||||
}
|
||||
|
||||
$result['class'][] = [
|
||||
$class->coverage,
|
||||
$class->ccn,
|
||||
str_replace($baseLink, '', $class->link),
|
||||
$className,
|
||||
$class->crap,
|
||||
];
|
||||
}
|
||||
|
||||
usort($result['class'], static fn (mixed $a, mixed $b) => ($a[0] <=> $b[0]));
|
||||
usort($result['method'], static fn (mixed $a, mixed $b) => ($a[0] <=> $b[0]));
|
||||
|
||||
$class = json_encode($result['class']);
|
||||
|
||||
assert($class !== false);
|
||||
|
||||
$method = json_encode($result['method']);
|
||||
|
||||
assert($method !== false);
|
||||
|
||||
return ['class' => $class, 'method' => $method];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, ProcessedClassType|ProcessedTraitType> $classes
|
||||
*
|
||||
* @return array{class: non-empty-string, method: non-empty-string}
|
||||
*/
|
||||
private function coverageDistribution(array $classes): array
|
||||
{
|
||||
$result = [
|
||||
'class' => [
|
||||
'0%' => 0,
|
||||
'0-10%' => 0,
|
||||
'10-20%' => 0,
|
||||
'20-30%' => 0,
|
||||
'30-40%' => 0,
|
||||
'40-50%' => 0,
|
||||
'50-60%' => 0,
|
||||
'60-70%' => 0,
|
||||
'70-80%' => 0,
|
||||
'80-90%' => 0,
|
||||
'90-100%' => 0,
|
||||
'100%' => 0,
|
||||
],
|
||||
'method' => [
|
||||
'0%' => 0,
|
||||
'0-10%' => 0,
|
||||
'10-20%' => 0,
|
||||
'20-30%' => 0,
|
||||
'30-40%' => 0,
|
||||
'40-50%' => 0,
|
||||
'50-60%' => 0,
|
||||
'60-70%' => 0,
|
||||
'70-80%' => 0,
|
||||
'80-90%' => 0,
|
||||
'90-100%' => 0,
|
||||
'100%' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($classes as $class) {
|
||||
foreach ($class->methods as $method) {
|
||||
if ($method->coverage === 0) {
|
||||
$result['method']['0%']++;
|
||||
} elseif ($method->coverage === 100) {
|
||||
$result['method']['100%']++;
|
||||
} else {
|
||||
$key = floor($method->coverage / 10) * 10;
|
||||
$key = $key . '-' . ($key + 10) . '%';
|
||||
$result['method'][$key]++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($class->coverage === 0) {
|
||||
$result['class']['0%']++;
|
||||
} elseif ($class->coverage === 100) {
|
||||
$result['class']['100%']++;
|
||||
} else {
|
||||
$key = floor($class->coverage / 10) * 10;
|
||||
$key = $key . '-' . ($key + 10) . '%';
|
||||
$result['class'][$key]++;
|
||||
}
|
||||
}
|
||||
|
||||
$class = json_encode(array_values($result['class']));
|
||||
|
||||
assert($class !== false);
|
||||
|
||||
$method = json_encode(array_values($result['method']));
|
||||
|
||||
assert($method !== false);
|
||||
|
||||
return ['class' => $class, 'method' => $method];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, ProcessedClassType|ProcessedTraitType> $classes
|
||||
*
|
||||
* @return array{class: string, method: string}
|
||||
*/
|
||||
private function insufficientCoverage(array $classes, string $baseLink): array
|
||||
{
|
||||
$leastTestedClasses = [];
|
||||
$leastTestedMethods = [];
|
||||
$result = ['class' => '', 'method' => ''];
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
foreach ($class->methods as $methodName => $method) {
|
||||
if ($method->coverage < $this->thresholds->highLowerBound()) {
|
||||
$key = $methodName;
|
||||
|
||||
if ($className !== '*') {
|
||||
$key = $className . '::' . $methodName;
|
||||
}
|
||||
|
||||
$leastTestedMethods[$key] = $method->coverage;
|
||||
}
|
||||
}
|
||||
|
||||
if ($class->coverage < $this->thresholds->highLowerBound()) {
|
||||
$leastTestedClasses[$className] = $class->coverage;
|
||||
}
|
||||
}
|
||||
|
||||
asort($leastTestedClasses);
|
||||
asort($leastTestedMethods);
|
||||
|
||||
foreach ($leastTestedClasses as $className => $coverage) {
|
||||
$result['class'] .= sprintf(
|
||||
' <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n",
|
||||
str_replace($baseLink, '', $classes[$className]->link),
|
||||
$className,
|
||||
$coverage,
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($leastTestedMethods as $methodName => $coverage) {
|
||||
[$class, $method] = explode('::', $methodName);
|
||||
|
||||
$result['method'] .= sprintf(
|
||||
' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d%%</td></tr>' . "\n",
|
||||
str_replace($baseLink, '', $classes[$class]->methods[$method]->link),
|
||||
$methodName,
|
||||
$method,
|
||||
$coverage,
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, ProcessedClassType|ProcessedTraitType> $classes
|
||||
*
|
||||
* @return array{class: string, method: string}
|
||||
*/
|
||||
private function projectRisks(array $classes, string $baseLink): array
|
||||
{
|
||||
$classRisks = [];
|
||||
$methodRisks = [];
|
||||
$result = ['class' => '', 'method' => ''];
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
foreach ($class->methods as $methodName => $method) {
|
||||
if ($method->coverage < $this->thresholds->highLowerBound() && $method->ccn > 1) {
|
||||
$key = $methodName;
|
||||
|
||||
if ($className !== '*') {
|
||||
$key = $className . '::' . $methodName;
|
||||
}
|
||||
|
||||
$methodRisks[$key] = $method;
|
||||
}
|
||||
}
|
||||
|
||||
if ($class->coverage < $this->thresholds->highLowerBound() &&
|
||||
$class->ccn > count($class->methods)) {
|
||||
$classRisks[$className] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
uasort($classRisks, static function (ProcessedClassType|ProcessedTraitType $a, ProcessedClassType|ProcessedTraitType $b)
|
||||
{
|
||||
return ((int) ($a->crap) <=> (int) ($b->crap)) * -1;
|
||||
});
|
||||
uasort($methodRisks, static function (ProcessedMethodType $a, ProcessedMethodType $b)
|
||||
{
|
||||
return ((int) ($a->crap) <=> (int) ($b->crap)) * -1;
|
||||
});
|
||||
|
||||
foreach ($classRisks as $className => $class) {
|
||||
$result['class'] .= sprintf(
|
||||
' <tr><td><a href="%s">%s</a></td><td class="text-right">%.1f%%</td><td class="text-right">%d</td><td class="text-right">%d</td></tr>' . "\n",
|
||||
str_replace($baseLink, '', $classes[$className]->link),
|
||||
$className,
|
||||
$class->coverage,
|
||||
$class->ccn,
|
||||
$class->crap,
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($methodRisks as $methodName => $methodVals) {
|
||||
[$class, $method] = explode('::', $methodName);
|
||||
|
||||
$result['method'] .= sprintf(
|
||||
' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%.1f%%</td><td class="text-right">%d</td><td class="text-right">%d</td></tr>' . "\n",
|
||||
str_replace($baseLink, '', $classes[$class]->methods[$method]->link),
|
||||
$methodName,
|
||||
$method,
|
||||
$methodVals->coverage,
|
||||
$methodVals->ccn,
|
||||
$methodVals->crap,
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (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 function count;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
use SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
|
||||
use SebastianBergmann\CodeCoverage\Node\AbstractNode as Node;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\Template\Exception;
|
||||
use SebastianBergmann\Template\Template;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Directory extends Renderer
|
||||
{
|
||||
public function render(DirectoryNode $node, string $file): void
|
||||
{
|
||||
$templateName = $this->templatePath . ($this->hasBranchCoverage ? 'directory_branch.html' : 'directory.html');
|
||||
$template = new Template($templateName, '{{', '}}');
|
||||
|
||||
$this->setCommonTemplateVariables($template, $node);
|
||||
|
||||
$items = $this->renderItem($node, true);
|
||||
|
||||
foreach ($node->directories() as $item) {
|
||||
$items .= $this->renderItem($item);
|
||||
}
|
||||
|
||||
foreach ($node->files() as $item) {
|
||||
$items .= $this->renderItem($item);
|
||||
}
|
||||
|
||||
$template->setVar(
|
||||
[
|
||||
'id' => $node->id(),
|
||||
'items' => $items,
|
||||
],
|
||||
);
|
||||
|
||||
try {
|
||||
$template->renderTo($file);
|
||||
} catch (Exception $e) {
|
||||
throw new FileCouldNotBeWrittenException(
|
||||
$e->getMessage(),
|
||||
$e->getCode(),
|
||||
$e,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function renderItem(Node $node, bool $total = false): string
|
||||
{
|
||||
$data = [
|
||||
'numClasses' => $node->numberOfClassesAndTraits(),
|
||||
'numTestedClasses' => $node->numberOfTestedClassesAndTraits(),
|
||||
'numMethods' => $node->numberOfFunctionsAndMethods(),
|
||||
'numTestedMethods' => $node->numberOfTestedFunctionsAndMethods(),
|
||||
'linesExecutedPercent' => $node->percentageOfExecutedLines()->asFloat(),
|
||||
'linesExecutedPercentAsString' => $node->percentageOfExecutedLines()->asString(),
|
||||
'numExecutedLines' => $node->numberOfExecutedLines(),
|
||||
'numExecutableLines' => $node->numberOfExecutableLines(),
|
||||
'branchesExecutedPercent' => $node->percentageOfExecutedBranches()->asFloat(),
|
||||
'branchesExecutedPercentAsString' => $node->percentageOfExecutedBranches()->asString(),
|
||||
'numExecutedBranches' => $node->numberOfExecutedBranches(),
|
||||
'numExecutableBranches' => $node->numberOfExecutableBranches(),
|
||||
'pathsExecutedPercent' => $node->percentageOfExecutedPaths()->asFloat(),
|
||||
'pathsExecutedPercentAsString' => $node->percentageOfExecutedPaths()->asString(),
|
||||
'numExecutedPaths' => $node->numberOfExecutedPaths(),
|
||||
'numExecutablePaths' => $node->numberOfExecutablePaths(),
|
||||
'testedMethodsPercent' => $node->percentageOfTestedFunctionsAndMethods()->asFloat(),
|
||||
'testedMethodsPercentAsString' => $node->percentageOfTestedFunctionsAndMethods()->asString(),
|
||||
'testedClassesPercent' => $node->percentageOfTestedClassesAndTraits()->asFloat(),
|
||||
'testedClassesPercentAsString' => $node->percentageOfTestedClassesAndTraits()->asString(),
|
||||
];
|
||||
|
||||
if ($total) {
|
||||
$data['name'] = 'Total';
|
||||
} else {
|
||||
$up = str_repeat('../', count($node->pathAsArray()) - 2);
|
||||
$data['icon'] = sprintf('<img src="%s_icons/file-code.svg" class="octicon" />', $up);
|
||||
|
||||
if ($node instanceof DirectoryNode) {
|
||||
$data['name'] = sprintf(
|
||||
'<a href="%s/index.html">%s</a>',
|
||||
$node->name(),
|
||||
$node->name(),
|
||||
);
|
||||
$data['icon'] = sprintf('<img src="%s_icons/file-directory.svg" class="octicon" />', $up);
|
||||
} elseif ($this->hasBranchCoverage) {
|
||||
$data['name'] = sprintf(
|
||||
'%s <a class="small" href="%s.html">[line]</a> <a class="small" href="%s_branch.html">[branch]</a> <a class="small" href="%s_path.html">[path]</a>',
|
||||
$node->name(),
|
||||
$node->name(),
|
||||
$node->name(),
|
||||
$node->name(),
|
||||
);
|
||||
} else {
|
||||
$data['name'] = sprintf(
|
||||
'<a href="%s.html">%s</a>',
|
||||
$node->name(),
|
||||
$node->name(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$templateName = $this->templatePath . ($this->hasBranchCoverage ? 'directory_item_branch.html' : 'directory_item.html');
|
||||
|
||||
return $this->renderItemTemplate(
|
||||
new Template($templateName, '{{', '}}'),
|
||||
$data,
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+9
@@ -0,0 +1,9 @@
|
||||
<hr/>
|
||||
<h4>Branches</h4>
|
||||
<p>
|
||||
Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not
|
||||
necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once.
|
||||
Please also be aware that some branches may be implicit rather than explicit, e.g. an <code>if</code> statement
|
||||
<i>always</i> has an <code>else</code> as part of its logical flow even if you didn't write one.
|
||||
</p>
|
||||
{{branches}}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<div class="progress">
|
||||
<div class="progress-bar bg-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
|
||||
<span class="visually-hidden">{{percent}}% covered ({{level}})</span>
|
||||
</div>
|
||||
</div>
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
<div class="progress">
|
||||
<div class="progress-bar bg-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
|
||||
<span class="visually-hidden">{{percent}}% covered ({{level}})</span>
|
||||
</div>
|
||||
</div>
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*!
|
||||
* Copyright (c) 2017 ~ present NAVER Corp.
|
||||
* billboard.js project is licensed under the MIT license
|
||||
*
|
||||
* billboard.js, JavaScript chart library
|
||||
* https://naver.github.io/billboard.js/
|
||||
*
|
||||
* @version 3.15.1
|
||||
*/
|
||||
.bb svg{font:10px sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0)}.bb path,.bb line{fill:none;stroke:#000}.bb text,.bb .bb-button{-webkit-user-select:none;-moz-user-select:none;user-select:none}.bb-legend-item-tile,.bb-xgrid-focus,.bb-ygrid-focus,.bb-ygrid{shape-rendering:crispEdges}.bb-chart-arcs .bb-needle,.bb-chart-arc .bb-gauge-value{fill:#000}.bb-chart-arc path{stroke:#fff}.bb-chart-arc rect{stroke:#fff;stroke-width:1}.bb-chart-arc text{fill:#fff;font-size:13px}.bb-chart-funnels path{stroke-width:0}.bb-chart-funnels+.bb-chart-texts text{font-size:13px;fill:#fff}.bb-axis{shape-rendering:crispEdges}.bb-axis .bb-axis-x-tooltip,.bb-axis .bb-axis-y-tooltip,.bb-axis .bb-axis-y2-tooltip{font-size:1em;fill:#fff;white-space:nowrap}.bb-grid{pointer-events:none}.bb-grid line{stroke:#aaa}.bb-grid text{fill:#aaa}.bb-xgrid,.bb-ygrid{stroke-dasharray:3 3}.bb-text.bb-empty{fill:gray;font-size:2em}.bb-line{stroke-width:1px}.bb-circle._expanded_{stroke-width:1px;stroke:#fff}.bb-selected-circle{fill:#fff;stroke-width:2px}.bb-bar{stroke-width:0}.bb-bar._expanded_{fill-opacity:.75}.bb-candlestick{stroke-width:1px}.bb-candlestick._expanded_{fill-opacity:.75}.bb-target.bb-focused,.bb-circles.bb-focused{opacity:1}.bb-target.bb-focused path.bb-line,.bb-target.bb-focused path.bb-step,.bb-circles.bb-focused path.bb-line,.bb-circles.bb-focused path.bb-step{stroke-width:2px}.bb-target.bb-defocused,.bb-circles.bb-defocused{opacity:.3!important}.bb-target.bb-defocused .text-overlapping,.bb-circles.bb-defocused .text-overlapping{opacity:.05!important}.bb-region{fill:#4682b4}.bb-region rect{fill-opacity:.1}.bb-zoom-brush,.bb-brush .extent{fill-opacity:.1}.bb-legend-item{font-size:12px;user-select:none}.bb-legend-item-hidden{opacity:.15}.bb-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.bb-title{font:14px sans-serif}.bb-chart-treemaps rect{stroke:#fff;stroke-width:1px}.bb-tooltip-container{z-index:10;user-select:none}.bb-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;opacity:.9;box-shadow:7px 7px 12px -9px #777;white-space:nowrap}.bb-tooltip tr{border:1px solid #CCC}.bb-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#fff}.bb-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.bb-tooltip td>span,.bb-tooltip td>svg{display:inline-block;width:10px;height:10px;margin-right:6px}.bb-tooltip.value{text-align:right}.bb-area{stroke-width:0;opacity:.2}.bb-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}text.bb-chart-arcs-gauge-title{dominant-baseline:middle;font-size:2.7em}.bb-chart-arcs .bb-chart-arcs-background{fill:#e0e0e0;stroke:#fff}.bb-chart-arcs .bb-chart-arcs-gauge-unit{fill:#000;font-size:16px}.bb-chart-arcs .bb-chart-arcs-gauge-max,.bb-chart-arcs .bb-chart-arcs-gauge-min{fill:#777}.bb-chart-arcs .bb-levels circle{fill:none;stroke:#848282;stroke-width:.5px}.bb-chart-arcs .bb-levels text{fill:#848282}.bb-chart-radars .bb-levels polygon{fill:none;stroke:#848282;stroke-width:.5px}.bb-chart-radars .bb-levels text{fill:#848282}.bb-chart-radars .bb-axis line{stroke:#848282;stroke-width:.5px}.bb-chart-radars .bb-axis text{font-size:1.15em;cursor:default}.bb-chart-radars .bb-shapes polygon{fill-opacity:.2;stroke-width:1px}.bb-button{position:absolute;top:10px;right:10px}.bb-button .bb-zoom-reset{font-size:11px;border:solid 1px #ccc;background-color:#fff;padding:5px;border-radius:5px;cursor:pointer}
|
||||
+6
File diff suppressed because one or more lines are too long
+5
@@ -0,0 +1,5 @@
|
||||
.octicon {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
fill: currentColor;
|
||||
}
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
|
||||
:root {
|
||||
/* Implementing an auto-selection of dark/light theme via: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark */
|
||||
color-scheme: light dark;
|
||||
|
||||
/* PHPUnit light/dark colors */
|
||||
--phpunit-breadcrumbs: light-dark(var(--bs-gray-200), var(--bs-gray-800));
|
||||
--phpunit-success-bar: light-dark(#28a745 ,#1f8135);
|
||||
--phpunit-success-high: light-dark(#99cb84, #3d5c4e);
|
||||
--phpunit-success-medium: light-dark(#c3e3b5,#3c6051);
|
||||
--phpunit-success-low: light-dark(#dff0d8, #2d4431);
|
||||
--phpunit-warning: light-dark(#fcf8e3, #3e3408);
|
||||
--phpunit-warning-bar: light-dark(#ffc107 ,#c19406);
|
||||
--phpunit-danger: light-dark(#f2dede, #42221e);
|
||||
--phpunit-danger-bar: light-dark(#dc3545, #a62633);
|
||||
|
||||
/* Bootstrap v5.3 default colors (light, dark) */
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-body-bg: light-dark(#fff, #212529);
|
||||
--bs-body-color-rgb: light-dark(33, 37, 41, 222, 226, 230);
|
||||
--bs-body-color: light-dark(#212529, #dee2e6);
|
||||
--bs-border-color-translucent: light-dark(rgba(0, 0, 0, 0.175), rgba(255, 255, 255, 0.15));
|
||||
--bs-border-color: light-dark(#dee2e6, #495057);
|
||||
--bs-code-color: light-dark(#d63384, #e685b5);
|
||||
--bs-danger-bg-subtle: light-dark(#f8d7da, #2c0b0e);
|
||||
--bs-danger-border-subtle: light-dark(#f1aeb5, #842029);
|
||||
--bs-danger-text-emphasis: light-dark(#58151c, #ea868f);
|
||||
--bs-dark-bg-subtle: light-dark(#ced4da, #1a1d20);
|
||||
--bs-dark-border-subtle: light-dark(#adb5bd, #343a40);
|
||||
--bs-dark-text-emphasis: light-dark(#495057, #dee2e6);
|
||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||
--bs-emphasis-color: light-dark(#000, #fff);
|
||||
--bs-form-invalid-border-color: light-dark(#dc3545, #ea868f);
|
||||
--bs-form-invalid-color: light-dark(#dc3545, #ea868f);
|
||||
--bs-form-valid-border-color: light-dark(#198754, #75b798);
|
||||
--bs-form-valid-color: light-dark(#198754, #75b798);
|
||||
--bs-highlight-bg: light-dark(#fff3cd, #664d03);
|
||||
--bs-highlight-color: light-dark(#212529, #dee2e6);
|
||||
--bs-info-bg-subtle: light-dark(#cff4fc, #032830);
|
||||
--bs-info-border-subtle: light-dark(#9eeaf9, #087990);
|
||||
--bs-info-text-emphasis: light-dark(#055160, #6edff6);
|
||||
--bs-light-bg-subtle: light-dark(#fcfcfd, #343a40);
|
||||
--bs-light-border-subtle: light-dark(#e9ecef, #495057);
|
||||
--bs-light-text-emphasis: light-dark(#495057, #f8f9fa);
|
||||
--bs-link-color-rgb: 13, 110, 253;
|
||||
--bs-link-color: light-dark(#0d6efd, #6ea8fe);
|
||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||
--bs-link-hover-color: light-dark(#0a58ca, #8bb9fe);
|
||||
--bs-primary-bg-subtle: light-dark(#cfe2ff, #031633);
|
||||
--bs-primary-border-subtle: light-dark(#9ec5fe, #084298);
|
||||
--bs-primary-text-emphasis: light-dark(#052c65, #6ea8fe);
|
||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||
--bs-secondary-bg-subtle: light-dark(#e2e3e5, #161719);
|
||||
--bs-secondary-bg: light-dark(#e9ecef, #343a40);
|
||||
--bs-secondary-border-subtle: light-dark(#c4c8cb, #41464b);
|
||||
--bs-secondary-color-rgb: 33, 37, 41;
|
||||
--bs-secondary-color: light-dark(rgba(33, 37, 41, 0.75), rgba(222, 226, 230, 0.75));
|
||||
--bs-secondary-text-emphasis: light-dark(#2b2f32, #a7acb1);
|
||||
--bs-success-bg-subtle: light-dark(#d1e7dd, #051b11);
|
||||
--bs-success-border-subtle: light-dark(#a3cfbb, #0f5132);
|
||||
--bs-success-text-emphasis: light-dark(#0a3622, #75b798);
|
||||
--bs-tertiary-bg-rgb: light-dark(248, 249, 250, 43, 48, 53);
|
||||
--bs-tertiary-bg: light-dark(#f8f9fa, #2b3035);
|
||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||
--bs-tertiary-color: light-dark(rgba(33, 37, 41, 0.5), rgba(222, 226, 230, 0.5));
|
||||
--bs-warning-bg-subtle: light-dark(#fff3cd, #332701);
|
||||
--bs-warning-border-subtle: light-dark(#ffe69c, #997404);
|
||||
--bs-warning-text-emphasis: light-dark(#664d03, #ffda6a);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bs-body-bg-rgb: 33, 37, 41;
|
||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||
--bs-link-color-rgb: 110, 168, 254;
|
||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||
--bs-secondary-color-rgb: 222, 226, 230;
|
||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||
}
|
||||
|
||||
/* Invert icon's colors on dark mode to improve readability */
|
||||
img.octicon { filter: invert(1); }
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
font-kerning: normal;
|
||||
text-rendering: optimizeLegibility;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
nav .breadcrumb {
|
||||
border-radius: var(--bs-border-radius);
|
||||
background-color: var(--phpunit-breadcrumbs);
|
||||
padding: .75rem 1rem;
|
||||
}
|
||||
|
||||
.popover {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.popover-body {
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
margin-right:.25em;
|
||||
vertical-align: baseline;
|
||||
width: 0.75em;
|
||||
}
|
||||
|
||||
.table-bordered>thead>tr>td {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.table tbody>tr>td, .table thead>tr>td {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
.table-condensed tbody>tr>td {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.table .progress {
|
||||
margin-bottom: inherit;
|
||||
}
|
||||
|
||||
.table-borderless th, .table-borderless td {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.table tbody tr.covered-by-large-tests, .table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, tr.success td, td.success, li.success, span.success {
|
||||
background-color: var(--phpunit-success-low);
|
||||
}
|
||||
|
||||
.table tbody tr.covered-by-medium-tests, .table tbody tr.covered-by-medium-tests td, li.covered-by-medium-tests {
|
||||
background-color: var(--phpunit-success-medium);
|
||||
}
|
||||
|
||||
.table tbody tr.covered-by-small-tests, .table tbody tr.covered-by-small-tests td, li.covered-by-small-tests {
|
||||
background-color: var(--phpunit-success-high);
|
||||
}
|
||||
|
||||
.table tbody tr.warning, .table tbody tr.warning td, .table tbody td.warning, li.warning, span.warning {
|
||||
background-color: var(--phpunit-warning);
|
||||
}
|
||||
|
||||
.table tbody tr.danger, .table tbody tr.danger td, .table tbody td.danger, li.danger, span.danger {
|
||||
background-color: var(--phpunit-danger);
|
||||
}
|
||||
|
||||
.table tbody td.info {
|
||||
background-color: rgb(from var(--bs-info) r g b / 0.25);
|
||||
}
|
||||
|
||||
td.big {
|
||||
vertical-align: middle;
|
||||
width: 117px;
|
||||
}
|
||||
|
||||
td.small {
|
||||
}
|
||||
|
||||
td.codeLine {
|
||||
font-family: "Source Code Pro", var(--bs-font-monospace);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
td span.comment {
|
||||
color: var(--bs-secondary-color);
|
||||
}
|
||||
|
||||
td span.default {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
td span.html {
|
||||
color: var(--bs-secondary-color);
|
||||
}
|
||||
|
||||
td span.keyword {
|
||||
color: var(--bs-body-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
pre span.string {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
span.success, span.warning, span.danger {
|
||||
margin-right: 2px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#toplink {
|
||||
position: fixed;
|
||||
left: 5px;
|
||||
bottom: 5px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
svg text {
|
||||
font-family: var(--bs-font-sans-serif);
|
||||
font-size: 11px;
|
||||
color: var(--bs-gray);
|
||||
fill: var(--bs-gray);
|
||||
}
|
||||
|
||||
.scrollbox {
|
||||
height:245px;
|
||||
overflow-x:scroll;
|
||||
overflow-y:scroll;
|
||||
}
|
||||
|
||||
table + .structure-heading {
|
||||
border-top: 1px solid var(--bs-gray-200);
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
|
||||
table#code td:first-of-type {
|
||||
padding-left: .75em;
|
||||
padding-right: .75em;
|
||||
}
|
||||
|
||||
table#code td:first-of-type a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.legend {
|
||||
font-weight: bold;
|
||||
margin-right: 2px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.covered-by-small-tests {
|
||||
background-color: var(--phpunit-success-high);
|
||||
}
|
||||
|
||||
.covered-by-medium-tests {
|
||||
background-color: var(--phpunit-success-medium);
|
||||
}
|
||||
|
||||
.covered-by-large-tests {
|
||||
background-color: var(--phpunit-success-low);
|
||||
}
|
||||
|
||||
.not-covered {
|
||||
background-color: var(--phpunit-danger);
|
||||
}
|
||||
|
||||
.not-coverable {
|
||||
background-color: var(--phpunit-warning);
|
||||
}
|
||||
|
||||
.progress-bar.bg-success {
|
||||
background-color: var(--phpunit-success-bar) !important;
|
||||
}
|
||||
|
||||
.progress-bar.bg-warning {
|
||||
background-color: var(--phpunit-warning-bar) !important;
|
||||
}
|
||||
|
||||
.progress-bar.bg-danger {
|
||||
background-color: var(--phpunit-danger-bar) !important;
|
||||
}
|
||||
+299
@@ -0,0 +1,299 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Dashboard for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/billboard.min.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2>Classes</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Coverage Distribution</h3>
|
||||
<div id="classesCoverageDistribution" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Complexity</h3>
|
||||
<div id="classComplexity" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3 style="margin-top: 2rem;">Insufficient Coverage</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{insufficient_coverage_classes}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3 style="margin-top: 2rem;">Project Risks</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
<th class="text-right">Complexity</th>
|
||||
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{project_risks_classes}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2 style="margin-top: 3rem;">Methods</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Coverage Distribution</h3>
|
||||
<div id="methodsCoverageDistribution" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Complexity</h3>
|
||||
<div id="methodComplexity" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3 style="margin-top: 2rem;">Insufficient Coverage</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{insufficient_coverage_methods}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3 style="margin-top: 2rem;">Project Risks</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
<th class="text-right">Complexity</th>
|
||||
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{project_risks_methods}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<hr/>
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="{{path_to_root}}_js/billboard.pkgd.min.js?v={{version}}" type="text/javascript"></script>
|
||||
<script type="application/json" id="complexity_class">{{complexity_class}}</script>
|
||||
<script type="application/json" id="complexity_method">{{complexity_method}}</script>
|
||||
<script type="text/javascript" defer>
|
||||
const barLabels = [
|
||||
'0%',
|
||||
'0-10%',
|
||||
'10-20%',
|
||||
'20-30%',
|
||||
'30-40%',
|
||||
'40-50%',
|
||||
'50-60%',
|
||||
'60-70%',
|
||||
'70-80%',
|
||||
'80-90%',
|
||||
'90-100%',
|
||||
'100%'
|
||||
];
|
||||
const barConfig = (name, fullName, values) => ({
|
||||
axis: {
|
||||
x: {
|
||||
type: "category",
|
||||
categories: barLabels,
|
||||
},
|
||||
y: {
|
||||
label: {
|
||||
text: `#${name}`,
|
||||
position: 'outer-top',
|
||||
},
|
||||
},
|
||||
},
|
||||
bindto: `#${name}CoverageDistribution`,
|
||||
data: {
|
||||
columns: [
|
||||
[fullName].concat(values),
|
||||
],
|
||||
colors: {
|
||||
[fullName]: "rgba(69, 114, 167, 0.75)",
|
||||
},
|
||||
type: "bar",
|
||||
},
|
||||
bar: {
|
||||
width: {
|
||||
ratio: 0.9,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
focus: {
|
||||
show: false,
|
||||
},
|
||||
x: {
|
||||
show: true,
|
||||
},
|
||||
y: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
tooltip: {
|
||||
contents: function (data) {
|
||||
return `<table class="bb-tooltip"><tbody>
|
||||
<tr><th colspan="2">Coverage ${barLabels[data[0].x]}</th></tr>
|
||||
<tr><td class="value">${data[0].value} ${name}</td></tr>
|
||||
</tbody></table>`;
|
||||
},
|
||||
grouped: false,
|
||||
},
|
||||
});
|
||||
bb.generate(
|
||||
barConfig('classes', "Class Coverage", {{class_coverage_distribution}})
|
||||
);
|
||||
bb.generate(
|
||||
barConfig('methods', "Method Coverage", {{method_coverage_distribution}})
|
||||
);
|
||||
|
||||
const scatterConfig = (name, complexityData) => ({
|
||||
axis: {
|
||||
x: {
|
||||
label: {
|
||||
text: 'Code Coverage (in percent)',
|
||||
position: 'outer-right',
|
||||
},
|
||||
tick: {
|
||||
values: [0, 20, 40, 60, 80, 100],
|
||||
},
|
||||
},
|
||||
y: {
|
||||
label: {
|
||||
text: 'Cyclomatic Complexity',
|
||||
position: 'outer-top',
|
||||
},
|
||||
min: 0,
|
||||
padding: {
|
||||
bottom: 0,
|
||||
top: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
bindto: `#${name}Complexity`,
|
||||
data: {
|
||||
columns: [
|
||||
["complexity_x"].concat(complexityData.map(d => d[0])),
|
||||
["complexity"].concat(complexityData.map(d => d[1])),
|
||||
],
|
||||
onclick: function(data, element) {
|
||||
window.location = complexityData[data.index][2];
|
||||
},
|
||||
type: "scatter",
|
||||
xs: {
|
||||
"complexity": "complexity_x",
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
focus: {
|
||||
show: true,
|
||||
y: true,
|
||||
},
|
||||
x: {
|
||||
show: true,
|
||||
},
|
||||
y: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
tooltip: {
|
||||
contents: function (data) {
|
||||
const coverage = Math.round(data[0].x);
|
||||
const complexity = data[0].value;
|
||||
const targetName = complexityData[data[0].index][3];
|
||||
const crap = complexityData[data[0].index][4];
|
||||
return `<table class="bb-tooltip"><tbody>
|
||||
<tr><th colspan="2">${targetName}</th></tr>
|
||||
<tr class="bb-tooltip-name-complexity"><td>Coverage</td><td class="name">${coverage}%</td></tr>
|
||||
<tr class="bb-tooltip-name-complexity"><td>Complexity</td><td class="value">${complexity}</td></tr>
|
||||
<tr class="bb-tooltip-name-complexity"><td>Crap</td><td class="value">${crap}</td></tr>
|
||||
</tbody></table>`;
|
||||
},
|
||||
grouped: false,
|
||||
},
|
||||
});
|
||||
const classComplexityData = JSON.parse(document.getElementById('complexity_class').textContent);
|
||||
bb.generate(
|
||||
scatterConfig("class", classComplexityData)
|
||||
);
|
||||
const methodComplexityData = JSON.parse(document.getElementById('complexity_method').textContent);
|
||||
bb.generate(
|
||||
scatterConfig("method", methodComplexityData),
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+293
@@ -0,0 +1,293 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Dashboard for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/billboard.min.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2>Classes</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Coverage Distribution</h3>
|
||||
<div id="classesCoverageDistribution" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Complexity</h3>
|
||||
<div id="classComplexity" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3 style="margin-top: 2rem;">Insufficient Coverage</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{insufficient_coverage_classes}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3 style="margin-top: 2rem;">Project Risks</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{project_risks_classes}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2 style="margin-top: 3rem;">Methods</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Coverage Distribution</h3>
|
||||
<div id="methodsCoverageDistribution" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Complexity</h3>
|
||||
<div id="methodComplexity" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3 style="margin-top: 2rem;">Insufficient Coverage</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{insufficient_coverage_methods}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3 style="margin-top: 2rem;">Project Risks</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{project_risks_methods}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<hr/>
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="_js/billboard.pkgd.min.js?v={{version}}" type="text/javascript"></script>
|
||||
<script type="application/json" id="complexity_class">{{complexity_class}}</script>
|
||||
<script type="application/json" id="complexity_method">{{complexity_method}}</script>
|
||||
<script type="text/javascript" defer>
|
||||
const barLabels = [
|
||||
'0%',
|
||||
'0-10%',
|
||||
'10-20%',
|
||||
'20-30%',
|
||||
'30-40%',
|
||||
'40-50%',
|
||||
'50-60%',
|
||||
'60-70%',
|
||||
'70-80%',
|
||||
'80-90%',
|
||||
'90-100%',
|
||||
'100%'
|
||||
];
|
||||
const barConfig = (name, fullName, values) => ({
|
||||
axis: {
|
||||
x: {
|
||||
type: "category",
|
||||
categories: barLabels,
|
||||
},
|
||||
y: {
|
||||
label: {
|
||||
text: `#${name}`,
|
||||
position: 'outer-top',
|
||||
},
|
||||
},
|
||||
},
|
||||
bindto: `#${name}CoverageDistribution`,
|
||||
data: {
|
||||
columns: [
|
||||
[fullName].concat(values),
|
||||
],
|
||||
colors: {
|
||||
[fullName]: "rgba(69, 114, 167, 0.75)",
|
||||
},
|
||||
type: "bar",
|
||||
},
|
||||
bar: {
|
||||
width: {
|
||||
ratio: 0.9,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
focus: {
|
||||
show: false,
|
||||
},
|
||||
x: {
|
||||
show: true,
|
||||
},
|
||||
y: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
tooltip: {
|
||||
contents: function (data) {
|
||||
return `<table class="bb-tooltip"><tbody>
|
||||
<tr><th colspan="2">Coverage ${barLabels[data[0].x]}</th></tr>
|
||||
<tr><td class="value">${data[0].value} ${name}</td></tr>
|
||||
</tbody></table>`;
|
||||
},
|
||||
grouped: false,
|
||||
},
|
||||
});
|
||||
bb.generate(
|
||||
barConfig('classes', "Class Coverage", {{class_coverage_distribution}})
|
||||
);
|
||||
bb.generate(
|
||||
barConfig('methods', "Method Coverage", {{method_coverage_distribution}})
|
||||
);
|
||||
|
||||
const scatterConfig = (name, complexityData) => ({
|
||||
axis: {
|
||||
x: {
|
||||
label: {
|
||||
text: 'Code Coverage (in percent)',
|
||||
position: 'outer-right',
|
||||
},
|
||||
tick: {
|
||||
values: [0, 20, 40, 60, 80, 100],
|
||||
},
|
||||
},
|
||||
y: {
|
||||
label: {
|
||||
text: 'Cyclomatic Complexity',
|
||||
position: 'outer-top',
|
||||
},
|
||||
min: 0,
|
||||
padding: {
|
||||
bottom: 0,
|
||||
top: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
bindto: `#${name}Complexity`,
|
||||
data: {
|
||||
columns: [
|
||||
["complexity_x"].concat(complexityData.map(d => d[0])),
|
||||
["complexity"].concat(complexityData.map(d => d[1])),
|
||||
],
|
||||
onclick: function(data, element) {
|
||||
window.location = complexityData[data.index][2];
|
||||
},
|
||||
type: "scatter",
|
||||
xs: {
|
||||
"complexity": "complexity_x",
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
focus: {
|
||||
show: true,
|
||||
y: true,
|
||||
},
|
||||
x: {
|
||||
show: true,
|
||||
},
|
||||
y: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
tooltip: {
|
||||
contents: function (data) {
|
||||
const coverage = Math.round(data[0].x);
|
||||
const complexity = data[0].value;
|
||||
const targetName = complexityData[data[0].index][3];
|
||||
return `<table class="bb-tooltip"><tbody>
|
||||
<tr><th colspan="2">${targetName}</th></tr>
|
||||
<tr class="bb-tooltip-name-complexity"><td>Coverage</td><td class="name">${coverage}%</td></tr>
|
||||
<tr class="bb-tooltip-name-complexity"><td>Complexity</td><td class="value">${complexity}</td></tr>
|
||||
</tbody></table>`;
|
||||
},
|
||||
grouped: false,
|
||||
},
|
||||
});
|
||||
const classComplexityData = JSON.parse(document.getElementById('complexity_class').textContent);
|
||||
bb.generate(
|
||||
scatterConfig("class", classComplexityData)
|
||||
);
|
||||
const methodComplexityData = JSON.parse(document.getElementById('complexity_method').textContent);
|
||||
bb.generate(
|
||||
scatterConfig("method", methodComplexityData),
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Code Coverage for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{items}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<footer>
|
||||
<hr/>
|
||||
<h4>Legend</h4>
|
||||
<p>
|
||||
<span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
|
||||
<span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
|
||||
<span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
|
||||
</p>
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Code Coverage for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="15"><div align="center"><strong>Code Coverage</strong></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Branches</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Paths</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{items}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<footer>
|
||||
<hr/>
|
||||
<h4>Legend</h4>
|
||||
<p>
|
||||
<span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
|
||||
<span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
|
||||
<span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
|
||||
</p>
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
<tr>
|
||||
<td class="{{lines_level}}">{{icon}}{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
</tr>
|
||||
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
<tr>
|
||||
<td class="{{lines_level}}">{{icon}}{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
</tr>
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Code Coverage for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
<td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{items}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{lines}}
|
||||
{{structure}}
|
||||
<footer>
|
||||
<hr/>
|
||||
<h4>Legend</h4>
|
||||
{{legend}}
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
<a title="Back to the top" id="toplink" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 11L6 5l-6 6h12z"/></svg>
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/bootstrap.bundle.min.js?v={{version}}" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/file.js?v={{version}}" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Code Coverage for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="16"><div align="center"><strong>Code Coverage</strong></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Branches</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Paths</strong></div></td>
|
||||
<td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{items}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{lines}}
|
||||
{{structure}}
|
||||
<footer>
|
||||
<hr/>
|
||||
<h4>Legend</h4>
|
||||
{{legend}}
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
<a title="Back to the top" id="toplink" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 11L6 5l-6 6h12z"/></svg>
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/bootstrap.bundle.min.js?v={{version}}" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/file.js?v={{version}}" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<tr>
|
||||
<td class="{{lines_level}}">{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
</tr>
|
||||
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
<tr>
|
||||
<td class="{{lines_level}}">{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
</tr>
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM5 6.98L3.5 8.5 5 10l-.5 1L2 8.5 4.5 6l.5.98zM7.5 6L10 8.5 7.5 11l-.5-.98L8.5 8.5 7 7l.5-1z"/></svg>
|
||||
|
After Width: | Height: | Size: 304 B |
Vendored
+1
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z"/></svg>
|
||||
|
After Width: | Height: | Size: 234 B |
Vendored
+57
File diff suppressed because one or more lines are too long
Vendored
+7
File diff suppressed because one or more lines are too long
+53
@@ -0,0 +1,53 @@
|
||||
$(function () {
|
||||
var $window = $(window)
|
||||
, $top_link = $('#toplink')
|
||||
, $body = $('body, html')
|
||||
, offset = $('#code').offset().top;
|
||||
|
||||
$top_link.hide().click(function (event) {
|
||||
event.preventDefault();
|
||||
$body.animate({scrollTop: 0}, 800);
|
||||
});
|
||||
|
||||
$window.scroll(function () {
|
||||
if ($window.scrollTop() > offset) {
|
||||
$top_link.fadeIn();
|
||||
} else {
|
||||
$top_link.fadeOut();
|
||||
}
|
||||
});
|
||||
|
||||
var $popovers = $('.popin > :first-child');
|
||||
$('.popin').on({
|
||||
'click.popover': function (event) {
|
||||
event.stopPropagation();
|
||||
|
||||
var $container = $(this).children().first();
|
||||
|
||||
//Close all other popovers:
|
||||
$popovers.each(function () {
|
||||
var $current = $(this);
|
||||
if (!$current.is($container)) {
|
||||
$current.popover('hide');
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle this popover:
|
||||
$container.popover('toggle');
|
||||
},
|
||||
});
|
||||
|
||||
//Hide all popovers on outside click:
|
||||
$(document).click(function (event) {
|
||||
if ($(event.target).closest($('.popover')).length === 0) {
|
||||
$popovers.popover('hide');
|
||||
}
|
||||
});
|
||||
|
||||
//Hide all popovers on escape:
|
||||
$(document).keyup(function (event) {
|
||||
if (event.key === 'Escape') {
|
||||
$popovers.popover('hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
+2
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
<tr class="{{class}} d-flex"><td {{popover}} class="col-1 text-end"><a id="{{lineNumber}}" href="#{{lineNumber}}">{{lineNumber}}</a></td><td class="col-11 codeLine">{{lineContent}}</td></tr>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<table id="code" class="table table-borderless table-condensed">
|
||||
<tbody>
|
||||
{{lines}}
|
||||
</tbody>
|
||||
</table>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<tr>
|
||||
<td class="{{lines_level}}">{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{methods_level}}" colspan="3"></td>
|
||||
</tr>
|
||||
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
<tr>
|
||||
<td class="{{lines_level}}">{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{methods_level}}" colspan="3"></td>
|
||||
</tr>
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<hr/>
|
||||
<h4>Paths</h4>
|
||||
<p>
|
||||
Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
|
||||
necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
|
||||
Please also be aware that some paths may include implicit rather than explicit branches, e.g. an <code>if</code> statement
|
||||
<i>always</i> has an <code>else</code> as part of its logical flow even if you didn't write one.
|
||||
</p>
|
||||
{{paths}}
|
||||
Reference in New Issue
Block a user