php-code-coverage icon indicating copy to clipboard operation
php-code-coverage copied to clipboard

Updates to Bootstrap 5 and adds theme support for code coverage.

Open gammamatrix opened this issue 1 year ago • 7 comments

Changes

  • Upgrades Bootstrap to v5.3.3
  • Upgrades jQuery v3.7.1
  • Allows themes using Bootstrap CSS Variables
  • popovers still supported.

Assets

I used these from jsdeliver and Cloudflare:

Theme support

Bootstrap 5.3 comes with dark and light mode support.

The <html> tag of each top level webpage gets a new element:

<html lang="en" data-bs-theme="dark">
  • Propose new theme variable in code coverage section:
<html lang="en" data-bs-theme="{{theme}}">

For example: src/Report/Html/Renderer/Template/directory.html.dist

This custom theme file provides some simple examples, the colors are not perfect, but good enough to test the code.

I put these themes into customCssFile="./phpunit-themes.css"

Example phpunit-themes.css for customCssFile
[data-bs-theme="lavender"] {
    color-scheme: lavender;
    --bs-body-color: #483d8b;
    --bs-body-color-rgb: 72, 61, 139;
    --bs-body-bg: #d8bfd8;
    --bs-body-bg-rgb: 216, 191, 216;
    --bs-emphasis-color: #fff;
    --bs-emphasis-color-rgb: 255, 255, 255;
    --bs-secondary-color: rgba(222, 226, 230, 0.75);
    --bs-secondary-color-rgb: 222, 226, 230;
    --bs-secondary-bg: #343a40;
    --bs-secondary-bg-rgb: 52, 58, 64;
    --bs-tertiary-color: rgba(222, 226, 230, 0.5);
    --bs-tertiary-color-rgb: 222, 226, 230;
    --bs-tertiary-bg: #483D8B;
    --bs-tertiary-bg-rgb: 72, 61, 139;
}

[data-bs-theme="blue"] {
    color-scheme: blue;
    --bs-body-color: #2F4F4F;
    --bs-body-color-rgb: 47, 79, 79;
    --bs-body-bg: #1E90FF;
    --bs-body-bg-rgb: 30, 144, 255;
    --bs-emphasis-color: #fff;
    --bs-emphasis-color-rgb: 255, 255, 255;
    --bs-secondary-color: #DCDCDC;
    --bs-secondary-color-rgb: 220, 220, 220;
    --bs-secondary-bg: #64daed;
    --bs-secondary-bg-rgb: 100, 218, 237;
    --bs-tertiary-color: rgba(222, 226, 230, 0.5);
    --bs-tertiary-color-rgb: 222, 226, 230;
    --bs-tertiary-bg: #00BFFF;
    --bs-tertiary-bg-rgb: 0, 191, 255;
}

[data-bs-theme="wheat"] {
    color-scheme: wheat;
    --bs-body-color: #2f4f4f;
    --bs-body-color-rgb: 47, 79, 79;
    --bs-border-color: #2f4f4f;
    --bs-border-color-translucent: rgba(47, 79, 79, 0.175);
    --bs-body-bg: #f5deb3;
    --bs-body-bg-rgb: rgba(245, 222, 179, 50);
    --bs-emphasis-color: #3f2f4f;
    --bs-emphasis-color-rgb: 63, 47, 79;
    --bs-secondary-color: rgba(63, 79, 47, 0.75);
    --bs-secondary-color-rgb: 63, 79, 47;
    --bs-secondary-bg: #f5b3eb;
    --bs-secondary-bg-rgb: 245, 179, 235;
    --bs-tertiary-color: rgba(222, 226, 230, 0.5);
    --bs-tertiary-color-rgb: 222, 226, 230;
    --bs-tertiary-bg: #b3f5bd;
    --bs-tertiary-bg-rgb: 179, 245, 189;
}

[data-bs-theme="pepper"] {
    color-scheme: pepper;
    --bs-body-color: #2F4F4F;
    --bs-body-color-rgb: 47, 79, 79;
    --bs-body-bg: #cd5c5c;
    --bs-body-bg-rgb: 205, 92, 92;
    --bs-emphasis-color: #fff;
    --bs-emphasis-color-rgb: 255, 255, 255;
    --bs-secondary-color: rgba(222, 226, 230, 0.75);
    --bs-secondary-color-rgb: 222, 226, 230;
    --bs-secondary-bg: #5ccdcd;
    --bs-secondary-bg-rgb: 92, 205, 205;
    --bs-tertiary-color: rgba(222, 226, 230, 0.5);
    --bs-tertiary-color-rgb: 222, 226, 230;
    --bs-tertiary-bg: #8FBC8F;
    --bs-tertiary-bg-rgb: 143, 188, 143;
}

phpunit.xml changes

<coverage
    includeUncoveredFiles="true"
    pathCoverage="false"
    ignoreDeprecatedCodeUnits="true"
    disableCodeCoverageIgnore="true">
    <report>
        <clover outputFile="output/clover.xml" />
        <cobertura outputFile="output/cobertura.xml" />
        <crap4j outputFile="output/crap4j.xml" threshold="50" />
        <html outputDirectory="output/html" lowUpperBound="50" highLowerBound="90" customCssFile="./phpunit-themes.css" />
        <php outputFile="output/coverage.php" />
        <text outputFile="output/coverage.txt" showUncoveredFiles="false" showOnlySummary="true" />
        <xml outputDirectory="output/xml" />
    </report>
</coverage>

Proposed theme variable:

<html outputDirectory="output/html" lowUpperBound="50" highLowerBound="90" customCssFile="./phpunit-themes.css" theme="dark" />

CSS Variables in style.css

I had to slightly adjust the existing CSS rules, such as adding a td to increase override priority from the Bootstrap 5 rules.

See src/Report/Html/Renderer/Template/css/style.css

These new default rules should be compatible across other themes.

Here are few I updated, but did not finalize:

  • The alpha value could be adjusted for the different rules.
.table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
 background-color: {{success-low}};
 /* background-color: rgb(from var(--bs-success) r g b / 0.25); */
}

.table tbody tr.covered-by-medium-tests td, li.covered-by-medium-tests {
 background-color: {{success-medium}};
 /* background-color: rgb(from var(--bs-success) r g b / 0.5); */
}

.table tbody tr.covered-by-small-tests td, li.covered-by-small-tests {
 background-color: {{success-high}};
 /* background-color: rgb(from var(--bs-success) r g b / 0.75); */
}

.table tbody tr.warning td, .table tbody td.warning, li.warning, span.warning {
 background-color: {{warning}};
 /* background-color: rgb(from var(--bs-warning) r g b / 0.25); */
}

.table tbody tr.danger td, .table tbody td.danger, li.danger, span.danger {
 background-color: {{danger}};
 /* background-color: rgb(from var(--bs-danger) r g b / 0.25); */
}

.table tbody td.info {
 /* background-color: #d9edf7; */
 /* background-color: var(--bs-info-bg-subtle); */
 background-color: rgb(from var(--bs-info) r g b / 0.25);
}

Dev Notes

Testing themes

Here is a screenshot of testing the example themes in: phpunit-themes.css

phpunit-code-coverage-with-themes

You can inspect the DOM to manually change

<html lang="en" data-bs-theme="">
<html lang="en" data-bs-theme="dark">
<html lang="en" data-bs-theme="lavender">
<html lang="en" data-bs-theme="wheat">
<html lang="en" data-bs-theme="blue">
<html lang="en" data-bs-theme="light">
  • The theme value would get set via phpunit.xml. Optionally, javascript theme switching can be added to the page, but that might be too crude.

Tech Debt

There are a few other things that are a bit out of date.

NOTE: I think these fixes are beyond the scope of this PR and I would not mind tackling those after this:

  • The d3 library for charts on the dashboard.
  • There are a few HTML tags that have been deprecated, such as align="center".
  • If these changes were made, the git diff would be huge.

gammamatrix avatar May 07 '24 05:05 gammamatrix

Should I create another Pull Request, in PHPUnit, to add a theme variable to phpunit.xsd?

<xs:complexType name="coverageReportHtmlType">
    <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
    <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
    <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
    <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
    <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
    <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
    <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
    <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
    <xs:attribute name="customCssFile" type="xs:string"/>
    <xs:attribute name="theme" type="xs:string" default=""/>
</xs:complexType>

The colors for low, medium, high, warning, and danger can be controlled by setting the CSS Variables:

.table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
  background-color: {{success-low}};
  /* background-color: rgb(from var(--bs-success) r g b / 0.25); */
}
Variable CSS
colorSuccessLow rgb(from var(--bs-success) r g b / 0.25)
colorSuccessMedium rgb(from var(--bs-success) r g b / 0.5)
colorSuccessHigh rgb(from var(--bs-success) r g b / 0.75)
colorWarning rgb(from var(--bs-warning) r g b / 0.25)
colorDanger rgb(from var(--bs-danger) r g b / 0.25)
  • Using these rules make it safe between switching themes and the colors will match the Bootstrap Progress Bar and Popovers.

The Bootstrap CSS Variables may be overridden in a theme defined with the existing:

customCssFile="./phpunit-themes.css"

NOTE: The CSS rules defined in style.css may still be overridden in customCssFile.

.table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
  background-color: var(--bs-teal);
}

I tested passing both overriding with the customCssFile and in overriding the colors with CSS variables in the phpunit.xml configuration as well and both work fine.

  • The custom rules in customCssFile may override the colors defined phpunit.xml.
colors
<html
    outputDirectory="output/html"
    lowUpperBound="50"
    highLowerBound="90"
    customCssFile="./phpunit-themes.css"
    colorSuccessLow="rgb(from var(--bs-purple) r g b / 0.75)"
    colorSuccessMedium="rgb(from var(--bs-blue) r g b / 0.55)"
    colorSuccessHigh="rgb(from var(--bs-teal) r g b / 0.25)"
    colorWarning="rgb(from var(--bs-warning) r g b / 0.25)"
    colorDanger="rgb(from var(--bs-danger) r g b / 0.25)"
    theme="dark" />
And with these custom CSS rules:
.table tbody tr.covered-by-medium-tests td, li.covered-by-medium-tests {
    background-color: purple;
}

.table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
    background-color: aquamarine;
}

.table tbody tr.danger td, .table tbody td.danger, li.danger, span.danger {
    background-color: wheat;
}


.table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
    background-color: aquamarine;
}

.table tbody tr.covered-by-medium-tests td, li.covered-by-medium-tests {
    background-color: purple;
}

.table tbody tr.covered-by-small-tests td, li.covered-by-small-tests {
    background-color: var(--bs-teal);
}

.table tbody tr.warning td, .table tbody td.warning, li.warning, span.warning {
    background-color: var(--bs-yellow);
}

.table tbody tr.danger td, .table tbody td.danger, li.danger, span.danger {
    background-color: crimson;
}

.covered-by-small-tests, tr.covered-by-small-tests td {
    background-color: var(--bs-teal);
}

.covered-by-medium-tests, tr.covered-by-medium-tests td {
    background-color: purple;
}

.covered-by-large-tests, tr.covered-by-large-tests td {
    background-color: aquamarine;
}

.not-covered, tr.not-covered td {
    background-color: crimson;
}

.not-coverable, tr.not-coverable td {
    background-color: var(--bs-yellow);
}

gammamatrix avatar May 07 '24 22:05 gammamatrix

I wonder whether we need this new theme configuration, or whether it would be enough to use coverageHtmlCustomCssFile to define custom css-variable values and reduce the PR to just adding css-variables?

staabm avatar May 08 '24 07:05 staabm

I wonder whether we need this new theme configuration, or whether it would be enough to use coverageHtmlCustomCssFile to define custom css-variable values and reduce the PR to just adding css-variables?

The main reason why the theme configuration is required is so you can select the dark theme, which is provided in Bootstrap 5.

<html
    outputDirectory="output/html"
    lowUpperBound="50"
    highLowerBound="90"
    theme="dark" />
  • Just adding theme="dark" would enable dark mode.

I added some more information on the changes needed for the phpunit.xsd in https://github.com/sebastianbergmann/phpunit/pull/5833

gammamatrix avatar May 08 '24 14:05 gammamatrix

Please split this into two pull requests: one for the Bootstrap update and one for the functional changes.

sebastianbergmann avatar May 11 '24 08:05 sebastianbergmann

Please split this into two pull requests: one for the Bootstrap update and one for the functional changes.

Here are the Bootstrap-only changes, for src and tests:

  • https://github.com/sebastianbergmann/php-code-coverage/pull/1037

FYI:

  1. The only code I changed, besides removing the theme feature, was lightening up the alpha filtering to match the previous colors:
final class Colors
{
    private readonly string $successLow;
    private readonly string $successMedium;
    private readonly string $successHigh;
    private readonly string $warning;
    private readonly string $danger;

    public static function default(): self
    {
        return new self(
            'rgb(from var(--bs-success) r g b / 0.1)',
            'rgb(from var(--bs-success) r g b / 0.33)',
            'rgb(from var(--bs-success) r g b / 0.67)',
            'rgb(from var(--bs-warning) r g b / 0.1)',
            'rgb(from var(--bs-danger) r g b / 0.1)',
        );
    }
  • low was 0.25 and is now 0.1
  • medium was 0.5 and is now 0.33
  • high was 0.75 and is now 0.67
  • warning was 0.25 and is now 0.1
  • danger was 0.25 and is now 0.1
  1. You can still test dark mode on generated code coverage by editing the HTML tag:
<html lang="en" data-bs-theme="dark">

gammamatrix avatar May 12 '24 01:05 gammamatrix

FYI: I just tried running the tests, my installation is on PHPUnit 11.3.0 and I did not see the whitespace error.

  • I did confirm the test testPathCoverageForBankAccountTest ran with team city. I will test it a bit more to make sure I am actually testing what I am expecting.
➜  php-code-coverage git:(main) vendor/bin/phpunit --coverage-text
PHPUnit 11.3.0 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.10 with Xdebug 3.3.1
Configuration: playground-directory/vendor/phpunit/php-code-coverage/phpunit.xml

SSSSSSSSSSSSSSSSSSS............................................  63 / 122 ( 51%)
...........................................................     122 / 122 (100%)

Time: 00:02.056, Memory: 20.00 MB

OK, but some tests were skipped!
Tests: 122, Assertions: 333, Skipped: 19.


Code Coverage Report:
  2024-08-09 05:57:18

 Summary:
  Classes: 21.74% (15/69)
  Methods: 61.45% (263/428)
  Lines:   85.06% (3222/3788)

gammamatrix avatar Aug 09 '24 06:08 gammamatrix

My last test (https://github.com/sebastianbergmann/php-code-coverage/pull/1037#issuecomment-2250124852) was with the other PR (#1037). Can you please test with that, too? Thanks!

sebastianbergmann avatar Aug 09 '24 06:08 sebastianbergmann

@sebastianbergmann Should we close this PR?

  • I would still be willing to add an option to enable themes to add dark mode: https://github.com/sebastianbergmann/phpunit/pull/5833
  • If you do not want to add the full themes, we could at least add a boolean toggle for dark mode?

gammamatrix avatar Oct 19 '25 02:10 gammamatrix

Support for light/dark mode was implemented in #1095.

sebastianbergmann avatar Oct 19 '25 04:10 sebastianbergmann