Skip to content

Commit 8531b85

Browse files
committed
TDD generation of controller stub
1 parent 8efe1bc commit 8531b85

File tree

6 files changed

+217
-0
lines changed

6 files changed

+217
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace Blueprint\Generators;
4+
5+
use Blueprint\Column;
6+
use Blueprint\Contracts\Generator;
7+
use Blueprint\Controller;
8+
use Illuminate\Support\Str;
9+
10+
class ControllerGenerator implements Generator
11+
{
12+
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
13+
private $files;
14+
15+
public function __construct($files)
16+
{
17+
$this->files = $files;
18+
}
19+
20+
public function output(array $tree): array
21+
{
22+
$output = [];
23+
24+
$stub = $this->files->get(STUBS_PATH . '/controller/class.stub');
25+
26+
/** @var \Blueprint\Controller $controller */
27+
foreach ($tree['controllers'] as $controller) {
28+
$path = $this->getPath($controller);
29+
$this->files->put(
30+
$path,
31+
$this->populateStub($stub, $controller)
32+
);
33+
34+
$output['created'][] = $path;
35+
}
36+
37+
return $output;
38+
}
39+
40+
protected function populateStub(string $stub, Controller $controller)
41+
{
42+
$stub = str_replace('DummyNamespace', 'App\\Http\\Controllers', $stub);
43+
$stub = str_replace('DummyClass', $this->className($controller), $stub);
44+
$stub = str_replace('// methods...', $this->buildMethods($controller), $stub);
45+
$stub = $this->addImports($controller, $stub);
46+
47+
return $stub;
48+
}
49+
50+
private function buildMethods(Controller $controller)
51+
{
52+
$template = $this->methodStub();
53+
54+
$methods = '';
55+
56+
foreach ($controller->methods() as $name => $body) {
57+
$methods .= PHP_EOL . str_replace('DummyMethod', $name, $template);
58+
// TODO:
59+
// foreach statements
60+
// output their resulting code
61+
// validate => replace Request injection (addImport)
62+
// queue => output Job::dispatch($data) (addImport)
63+
}
64+
65+
return trim($methods);
66+
}
67+
68+
protected function getPath(Controller $controller)
69+
{
70+
return 'app/Http/Controllers/' . $this->className($controller) . '.php';
71+
}
72+
73+
private function methodStub()
74+
{
75+
static $stub = '';
76+
77+
if (empty($stub)) {
78+
$stub = $this->files->get(STUBS_PATH . '/controller/method.stub');
79+
}
80+
81+
return $stub;
82+
}
83+
84+
private function addImports(Controller $controller, $stub)
85+
{
86+
return $stub;
87+
}
88+
89+
protected function className(Controller $controller): string
90+
{
91+
return $controller->name() . (Str::endsWith($controller->name(), 'Controller') ? '' : 'Controller');
92+
}
93+
}

stubs/controller/class.stub

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace DummyNamespace;
4+
5+
use Illuminate\Http\Request;
6+
7+
class DummyClass extends Controller
8+
{
9+
// methods...
10+
}

stubs/controller/method.stub

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @param \Illuminate\Http\Request $request
3+
* @return \Illuminate\Http\Response
4+
*/
5+
public function DummyMethod(Request $request)
6+
{
7+
//
8+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace Tests\Feature\Generators;
4+
5+
use Blueprint\Blueprint;
6+
use Blueprint\Generators\ControllerGenerator;
7+
use Blueprint\Lexers\StatementLexer;
8+
use Tests\TestCase;
9+
10+
class ControllerGeneratorTest extends TestCase
11+
{
12+
private $blueprint;
13+
14+
private $files;
15+
16+
/** @var ControllerGenerator */
17+
private $subject;
18+
19+
protected function setUp(): void
20+
{
21+
parent::setUp();
22+
23+
$this->files = \Mockery::mock();
24+
$this->subject = new ControllerGenerator($this->files);
25+
26+
$this->blueprint = new Blueprint();
27+
$this->blueprint->registerLexer(new \Blueprint\Lexers\ControllerLexer(new StatementLexer()));
28+
$this->blueprint->registerGenerator($this->subject);
29+
}
30+
31+
/**
32+
* @test
33+
*/
34+
public function output_writes_nothing_for_empty_tree()
35+
{
36+
$this->files->expects('get')
37+
->with('stubs/controller/class.stub')
38+
->andReturn(file_get_contents('stubs/controller/class.stub'));
39+
40+
$this->files->shouldNotHaveReceived('put');
41+
42+
$this->assertEquals([], $this->subject->output(['controllers' => []]));
43+
}
44+
45+
/**
46+
* @test
47+
* @dataProvider controllerTreeDataProvider
48+
*/
49+
public function output_writes_migration_for_controller_tree($definition, $path, $controller)
50+
{
51+
static $iteration = 0;
52+
53+
$this->files->expects('get')
54+
->with('stubs/controller/class.stub')
55+
->andReturn(file_get_contents('stubs/controller/class.stub'));
56+
57+
if ($iteration === 0) {
58+
$this->files->expects('get')
59+
->with('stubs/controller/method.stub')
60+
->andReturn(file_get_contents('stubs/controller/method.stub'));
61+
}
62+
63+
$this->files->expects('put')
64+
->with($path, $this->fixture($controller));
65+
66+
$tokens = $this->blueprint->parse($this->fixture($definition));
67+
$tree = $this->blueprint->analyze($tokens);
68+
69+
$this->assertEquals(['created' => [$path]], $this->subject->output($tree));
70+
++$iteration;
71+
}
72+
73+
74+
public function controllerTreeDataProvider()
75+
{
76+
return [
77+
['definitions/readme-example.bp', 'app/Http/Controllers/PostController.php', 'controllers/readme-example.php'],
78+
];
79+
}
80+
}

tests/fixtures/controllers/controller-only.php

Whitespace-only changes.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use Illuminate\Http\Request;
6+
7+
class PostController extends Controller
8+
{
9+
/**
10+
* @param \Illuminate\Http\Request $request
11+
* @return \Illuminate\Http\Response
12+
*/
13+
public function index(Request $request)
14+
{
15+
//
16+
}
17+
18+
/**
19+
* @param \Illuminate\Http\Request $request
20+
* @return \Illuminate\Http\Response
21+
*/
22+
public function store(Request $request)
23+
{
24+
//
25+
}
26+
}

0 commit comments

Comments
 (0)