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 * @license GPL-3.0-or-later
5 */
6
7namespace Wikimedia\CloverDiff;
8
9use Symfony\Component\Console\Helper\Table;
10use Symfony\Component\Console\Output\OutputInterface;
11
12/**
13 * Print the result of a diff in a
14 * cool table
15 */
16class DiffPrinter {
17
18    /**
19     * @var OutputInterface
20     */
21    private OutputInterface $output;
22
23    /**
24     * @param OutputInterface $output stdout
25     */
26    public function __construct( OutputInterface $output ) {
27        $this->output = $output;
28    }
29
30    /**
31     * Fancy coloring and padding for numbers
32     *
33     * @param float $num
34     *
35     * @return string
36     */
37    private function format( float $num ): string {
38        if ( $num < 50 ) {
39            $color = 'error';
40        } elseif ( $num > 90 ) {
41            $color = 'info';
42        } else {
43            $color = 'comment';
44        }
45        // Pad leading 0s
46        $pad = str_pad(
47            number_format( $num, 2 ),
48            5,
49            '0',
50            STR_PAD_LEFT
51        );
52        // Pad leading space to line up with 100%,
53        // and pick a color!
54        return "<$color>" . str_pad(
55            $pad,
56            6,
57            ' ',
58            STR_PAD_LEFT
59        ) . "</$color>";
60    }
61
62    /**
63     * @param Diff $diff Diff to print
64     *
65     * @return bool Whether any file had lower coverage afterwards
66     */
67    public function show( Diff $diff ): bool {
68        $tableRows = [];
69        foreach ( $diff->getMissingFromNew() as $fname => $val ) {
70            $tableRows[] = [
71                $fname,
72                $this->format( $val ),
73                0,
74            ];
75        }
76
77        foreach ( $diff->getMissingFromOld() as $fname => $val ) {
78            $tableRows[] = [
79                $fname,
80                0,
81                $this->format( $val ),
82            ];
83        }
84
85        $lowered = false;
86        foreach ( $diff->getChanged() as $fname => $info ) {
87            [ $old, $new ] = $info;
88            $tableRows[] = [
89                $fname,
90                $this->format( $old ),
91                $this->format( $new ),
92            ];
93
94            // Fail if any file has less coverage.
95            if ( $new < $old ) {
96                $lowered = true;
97            }
98        }
99
100        if ( $tableRows ) {
101            // Sort all files in order!
102            usort( $tableRows, static function ( $a, $b ) {
103                return strcmp( $a[0], $b[0] );
104            } );
105
106            $table = new Table( $this->output );
107            $table->setHeaders( [
108                'Filename', 'Old %', 'New %'
109            ] )->setRows( $tableRows )->render();
110        } else {
111            $this->output->writeln(
112                '<info>No coverage changes found.</info>'
113            );
114        }
115
116        return $lowered;
117    }
118}