mirror of
https://github.com/symfony/console.git
synced 2026-03-24 01:12:13 +01:00
* 6.4: [RateLimiter] Fix retryAfter when consuming exactly all remaining tokens in FixedWindow and TokenBucket [RateLimiter] Fix retryAfter value on last token consume (SlidingWindow) [RateLimiter] Fix reservations outside the second fixed window [Filesystem] makePathRelative with existing files, remove ending / [Config][Routing] Fix exclude option being ignored for non-glob and PSR-4 resources [Serializer][Validator] Fix propertyPath in ConstraintViolationListNormalizer with MetadataAwareNameConverter [Messenger][Amqp] Don't use retry routing key when sending to failure transport [Messenger] Fix re-sending failed messages to a different failure transport [DependencyInjection] Fix #[AsTaggedItem] discovery through multi-level decoration chains [DependencyInjection] Fix PriorityTaggedServiceTrait not discovering #[AsTaggedItem] on decorated services [Mailer] Clarify the purpose of SentMessage's "message id" concept [TwigBridge] Fix Bootstrap 4 form error layout [Form] Fix merging POST params and files when collection entries have mismatched indices [Validator] Fix type error for non-array items when Unique::fields is set [HttpKernel] Fix default locale ignored when Accept-Language has no enabled-locale match [FrameworkBundle] Make `ConfigDebugCommand` use its container to resolve env vars [Console] Fix various completion edge cases [Messenger][AmazonSqs] Add test for default queue_name when not set in DSN path or options
160 lines
6.7 KiB
PHP
160 lines
6.7 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Symfony\Component\Console\Tests\Command;
|
|
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Symfony\Component\Console\Application;
|
|
use Symfony\Component\Console\Command\Command;
|
|
use Symfony\Component\Console\Command\CompleteCommand;
|
|
use Symfony\Component\Console\Completion\CompletionInput;
|
|
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
|
use Symfony\Component\Console\Completion\Output\BashCompletionOutput;
|
|
use Symfony\Component\Console\Input\InputArgument;
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
use Symfony\Component\Console\Tester\CommandTester;
|
|
|
|
class CompleteCommandTest extends TestCase
|
|
{
|
|
private CompleteCommand $command;
|
|
private Application $application;
|
|
private CommandTester $tester;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->command = new CompleteCommand();
|
|
|
|
$this->application = new Application();
|
|
$this->application->addCommand(new CompleteCommandTest_HelloCommand());
|
|
$this->application->getDefinition()
|
|
->addOption(new InputOption('global-option', null, InputOption::VALUE_REQUIRED, suggestedValues: ['foo', 'bar', 'baz']));
|
|
|
|
$this->command->setApplication($this->application);
|
|
$this->tester = new CommandTester($this->command);
|
|
}
|
|
|
|
public function testRequiredShellOption()
|
|
{
|
|
$this->expectExceptionMessage('The "--shell" option must be set.');
|
|
$this->execute([]);
|
|
}
|
|
|
|
public function testUnsupportedShellOption()
|
|
{
|
|
$this->expectExceptionMessage('Shell completion is not supported for your shell: "unsupported" (supported: "bash", "fish", "zsh").');
|
|
$this->execute(['--shell' => 'unsupported']);
|
|
}
|
|
|
|
public function testAdditionalShellSupport()
|
|
{
|
|
$this->expectNotToPerformAssertions();
|
|
|
|
$this->command = new CompleteCommand(['supported' => BashCompletionOutput::class]);
|
|
$this->command->setApplication($this->application);
|
|
$this->tester = new CommandTester($this->command);
|
|
|
|
$this->execute(['--shell' => 'supported', '--current' => '1', '--input' => ['bin/console']]);
|
|
|
|
// verify that the default set of shells is still supported
|
|
$this->execute(['--shell' => 'bash', '--current' => '1', '--input' => ['bin/console']]);
|
|
}
|
|
|
|
#[DataProvider('provideInputAndCurrentOptionValues')]
|
|
public function testInputAndCurrentOptionValidation(array $input, ?string $exceptionMessage)
|
|
{
|
|
if ($exceptionMessage) {
|
|
$this->expectExceptionMessage($exceptionMessage);
|
|
}
|
|
|
|
$this->execute($input + ['--shell' => 'bash']);
|
|
|
|
if (!$exceptionMessage) {
|
|
$this->tester->assertCommandIsSuccessful();
|
|
}
|
|
}
|
|
|
|
public static function provideInputAndCurrentOptionValues()
|
|
{
|
|
yield [[], 'The "--current" option must be set and it must be an integer'];
|
|
yield [['--current' => 'a'], 'The "--current" option must be set and it must be an integer'];
|
|
yield [['--current' => '1', '--input' => ['bin/console']], null];
|
|
yield [['--current' => '2', '--input' => ['bin/console']], 'Current index is invalid, it must be the number of input tokens or one more.'];
|
|
yield [['--current' => '1', '--input' => ['bin/console', 'cache:clear']], null];
|
|
yield [['--current' => '2', '--input' => ['bin/console', 'cache:clear']], null];
|
|
}
|
|
|
|
#[DataProvider('provideCompleteCommandNameInputs')]
|
|
public function testCompleteCommandName(array $input, array $suggestions)
|
|
{
|
|
$this->execute(['--current' => '1', '--input' => $input]);
|
|
$this->assertEquals(implode("\n", $suggestions).\PHP_EOL, $this->tester->getDisplay());
|
|
}
|
|
|
|
public static function provideCompleteCommandNameInputs()
|
|
{
|
|
yield 'empty' => [['bin/console'], ['help', 'list', 'completion', 'hello', 'ahoy', 'h', 'ahah']];
|
|
yield 'partial' => [['bin/console', 'he'], ['help', 'list', 'completion', 'hello', 'ahoy', 'h', 'ahah']];
|
|
yield 'complete-shortcut-name' => [['bin/console', 'hell'], ['hello']];
|
|
yield 'complete-aliases' => [['bin/console', 'ah'], ['ahoy']];
|
|
yield 'short-alias-completes-to-name' => [['bin/console', 'h'], ['hello']];
|
|
yield 'ambiguous-of-same-command-completes-to-first-match' => [['bin/console', 'ah'], ['ahoy']];
|
|
}
|
|
|
|
#[DataProvider('provideCompleteCommandInputDefinitionInputs')]
|
|
public function testCompleteCommandInputDefinition(array $input, array $suggestions)
|
|
{
|
|
$this->execute(['--current' => '2', '--input' => $input]);
|
|
$this->assertEquals(implode("\n", $suggestions).\PHP_EOL, $this->tester->getDisplay());
|
|
}
|
|
|
|
public static function provideCompleteCommandInputDefinitionInputs()
|
|
{
|
|
yield 'definition' => [['bin/console', 'hello', '-'], ['--help', '--silent', '--quiet', '--verbose', '--version', '--ansi', '--no-ansi', '--no-interaction', '--global-option']];
|
|
yield 'custom' => [['bin/console', 'hello'], ['Fabien', 'Robin', 'Wouter']];
|
|
yield 'definition-aliased' => [['bin/console', 'ahoy', '-'], ['--help', '--silent', '--quiet', '--verbose', '--version', '--ansi', '--no-ansi', '--no-interaction', '--global-option']];
|
|
yield 'custom-aliased' => [['bin/console', 'ahoy'], ['Fabien', 'Robin', 'Wouter']];
|
|
yield 'custom-aliased-input' => [['bin/console', 'ahoy', 'Fa'], ['Fabien', 'Robin', 'Wouter']];
|
|
yield 'global-option-values' => [['bin/console', '--global-option'], ['foo', 'bar', 'baz']];
|
|
yield 'global-option-with-command-values' => [['bin/console', 'ahoy', '--global-option'], ['foo', 'bar', 'baz']];
|
|
}
|
|
|
|
private function execute(array $input)
|
|
{
|
|
// run in verbose mode to assert exceptions
|
|
$this->tester->execute($input ? ($input + ['--shell' => 'bash', '--api-version' => CompleteCommand::COMPLETION_API_VERSION]) : $input, ['verbosity' => OutputInterface::VERBOSITY_DEBUG]);
|
|
}
|
|
}
|
|
|
|
class CompleteCommandTest_HelloCommand extends Command
|
|
{
|
|
public function configure(): void
|
|
{
|
|
$this->setName('hello')
|
|
->setAliases(['ahoy', 'h', 'ahah'])
|
|
->setDescription('Hello test command')
|
|
->addArgument('name', InputArgument::REQUIRED)
|
|
;
|
|
}
|
|
|
|
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
|
|
{
|
|
if ($input->mustSuggestArgumentValuesFor('name')) {
|
|
$suggestions->suggestValues(['Fabien', 'Robin', 'Wouter']);
|
|
|
|
return;
|
|
}
|
|
|
|
parent::complete($input, $suggestions);
|
|
}
|
|
}
|