Skip to content

Commit

Permalink
feature symfony#1603 [make:controller] add ability to create controll…
Browse files Browse the repository at this point in the history
…er with tests
  • Loading branch information
jrushlow authored Sep 27, 2024
1 parent 3280a5d commit de15602
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/Maker/MakeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -34,6 +36,8 @@
*/
final class MakeController extends AbstractMaker
{
use CanGenerateTestsTrait;

public function __construct(private ?PhpCompatUtil $phpCompatUtil = null)
{
if (null !== $phpCompatUtil) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
16 changes: 16 additions & 0 deletions src/Resources/skeleton/controller/test/Test.tpl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?= "<?php\n" ?>

namespace <?= $class_data->getNamespace(); ?>;

<?= $class_data->getUseStatements(); ?>

<?= $class_data->getClassDeclaration(); ?>
{
public function testIndex(): void
{
$client = static::createClient();
$client->request('GET', '<?= $route_path; ?>');

self::assertResponseIsSuccessful();
}
}
18 changes: 18 additions & 0 deletions tests/Maker/MakeControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down

0 comments on commit de15602

Please sign in to comment.