MarkdownReporter::writeResultHeader()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
/**
4
 * This file is part of cloak.
5
 *
6
 * (c) Noritaka Horio <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace cloak\reporter;
13
14
use cloak\AnalyzedCoverageResult;
15
use cloak\result\FileResult;
16
use cloak\writer\FileWriter;
17
use cloak\event\InitializeEvent;
18
use cloak\event\AnalyzeStartEvent;
19
use cloak\event\AnalyzeStopEvent;
20
use cloak\event\FinalizeEvent;
21
use cloak\result\CoverageResultNodeCollection;
22
use cloak\value\CoverageBounds;
23
use PHPExtra\EventManager\EventManager;
24
25
26
/**
27
 * Class MarkdownReporter
28
 * @package cloak\reporter
29
 */
30
class MarkdownReporter
31
    implements Reporter, InitializeEventListener, FinalizeEventListener, AnalyzeStartEventListener, AnalyzeStopEventListener
32
{
33
34
35
    const TABLE_SEPARATOR_CHAR = '|';
36
37
    const ALIGN_LEFT = ':--';
38
    const ALIGN_RIGTH = '--:';
39
40
    private $columnHeaders = [
41
        ' No. ',
42
        ' File ',
43
        ' Line ',
44
        ' Coverage '
45
    ];
46
47
    private $columnHeaderAlignments = [
48
        self::ALIGN_RIGTH,
49
        self::ALIGN_LEFT,
50
        self::ALIGN_RIGTH,
51
        self::ALIGN_RIGTH
52
    ];
53
54
    /**
55
     * @var string Report file name
56
     */
57
    private $fileName;
58
59
    /**
60
     * @var CoverageBounds
61
     */
62
    private $bounds;
63
64
    /**
65
     * @var \cloak\writer\FileWriter
66
     */
67
    private $reportWriter;
68
69
    /**
70
     * @var \DateTimeImmutable
71
     */
72
    private $generatedAt;
73
74
75
    /**
76
     * @param string $fileName
77
     */
78
    public function __construct ($fileName)
79
    {
80
        $this->fileName = $fileName;
81
    }
82
83
    /**
84
     * @param \cloak\event\InitializeEvent $event
85
     */
86 View Code Duplication
    public function onInitialize(InitializeEvent $event)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
    {
88
        $this->bounds = $event->getCoverageBounds();
89
90
        $reportDirectory = $event->getReportDirectory();
91
        $reportFile = $reportDirectory->join($this->fileName);
92
93
        $this->reportWriter = new FileWriter( $reportFile->stringify() );
94
    }
95
96
    /**
97
     * @param AnalyzeStartEvent $event
98
     */
99
    public function onAnalyzeStart(AnalyzeStartEvent $event)
100
    {
101
        $this->generatedAt = $event->getSendAt();
102
    }
103
104
    /**
105
     * @param AnalyzeStopEvent $event
106
     */
107
    public function onAnalyzeStop(AnalyzeStopEvent $event)
108
    {
109
        $this->writeMarkdownReport($event->getResult());
110
    }
111
112
    /**
113
     * @param FinalizeEvent $event
114
     */
115
    public function onFinalize(FinalizeEvent $event)
116
    {
117
        $this->reportWriter = null;
118
    }
119
120
    /**
121
     * @param AnalyzedCoverageResult $result
122
     */
123
    private function writeMarkdownReport(AnalyzedCoverageResult $result)
124
    {
125
        $this->writeTitle();
126
        $this->writeDescription();
127
        $this->writeResult($result);
128
    }
129
130
    private function writeTitle()
131
    {
132
        $this->reportWriter->writeLine('# Code Coverage Report');
133
        $this->reportWriter->writeEOL();
134
    }
135
136
    private function writeDescription()
137
    {
138
        $generatedDateTime = $this->generatedAt->format('j F Y \a\t H:i');
139
140
        $this->reportWriter->writeLine('Generator: cloak  ');
141
        $this->reportWriter->writeLine("Generated at: $generatedDateTime  ");
142
        $this->reportWriter->writeEOL();
143
    }
144
145
    /**
146
     * @param AnalyzedCoverageResult $result
147
     */
148
    private function writeResult(AnalyzedCoverageResult $result)
149
    {
150
        $files = $result->getFiles();
151
152
        $criticalValue = $this->bounds->getCriticalCoverage();
153
        $criticalResults = $files->selectByCoverageLessThan($criticalValue);
154
155
        $satisfactoryValue = $this->bounds->getSatisfactoryCoverage();
156
        $satisfactoryResults = $files->selectByCoverageGreaterEqual($satisfactoryValue);
157
158
        $warningResults = $files->exclude($criticalResults)
159
            ->exclude($satisfactoryResults);
160
161
        $this->writeGroup('Critical', $criticalResults);
162
        $this->writeGroup('Warning', $warningResults);
163
        $this->writeGroup('Satisfactory', $satisfactoryResults);
164
    }
165
166
    /**
167
     * @param string $title
168
     * @param CoverageResultNodeCollection $files
169
     */
170
    private function writeGroup($title, CoverageResultNodeCollection $files)
171
    {
172
        $this->writeResultHeader($title);
173
        $this->writeFilesResultHeader();
174
        $this->writeFileResults($files);
175
    }
176
177
    /**
178
     * @param string $title
179
     */
180
    private function writeResultHeader($title)
181
    {
182
        $this->reportWriter->writeLine('## ' . $title);
183
        $this->reportWriter->writeEOL();
184
    }
185
186
    private function writeFilesResultHeader()
187
    {
188
        $record = $this->toTableRow($this->columnHeaders);
189
        $this->reportWriter->writeLine($record);
190
191
        $record = $this->toTableRow($this->columnHeaderAlignments);
192
        $this->reportWriter->writeLine($record);
193
    }
194
195
    /**
196
     * @param CoverageResultNodeCollection $files
197
     */
198
    private function writeFileResults(CoverageResultNodeCollection $files)
199
    {
200
        $orderNumber = 1;
201
202
        foreach ($files as $key => $file) {
203
            $this->writeFileResult($orderNumber, $file);
204
            $orderNumber++;
205
        }
206
207
        $this->reportWriter->writeEOL();
208
    }
209
210
    /**
211
     * @param int $orderNumber
212
     * @param FileResult $file
213
     */
214
    private function writeFileResult($orderNumber, FileResult $file)
215
    {
216
217
        $lineResult = sprintf("%2d/%2d",
218
            $file->getExecutedLineCount(),
219
            $file->getExecutableLineCount()
220
        );
221
222
        $coverageResult = sprintf('%6.2f%%', $file->getCodeCoverage()->value());
223
224
        $parts = [
225
            $orderNumber,
226
            $file->getRelativePath(getcwd()),
227
            $lineResult,
228
            $coverageResult
229
        ];
230
231
        $record = $this->toTableRow($parts);
232
        $this->reportWriter->writeLine($record);
233
    }
234
235
    /**
236
     * @param array $values
237
     * @return string
238
     */
239
    private function toTableRow(array $values)
240
    {
241
        $record = implode(static::TABLE_SEPARATOR_CHAR, $values);
242
        $record = static::TABLE_SEPARATOR_CHAR . $record . static::TABLE_SEPARATOR_CHAR;
243
244
        return $record;
245
    }
246
247
    /**
248
     * @param EventManager $eventManager
249
     */
250
    public function registerTo(EventManager $eventManager)
251
    {
252
        $eventManager->add($this);
253
    }
254
255
}
256