Skip to content

Commit b762082

Browse files
committed
Add colorizer stats
1 parent c1db66f commit b762082

File tree

4 files changed

+156
-41
lines changed

4 files changed

+156
-41
lines changed

src/PHPUnit/Cobertura/Formatter/Application.php

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,33 @@
1212
namespace AndreyTech\PHPUnit\Cobertura\Formatter;
1313

1414
use AndreyTech\PHPUnit\Cobertura\Formatter\Config\CommandLine;
15-
use AndreyTech\PHPUnit\Cobertura\Formatter\Config\File as ConfigFile;
1615
use AndreyTech\PHPUnit\Cobertura\Formatter\Config\File\Creator;
17-
use AndreyTech\PHPUnit\Cobertura\Formatter\Parser\File as CoberturaFile;
18-
use AndreyTech\PHPUnit\Cobertura\Formatter\Renderer\Colorizer;
1916
use Exception;
2017
use Symfony\Component\Console\Output\ConsoleOutput;
2118
use Throwable;
22-
use AndreyTech\PHPUnit\Cobertura\Formatter\Parser\Filter\ClassName as ClassNameFilter;
2319

2420
use function sprintf;
2521

2622
final class Application
2723
{
2824
private const int EXIT_CODE_OK = 0;
2925
private const int EXIT_CODE_ERROR = 1;
26+
private const int EXIT_CODE_RED_METRICS = 2;
27+
private const int EXIT_CODE_YELLOW_METRICS = 3;
3028

3129
private ConsoleOutput $consoleOutput;
3230
private CommandLine $commandLine;
31+
private Processor $processor;
3332
private Stats $stats;
3433

3534
public function __construct()
3635
{
3736
$this->consoleOutput = new ConsoleOutput();
3837
$this->commandLine = new CommandLine();
38+
$this->processor = new Processor(
39+
$this->consoleOutput,
40+
$this->commandLine
41+
);
3942
$this->stats = new Stats();
4043
}
4144

@@ -53,7 +56,7 @@ public function run(): int
5356
}
5457

5558
$this->stats->finish();
56-
$this->showStats($exitCode);
59+
$this->printStats($exitCode);
5760

5861
return $exitCode;
5962
}
@@ -73,51 +76,27 @@ private function doRun(): int
7376
return self::EXIT_CODE_OK;
7477
}
7578

76-
$this->parseAndRender();
79+
$this->processor->process();
7780

78-
return self::EXIT_CODE_OK;
81+
return $this->calculateExitCode();
7982
}
8083

81-
/**
82-
* @throws Exception
83-
*/
84-
private function parseAndRender(): void
84+
private function calculateExitCode(): int
8585
{
86-
(new Renderer(
87-
$this->consoleOutput,
88-
new Colorizer(
89-
new ConfigFile(
90-
$this->commandLine->optionConfigFile()
91-
)
92-
)
93-
))->render(
94-
(new ClassNameFilter(
95-
$this->commandLine->optionFilterClassName()
96-
))->filter(
97-
(new Parser())->parse(
98-
new CoberturaFile(
99-
$this->commandLine->coberturaFile()
100-
)
101-
)
102-
)
103-
);
104-
}
86+
if ($this->processor->colorizerStats->isRed()) {
87+
return self::EXIT_CODE_RED_METRICS;
88+
}
10589

106-
private function message(string $message): void
107-
{
108-
$this->consoleOutput->writeln($message);
109-
}
90+
if ($this->processor->colorizerStats->isYellow()) {
91+
return self::EXIT_CODE_YELLOW_METRICS;
92+
}
11093

111-
private function error(string $message): void
112-
{
113-
$this->consoleOutput->writeln(
114-
sprintf('<fg=red;options=bold>%s</>', $message)
115-
);
94+
return self::EXIT_CODE_OK;
11695
}
11796

118-
private function showStats(int $exitCode): void
97+
private function printStats(int $exitCode): void
11998
{
120-
$this->message(
99+
$this->consoleOutput->writeln(
121100
sprintf(
122101
'Exit code: %s, Time: %s, Memory: %s.',
123102
$exitCode,
@@ -126,4 +105,11 @@ private function showStats(int $exitCode): void
126105
)
127106
);
128107
}
108+
109+
private function error(string $message): void
110+
{
111+
$this->consoleOutput->writeln(
112+
sprintf('<fg=red;options=bold>%s</>', $message)
113+
);
114+
}
129115
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/**
4+
* @author andrey-tech
5+
* @copyright 2025 andrey-tech
6+
* @link https://github.com/andrey-tech/
7+
* @license MIT
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace AndreyTech\PHPUnit\Cobertura\Formatter;
13+
14+
use AndreyTech\PHPUnit\Cobertura\Formatter\Config\CommandLine;
15+
use AndreyTech\PHPUnit\Cobertura\Formatter\Config\File as ConfigFile;
16+
use AndreyTech\PHPUnit\Cobertura\Formatter\Parser\File as CoberturaFile;
17+
use AndreyTech\PHPUnit\Cobertura\Formatter\Parser\Filter\ClassName as ClassNameFilter;
18+
use AndreyTech\PHPUnit\Cobertura\Formatter\Renderer\Colorizer;
19+
use AndreyTech\PHPUnit\Cobertura\Formatter\Renderer\Colorizer\Stats as ColorizerStats;
20+
use Exception;
21+
use Symfony\Component\Console\Output\ConsoleOutput;
22+
23+
final readonly class Processor
24+
{
25+
public ColorizerStats $colorizerStats;
26+
27+
public function __construct(
28+
private ConsoleOutput $consoleOutput,
29+
private CommandLine $commandLine
30+
) {
31+
$this->colorizerStats = new ColorizerStats();
32+
}
33+
34+
/**
35+
* @throws Exception
36+
*/
37+
public function process(): void
38+
{
39+
(new Renderer(
40+
$this->consoleOutput,
41+
new Colorizer(
42+
$this->colorizerStats,
43+
new ConfigFile(
44+
$this->commandLine->optionConfigFile()
45+
)
46+
)
47+
))->render(
48+
(new ClassNameFilter(
49+
$this->commandLine->optionFilterClassName()
50+
))->filter(
51+
(new Parser())->parse(
52+
new CoberturaFile(
53+
$this->commandLine->coberturaFile()
54+
)
55+
)
56+
)
57+
);
58+
}
59+
}

src/PHPUnit/Cobertura/Formatter/Renderer/Colorizer.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use AndreyTech\PHPUnit\Cobertura\Formatter\Config\File as Config;
1515
use AndreyTech\PHPUnit\Cobertura\Formatter\Parser\ClassMetrics;
1616
use AndreyTech\PHPUnit\Cobertura\Formatter\Parser\MethodMetrics;
17+
use AndreyTech\PHPUnit\Cobertura\Formatter\Renderer\Colorizer\Stats;
1718

1819
use function array_shift;
1920
use function explode;
@@ -25,6 +26,7 @@
2526
final readonly class Colorizer
2627
{
2728
public function __construct(
29+
private Stats $stats,
2830
private Config $config
2931
) {
3032
}
@@ -129,6 +131,8 @@ private function colorize(int|float $value, ?array $ranges, string $format): str
129131

130132
private function renderTemplate(int|float $value, string $decor, string $format): string
131133
{
134+
$this->stats->update($decor);
135+
132136
$decorElements = explode('+', $decor);
133137
$tags = [sprintf('fg=%s', array_shift($decorElements))];
134138

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
/**
4+
* @author andrey-tech
5+
* @copyright 2025 andrey-tech
6+
* @link https://github.com/andrey-tech/
7+
* @license MIT
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace AndreyTech\PHPUnit\Cobertura\Formatter\Renderer\Colorizer;
13+
14+
use function str_contains;
15+
16+
final class Stats
17+
{
18+
private const string TAG_RED = 'red';
19+
private const string TAG_YELLOW = 'yellow';
20+
21+
/**
22+
* @var array<string, int>
23+
*/
24+
private array $tagCounts = [];
25+
26+
public function update(string $tag): void
27+
{
28+
if (!isset($this->tagCounts[$tag])) {
29+
$this->tagCounts[$tag] = 0;
30+
}
31+
32+
$this->tagCounts[$tag]++;
33+
}
34+
35+
public function isRed(): bool
36+
{
37+
return (bool) $this->redCount();
38+
}
39+
40+
public function isYellow(): bool
41+
{
42+
return (bool) $this->yellowCount();
43+
}
44+
45+
private function redCount(): int
46+
{
47+
return $this->tagCount(self::TAG_RED);
48+
}
49+
50+
private function yellowCount(): int
51+
{
52+
return $this->tagCount(self::TAG_YELLOW);
53+
}
54+
55+
private function tagCount(string $tag): int
56+
{
57+
$count = 0;
58+
foreach ($this->tagCounts as $key => $value) {
59+
if (str_contains($key, $tag)) {
60+
$count += $value;
61+
}
62+
}
63+
64+
return $count;
65+
}
66+
}

0 commit comments

Comments
 (0)