diff --git a/src/Maker/MakeController.php b/src/Maker/MakeController.php index 429502ae1..227b6135e 100644 --- a/src/Maker/MakeController.php +++ b/src/Maker/MakeController.php @@ -12,10 +12,12 @@ namespace Symfony\Bundle\MakerBundle\Maker; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; use Symfony\Bundle\MakerBundle\Generator; use Symfony\Bundle\MakerBundle\InputConfiguration; +use Symfony\Bundle\MakerBundle\Maker\Common\CanGenerateTestsTrait; use Symfony\Bundle\MakerBundle\Str; use Symfony\Bundle\MakerBundle\Util\ClassSource\Model\ClassData; use Symfony\Bundle\MakerBundle\Util\PhpCompatUtil; @@ -34,6 +36,8 @@ */ final class MakeController extends AbstractMaker { + use CanGenerateTestsTrait; + public function __construct(private ?PhpCompatUtil $phpCompatUtil = null) { if (null !== $phpCompatUtil) { @@ -63,6 +67,13 @@ public function configureCommand(Command $command, InputConfiguration $inputConf ->addOption('invokable', 'i', InputOption::VALUE_NONE, 'Use this option to create an invokable controller') ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeController.txt')) ; + + $this->configureCommandWithTestsOption($command); + } + + public function interact(InputInterface $input, ConsoleStyle $io, Command $command): void + { + $this->interactSetGenerateTests($input, $io); } public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void @@ -121,6 +132,24 @@ class: $controllerClassName, ); } + if ($this->shouldGenerateTests()) { + $testClassData = ClassData::create( + class: \sprintf('Tests\Controller\%s', $controllerClassData->getClassName(relative: true, withoutSuffix: true)), + suffix: 'ControllerTest', + extendsClass: WebTestCase::class, + useStatements: [ + ] + ); + + $generator->generateClassFromClassData($testClassData, 'controller/test/Test.tpl.php', [ + 'route_path' => Str::asRoutePath($controllerClassData->getClassName(relative: true, withoutSuffix: true)), + ]); + + if (!class_exists(WebTestCase::class)) { + $io->caution('You\'ll need to install the `symfony/test-pack` to execute the tests for your new controller.'); + } + } + $generator->writeChanges(); $this->writeSuccessMessage($io); diff --git a/src/Resources/skeleton/controller/test/Test.tpl.php b/src/Resources/skeleton/controller/test/Test.tpl.php new file mode 100644 index 000000000..802fcc694 --- /dev/null +++ b/src/Resources/skeleton/controller/test/Test.tpl.php @@ -0,0 +1,16 @@ + + +namespace getNamespace(); ?>; + +getUseStatements(); ?> + +getClassDeclaration(); ?> +{ + public function testIndex(): void + { + $client = static::createClient(); + $client->request('GET', ''); + + self::assertResponseIsSuccessful(); + } +} diff --git a/tests/Maker/MakeControllerTest.php b/tests/Maker/MakeControllerTest.php index 8ef1e6713..656a4884a 100644 --- a/tests/Maker/MakeControllerTest.php +++ b/tests/Maker/MakeControllerTest.php @@ -47,6 +47,24 @@ public function getTestDetails(): \Generator }), ]; + yield 'it_generates_a_controller-with-tests' => [$this->createMakerTest() + ->addExtraDependencies('symfony/test-pack') + ->run(function (MakerTestRunner $runner) { + $output = $runner->runMaker([ + 'FooBar', // controller class name + 'y', // create tests + ]); + + $this->assertStringContainsString('src/Controller/FooBarController.php', $output); + $this->assertStringContainsString('tests/Controller/FooBarControllerTest.php', $output); + + $this->assertFileExists($runner->getPath('src/Controller/FooBarController.php')); + $this->assertFileExists($runner->getPath('tests/Controller/FooBarControllerTest.php')); + + $this->runControllerTest($runner, 'it_generates_a_controller.php'); + }), + ]; + yield 'it_generates_a_controller__no_input' => [$this->createMakerTest() ->run(function (MakerTestRunner $runner) { $output = $runner->runMaker([], 'FooBar');