From 92e21ef852abfda23ce001756183932eca61aa49 Mon Sep 17 00:00:00 2001 From: Nathan E Date: Thu, 16 Apr 2020 21:07:43 -0400 Subject: [PATCH 1/3] fix: controller namespace close #116 --- src/Generators/ControllerGenerator.php | 33 +++++++++++++++++++ src/Generators/RouteGenerator.php | 2 +- src/Generators/TestGenerator.php | 17 +++++++++- .../Generator/ControllerGeneratorTest.php | 2 +- .../Feature/Generator/RouteGeneratorTest.php | 1 + .../controllers/respond-statements.php | 7 ++-- .../definitions/respond-statements.bp | 1 + tests/fixtures/routes/respond-statements.php | 4 +++ tests/fixtures/tests/respond-statements.php | 22 +++++++++++-- 9 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 tests/fixtures/routes/respond-statements.php diff --git a/src/Generators/ControllerGenerator.php b/src/Generators/ControllerGenerator.php index 8019f84f..ea5820a0 100644 --- a/src/Generators/ControllerGenerator.php +++ b/src/Generators/ControllerGenerator.php @@ -4,6 +4,7 @@ use Blueprint\Blueprint; use Blueprint\Contracts\Generator; +use Blueprint\Models\Model; use Blueprint\Models\Controller; use Blueprint\Models\Statements\DispatchStatement; use Blueprint\Models\Statements\EloquentStatement; @@ -27,6 +28,8 @@ class ControllerGenerator implements Generator private $imports = []; + private $models = []; + public function __construct($files) { $this->files = $files; @@ -38,6 +41,8 @@ public function output(array $tree): array $stub = $this->files->stub('controller/class.stub'); + $this->registerModels($tree); + /** @var \Blueprint\Models\Controller $controller */ foreach ($tree['controllers'] as $controller) { $this->addImport($controller, 'Illuminate\\Http\\Request'); @@ -198,6 +203,34 @@ private function fullyQualifyModelReference(string $sub_namespace, string $model // TODO: get model_name from tree. // If not found, assume parallel namespace as controller. // Use respond-statement.php as test case. + + /** @var \Blueprint\Models\Model $model */ + $model = $this->modelForContext($model_name); + + if (isset($this->models[Str::studly($model_name)])) { + return $model->fullyQualifiedClassName(); + } + return config('blueprint.namespace') . '\\' . ($sub_namespace ? $sub_namespace . '\\' : '') . $model_name; } + + private function modelForContext(string $context) + { + if (isset($this->models[Str::studly($context)])) { + return $this->models[Str::studly($context)]; + } + + $matches = array_filter(array_keys($this->models), function ($key) use ($context) { + return Str::endsWith($key, '/'.Str::studly($context)); + }); + + if (count($matches) === 1) { + return $this->models[$matches[0]]; + } + } + + private function registerModels(array $tree) + { + $this->models = array_merge($tree['cache'] ?? [], $tree['models'] ?? []); + } } diff --git a/src/Generators/RouteGenerator.php b/src/Generators/RouteGenerator.php index 3108a604..9cc5da30 100644 --- a/src/Generators/RouteGenerator.php +++ b/src/Generators/RouteGenerator.php @@ -40,7 +40,7 @@ protected function buildRoutes(Controller $controller) $routes = ''; $methods = array_keys($controller->methods()); - $className = $controller->className(); + $className = str_replace('App\Http\Controllers\\','',$controller->fullyQualifiedClassName()); $slug = Str::kebab($controller->prefix()); $resource_methods = array_intersect($methods, Controller::$resourceMethods); diff --git a/src/Generators/TestGenerator.php b/src/Generators/TestGenerator.php index b8ce0a5b..75ab0f41 100644 --- a/src/Generators/TestGenerator.php +++ b/src/Generators/TestGenerator.php @@ -155,7 +155,13 @@ protected function buildTestCases(Controller $controller) } elseif ($statement instanceof ValidateStatement) { $this->addTestAssertionsTrait($controller); - $class = $controller->name() . Str::studly($name) . 'Request'; + $class = $this->buildFormRequestName($controller, $name); +// dd([ +// $class, +//// $controller, +//// $controller->namespace(), +//// $controller->fullyQualifiedClassName() +// ]); $test_case = $this->buildFormRequestTestCase($controller->fullyQualifiedClassName(), $name, config('blueprint.namespace') . '\\Http\\Requests\\' . $class) . PHP_EOL . PHP_EOL . $test_case; if ($statement->data()) { @@ -438,6 +444,15 @@ private function determineModel(string $prefix, ?string $reference) return Str::studly($reference); } + private function buildFormRequestName(Controller $controller, string $name) + { + if (empty($controller->namespace())) { + return $controller->name() . Str::studly($name) . 'Request'; + } + + return $controller->namespace() .'\\'. $controller->name() . Str::studly($name) . 'Request'; + } + private function buildFormRequestTestCase(string $controller, string $action, string $form_request) { return <<< END diff --git a/tests/Feature/Generator/ControllerGeneratorTest.php b/tests/Feature/Generator/ControllerGeneratorTest.php index 675a37fa..0a88e22d 100644 --- a/tests/Feature/Generator/ControllerGeneratorTest.php +++ b/tests/Feature/Generator/ControllerGeneratorTest.php @@ -27,6 +27,7 @@ protected function setUp(): void $this->subject = new ControllerGenerator($this->files); $this->blueprint = new Blueprint(); + $this->blueprint->registerLexer(new \Blueprint\Lexers\ModelLexer()); $this->blueprint->registerLexer(new \Blueprint\Lexers\ControllerLexer(new StatementLexer())); $this->blueprint->registerGenerator($this->subject); } @@ -66,7 +67,6 @@ public function output_writes_migration_for_controller_tree($definition, $path, $tokens = $this->blueprint->parse($this->fixture($definition)); $tree = $this->blueprint->analyze($tokens); - $this->assertEquals(['created' => [$path]], $this->subject->output($tree)); } diff --git a/tests/Feature/Generator/RouteGeneratorTest.php b/tests/Feature/Generator/RouteGeneratorTest.php index 7200b7f5..509b8b91 100644 --- a/tests/Feature/Generator/RouteGeneratorTest.php +++ b/tests/Feature/Generator/RouteGeneratorTest.php @@ -63,6 +63,7 @@ public function controllerTreeDataProvider() ['definitions/readme-example.bp', 'routes/readme-example.php'], ['definitions/cruddy.bp', 'routes/cruddy.php'], ['definitions/non-cruddy.bp', 'routes/non-cruddy.php'], + ['definitions/respond-statements.bp', 'routes/respond-statements.php'], ]; } } diff --git a/tests/fixtures/controllers/respond-statements.php b/tests/fixtures/controllers/respond-statements.php index 5e753332..71414092 100644 --- a/tests/fixtures/controllers/respond-statements.php +++ b/tests/fixtures/controllers/respond-statements.php @@ -2,8 +2,9 @@ namespace App\Http\Controllers\Api; -use App\Api\Post; use App\Http\Controllers\Controller; +use App\Http\Requests\Api\PostStoreRequest; +use App\Post; use Illuminate\Http\Request; class PostController extends Controller @@ -20,10 +21,10 @@ public function index(Request $request) } /** - * @param \Illuminate\Http\Request $request + * @param \App\Http\Requests\Api\PostStoreRequest $request * @return \Illuminate\Http\Response */ - public function store(Request $request) + public function store(PostStoreRequest $request) { return response()->noContent(); } diff --git a/tests/fixtures/definitions/respond-statements.bp b/tests/fixtures/definitions/respond-statements.bp index 5cbc53b7..61d8bc30 100644 --- a/tests/fixtures/definitions/respond-statements.bp +++ b/tests/fixtures/definitions/respond-statements.bp @@ -8,6 +8,7 @@ controllers: query: all respond: posts store: + validate: title respond: 204 error: respond: 400 diff --git a/tests/fixtures/routes/respond-statements.php b/tests/fixtures/routes/respond-statements.php new file mode 100644 index 00000000..ce969c5f --- /dev/null +++ b/tests/fixtures/routes/respond-statements.php @@ -0,0 +1,4 @@ + + +Route::resource('post', 'Api\PostController')->only('index', 'store'); +Route::get('post/error', 'Api\PostController@error'); diff --git a/tests/fixtures/tests/respond-statements.php b/tests/fixtures/tests/respond-statements.php index db6d48b7..a29f6dd4 100644 --- a/tests/fixtures/tests/respond-statements.php +++ b/tests/fixtures/tests/respond-statements.php @@ -4,6 +4,8 @@ use App\Post; use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Foundation\Testing\WithFaker; +use JMac\Testing\Traits\AdditionalAssertions; use Tests\TestCase; /** @@ -11,7 +13,7 @@ */ class PostControllerTest extends TestCase { - use RefreshDatabase; + use AdditionalAssertions, RefreshDatabase, WithFaker; /** * @test @@ -27,12 +29,28 @@ public function index_responds_with() } + /** + * @test + */ + public function store_uses_form_request_validation() + { + $this->assertActionUsesFormRequest( + \App\Http\Controllers\Api\PostController::class, + 'store', + \App\Http\Requests\Api\PostStoreRequest::class + ); + } + /** * @test */ public function store_responds_with() { - $response = $this->post(route('post.store')); + $title = $this->faker->sentence(4); + + $response = $this->post(route('post.store'), [ + 'title' => $title, + ]); $response->assertNoContent(); } From e603b16cd55c663a932dafbbb5d5ed4362c83d8d Mon Sep 17 00:00:00 2001 From: Nathan E Date: Thu, 16 Apr 2020 21:09:03 -0400 Subject: [PATCH 2/3] chore: formatting --- src/Generators/RouteGenerator.php | 2 +- src/Generators/TestGenerator.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Generators/RouteGenerator.php b/src/Generators/RouteGenerator.php index 9cc5da30..15d9fc8e 100644 --- a/src/Generators/RouteGenerator.php +++ b/src/Generators/RouteGenerator.php @@ -40,7 +40,7 @@ protected function buildRoutes(Controller $controller) $routes = ''; $methods = array_keys($controller->methods()); - $className = str_replace('App\Http\Controllers\\','',$controller->fullyQualifiedClassName()); + $className = str_replace('App\Http\Controllers\\', '', $controller->fullyQualifiedClassName()); $slug = Str::kebab($controller->prefix()); $resource_methods = array_intersect($methods, Controller::$resourceMethods); diff --git a/src/Generators/TestGenerator.php b/src/Generators/TestGenerator.php index 75ab0f41..c5fcf218 100644 --- a/src/Generators/TestGenerator.php +++ b/src/Generators/TestGenerator.php @@ -158,9 +158,9 @@ protected function buildTestCases(Controller $controller) $class = $this->buildFormRequestName($controller, $name); // dd([ // $class, -//// $controller, -//// $controller->namespace(), -//// $controller->fullyQualifiedClassName() + //// $controller, + //// $controller->namespace(), + //// $controller->fullyQualifiedClassName() // ]); $test_case = $this->buildFormRequestTestCase($controller->fullyQualifiedClassName(), $name, config('blueprint.namespace') . '\\Http\\Requests\\' . $class) . PHP_EOL . PHP_EOL . $test_case; From 1615ea5eba744658f458ba1a2e1b35d395c1a128 Mon Sep 17 00:00:00 2001 From: Nathan E Date: Thu, 16 Apr 2020 21:17:22 -0400 Subject: [PATCH 3/3] chore: remove dead code --- src/Generators/TestGenerator.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Generators/TestGenerator.php b/src/Generators/TestGenerator.php index c5fcf218..bd3d31f7 100644 --- a/src/Generators/TestGenerator.php +++ b/src/Generators/TestGenerator.php @@ -156,12 +156,6 @@ protected function buildTestCases(Controller $controller) $this->addTestAssertionsTrait($controller); $class = $this->buildFormRequestName($controller, $name); -// dd([ -// $class, - //// $controller, - //// $controller->namespace(), - //// $controller->fullyQualifiedClassName() -// ]); $test_case = $this->buildFormRequestTestCase($controller->fullyQualifiedClassName(), $name, config('blueprint.namespace') . '\\Http\\Requests\\' . $class) . PHP_EOL . PHP_EOL . $test_case; if ($statement->data()) {