Skip to content

Commit 7e9db14

Browse files
Merge pull request #5 from DeGraciaMathieu/feat/add-render-module
feat : added render module
2 parents 46f86ad + 0cedcb0 commit 7e9db14

File tree

12 files changed

+203
-35
lines changed

12 files changed

+203
-35
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ php smelly-code-detector inspect-method {path}
6565
| --protected | Show only protected methods.|
6666
| --without-constructor | Hide constructors.|
6767
| --sort-by=smell | Sort order (smell, loc, arg, ccl), default smell.|
68+
| --json | Render metrics in JSON|
6869

6970

7071
## Examples
@@ -151,7 +152,7 @@ php smelly-code-detector inspect-class {path}
151152
| --protected | Show only protected methods.|
152153
| --without-constructor | Hide constructors.|
153154
| --sort-by=smell | Sort order (count, smell, avg), default smell.|
154-
155+
| --json | Render metrics in JSON|
155156

156157
## Examples
157158

app/Commands/InspectClassCommand.php

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
};
1515

1616
use App\Modules\Render\ {
17+
RendererFactory,
1718
RenderService,
1819
Pipes\SortRows,
1920
Pipes\CutRows,
21+
Dtos\Option,
2022
};
2123

2224
class InspectClassCommand extends Command
@@ -38,7 +40,9 @@ class InspectClassCommand extends Command
3840
{--private : Show only private methods.}
3941
{--protected : Show only protected methods.}
4042
{--without-constructor : Hide constructors.}
41-
{--sort-by=smell : Sort order (count, smell, avg).}';
43+
{--sort-by=smell : Sort order (count, smell, avg).}
44+
{--json : Render metrics in JSON.}
45+
';
4246

4347
/**
4448
* The description of the command.
@@ -49,7 +53,7 @@ class InspectClassCommand extends Command
4953

5054
public function handle(): void
5155
{
52-
$this->info('❀ PHP Smelly Code Detector ❀');
56+
$this->hello();
5357

5458
$files = $this->getAllFiles();
5559

@@ -59,10 +63,7 @@ public function handle(): void
5963

6064
$rows = $this->prepareMetricsToBeDisplayed($metrics);
6165

62-
$this->display([
63-
'displayableRows' => $rows,
64-
'numberOfRows' => count($metrics),
65-
]);
66+
$this->display($rows, $metrics);
6667
}
6768

6869
private function analysisMetricsBag(array $analysis): array
@@ -114,11 +115,16 @@ private function prepareMetricsToBeDisplayed(array $metrics): array
114115
);
115116
}
116117

117-
private function makeHtml(array $attributes): ViewContract
118+
private function display(array $rows, array $metrics): void
118119
{
119-
return View::make('inspect-class', [
120-
'displayableRows' => $attributes['displayableRows'],
121-
'numberOfRows' => $attributes['numberOfRows'],
122-
]);
120+
$renderer = $this->makeRendererInstance();
121+
122+
$renderer->display(
123+
view: 'inspect-class',
124+
attributes: [
125+
'displayableRows' => $rows,
126+
'numberOfRows' => count($metrics),
127+
],
128+
);
123129
}
124130
}

app/Commands/InspectMethodCommand.php

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ class InspectMethodCommand extends Command
3939
{--private : Show only private methods.}
4040
{--protected : Show only protected methods.}
4141
{--without-constructor : Hide constructors.}
42-
{--sort-by=smell : Sort order (smell, loc, arg, ccl).}';
42+
{--sort-by=smell : Sort order (smell, loc, arg, ccl).}
43+
{--json : Render metrics in JSON.}
44+
';
4345

4446
/**
4547
* The description of the command.
@@ -53,7 +55,7 @@ class InspectMethodCommand extends Command
5355
*/
5456
public function handle(): void
5557
{
56-
$this->info('❀ PHP Smelly Code Detector ❀');
58+
$this->hello();
5759

5860
$files = $this->getAllFiles();
5961

@@ -63,10 +65,7 @@ public function handle(): void
6365

6466
$rows = $this->prepareMetricsToBeDisplayed($metrics);
6567

66-
$this->display([
67-
'displayableRows' => $rows,
68-
'numberOfRows' => count($metrics),
69-
]);
68+
$this->display($rows, $metrics);
7069
}
7170

7271
private function analysisMetricsBag(array $analysis): array
@@ -119,11 +118,16 @@ private function prepareMetricsToBeDisplayed(array $metrics): array
119118
);
120119
}
121120

122-
private function makeHtml(array $attributes): ViewContract
121+
private function display(array $rows, array $metrics): void
123122
{
124-
return View::make('inspect-method', [
125-
'displayableRows' => $attributes['displayableRows'],
126-
'numberOfRows' => $attributes['numberOfRows'],
127-
]);
123+
$renderer = $this->makeRendererInstance();
124+
125+
$renderer->display(
126+
view: 'inspect-method',
127+
attributes: [
128+
'displayableRows' => $rows,
129+
'numberOfRows' => count($metrics),
130+
],
131+
);
128132
}
129133
}

app/Commands/Traits/HtmlRenderingTrait.php

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,31 @@
22

33
namespace App\Commands\Traits;
44

5-
use Termwind\HtmlRenderer;
6-
use Symfony\Component\Console\Output\OutputInterface;
7-
use Illuminate\Contracts\View\View as ViewContract;
5+
use App\Modules\Render\RendererFactory;
6+
use App\Modules\Render\Dtos\Option;
7+
use App\Modules\Render\Contracts\Renderer;
88

99
trait HtmlRenderingTrait
1010
{
11-
abstract protected function makeHtml(array $attributes): ViewContract;
11+
abstract private function display(array $rows, array $metrics): void;
1212

13-
protected function display(array $attributes): void
13+
protected function hello()
1414
{
15-
$html = $this->makeHtml($attributes);
15+
/**
16+
* In the case of rendering in JSON,
17+
* the prompt should not be polluted
18+
*/
19+
$mustSayHello = ! $this->option('json');
1620

17-
$this->renderHtml($html);
21+
if ($mustSayHello) {
22+
$this->info('❀ PHP Smelly Code Detector ❀');
23+
}
1824
}
1925

20-
private function renderHtml($html): void
26+
protected function makeRendererInstance(): Renderer
2127
{
22-
$htmlRenderer = new HtmlRenderer();
23-
24-
$htmlRenderer->render($html, OutputInterface::OUTPUT_NORMAL);
28+
return app(RendererFactory::class)->from(
29+
Option::fromCommand($this->options()),
30+
);
2531
}
2632
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace App\Modules\Render\Contracts;
4+
5+
interface Renderer
6+
{
7+
public function display(string $view, array $attributes): void;
8+
}

app/Modules/Render/Dtos/Option.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace App\Modules\Render\Dtos;
4+
5+
use App\Modules\Render\Enums\RenderType;
6+
7+
class Option
8+
{
9+
public function __construct(
10+
public RenderType $type,
11+
) {}
12+
13+
public static function fromCommand(array $attributes): Option
14+
{
15+
$type = $attributes['json'] ? RenderType::Json : RenderType::View;
16+
17+
return new self($type);
18+
}
19+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace App\Modules\Render\Enums;
4+
5+
enum RenderType: string
6+
{
7+
case Json = 'json';
8+
case View = 'view';
9+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace App\Modules\Render;
4+
5+
use App\Modules\Render\Dtos\Option;
6+
use App\Modules\Render\Contracts\Renderer;
7+
use App\Modules\Render\Renderers\JsonRenderer;
8+
use App\Modules\Render\Renderers\ViewRenderer;
9+
10+
class RendererFactory
11+
{
12+
private array $renderers = [
13+
'json' => JsonRenderer::class,
14+
'view' => ViewRenderer::class,
15+
];
16+
17+
public function from(Option $option): Renderer
18+
{
19+
$renderer = $this->renderers[$option->type->value];
20+
21+
return app($renderer);
22+
}
23+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace App\Modules\Render\Renderers;
4+
5+
use App\Modules\Render\Contracts\Renderer;
6+
7+
class JsonRenderer implements Renderer
8+
{
9+
public function display(string $view, array $attributes): void
10+
{
11+
echo json_encode($attributes);
12+
}
13+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace App\Modules\Render\Renderers;
4+
5+
use App\Modules\Render\Contracts\Renderer;
6+
use Termwind\HtmlRenderer;
7+
use Symfony\Component\Console\Output\OutputInterface;
8+
use Illuminate\Contracts\View\View as ViewContract;
9+
use Illuminate\View\Factory as ViewFactory;
10+
11+
class ViewRenderer implements Renderer
12+
{
13+
public function __construct(
14+
private ViewFactory $view,
15+
private HtmlRenderer $htmlRenderer,
16+
) {}
17+
18+
public function display(string $view, array $attributes): void
19+
{
20+
$html = $this->makeHtml($view, $attributes);
21+
22+
$this->renderHtml($html);
23+
}
24+
25+
protected function makeHtml(string $view, array $attributes): ViewContract
26+
{
27+
return $this->view->make($view, $attributes);
28+
}
29+
30+
private function renderHtml(ViewContract $html): void
31+
{
32+
$this->htmlRenderer->render($html, OutputInterface::OUTPUT_NORMAL);
33+
}
34+
}

phpstan.neon

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ parameters:
44
level: 5
55
ignoreErrors:
66
- '#Match expression does not handle remaining value: mixed#'
7-
- '#Property App\\Modules\\Analyzer\\Visitors\\ClassMethodVisitor::\$metrics is never read, only written\.#'
7+
- '#Property App\\Modules\\Analyzer\\Visitors\\ClassMethodVisitor::\$metrics is never read, only written\.#'
8+
- '#Parameter \#1 \$html of method Termwind\\HtmlRenderer::render\(\) expects string, Illuminate\\Contracts\\View\\View given\.#'
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Tests\Unit\Render;
4+
5+
use Tests\TestCase;
6+
use App\Modules\Render\RendererFactory;
7+
use App\Modules\Render\Dtos\Option;
8+
use App\Modules\Render\Renderers\JsonRenderer;
9+
use App\Modules\Render\Renderers\ViewRenderer;
10+
11+
class RendererFactoryTest extends TestCase
12+
{
13+
/**
14+
* @test
15+
*/
16+
public function it_able_to_instantiate_json_renderer(): void
17+
{
18+
$factory = new RendererFactory();
19+
20+
$renderer = $factory->from(
21+
Option::fromCommand(attributes: [
22+
'json' => true,
23+
]),
24+
);
25+
26+
$this->assertInstanceOf(JsonRenderer::class, $renderer);
27+
}
28+
29+
/**
30+
* @test
31+
*/
32+
public function it_able_to_instantiate_view_renderer(): void
33+
{
34+
$factory = new RendererFactory();
35+
36+
$renderer = $factory->from(
37+
Option::fromCommand(attributes: [
38+
'json' => false,
39+
]),
40+
);
41+
42+
$this->assertInstanceOf(ViewRenderer::class, $renderer);
43+
}
44+
}

0 commit comments

Comments
 (0)