4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Console\Tests\Helper;
14 use Symfony\Component\Console\Formatter\OutputFormatter;
15 use Symfony\Component\Console\Helper\QuestionHelper;
16 use Symfony\Component\Console\Helper\HelperSet;
17 use Symfony\Component\Console\Helper\FormatterHelper;
18 use Symfony\Component\Console\Output\StreamOutput;
19 use Symfony\Component\Console\Question\ChoiceQuestion;
20 use Symfony\Component\Console\Question\ConfirmationQuestion;
21 use Symfony\Component\Console\Question\Question;
26 class QuestionHelperTest extends AbstractQuestionHelperTest
28 public function testAskChoice()
30 $questionHelper = new QuestionHelper();
32 $helperSet = new HelperSet(array(new FormatterHelper()));
33 $questionHelper->setHelperSet($helperSet);
35 $heroes = array('Superman', 'Batman', 'Spiderman');
37 $inputStream = $this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n");
39 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2');
40 $question->setMaxAttempts(1);
41 // first answer is an empty answer, we're supposed to receive the default value
42 $this->assertEquals('Spiderman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
44 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
45 $question->setMaxAttempts(1);
46 $this->assertEquals('Batman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
47 $this->assertEquals('Batman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
49 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
50 $question->setErrorMessage('Input "%s" is not a superhero!');
51 $question->setMaxAttempts(2);
52 $this->assertEquals('Batman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $output = $this->createOutputInterface(), $question));
54 rewind($output->getStream());
55 $stream = stream_get_contents($output->getStream());
56 $this->assertContains('Input "Fabien" is not a superhero!', $stream);
59 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1');
60 $question->setMaxAttempts(1);
61 $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $output = $this->createOutputInterface(), $question);
63 } catch (\InvalidArgumentException $e) {
64 $this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
67 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
68 $question->setMaxAttempts(1);
69 $question->setMultiselect(true);
71 $this->assertEquals(array('Batman'), $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
72 $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
73 $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
75 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1');
76 $question->setMaxAttempts(1);
77 $question->setMultiselect(true);
79 $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
81 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 ');
82 $question->setMaxAttempts(1);
83 $question->setMultiselect(true);
85 $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
88 public function testAsk()
90 $dialog = new QuestionHelper();
92 $inputStream = $this->getInputStream("\n8AM\n");
94 $question = new Question('What time is it?', '2PM');
95 $this->assertEquals('2PM', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
97 $question = new Question('What time is it?', '2PM');
98 $this->assertEquals('8AM', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $output = $this->createOutputInterface(), $question));
100 rewind($output->getStream());
101 $this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
104 public function testAskWithAutocomplete()
106 if (!$this->hasSttyAvailable()) {
107 $this->markTestSkipped('`stty` is required to test autocomplete functionality');
111 // Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
113 // <UP ARROW><UP ARROW><NEWLINE>
114 // <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
115 // <DOWN ARROW><NEWLINE>
116 // S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
117 // F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
118 $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
120 $dialog = new QuestionHelper();
121 $helperSet = new HelperSet(array(new FormatterHelper()));
122 $dialog->setHelperSet($helperSet);
124 $question = new Question('Please select a bundle', 'FrameworkBundle');
125 $question->setAutocompleterValues(array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle'));
127 $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
128 $this->assertEquals('AsseticBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
129 $this->assertEquals('FrameworkBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
130 $this->assertEquals('SecurityBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
131 $this->assertEquals('FooBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
132 $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
133 $this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
134 $this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
137 public function testAskWithAutocompleteWithNonSequentialKeys()
139 if (!$this->hasSttyAvailable()) {
140 $this->markTestSkipped('`stty` is required to test autocomplete functionality');
143 // <UP ARROW><UP ARROW><NEWLINE><DOWN ARROW><DOWN ARROW><NEWLINE>
144 $inputStream = $this->getInputStream("\033[A\033[A\n\033[B\033[B\n");
146 $dialog = new QuestionHelper();
147 $dialog->setHelperSet(new HelperSet(array(new FormatterHelper())));
149 $question = new ChoiceQuestion('Please select a bundle', array(1 => 'AcmeDemoBundle', 4 => 'AsseticBundle'));
150 $question->setMaxAttempts(1);
152 $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
153 $this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
156 public function testAskHiddenResponse()
158 if ('\\' === DIRECTORY_SEPARATOR) {
159 $this->markTestSkipped('This test is not supported on Windows');
162 $dialog = new QuestionHelper();
164 $question = new Question('What time is it?');
165 $question->setHidden(true);
167 $this->assertEquals('8AM', $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("8AM\n")), $this->createOutputInterface(), $question));
171 * @dataProvider getAskConfirmationData
173 public function testAskConfirmation($question, $expected, $default = true)
175 $dialog = new QuestionHelper();
177 $inputStream = $this->getInputStream($question."\n");
178 $question = new ConfirmationQuestion('Do you like French fries?', $default);
179 $this->assertEquals($expected, $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question), 'confirmation question should '.($expected ? 'pass' : 'cancel'));
182 public function getAskConfirmationData()
186 array('', false, false),
194 public function testAskConfirmationWithCustomTrueAnswer()
196 $dialog = new QuestionHelper();
198 $inputStream = $this->getInputStream("j\ny\n");
199 $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
200 $this->assertTrue($dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
201 $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
202 $this->assertTrue($dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
205 public function testAskAndValidate()
207 $dialog = new QuestionHelper();
208 $helperSet = new HelperSet(array(new FormatterHelper()));
209 $dialog->setHelperSet($helperSet);
211 $error = 'This is not a color!';
212 $validator = function ($color) use ($error) {
213 if (!in_array($color, array('white', 'black'))) {
214 throw new \InvalidArgumentException($error);
220 $question = new Question('What color was the white horse of Henry IV?', 'white');
221 $question->setValidator($validator);
222 $question->setMaxAttempts(2);
224 $inputStream = $this->getInputStream("\nblack\n");
225 $this->assertEquals('white', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
226 $this->assertEquals('black', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
229 $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("green\nyellow\norange\n")), $this->createOutputInterface(), $question);
231 } catch (\InvalidArgumentException $e) {
232 $this->assertEquals($error, $e->getMessage());
237 * @dataProvider simpleAnswerProvider
239 public function testSelectChoiceFromSimpleChoices($providedAnswer, $expectedValue)
241 $possibleChoices = array(
247 $dialog = new QuestionHelper();
248 $helperSet = new HelperSet(array(new FormatterHelper()));
249 $dialog->setHelperSet($helperSet);
251 $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
252 $question->setMaxAttempts(1);
253 $answer = $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream($providedAnswer."\n")), $this->createOutputInterface(), $question);
255 $this->assertSame($expectedValue, $answer);
258 public function simpleAnswerProvider()
261 array(0, 'My environment 1'),
262 array(1, 'My environment 2'),
263 array(2, 'My environment 3'),
264 array('My environment 1', 'My environment 1'),
265 array('My environment 2', 'My environment 2'),
266 array('My environment 3', 'My environment 3'),
271 * @dataProvider specialCharacterInMultipleChoice
273 public function testSpecialCharacterChoiceFromMultipleChoiceList($providedAnswer, $expectedValue)
275 $possibleChoices = array(
280 $dialog = new QuestionHelper();
281 $inputStream = $this->getInputStream($providedAnswer."\n");
282 $helperSet = new HelperSet(array(new FormatterHelper()));
283 $dialog->setHelperSet($helperSet);
285 $question = new ChoiceQuestion('Please select the directory', $possibleChoices);
286 $question->setMaxAttempts(1);
287 $question->setMultiselect(true);
288 $answer = $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question);
290 $this->assertSame($expectedValue, $answer);
293 public function specialCharacterInMultipleChoice()
296 array('.', array('.')),
297 array('., src', array('.', 'src')),
302 * @dataProvider mixedKeysChoiceListAnswerProvider
304 public function testChoiceFromChoicelistWithMixedKeys($providedAnswer, $expectedValue)
306 $possibleChoices = array(
307 '0' => 'No environment',
308 '1' => 'My environment 1',
309 'env_2' => 'My environment 2',
310 3 => 'My environment 3',
313 $dialog = new QuestionHelper();
314 $helperSet = new HelperSet(array(new FormatterHelper()));
315 $dialog->setHelperSet($helperSet);
317 $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
318 $question->setMaxAttempts(1);
319 $answer = $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream($providedAnswer."\n")), $this->createOutputInterface(), $question);
321 $this->assertSame($expectedValue, $answer);
324 public function mixedKeysChoiceListAnswerProvider()
328 array('No environment', '0'),
330 array('env_2', 'env_2'),
332 array('My environment 1', '1'),
337 * @dataProvider answerProvider
339 public function testSelectChoiceFromChoiceList($providedAnswer, $expectedValue)
341 $possibleChoices = array(
342 'env_1' => 'My environment 1',
343 'env_2' => 'My environment',
344 'env_3' => 'My environment',
347 $dialog = new QuestionHelper();
348 $helperSet = new HelperSet(array(new FormatterHelper()));
349 $dialog->setHelperSet($helperSet);
351 $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
352 $question->setMaxAttempts(1);
353 $answer = $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream($providedAnswer."\n")), $this->createOutputInterface(), $question);
355 $this->assertSame($expectedValue, $answer);
359 * @expectedException \InvalidArgumentException
360 * @expectedExceptionMessage The provided answer is ambiguous. Value should be one of env_2 or env_3.
362 public function testAmbiguousChoiceFromChoicelist()
364 $possibleChoices = array(
365 'env_1' => 'My first environment',
366 'env_2' => 'My environment',
367 'env_3' => 'My environment',
370 $dialog = new QuestionHelper();
371 $helperSet = new HelperSet(array(new FormatterHelper()));
372 $dialog->setHelperSet($helperSet);
374 $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
375 $question->setMaxAttempts(1);
377 $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("My environment\n")), $this->createOutputInterface(), $question);
380 public function answerProvider()
383 array('env_1', 'env_1'),
384 array('env_2', 'env_2'),
385 array('env_3', 'env_3'),
386 array('My environment 1', 'env_1'),
390 public function testNoInteraction()
392 $dialog = new QuestionHelper();
393 $question = new Question('Do you have a job?', 'not yet');
394 $this->assertEquals('not yet', $dialog->ask($this->createStreamableInputInterfaceMock(null, false), $this->createOutputInterface(), $question));
398 * @requires function mb_strwidth
400 public function testChoiceOutputFormattingQuestionForUtf8Keys()
402 $question = 'Lorem ipsum?';
403 $possibleChoices = array(
408 $outputShown = array(
410 ' [<info>foo </info>] foo',
411 ' [<info>żółw </info>] bar',
412 ' [<info>łabądź</info>] baz',
414 $output = $this->getMockBuilder('\Symfony\Component\Console\Output\OutputInterface')->getMock();
415 $output->method('getFormatter')->willReturn(new OutputFormatter());
417 $dialog = new QuestionHelper();
418 $helperSet = new HelperSet(array(new FormatterHelper()));
419 $dialog->setHelperSet($helperSet);
421 $output->expects($this->once())->method('writeln')->with($this->equalTo($outputShown));
423 $question = new ChoiceQuestion($question, $possibleChoices, 'foo');
424 $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("\n")), $output, $question);
430 public function testLegacyAskChoice()
432 $questionHelper = new QuestionHelper();
434 $helperSet = new HelperSet(array(new FormatterHelper()));
435 $questionHelper->setHelperSet($helperSet);
437 $heroes = array('Superman', 'Batman', 'Spiderman');
439 $questionHelper->setInputStream($this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n"));
441 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2');
442 $question->setMaxAttempts(1);
443 // first answer is an empty answer, we're supposed to receive the default value
444 $this->assertEquals('Spiderman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
446 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
447 $question->setMaxAttempts(1);
448 $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
449 $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
451 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
452 $question->setErrorMessage('Input "%s" is not a superhero!');
453 $question->setMaxAttempts(2);
454 $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
456 rewind($output->getStream());
457 $stream = stream_get_contents($output->getStream());
458 $this->assertContains('Input "Fabien" is not a superhero!', $stream);
461 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1');
462 $question->setMaxAttempts(1);
463 $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question);
465 } catch (\InvalidArgumentException $e) {
466 $this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
469 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
470 $question->setMaxAttempts(1);
471 $question->setMultiselect(true);
473 $this->assertEquals(array('Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
474 $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
475 $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
477 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1');
478 $question->setMaxAttempts(1);
479 $question->setMultiselect(true);
481 $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
483 $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 ');
484 $question->setMaxAttempts(1);
485 $question->setMultiselect(true);
487 $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
493 public function testLegacyAsk()
495 $dialog = new QuestionHelper();
497 $dialog->setInputStream($this->getInputStream("\n8AM\n"));
499 $question = new Question('What time is it?', '2PM');
500 $this->assertEquals('2PM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
502 $question = new Question('What time is it?', '2PM');
503 $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
505 rewind($output->getStream());
506 $this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
512 public function testLegacyAskWithAutocomplete()
514 if (!$this->hasSttyAvailable()) {
515 $this->markTestSkipped('`stty` is required to test autocomplete functionality');
519 // Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
521 // <UP ARROW><UP ARROW><NEWLINE>
522 // <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
523 // <DOWN ARROW><NEWLINE>
524 // S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
525 // F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
526 $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
528 $dialog = new QuestionHelper();
529 $dialog->setInputStream($inputStream);
530 $helperSet = new HelperSet(array(new FormatterHelper()));
531 $dialog->setHelperSet($helperSet);
533 $question = new Question('Please select a bundle', 'FrameworkBundle');
534 $question->setAutocompleterValues(array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle'));
536 $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
537 $this->assertEquals('AsseticBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
538 $this->assertEquals('FrameworkBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
539 $this->assertEquals('SecurityBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
540 $this->assertEquals('FooBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
541 $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
542 $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
543 $this->assertEquals('FooBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
549 public function testLegacyAskWithAutocompleteWithNonSequentialKeys()
551 if (!$this->hasSttyAvailable()) {
552 $this->markTestSkipped('`stty` is required to test autocomplete functionality');
555 // <UP ARROW><UP ARROW><NEWLINE><DOWN ARROW><DOWN ARROW><NEWLINE>
556 $inputStream = $this->getInputStream("\033[A\033[A\n\033[B\033[B\n");
558 $dialog = new QuestionHelper();
559 $dialog->setInputStream($inputStream);
560 $dialog->setHelperSet(new HelperSet(array(new FormatterHelper())));
562 $question = new ChoiceQuestion('Please select a bundle', array(1 => 'AcmeDemoBundle', 4 => 'AsseticBundle'));
563 $question->setMaxAttempts(1);
565 $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
566 $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
572 public function testLegacyAskHiddenResponse()
574 if ('\\' === DIRECTORY_SEPARATOR) {
575 $this->markTestSkipped('This test is not supported on Windows');
578 $dialog = new QuestionHelper();
579 $dialog->setInputStream($this->getInputStream("8AM\n"));
581 $question = new Question('What time is it?');
582 $question->setHidden(true);
584 $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
589 * @dataProvider getAskConfirmationData
591 public function testLegacyAskConfirmation($question, $expected, $default = true)
593 $dialog = new QuestionHelper();
595 $dialog->setInputStream($this->getInputStream($question."\n"));
596 $question = new ConfirmationQuestion('Do you like French fries?', $default);
597 $this->assertEquals($expected, $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question), 'confirmation question should '.($expected ? 'pass' : 'cancel'));
603 public function testLegacyAskConfirmationWithCustomTrueAnswer()
605 $dialog = new QuestionHelper();
607 $dialog->setInputStream($this->getInputStream("j\ny\n"));
608 $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
609 $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
610 $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
611 $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
617 public function testLegacyAskAndValidate()
619 $dialog = new QuestionHelper();
620 $helperSet = new HelperSet(array(new FormatterHelper()));
621 $dialog->setHelperSet($helperSet);
623 $error = 'This is not a color!';
624 $validator = function ($color) use ($error) {
625 if (!in_array($color, array('white', 'black'))) {
626 throw new \InvalidArgumentException($error);
632 $question = new Question('What color was the white horse of Henry IV?', 'white');
633 $question->setValidator($validator);
634 $question->setMaxAttempts(2);
636 $dialog->setInputStream($this->getInputStream("\nblack\n"));
637 $this->assertEquals('white', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
638 $this->assertEquals('black', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
640 $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n"));
642 $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
644 } catch (\InvalidArgumentException $e) {
645 $this->assertEquals($error, $e->getMessage());
651 * @dataProvider simpleAnswerProvider
653 public function testLegacySelectChoiceFromSimpleChoices($providedAnswer, $expectedValue)
655 $possibleChoices = array(
661 $dialog = new QuestionHelper();
662 $dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
663 $helperSet = new HelperSet(array(new FormatterHelper()));
664 $dialog->setHelperSet($helperSet);
666 $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
667 $question->setMaxAttempts(1);
668 $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
670 $this->assertSame($expectedValue, $answer);
675 * @dataProvider mixedKeysChoiceListAnswerProvider
677 public function testLegacyChoiceFromChoicelistWithMixedKeys($providedAnswer, $expectedValue)
679 $possibleChoices = array(
680 '0' => 'No environment',
681 '1' => 'My environment 1',
682 'env_2' => 'My environment 2',
683 3 => 'My environment 3',
686 $dialog = new QuestionHelper();
687 $dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
688 $helperSet = new HelperSet(array(new FormatterHelper()));
689 $dialog->setHelperSet($helperSet);
691 $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
692 $question->setMaxAttempts(1);
693 $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
695 $this->assertSame($expectedValue, $answer);
700 * @dataProvider answerProvider
702 public function testLegacySelectChoiceFromChoiceList($providedAnswer, $expectedValue)
704 $possibleChoices = array(
705 'env_1' => 'My environment 1',
706 'env_2' => 'My environment',
707 'env_3' => 'My environment',
710 $dialog = new QuestionHelper();
711 $dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
712 $helperSet = new HelperSet(array(new FormatterHelper()));
713 $dialog->setHelperSet($helperSet);
715 $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
716 $question->setMaxAttempts(1);
717 $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
719 $this->assertSame($expectedValue, $answer);
724 * @expectedException \InvalidArgumentException
725 * @expectedExceptionMessage The provided answer is ambiguous. Value should be one of env_2 or env_3.
727 public function testLegacyAmbiguousChoiceFromChoicelist()
729 $possibleChoices = array(
730 'env_1' => 'My first environment',
731 'env_2' => 'My environment',
732 'env_3' => 'My environment',
735 $dialog = new QuestionHelper();
736 $dialog->setInputStream($this->getInputStream("My environment\n"));
737 $helperSet = new HelperSet(array(new FormatterHelper()));
738 $dialog->setHelperSet($helperSet);
740 $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
741 $question->setMaxAttempts(1);
743 $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
747 * @requires function mb_strwidth
750 public function testLegacyChoiceOutputFormattingQuestionForUtf8Keys()
752 $question = 'Lorem ipsum?';
753 $possibleChoices = array(
758 $outputShown = array(
760 ' [<info>foo </info>] foo',
761 ' [<info>żółw </info>] bar',
762 ' [<info>łabądź</info>] baz',
764 $output = $this->getMockBuilder('\Symfony\Component\Console\Output\OutputInterface')->getMock();
765 $output->method('getFormatter')->willReturn(new OutputFormatter());
767 $dialog = new QuestionHelper();
768 $dialog->setInputStream($this->getInputStream("\n"));
769 $helperSet = new HelperSet(array(new FormatterHelper()));
770 $dialog->setHelperSet($helperSet);
772 $output->expects($this->once())->method('writeln')->with($this->equalTo($outputShown));
774 $question = new ChoiceQuestion($question, $possibleChoices, 'foo');
775 $dialog->ask($this->createInputInterfaceMock(), $output, $question);
779 * @expectedException \Symfony\Component\Console\Exception\RuntimeException
780 * @expectedExceptionMessage Aborted
782 public function testAskThrowsExceptionOnMissingInput()
784 $dialog = new QuestionHelper();
785 $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), new Question('What\'s your name?'));
789 * @expectedException \Symfony\Component\Console\Exception\RuntimeException
790 * @expectedExceptionMessage Aborted
792 public function testAskThrowsExceptionOnMissingInputWithValidator()
794 $dialog = new QuestionHelper();
796 $question = new Question('What\'s your name?');
797 $question->setValidator(function () {
799 throw new \Exception('A value is required.');
803 $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), $question);
807 * @expectedException \LogicException
808 * @expectedExceptionMessage Choice question must have at least 1 choice available.
810 public function testEmptyChoices()
812 new ChoiceQuestion('Question', array(), 'irrelevant');
815 protected function getInputStream($input)
817 $stream = fopen('php://memory', 'r+', false);
818 fwrite($stream, $input);
824 protected function createOutputInterface()
826 return new StreamOutput(fopen('php://memory', 'r+', false));
829 protected function createInputInterfaceMock($interactive = true)
831 $mock = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface')->getMock();
832 $mock->expects($this->any())
833 ->method('isInteractive')
834 ->will($this->returnValue($interactive));
839 private function hasSttyAvailable()
841 exec('stty 2>&1', $output, $exitcode);
843 return $exitcode === 0;