Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.91% covered (warning)
84.91%
45 / 53
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
DiffPrinter
84.91% covered (warning)
84.91%
45 / 53
66.67% covered (warning)
66.67%
2 / 3
10.34
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 format
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
3
 show
77.14% covered (warning)
77.14%
27 / 35
0.00% covered (danger)
0.00%
0 / 1
6.43
1<?php
2/**
3 * Copyright (C) 2018 Kunal Mehta <legoktm@debian.org>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19namespace Wikimedia\CloverDiff;
20
21use Symfony\Component\Console\Helper\Table;
22use Symfony\Component\Console\Output\OutputInterface;
23
24/**
25 * Print the result of a diff in a
26 * cool table
27 */
28class DiffPrinter {
29
30    /**
31     * @var OutputInterface
32     */
33    private OutputInterface $output;
34
35    /**
36     * @param OutputInterface $output stdout
37     */
38    public function __construct( OutputInterface $output ) {
39        $this->output = $output;
40    }
41
42    /**
43     * Fancy coloring and padding for numbers
44     *
45     * @param float $num
46     *
47     * @return string
48     */
49    private function format( float $num ): string {
50        if ( $num < 50 ) {
51            $color = 'error';
52        } elseif ( $num > 90 ) {
53            $color = 'info';
54        } else {
55            $color = 'comment';
56        }
57        // Pad leading 0s
58        $pad = str_pad(
59            number_format( $num, 2 ),
60            5,
61            '0',
62            STR_PAD_LEFT
63        );
64        // Pad leading space to line up with 100%,
65        // and pick a color!
66        return "<$color>" . str_pad(
67            $pad,
68            6,
69            ' ',
70            STR_PAD_LEFT
71        ) . "</$color>";
72    }
73
74    /**
75     * @param Diff $diff Diff to print
76     *
77     * @return bool Whether any file had lower coverage afterwards
78     */
79    public function show( Diff $diff ): bool {
80        $tableRows = [];
81        foreach ( $diff->getMissingFromNew() as $fname => $val ) {
82            $tableRows[] = [
83                $fname,
84                $this->format( $val ),
85                0,
86            ];
87        }
88
89        foreach ( $diff->getMissingFromOld() as $fname => $val ) {
90            $tableRows[] = [
91                $fname,
92                0,
93                $this->format( $val ),
94            ];
95        }
96
97        $lowered = false;
98        foreach ( $diff->getChanged() as $fname => $info ) {
99            [ $old, $new ] = $info;
100            $tableRows[] = [
101                $fname,
102                $this->format( $old ),
103                $this->format( $new ),
104            ];
105
106            // Fail if any file has less coverage.
107            if ( $new < $old ) {
108                $lowered = true;
109            }
110        }
111
112        if ( $tableRows ) {
113            // Sort all files in order!
114            usort( $tableRows, static function ( $a, $b ) {
115                return strcmp( $a[0], $b[0] );
116            } );
117
118            $table = new Table( $this->output );
119            $table->setHeaders( [
120                'Filename', 'Old %', 'New %'
121            ] )->setRows( $tableRows )->render();
122        } else {
123            $this->output->writeln(
124                '<info>No coverage changes found.</info>'
125            );
126        }
127
128        return $lowered;
129    }
130}