$codeLines
*/
- private function renderBranchLines(array $branch, array $codeLines, array $testData): string
+ private function renderBranchLines(ProcessedBranchCoverageData $branch, array $codeLines, array $testData): string
{
$linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
$singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
$lines = '';
- $branchLines = range($branch['line_start'], $branch['line_end']);
+ $branchLines = range($branch->line_start, $branch->line_end);
sort($branchLines); // sometimes end_line < start_line
/** @var int $line */
@@ -818,7 +819,7 @@ private function renderBranchLines(array $branch, array $codeLines, array $testD
$popoverContent = '';
$popoverTitle = '';
- $numTests = count($branch['hit']);
+ $numTests = count($branch->hit);
if ($numTests === 0) {
$trClass = 'danger';
@@ -832,7 +833,7 @@ private function renderBranchLines(array $branch, array $codeLines, array $testD
$popoverTitle = '1 test covers this branch';
}
- foreach ($branch['hit'] as $test) {
+ foreach ($branch->hit as $test) {
if ($lineCss === 'covered-by-large-tests' && $testData[$test]['size'] === 'medium') {
$lineCss = 'covered-by-medium-tests';
} elseif ($testData[$test]['size'] === 'small') {
@@ -877,21 +878,18 @@ private function renderPathStructure(FileNode $node): string
ksort($coverageData);
+ /** @var ProcessedFunctionCoverageData $methodData */
foreach ($coverageData as $methodName => $methodData) {
- if (!$methodData['paths']) {
- continue;
- }
-
$pathStructure = '';
- if (count($methodData['paths']) > 100) {
- $pathStructure .= '' . count($methodData['paths']) . ' is too many paths to sensibly render, consider refactoring your code to bring this number down.
';
+ if (count($methodData->paths) > 100) {
+ $pathStructure .= '' . count($methodData->paths) . ' is too many paths to sensibly render, consider refactoring your code to bring this number down.
';
continue;
}
- foreach ($methodData['paths'] as $path) {
- $pathStructure .= $this->renderPathLines($path, $methodData['branches'], $codeLines, $testData);
+ foreach ($methodData->paths as $path) {
+ $pathStructure .= $this->renderPathLines($path, $methodData->branches, $codeLines, $testData);
}
if ($pathStructure !== '') {
@@ -906,9 +904,10 @@ private function renderPathStructure(FileNode $node): string
}
/**
- * @param list $codeLines
+ * @param array $branches
+ * @param list $codeLines
*/
- private function renderPathLines(array $path, array $branches, array $codeLines, array $testData): string
+ private function renderPathLines(ProcessedPathCoverageData $path, array $branches, array $codeLines, array $testData): string
{
$linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
$singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
@@ -916,14 +915,14 @@ private function renderPathLines(array $path, array $branches, array $codeLines,
$lines = '';
$first = true;
- foreach ($path['path'] as $branchId) {
+ foreach ($path->path as $branchId) {
if ($first) {
$first = false;
} else {
$lines .= ' | |
' . "\n";
}
- $branchLines = range($branches[$branchId]['line_start'], $branches[$branchId]['line_end']);
+ $branchLines = range($branches[$branchId]->line_start, $branches[$branchId]->line_end);
sort($branchLines); // sometimes end_line < start_line
/** @var int $line */
@@ -935,7 +934,7 @@ private function renderPathLines(array $path, array $branches, array $codeLines,
$popoverContent = '';
$popoverTitle = '';
- $numTests = count($path['hit']);
+ $numTests = count($path->hit);
if ($numTests === 0) {
$trClass = 'danger';
@@ -949,7 +948,7 @@ private function renderPathLines(array $path, array $branches, array $codeLines,
$popoverTitle = '1 test covers this path';
}
- foreach ($path['hit'] as $test) {
+ foreach ($path->hit as $test) {
if ($lineCss === 'covered-by-large-tests' && $testData[$test]['size'] === 'medium') {
$lineCss = 'covered-by-medium-tests';
} elseif ($testData[$test]['size'] === 'small') {
diff --git a/src/Report/Html/Renderer/Template/css/style.css b/src/Report/Html/Renderer/Template/css/style.css
index c0a045889..4303bf844 100644
--- a/src/Report/Html/Renderer/Template/css/style.css
+++ b/src/Report/Html/Renderer/Template/css/style.css
@@ -1,13 +1,86 @@
+
:root {
- --phpunit-breadcrumbs: var(--bs-gray-200);
- --phpunit-success-bar: #28a745;
- --phpunit-success-high: {{success-high}};
- --phpunit-success-medium: {{success-medium}};
- --phpunit-success-low: {{success-low}};
- --phpunit-warning: {{warning}};
- --phpunit-warning-bar: #ffc107;
- --phpunit-danger: {{danger}};
- --phpunit-danger-bar: #dc3545;
+ /* 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 {
@@ -198,4 +271,4 @@ table#code td:first-of-type a {
.progress-bar.bg-danger {
background-color: var(--phpunit-danger-bar) !important;
-}
\ No newline at end of file
+}
diff --git a/src/Report/Html/Renderer/Template/dashboard.html.dist b/src/Report/Html/Renderer/Template/dashboard.html.dist
index a5d5a236e..d6575bc24 100644
--- a/src/Report/Html/Renderer/Template/dashboard.html.dist
+++ b/src/Report/Html/Renderer/Template/dashboard.html.dist
@@ -45,7 +45,7 @@
-
Insufficient Coverage
+
Insufficient Coverage