|
11 | 11 |
|
12 | 12 | namespace Symfony\Component\Console\Tests\Command; |
13 | 13 |
|
| 14 | +use PHPUnit\Framework\Assert; |
14 | 15 | use PHPUnit\Framework\TestCase; |
15 | 16 | use Symfony\Component\Console\Attribute\Argument; |
16 | 17 | use Symfony\Component\Console\Attribute\Option; |
17 | 18 | use Symfony\Component\Console\Command\Command; |
18 | 19 | use Symfony\Component\Console\Completion\CompletionInput; |
19 | 20 | use Symfony\Component\Console\Completion\CompletionSuggestions; |
20 | 21 | use Symfony\Component\Console\Completion\Suggestion; |
| 22 | +use Symfony\Component\Console\Exception\InvalidArgumentException; |
21 | 23 | use Symfony\Component\Console\Exception\InvalidOptionException; |
22 | 24 | use Symfony\Component\Console\Exception\LogicException; |
23 | 25 | use Symfony\Component\Console\Input\ArrayInput; |
@@ -132,6 +134,88 @@ public function testCommandInputOptionDefinition() |
132 | 134 | self::assertFalse($optInputOption->getDefault()); |
133 | 135 | } |
134 | 136 |
|
| 137 | + public function testEnumArgument() |
| 138 | + { |
| 139 | + $command = new Command('foo'); |
| 140 | + $command->setCode(function ( |
| 141 | + #[Argument] StringEnum $enum, |
| 142 | + #[Argument] StringEnum $enumWithDefault = StringEnum::Image, |
| 143 | + #[Argument] ?StringEnum $nullableEnum = null, |
| 144 | + ): int { |
| 145 | + Assert::assertSame(StringEnum::Image, $enum); |
| 146 | + Assert::assertSame(StringEnum::Image, $enumWithDefault); |
| 147 | + Assert::assertNull($nullableEnum); |
| 148 | + |
| 149 | + return 0; |
| 150 | + }); |
| 151 | + |
| 152 | + $enumInputArgument = $command->getDefinition()->getArgument('enum'); |
| 153 | + self::assertTrue($enumInputArgument->isRequired()); |
| 154 | + self::assertNull($enumInputArgument->getDefault()); |
| 155 | + self::assertTrue($enumInputArgument->hasCompletion()); |
| 156 | + |
| 157 | + $enumWithDefaultInputArgument = $command->getDefinition()->getArgument('enum-with-default'); |
| 158 | + self::assertFalse($enumWithDefaultInputArgument->isRequired()); |
| 159 | + self::assertSame('image', $enumWithDefaultInputArgument->getDefault()); |
| 160 | + self::assertTrue($enumWithDefaultInputArgument->hasCompletion()); |
| 161 | + |
| 162 | + $nullableEnumInputArgument = $command->getDefinition()->getArgument('nullable-enum'); |
| 163 | + self::assertFalse($nullableEnumInputArgument->isRequired()); |
| 164 | + self::assertNull($nullableEnumInputArgument->getDefault()); |
| 165 | + self::assertTrue($nullableEnumInputArgument->hasCompletion()); |
| 166 | + |
| 167 | + $enumInputArgument->complete(CompletionInput::fromTokens([], 0), $suggestions = new CompletionSuggestions()); |
| 168 | + self::assertEquals([new Suggestion('image'), new Suggestion('video')], $suggestions->getValueSuggestions()); |
| 169 | + |
| 170 | + $command->run(new ArrayInput(['enum' => 'image']), new NullOutput()); |
| 171 | + |
| 172 | + self::expectException(InvalidArgumentException::class); |
| 173 | + self::expectExceptionMessage('The value "incorrect" is not valid for the "enum" argument. Supported values are "image", "video".'); |
| 174 | + |
| 175 | + $command->run(new ArrayInput(['enum' => 'incorrect']), new NullOutput()); |
| 176 | + } |
| 177 | + |
| 178 | + public function testEnumOption() |
| 179 | + { |
| 180 | + $command = new Command('foo'); |
| 181 | + $command->setCode(function ( |
| 182 | + #[Option] StringEnum $enum = StringEnum::Video, |
| 183 | + #[Option] StringEnum $enumWithDefault = StringEnum::Image, |
| 184 | + #[Option] ?StringEnum $nullableEnum = null, |
| 185 | + ): int { |
| 186 | + Assert::assertSame(StringEnum::Image, $enum); |
| 187 | + Assert::assertSame(StringEnum::Image, $enumWithDefault); |
| 188 | + Assert::assertNull($nullableEnum); |
| 189 | + |
| 190 | + return 0; |
| 191 | + }); |
| 192 | + |
| 193 | + $enumInputOption = $command->getDefinition()->getOption('enum'); |
| 194 | + self::assertTrue($enumInputOption->isValueRequired()); |
| 195 | + self::assertSame('video', $enumInputOption->getDefault()); |
| 196 | + self::assertTrue($enumInputOption->hasCompletion()); |
| 197 | + |
| 198 | + $enumWithDefaultInputOption = $command->getDefinition()->getOption('enum-with-default'); |
| 199 | + self::assertTrue($enumWithDefaultInputOption->isValueRequired()); |
| 200 | + self::assertSame('image', $enumWithDefaultInputOption->getDefault()); |
| 201 | + self::assertTrue($enumWithDefaultInputOption->hasCompletion()); |
| 202 | + |
| 203 | + $nullableEnumInputOption = $command->getDefinition()->getOption('nullable-enum'); |
| 204 | + self::assertTrue($nullableEnumInputOption->isValueRequired()); |
| 205 | + self::assertNull($nullableEnumInputOption->getDefault()); |
| 206 | + self::assertTrue($nullableEnumInputOption->hasCompletion()); |
| 207 | + |
| 208 | + $enumInputOption->complete(CompletionInput::fromTokens([], 0), $suggestions = new CompletionSuggestions()); |
| 209 | + self::assertEquals([new Suggestion('image'), new Suggestion('video')], $suggestions->getValueSuggestions()); |
| 210 | + |
| 211 | + $command->run(new ArrayInput(['--enum' => 'image']), new NullOutput()); |
| 212 | + |
| 213 | + self::expectException(InvalidOptionException::class); |
| 214 | + self::expectExceptionMessage('The value "incorrect" is not valid for the "enum" option. Supported values are "image", "video".'); |
| 215 | + |
| 216 | + $command->run(new ArrayInput(['--enum' => 'incorrect']), new NullOutput()); |
| 217 | + } |
| 218 | + |
135 | 219 | public function testInvalidArgumentType() |
136 | 220 | { |
137 | 221 | $command = new Command('foo'); |
@@ -377,3 +461,10 @@ public function getSuggestedRoles(CompletionInput $input): array |
377 | 461 | return ['ROLE_ADMIN', 'ROLE_USER']; |
378 | 462 | } |
379 | 463 | } |
| 464 | + |
| 465 | + |
| 466 | +enum StringEnum: string |
| 467 | +{ |
| 468 | + case Image = 'image'; |
| 469 | + case Video = 'video'; |
| 470 | +} |
0 commit comments