From e84993593a48bb0b8f362ddc10392173e5a47fc0 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Thu, 5 Jan 2023 14:03:54 -0600 Subject: [PATCH 1/7] Add draft file Signed-off-by: Nathanael Esayeas --- .../drafts/controller-returns-view-typehint.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/fixtures/drafts/controller-returns-view-typehint.yaml diff --git a/tests/fixtures/drafts/controller-returns-view-typehint.yaml b/tests/fixtures/drafts/controller-returns-view-typehint.yaml new file mode 100644 index 00000000..1087b8e9 --- /dev/null +++ b/tests/fixtures/drafts/controller-returns-view-typehint.yaml @@ -0,0 +1,12 @@ +models: + User: + name: string + email: string unique + email_verified_at: datetime nullable + password: string + remember_token: rememberToken + softDeletes + +controllers: + User: + resource From 5ac6186907b614c32faecd78da5ccc3d3cced102 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Thu, 5 Jan 2023 14:04:25 -0600 Subject: [PATCH 2/7] Add test fixtures with expected output Signed-off-by: Nathanael Esayeas --- .../controller-returns-view-typehint.php | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 tests/fixtures/controllers/controller-returns-view-typehint.php diff --git a/tests/fixtures/controllers/controller-returns-view-typehint.php b/tests/fixtures/controllers/controller-returns-view-typehint.php new file mode 100644 index 00000000..b64d70d9 --- /dev/null +++ b/tests/fixtures/controllers/controller-returns-view-typehint.php @@ -0,0 +1,90 @@ +validated()); + + $request->session()->flash('user.id', $user->id); + + return redirect()->route('user.index'); + } + + /** + * @param \Illuminate\Http\Request $request + * @param \App\Models\User $user + * @return \Illuminate\View\View + */ + public function show(Request $request, User $user): \Illuminate\View\View + { + return view('user.show', compact('user')); + } + + /** + * @param \Illuminate\Http\Request $request + * @param \App\Models\User $user + * @return \Illuminate\View\View + */ + public function edit(Request $request, User $user): \Illuminate\View\View + { + return view('user.edit', compact('user')); + } + + /** + * @param \App\Http\Requests\UserUpdateRequest $request + * @param \App\Models\User $user + * @return \Illuminate\Routing\Redirector + */ + public function update(UserUpdateRequest $request, User $user): \Illuminate\Routing\Redirector + { + $user->update($request->validated()); + + $request->session()->flash('user.id', $user->id); + + return redirect()->route('user.index'); + } + + /** + * @param \Illuminate\Http\Request $request + * @param \App\Models\User $user + * @return \Illuminate\Routing\Redirector + */ + public function destroy(Request $request, User $user): \Illuminate\Routing\Redirector + { + $user->delete(); + + return redirect()->route('user.index'); + } +} From 56286954d83a01477b9f99ea7653668818f54cc5 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Thu, 5 Jan 2023 14:04:53 -0600 Subject: [PATCH 3/7] Add test Signed-off-by: Nathanael Esayeas --- .../Generators/ControllerGeneratorTest.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/Feature/Generators/ControllerGeneratorTest.php b/tests/Feature/Generators/ControllerGeneratorTest.php index 0abb1ada..9c451991 100644 --- a/tests/Feature/Generators/ControllerGeneratorTest.php +++ b/tests/Feature/Generators/ControllerGeneratorTest.php @@ -240,4 +240,32 @@ public function controllerTreeDataProvider() ['drafts/invokable-controller-shorthand.yaml', 'app/Http/Controllers/ReportController.php', 'controllers/invokable-controller-shorthand.php'], ]; } + + public function testOutputGeneratesControllersWithTypehints(): void + { + $definition = 'drafts/controller-returns-view-typehint.yaml'; + $path = 'app/Http/Controllers/UserController.php'; + $controller = 'controllers/controller-returns-view-typehint.php'; + + $this->app['config']->set('blueprint.use_return_types', true); + + $this->filesystem->expects('stub') + ->with('controller.class.stub') + ->andReturn($this->stub('controller.class.stub')); + $this->filesystem->expects('stub') + ->with('controller.method.stub') + ->andReturn($this->stub('controller.method.stub')); + + $this->filesystem->expects('exists') + ->with(dirname($path)) + ->andReturnTrue(); + $this->filesystem->expects('put') + ->with($path, $this->fixture($controller)); + + $tokens = $this->blueprint->parse($this->fixture($definition)); + $tree = $this->blueprint->analyze($tokens); + + self::assertSame(['created' => [$path]], $this->subject->output($tree)); + } + } From 653323b8c7ac76c0adf463dcc9f8825f3d214059 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Thu, 5 Jan 2023 14:06:18 -0600 Subject: [PATCH 4/7] Return correct return-type hints Signed-off-by: Nathanael Esayeas --- src/Generators/ControllerGenerator.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Generators/ControllerGenerator.php b/src/Generators/ControllerGenerator.php index 7e82307c..c49f61d1 100644 --- a/src/Generators/ControllerGenerator.php +++ b/src/Generators/ControllerGenerator.php @@ -158,7 +158,16 @@ protected function buildMethods(Controller $controller) if (isset($fqcn) && $name !== 'destroy' && $controller->isApiResource()) { $method = str_replace(')' . PHP_EOL, '): \\' . $fqcn . PHP_EOL, $method); } else { - $method = str_replace(')' . PHP_EOL, '): \Illuminate\Http\Response' . PHP_EOL, $method); + $returnType = match (true) { + $statement instanceof RenderStatement => 'Illuminate\View\View', + $statement instanceof RedirectStatement => 'Illuminate\Routing\Redirector', + default => 'Illuminate\Http\Response' + }; + + $method = Str::of($method) + ->replace('* @return \\Illuminate\\Http\\Response', '* @return \\' . $returnType) + ->replace(')' . PHP_EOL, '): \\' . $returnType . PHP_EOL) + ->toString(); } } From 87105738d9b274d86286f5b7f6ad027dfc514b61 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Thu, 5 Jan 2023 14:07:00 -0600 Subject: [PATCH 5/7] Update other fixtures Signed-off-by: Nathanael Esayeas --- .../controllers/return-type-declarations.php | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/fixtures/controllers/return-type-declarations.php b/tests/fixtures/controllers/return-type-declarations.php index c055009e..9ad6ef8a 100644 --- a/tests/fixtures/controllers/return-type-declarations.php +++ b/tests/fixtures/controllers/return-type-declarations.php @@ -11,9 +11,9 @@ class TermController extends Controller { /** * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ - public function index(Request $request): \Illuminate\Http\Response + public function index(Request $request): \Illuminate\View\View { $terms = Term::all(); @@ -22,18 +22,18 @@ public function index(Request $request): \Illuminate\Http\Response /** * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ - public function create(Request $request): \Illuminate\Http\Response + public function create(Request $request): \Illuminate\View\View { return view('term.create'); } /** * @param \App\Http\Requests\TermStoreRequest $request - * @return \Illuminate\Http\Response + * @return \Illuminate\Routing\Redirector */ - public function store(TermStoreRequest $request): \Illuminate\Http\Response + public function store(TermStoreRequest $request): \Illuminate\Routing\Redirector { $term = Term::create($request->validated()); @@ -45,9 +45,9 @@ public function store(TermStoreRequest $request): \Illuminate\Http\Response /** * @param \Illuminate\Http\Request $request * @param \App\Models\Term $term - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ - public function show(Request $request, Term $term): \Illuminate\Http\Response + public function show(Request $request, Term $term): \Illuminate\View\View { return view('term.show', compact('term')); } @@ -55,9 +55,9 @@ public function show(Request $request, Term $term): \Illuminate\Http\Response /** * @param \Illuminate\Http\Request $request * @param \App\Models\Term $term - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ - public function edit(Request $request, Term $term): \Illuminate\Http\Response + public function edit(Request $request, Term $term): \Illuminate\View\View { return view('term.edit', compact('term')); } @@ -65,9 +65,9 @@ public function edit(Request $request, Term $term): \Illuminate\Http\Response /** * @param \App\Http\Requests\TermUpdateRequest $request * @param \App\Models\Term $term - * @return \Illuminate\Http\Response + * @return \Illuminate\Routing\Redirector */ - public function update(TermUpdateRequest $request, Term $term): \Illuminate\Http\Response + public function update(TermUpdateRequest $request, Term $term): \Illuminate\Routing\Redirector { $term->update($request->validated()); @@ -79,9 +79,9 @@ public function update(TermUpdateRequest $request, Term $term): \Illuminate\Http /** * @param \Illuminate\Http\Request $request * @param \App\Models\Term $term - * @return \Illuminate\Http\Response + * @return \Illuminate\Routing\Redirector */ - public function destroy(Request $request, Term $term): \Illuminate\Http\Response + public function destroy(Request $request, Term $term): \Illuminate\Routing\Redirector { $term->delete(); From 6992a4384d8a5a25d946b2fe57f146813c1d3899 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Thu, 5 Jan 2023 14:18:44 -0600 Subject: [PATCH 6/7] Appease the CI gods Signed-off-by: Nathanael Esayeas --- tests/Feature/Generators/ControllerGeneratorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Feature/Generators/ControllerGeneratorTest.php b/tests/Feature/Generators/ControllerGeneratorTest.php index 9c451991..1b2973e3 100644 --- a/tests/Feature/Generators/ControllerGeneratorTest.php +++ b/tests/Feature/Generators/ControllerGeneratorTest.php @@ -267,5 +267,4 @@ public function testOutputGeneratesControllersWithTypehints(): void self::assertSame(['created' => [$path]], $this->subject->output($tree)); } - } From 5835ed57be634b9b8304266a6d0598443171d07b Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Thu, 5 Jan 2023 14:25:13 -0600 Subject: [PATCH 7/7] Fix Pint issues Signed-off-by: Nathanael Esayeas --- src/Generators/ControllerGenerator.php | 2 +- tests/Feature/BlueprintTest.php | 1 + tests/Feature/Generators/ControllerGeneratorTest.php | 1 + tests/Feature/Generators/FactoryGeneratorTest.php | 1 + tests/Feature/Generators/MigrationGeneratorTest.php | 2 ++ tests/Feature/Generators/ModelGeneratorTest.php | 2 ++ tests/Feature/Generators/RouteGeneratorTest.php | 1 + .../Statements/NotificationGeneratorTest.php | 1 + tests/Feature/Generators/TestGeneratorTest.php | 1 + tests/Feature/Lexers/ModelLexerTest.php | 2 ++ tests/Feature/Lexers/StatementLexerTest.php | 2 ++ tests/Feature/Translators/RulesTest.php | 10 ++++++++++ tests/Unit/EnumTypeTest.php | 1 + 13 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Generators/ControllerGenerator.php b/src/Generators/ControllerGenerator.php index c49f61d1..ede2b69f 100644 --- a/src/Generators/ControllerGenerator.php +++ b/src/Generators/ControllerGenerator.php @@ -158,7 +158,7 @@ protected function buildMethods(Controller $controller) if (isset($fqcn) && $name !== 'destroy' && $controller->isApiResource()) { $method = str_replace(')' . PHP_EOL, '): \\' . $fqcn . PHP_EOL, $method); } else { - $returnType = match (true) { + $returnType = match (true) { $statement instanceof RenderStatement => 'Illuminate\View\View', $statement instanceof RedirectStatement => 'Illuminate\Routing\Redirector', default => 'Illuminate\Http\Response' diff --git a/tests/Feature/BlueprintTest.php b/tests/Feature/BlueprintTest.php index a52dceb5..6562a847 100644 --- a/tests/Feature/BlueprintTest.php +++ b/tests/Feature/BlueprintTest.php @@ -662,6 +662,7 @@ public function generate_should_skip_specific_types() /** * @test + * * @dataProvider namespacesDataProvider */ public function relative_namespace_removes_namespace_prefix_from_reference($namespace, $expected, $reference) diff --git a/tests/Feature/Generators/ControllerGeneratorTest.php b/tests/Feature/Generators/ControllerGeneratorTest.php index 1b2973e3..73da3278 100644 --- a/tests/Feature/Generators/ControllerGeneratorTest.php +++ b/tests/Feature/Generators/ControllerGeneratorTest.php @@ -46,6 +46,7 @@ public function output_writes_nothing_for_empty_tree() /** * @test + * * @dataProvider controllerTreeDataProvider */ public function output_writes_migration_for_controller_tree($definition, $path, $controller) diff --git a/tests/Feature/Generators/FactoryGeneratorTest.php b/tests/Feature/Generators/FactoryGeneratorTest.php index f1f93ba5..bb289a3c 100644 --- a/tests/Feature/Generators/FactoryGeneratorTest.php +++ b/tests/Feature/Generators/FactoryGeneratorTest.php @@ -47,6 +47,7 @@ public function output_writes_nothing_for_empty_tree() /** * @test + * * @dataProvider modelTreeDataProvider */ public function output_writes_factory_for_model_tree($definition, $path, $factory) diff --git a/tests/Feature/Generators/MigrationGeneratorTest.php b/tests/Feature/Generators/MigrationGeneratorTest.php index 36706551..5ca2e673 100644 --- a/tests/Feature/Generators/MigrationGeneratorTest.php +++ b/tests/Feature/Generators/MigrationGeneratorTest.php @@ -48,6 +48,7 @@ public function output_writes_nothing_for_empty_tree() /** * @test + * * @dataProvider modelTreeDataProvider */ public function output_writes_migration_for_model_tree($definition, $path, $migration) @@ -80,6 +81,7 @@ public function output_writes_migration_for_model_tree($definition, $path, $migr /** * @test + * * @dataProvider modelTreeDataProvider */ public function output_updates_migration_for_model_tree($definition, $path, $migration) diff --git a/tests/Feature/Generators/ModelGeneratorTest.php b/tests/Feature/Generators/ModelGeneratorTest.php index d3c3b733..22a2430e 100644 --- a/tests/Feature/Generators/ModelGeneratorTest.php +++ b/tests/Feature/Generators/ModelGeneratorTest.php @@ -43,6 +43,7 @@ public function output_generates_nothing_for_empty_tree() /** * @test + * * @dataProvider modelTreeDataProvider */ public function output_generates_models($definition, $path, $model) @@ -393,6 +394,7 @@ public function output_respects_configuration() /** * @test + * * @dataProvider docBlockModelsDataProvider */ public function output_generates_phpdoc_for_model($definition, $path, $model) diff --git a/tests/Feature/Generators/RouteGeneratorTest.php b/tests/Feature/Generators/RouteGeneratorTest.php index b910cae4..46c62595 100644 --- a/tests/Feature/Generators/RouteGeneratorTest.php +++ b/tests/Feature/Generators/RouteGeneratorTest.php @@ -43,6 +43,7 @@ public function output_generates_nothing_for_empty_tree() /** * @test + * * @dataProvider controllerTreeDataProvider */ public function output_generates_web_routes($definition, $routes) diff --git a/tests/Feature/Generators/Statements/NotificationGeneratorTest.php b/tests/Feature/Generators/Statements/NotificationGeneratorTest.php index 6bfc93db..6f211a78 100644 --- a/tests/Feature/Generators/Statements/NotificationGeneratorTest.php +++ b/tests/Feature/Generators/Statements/NotificationGeneratorTest.php @@ -64,6 +64,7 @@ public function output_writes_nothing_tree_without_validate_statements() /** * @test + * * @dataProvider notificationDraftProvider */ public function output_writes_notifications($draft) diff --git a/tests/Feature/Generators/TestGeneratorTest.php b/tests/Feature/Generators/TestGeneratorTest.php index f198a153..93ec9d77 100644 --- a/tests/Feature/Generators/TestGeneratorTest.php +++ b/tests/Feature/Generators/TestGeneratorTest.php @@ -46,6 +46,7 @@ public function output_writes_nothing_for_empty_tree() /** * @test + * * @dataProvider controllerTreeDataProvider */ public function output_generates_test_for_controller_tree_l8($definition, $path, $test) diff --git a/tests/Feature/Lexers/ModelLexerTest.php b/tests/Feature/Lexers/ModelLexerTest.php index 156b3c62..da28f488 100644 --- a/tests/Feature/Lexers/ModelLexerTest.php +++ b/tests/Feature/Lexers/ModelLexerTest.php @@ -269,6 +269,7 @@ public function it_accepts_lowercase_keywords() /** * @test + * * @dataProvider dataTypeAttributesDataProvider */ public function it_handles_data_type_attributes($definition, $data_type, $attributes) @@ -304,6 +305,7 @@ public function it_handles_data_type_attributes($definition, $data_type, $attrib /** * @test + * * @dataProvider modifierAttributesProvider */ public function it_handles_modifier_attributes($definition, $modifier, $attributes) diff --git a/tests/Feature/Lexers/StatementLexerTest.php b/tests/Feature/Lexers/StatementLexerTest.php index 6a8ae117..d279b6fb 100644 --- a/tests/Feature/Lexers/StatementLexerTest.php +++ b/tests/Feature/Lexers/StatementLexerTest.php @@ -433,6 +433,7 @@ public function it_returns_a_validate_statement() /** * @test + * * @dataProvider eloquentTokensProvider */ public function it_returns_an_eloquent_statement($operation, $reference) @@ -471,6 +472,7 @@ public function it_returns_an_update_eloquent_statement_with_columns() /** * @test + * * @dataProvider sessionTokensProvider */ public function it_returns_a_session_statement($operation, $reference) diff --git a/tests/Feature/Translators/RulesTest.php b/tests/Feature/Translators/RulesTest.php index 585d2831..9654df55 100644 --- a/tests/Feature/Translators/RulesTest.php +++ b/tests/Feature/Translators/RulesTest.php @@ -33,6 +33,7 @@ public function forColumn_returns_nullable_rule() /** * @test + * * @dataProvider stringDataTypesProvider */ public function forColumn_returns_string_rule_for_string_data_types($data_type) @@ -58,6 +59,7 @@ public function forColumn_returns_max_rule_for_string_attributes() /** * @test + * * @dataProvider stringDataTypesProvider */ public function forColumn_uses_email_rule_for_columns_named_email_or_email_address($data_type) @@ -75,6 +77,7 @@ public function forColumn_uses_email_rule_for_columns_named_email_or_email_addre /** * @test + * * @dataProvider stringDataTypesProvider */ public function forColumn_uses_password_rule_for_columns_named_password($data_type) @@ -87,6 +90,7 @@ public function forColumn_uses_password_rule_for_columns_named_password($data_ty /** * @test + * * @dataProvider numericDataTypesProvider */ public function forColumn_returns_numeric_rule_for_numeric_types($data_type) @@ -98,6 +102,7 @@ public function forColumn_returns_numeric_rule_for_numeric_types($data_type) /** * @test + * * @dataProvider integerDataTypesProvider */ public function forColumn_returns_integer_rule_for_integer_types($data_type) @@ -138,6 +143,7 @@ public function forColumn_return_exists_rule_for_the_unique_modifier() /** * @test + * * @dataProvider relationshipColumnProvider */ public function forColumn_returns_exists_rule_for_foreign_keys($name, $table) @@ -179,6 +185,7 @@ public function forColumn_returns_in_rule_for_enums_and_sets() /** * @test + * * @dataProvider dateDataTypesProvider */ public function forColumn_returns_date_rule_for_date_types($data_type) @@ -224,6 +231,7 @@ public function forColumn_does_not_return_between_rule_for_unsigned_decimal_with /** * @test + * * @dataProvider noBetweenRuleDataProvider */ public function forColumn_does_not_return_between_rule_for_double_without_precision_and_scale($column) @@ -233,6 +241,7 @@ public function forColumn_does_not_return_between_rule_for_double_without_precis /** * @test + * * @dataProvider noBetweenRuleDataProvider */ public function forColumn_does_not_return_between_rule($column) @@ -242,6 +251,7 @@ public function forColumn_does_not_return_between_rule($column) /** * @test + * * @dataProvider betweenRuleDataProvider */ public function forColumn_returns_between_rule($column, $interval) diff --git a/tests/Unit/EnumTypeTest.php b/tests/Unit/EnumTypeTest.php index fb33b7aa..35602db6 100644 --- a/tests/Unit/EnumTypeTest.php +++ b/tests/Unit/EnumTypeTest.php @@ -11,6 +11,7 @@ class EnumTypeTest extends TestCase { /** * @test + * * @dataProvider enumOptionsDataProvider */ public function it_returns_options_for_enum($definition, $expected)