bug #40986 [Console] Negatable option are null by default (jderusse)

This PR was merged into the 5.3-dev branch.

Discussion
----------

[Console] Negatable option are null by default

| Q             | A
| ------------- | ---
| Branch?       | 5.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

given the command
```php
class TestCommand extends Command
{
    protected static $defaultName = 'test';

    protected function configure()
    {
        $this->addOption('ansi', null, InputOption::VALUE_NEGATABLE, 'Force/disable ANSI output');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        dump($input->getOption('ansi'));

        return Command::SUCCESS;
    }
}
```

 call | result
--- | ---
`bin/console test --no-ansi` | `false`
`bin/console test --ansi` | `true`
`bin/console test` | `null`

Commits
-------

22cb37cc85 [console] Negatable option are null by default
This commit is contained in:
Fabien Potencier 2021-04-29 16:17:51 +02:00
commit 694c052e3c
4 changed files with 20 additions and 13 deletions

View File

@ -1036,7 +1036,7 @@ class Application implements ResetInterface
new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),
new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),
new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'),
new InputOption('--ansi', '', InputOption::VALUE_NEGATABLE, 'Force (or disable --no-ansi) ANSI output', null),
new InputOption('--ansi', '', InputOption::VALUE_NEGATABLE, 'Force (or disable --no-ansi) ANSI output', false),
new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
]);
}

View File

@ -186,9 +186,6 @@ class InputOption
if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
}
if (self::VALUE_NEGATABLE === (self::VALUE_NEGATABLE & $this->mode) && null !== $default) {
throw new LogicException('Cannot set a default value when using InputOption::VALUE_NEGATABLE mode.');
}
if ($this->isArray()) {
if (null === $default) {
@ -198,7 +195,7 @@ class InputOption
}
}
$this->default = $this->acceptValue() ? $default : false;
$this->default = $this->acceptValue() || $this->isNegatable() ? $default : false;
}
/**

View File

@ -214,6 +214,24 @@ class ArgvInputTest extends TestCase
['foo' => false],
'->parse() parses long options without a value',
],
[
['cli.php'],
[new InputOption('foo', null, InputOption::VALUE_NEGATABLE)],
['foo' => null],
'->parse() parses long options without a value',
],
[
['cli.php'],
[new InputOption('foo', null, InputOption::VALUE_NONE | InputOption::VALUE_NEGATABLE)],
['foo' => null],
'->parse() parses long options without a value',
],
[
['cli.php'],
[new InputOption('foo', null, InputOption::VALUE_NEGATABLE, '', false)],
['foo' => false],
'->parse() parses long options without a value',
],
];
}

View File

@ -164,14 +164,6 @@ class InputOptionTest extends TestCase
$option->setDefault('default');
}
public function testDefaultValueWithValueBooleanMode()
{
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Cannot set a default value when using InputOption::VALUE_NEGATABLE mode.');
$option = new InputOption('foo', 'f', InputOption::VALUE_NEGATABLE);
$option->setDefault('default');
}
public function testDefaultValueWithIsArrayMode()
{
$this->expectException(\LogicException::class);