Skip to content

Commit 6a7cef0

Browse files
committed
Add a new make:test command
1 parent bc7ccf1 commit 6a7cef0

13 files changed

+324
-3
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1+
1.29
2+
====
3+
4+
* [make:test] Added the maker
5+
* [make:unit-test] Deprecated the maker
6+
* [make:functional-test] Deprecated the maker
7+
18
1.27
9+
====
210

311
* [make:registration-form] Added a new question to generate code that will allow
412
users to click on the "verify email" link in their email without needing to be

src/DependencyInjection/CompilerPass/MakeCommandRegistrationPass.php

+11
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public function process(ContainerBuilder $container)
2929
{
3030
foreach ($container->findTaggedServiceIds(self::MAKER_TAG) as $id => $tags) {
3131
$def = $container->getDefinition($id);
32+
if ($def->isDeprecated()) {
33+
continue;
34+
}
35+
3236
$class = $container->getParameterBag()->resolveValue($def->getClass());
3337
if (!is_subclass_of($class, MakerInterface::class)) {
3438
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, MakerInterface::class));
@@ -50,6 +54,13 @@ public function process(ContainerBuilder $container)
5054

5155
$commandDefinition->addTag('console.command', $tagAttributes);
5256

57+
// TODO: remove this block when removing make:unit-test and make:functional-test
58+
if (method_exists($class, 'getCommandAliases')) {
59+
foreach ($class::getCommandAliases() as $alias) {
60+
$commandDefinition->addTag('console.command', ['command' => $alias, 'description' => 'Deprecated alias of "make:test"']);
61+
}
62+
}
63+
5364
$container->setDefinition(sprintf('maker.auto_command.%s', Str::asTwigVariable($class::getCommandName())), $commandDefinition);
5465
}
5566
}

src/Maker/MakeFunctionalTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@
2323
use Symfony\Component\CssSelector\CssSelectorConverter;
2424
use Symfony\Component\Panther\PantherTestCaseTrait;
2525

26+
trigger_deprecation('symfony/maker-bundle', '1.29', 'The "%s" class is deprecated, use "%s" instead.', MakeFunctionalTest::class, MakeTest::class);
27+
2628
/**
29+
* @deprecated since MakerBundle 1.29, use Symfony\Bundle\MakerBundle\Maker\MakeTest instead.
30+
*
2731
* @author Javier Eguiluz <[email protected]>
2832
* @author Ryan Weaver <[email protected]>
2933
*/

src/Maker/MakeTest.php

+206
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Maker;
13+
14+
use Symfony\Bundle\FrameworkBundle\Test\WebTestAssertionsTrait;
15+
use Symfony\Bundle\MakerBundle\ConsoleStyle;
16+
use Symfony\Bundle\MakerBundle\DependencyBuilder;
17+
use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException;
18+
use Symfony\Bundle\MakerBundle\Generator;
19+
use Symfony\Bundle\MakerBundle\InputAwareMakerInterface;
20+
use Symfony\Bundle\MakerBundle\InputConfiguration;
21+
use Symfony\Bundle\MakerBundle\Validator;
22+
use Symfony\Component\BrowserKit\History;
23+
use Symfony\Component\Console\Command\Command;
24+
use Symfony\Component\Console\Input\InputArgument;
25+
use Symfony\Component\Console\Input\InputInterface;
26+
use Symfony\Component\CssSelector\CssSelectorConverter;
27+
use Symfony\Component\Panther\PantherTestCaseTrait;
28+
29+
/**
30+
* MakeTest
31+
*
32+
* @author Kévin Dunglas <[email protected]>
33+
* @author Javier Eguiluz <[email protected]>
34+
* @author Ryan Weaver <[email protected]>
35+
*/
36+
final class MakeTest extends AbstractMaker implements InputAwareMakerInterface
37+
{
38+
public static function getCommandName(): string
39+
{
40+
return 'make:test';
41+
}
42+
43+
// TODO: remove this method when removing make:unit-test and make:functional-test
44+
public static function getCommandAliases(): iterable
45+
{
46+
yield 'make:unit-test';
47+
yield 'make:functional-test';
48+
}
49+
50+
public static function getCommandDescription(): string
51+
{
52+
return 'Creates a new test class';
53+
}
54+
55+
public function configureCommand(Command $command, InputConfiguration $inputConf)
56+
{
57+
$command
58+
->addArgument('name', InputArgument::OPTIONAL, 'The name of the test class (e.g. <fg=yellow>BlogPostTest</>)')
59+
->addArgument('type', InputArgument::OPTIONAL, 'The type of test: <fg=yellow>unit</> (PHPUnit), <fg=yellow>integration</> (WebTestCase) or <fg=yellow>e2e</> (PantherTestCase)')
60+
->setHelp(file_get_contents(__DIR__ . '/../Resources/help/MakeTest.txt'));
61+
62+
$inputConf->setArgumentAsNonInteractive('type');
63+
}
64+
65+
public function interact(InputInterface $input, ConsoleStyle $io, Command $command)
66+
{
67+
// TODO: remove the following block when removing make:unit-test and make:functional-test
68+
$currentCommand = $input->getFirstArgument();
69+
switch ($currentCommand) {
70+
case 'make:unit-test':
71+
$input->setArgument('type', 'unit');
72+
$io->caution('The "make:unit-test" command is deprecated, use "make:test" instead.');
73+
74+
return;
75+
76+
case 'make:functional-test':
77+
$input->setArgument('type', trait_exists(PantherTestCaseTrait::class) ? 'e2e' : 'integration');
78+
$io->caution('The "make:functional-test" command is deprecated, use "make:test" instead.');
79+
80+
return;
81+
}
82+
83+
if (null !== $input->getArgument('type')) {
84+
$this->normalizeType($input);
85+
86+
return;
87+
}
88+
89+
$input->setArgument(
90+
'type',
91+
$io->choice($command->getDefinition()->getArgument('type')->getDescription(), ['unit', 'integration', 'e2e'])
92+
);
93+
}
94+
95+
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator)
96+
{
97+
$testClassNameDetails = $generator->createClassNameDetails(
98+
$input->getArgument('name'),
99+
'Tests\\',
100+
'Test'
101+
);
102+
103+
switch ($type = $input->getArgument('type')) {
104+
case 'unit':
105+
$generator->generateClass(
106+
$testClassNameDetails->getFullName(),
107+
'test/Unit.tpl.php',
108+
[]
109+
);
110+
$url = 'https://symfony.com/doc/current/testing.html#unit-tests';
111+
112+
break;
113+
114+
case 'integration':
115+
$generator->generateClass(
116+
$testClassNameDetails->getFullName(),
117+
'test/Functional.tpl.php',
118+
[
119+
'web_assertions_are_available' => trait_exists(WebTestAssertionsTrait::class),
120+
'panther_is_available' => false,
121+
]
122+
);
123+
$url = 'https://symfony.com/doc/current/testing.html#functional-tests';
124+
125+
break;
126+
127+
default:
128+
$generator->generateClass(
129+
$testClassNameDetails->getFullName(),
130+
'test/Functional.tpl.php',
131+
[
132+
'web_assertions_are_available' => trait_exists(WebTestAssertionsTrait::class),
133+
'panther_is_available' => true,
134+
]
135+
);
136+
$url = 'https://github.com/symfony/panther';
137+
138+
break;
139+
}
140+
141+
$generator->writeChanges();
142+
143+
$this->writeSuccessMessage($io);
144+
145+
$io->text([
146+
'Next: Open your new test class and start customizing it.',
147+
sprintf('Find the documentation at <fg=yellow>%s</>', $url),
148+
]);
149+
}
150+
151+
public function configureDependencies(DependencyBuilder $dependencies, InputInterface $input = null): void
152+
{
153+
if ($input === null) {
154+
return;
155+
}
156+
157+
switch ($input->getArgument('type')) {
158+
case 'integration':
159+
$dependencies->addClassDependency(
160+
History::class,
161+
'browser-kit',
162+
true,
163+
true
164+
);
165+
$dependencies->addClassDependency(
166+
CssSelectorConverter::class,
167+
'css-selector',
168+
true,
169+
true
170+
);
171+
return;
172+
173+
case 'e2e':
174+
$dependencies->addClassDependency(
175+
PantherTestCaseTrait::class,
176+
'panther',
177+
true,
178+
true
179+
);
180+
return;
181+
}
182+
}
183+
184+
private function normalizeType(InputInterface $input): void
185+
{
186+
switch ($type = $input->getArgument('type')) {
187+
case 'unit':
188+
return;
189+
190+
case 'integration':
191+
case 'web':
192+
case 'functional':
193+
$input->setArgument(type, 'integration');
194+
return;
195+
196+
case 'e2e':
197+
case 'ui':
198+
case 'panther':
199+
$input->setArgument(type, 'e2');
200+
return;
201+
202+
default:
203+
throw new RuntimeCommandException(sprintf('The test type must be "unit", "integration" or "e2e", "%s" given.', $type));
204+
}
205+
}
206+
}

src/Maker/MakeUnitTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
use Symfony\Component\Console\Input\InputArgument;
2020
use Symfony\Component\Console\Input\InputInterface;
2121

22+
trigger_deprecation('symfony/maker-bundle', '1.29', 'The "%s" class is deprecated, use "%s" instead.', MakeUnitTest::class, MakeTest::class);
23+
2224
/**
25+
* @deprecated since MakerBundle 1.29, use Symfony\Bundle\MakerBundle\Maker\MakeTest instead.
26+
*
2327
* @author Javier Eguiluz <[email protected]>
2428
* @author Ryan Weaver <[email protected]>
2529
*/

src/Resources/config/makers.xml

+6
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
</service>
5656

5757
<service id="maker.maker.make_functional_test" class="Symfony\Bundle\MakerBundle\Maker\MakeFunctionalTest">
58+
<deprecated package="symfony/maker-bundle" version="1.29">The "%service_id%" service is deprecated, use "maker.maker.make_test" instead.</deprecated>
5859
<tag name="maker.command" />
5960
</service>
6061

@@ -99,7 +100,12 @@
99100
<tag name="maker.command" />
100101
</service>
101102

103+
<service id="maker.maker.make_test" class="Symfony\Bundle\MakerBundle\Maker\MakeTest">
104+
<tag name="maker.command" />
105+
</service>
106+
102107
<service id="maker.maker.make_unit_test" class="Symfony\Bundle\MakerBundle\Maker\MakeUnitTest">
108+
<deprecated package="symfony/maker-bundle" version="1.29">The "%service_id%" service is deprecated, use "maker.maker.make_test" instead.</deprecated>
103109
<tag name="maker.command" />
104110
</service>
105111

src/Resources/help/MakeTest.txt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
The <info>%command.name%</info> command generates a new test class.
2+
3+
<info>php %command.full_name% BlogPostTest unit</info>
4+
5+
If the first argument is missing, the command will ask for the class name interactively.
6+
7+
If the second argument is missing, the command will ask for the test type interactively.
8+
Possible values are <info>unit</info>, <info>integration</info> and <info>e2e</info>.

src/Resources/skeleton/test/Functional.tpl.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,24 @@
1010

1111
class <?= $class_name ?> extends <?= $panther_is_available ? 'PantherTestCase' : 'WebTestCase' ?><?= "\n" ?>
1212
{
13-
public function testSomething()
13+
public function testSomething(): void
1414
{
15+
<?php if ($panther_is_available): ?>
16+
$client = static::createPantherClient();
17+
<?php else: ?>
1518
$client = static::createClient();
19+
<?php endif ?>
1620
$crawler = $client->request('GET', '/');
1721

1822
<?php if ($web_assertions_are_available): ?>
23+
<?php if (!$panther_is_available): ?>
1924
$this->assertResponseIsSuccessful();
25+
<?php endif ?>
2026
$this->assertSelectorTextContains('h1', 'Hello World');
2127
<?php else: ?>
28+
<?php if (!$panther_is_available): ?>
2229
$this->assertSame(200, $client->getResponse()->getStatusCode());
30+
<?php endif ?>
2331
$this->assertStringContainsString('Hello World', $crawler->filter('h1')->text());
2432
<?php endif ?>
2533
}

src/Resources/skeleton/test/Unit.tpl.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
class <?= $class_name ?> extends TestCase
88
{
9-
public function testSomething()
9+
public function testSomething(): void
1010
{
1111
$this->assertTrue(true);
1212
}

tests/Maker/FunctionalTest.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ public function testWiring()
3030
$kernel = new MakerTestKernel('dev', true);
3131

3232
$finder = new Finder();
33-
$finder->in(__DIR__.'/../../src/Maker');
33+
$finder
34+
->in(__DIR__.'/../../src/Maker')
35+
// exclude deprecated classes
36+
->notContains('/@deprecated/')
37+
;
3438

3539
$application = new Application($kernel);
3640
foreach ($finder as $file) {

tests/Maker/MakeFunctionalTestTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
use Symfony\Bundle\MakerBundle\Test\MakerTestCase;
1616
use Symfony\Bundle\MakerBundle\Test\MakerTestDetails;
1717

18+
/**
19+
* @group legacy
20+
*/
1821
class MakeFunctionalTestTest extends MakerTestCase
1922
{
2023
public function getTestDetails()

0 commit comments

Comments
 (0)