diff --git a/src/Generators/ControllerGenerator.php b/src/Generators/ControllerGenerator.php index 7e82307c..ede2b69f 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(); } } 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 0abb1ada..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) @@ -240,4 +241,31 @@ 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)); + } } 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) 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'); + } +} 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(); 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