Completed
Pull Request — master (#403)
by
unknown
01:49
created

Reporter::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Hal\Report\Cli;
3
4
use Hal\Application\Config\Config;
5
use Hal\Component\Output\Output;
6
use Hal\Metric\Consolidated;
7
use Hal\Metric\Metric;
8
use Hal\Metric\Metrics;
9
use Hal\Report\ReporterInterface;
10
11
/**
12
 * This class takes care about the global output into the STDOUT of consolidated metrics.
13
 */
14
class Reporter implements ReporterInterface
15
{
16
    /** @var Config */
17
    private $config;
18
19
    /** @var Output */
20
    private $output;
21
22
    /**
23
     * @param Config $config
24
     * @param Output $output
25
     */
26
    public function __construct(Config $config, Output $output)
27
    {
28
        $this->config = $config;
29
        $this->output = $output;
30
    }
31
32
    /**
33
     * {@inheritDoc}
34
     */
35
    public function generate(Metrics $metrics)
36
    {
37
        if ($this->config->has('quiet')) {
38
            return;
39
        }
40
41
        $consolidated = new Consolidated($metrics);
42
        $out = $this->reportConsolidated($metrics, $consolidated);
43
44
        if ($this->config->has('git')) {
45
            $out .= $this->reportGitUsages($consolidated);
46
        }
47
48
        if ($this->config->has('junit')) {
49
            $out .= $this->reportUnitTesting($metrics->get('unitTesting'));
0 ignored issues
show
Bug introduced by
It seems like $metrics->get('unitTesting') can be null; however, reportUnitTesting() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
50
        }
51
52
        $this->output->write($out . "\n");
53
    }
54
55
    /**
56
     * @param Metrics $metrics
57
     * @param Consolidated $consolidated
58
     * @return string
59
     */
60
    private function reportConsolidated(Metrics $metrics, Consolidated $consolidated)
61
    {
62
        $sum = $consolidated->getSum();
63
        $avg = $consolidated->getAvg();
64
65
        $methodsByClass = $locByClass = $locByMethod = 0;
66
        if ($sum->nbClasses > 0) {
67
            $methodsByClass = round($sum->nbMethods / $sum->nbClasses, 2);
68
            $locByClass = round($sum->lloc / $sum->nbClasses);
69
        }
70
        if ($sum->nbMethods > 0) {
71
            $locByMethod = round($sum->lloc / $sum->nbMethods);
72
        }
73
74
        $inheritanceTreeDepthReport = '';
75
        $treeMetric = $metrics->get('tree');
76
        if (null !== $treeMetric) {
77
            $inheritanceTreeDepthReport = <<<EOT
78
    Depth of Inheritance Tree                   {$treeMetric->get('depthOfInheritanceTree')}
79
80
EOT;
81
        }
82
83
        return <<<EOT
84
LOC
85
    Lines of code                               {$sum->loc}
86
    Logical lines of code                       {$sum->lloc}
87
    Comment lines of code                       {$sum->cloc}
88
    Average volume                              {$avg->volume}
89
    Average comment weight                      {$avg->commentWeight}
90
    Average intelligent content                 {$avg->commentWeight}
91
    Logical lines of code by class              {$locByClass}
92
    Logical lines of code by method             {$locByMethod}
93
94
Object oriented programming
95
    Classes                                     {$sum->nbClasses}
96
    Interface                                   {$sum->nbInterfaces}
97
    Methods                                     {$sum->nbMethods}
98
    Methods by class                            {$methodsByClass}
99
    Lack of cohesion of methods                 {$avg->lcom}
100
101
Coupling
102
    Average afferent coupling                   {$avg->afferentCoupling}
103
    Average efferent coupling                   {$avg->efferentCoupling}
104
    Average instability                         {$avg->instability}
105
{$inheritanceTreeDepthReport}
106
Package
107
    Packages                                    {$sum->nbPackages}
108
    Average classes per package                 {$avg->classesPerPackage}
109
    Average distance                            {$avg->distance}
110
    Average incoming class dependencies         {$avg->incomingCDep}
111
    Average outgoing class dependencies         {$avg->outgoingCDep}
112
    Average incoming package dependencies       {$avg->incomingPDep}
113
    Average outgoing package dependencies       {$avg->outgoingPDep}
114
115
Complexity
116
    Average Cyclomatic complexity by class      {$avg->ccn}
117
    Average Weighted method count by class      {$avg->wmc}
118
    Average Relative system complexity          {$avg->relativeSystemComplexity}
119
    Average Difficulty                          {$avg->difficulty}
120
121
Bugs
122
    Average bugs by class                       {$avg->bugs}
123
    Average defects by class (Kan)              {$avg->kanDefect}
124
125
Violations
126
    Critical                                    {$sum->violations->critical}
127
    Error                                       {$sum->violations->error}
128
    Warning                                     {$sum->violations->warning}
129
    Information                                 {$sum->violations->information}
130
131
EOT;
132
    }
133
134
    /**
135
     * Returns the CLI output block dedicated to Git stats.
136
     * @param Consolidated $consolidated
137
     * @return string
138
     */
139
    private function reportGitUsages(Consolidated $consolidated)
140
    {
141
        $out = '';
142
        $commits = [];
143
        foreach ($consolidated->getFiles() as $name => $file) {
144
            $commits[$name] = $file['gitChanges'];
145
        }
146
        arsort($commits);
147
        $commits = array_slice($commits, 0, 10);
148
149
        $out .= "\nTop 10 committed files";
150
        foreach ($commits as $file => $nb) {
151
            $out .= sprintf("\n    %d    %s", $nb, $file);
152
        }
153
        if ([] === $commits) {
154
            $out .= "\n    NA";
155
        }
156
        $out .= "\n";
157
158
        return $out;
159
    }
160
161
    /**
162
     * Returns the CLI output block dedicated to Unit Testing stats.
163
     * @param Metric $unitTestingMetric
164
     * @return string
165
     */
166
    private function reportUnitTesting(Metric $unitTestingMetric)
167
    {
168
        return <<<EOT
169
170
Unit testing
171
    Number of unit tests                        {$unitTestingMetric->get('nbSuites')}
172
    Classes called by tests                     {$unitTestingMetric->get('nbCoveredClasses')}
173
    Classes called by tests (percent)           {$unitTestingMetric->get('percentCoveredClasses')} %
174
175
EOT;
176
    }
177
}
178