QuestionHelperTest.php 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Console\Tests\Helper;
  11. use Symfony\Component\Console\Formatter\OutputFormatter;
  12. use Symfony\Component\Console\Helper\FormatterHelper;
  13. use Symfony\Component\Console\Helper\HelperSet;
  14. use Symfony\Component\Console\Helper\QuestionHelper;
  15. use Symfony\Component\Console\Output\StreamOutput;
  16. use Symfony\Component\Console\Question\ChoiceQuestion;
  17. use Symfony\Component\Console\Question\ConfirmationQuestion;
  18. use Symfony\Component\Console\Question\Question;
  19. /**
  20. * @group tty
  21. */
  22. class QuestionHelperTest extends AbstractQuestionHelperTest
  23. {
  24. public function testAskChoice()
  25. {
  26. $questionHelper = new QuestionHelper();
  27. $helperSet = new HelperSet([new FormatterHelper()]);
  28. $questionHelper->setHelperSet($helperSet);
  29. $heroes = ['Superman', 'Batman', 'Spiderman'];
  30. $inputStream = $this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n");
  31. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2');
  32. $question->setMaxAttempts(1);
  33. // first answer is an empty answer, we're supposed to receive the default value
  34. $this->assertEquals('Spiderman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  35. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
  36. $question->setMaxAttempts(1);
  37. $this->assertEquals('Batman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  38. $this->assertEquals('Batman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  39. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
  40. $question->setErrorMessage('Input "%s" is not a superhero!');
  41. $question->setMaxAttempts(2);
  42. $this->assertEquals('Batman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $output = $this->createOutputInterface(), $question));
  43. rewind($output->getStream());
  44. $stream = stream_get_contents($output->getStream());
  45. $this->assertContains('Input "Fabien" is not a superhero!', $stream);
  46. try {
  47. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1');
  48. $question->setMaxAttempts(1);
  49. $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $output = $this->createOutputInterface(), $question);
  50. $this->fail();
  51. } catch (\InvalidArgumentException $e) {
  52. $this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
  53. }
  54. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
  55. $question->setMaxAttempts(1);
  56. $question->setMultiselect(true);
  57. $this->assertEquals(['Batman'], $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  58. $this->assertEquals(['Superman', 'Spiderman'], $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  59. $this->assertEquals(['Superman', 'Spiderman'], $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  60. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1');
  61. $question->setMaxAttempts(1);
  62. $question->setMultiselect(true);
  63. $this->assertEquals(['Superman', 'Batman'], $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  64. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 ');
  65. $question->setMaxAttempts(1);
  66. $question->setMultiselect(true);
  67. $this->assertEquals(['Superman', 'Batman'], $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  68. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, 0);
  69. // We are supposed to get the default value since we are not in interactive mode
  70. $this->assertEquals('Superman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, true), $this->createOutputInterface(), $question));
  71. }
  72. public function testAskChoiceNonInteractive()
  73. {
  74. $questionHelper = new QuestionHelper();
  75. $helperSet = new HelperSet([new FormatterHelper()]);
  76. $questionHelper->setHelperSet($helperSet);
  77. $inputStream = $this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n");
  78. $heroes = ['Superman', 'Batman', 'Spiderman'];
  79. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0');
  80. $this->assertSame('Superman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
  81. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, 'Batman');
  82. $this->assertSame('Batman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
  83. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
  84. $this->assertNull($questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
  85. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0');
  86. $question->setValidator(null);
  87. $this->assertSame('Superman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
  88. try {
  89. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
  90. $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question);
  91. } catch (\InvalidArgumentException $e) {
  92. $this->assertSame('Value "" is invalid', $e->getMessage());
  93. }
  94. $question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '0, 1');
  95. $question->setMultiselect(true);
  96. $this->assertSame(['Superman', 'Batman'], $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
  97. $question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '0, 1');
  98. $question->setMultiselect(true);
  99. $question->setValidator(null);
  100. $this->assertSame(['Superman', 'Batman'], $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
  101. $question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '0, Batman');
  102. $question->setMultiselect(true);
  103. $this->assertSame(['Superman', 'Batman'], $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
  104. $question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, null);
  105. $question->setMultiselect(true);
  106. $this->assertNull($questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
  107. try {
  108. $question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '');
  109. $question->setMultiselect(true);
  110. $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question);
  111. } catch (\InvalidArgumentException $e) {
  112. $this->assertSame('Value "" is invalid', $e->getMessage());
  113. }
  114. }
  115. public function testAsk()
  116. {
  117. $dialog = new QuestionHelper();
  118. $inputStream = $this->getInputStream("\n8AM\n");
  119. $question = new Question('What time is it?', '2PM');
  120. $this->assertEquals('2PM', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  121. $question = new Question('What time is it?', '2PM');
  122. $this->assertEquals('8AM', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $output = $this->createOutputInterface(), $question));
  123. rewind($output->getStream());
  124. $this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
  125. }
  126. public function testAskWithAutocomplete()
  127. {
  128. if (!$this->hasSttyAvailable()) {
  129. $this->markTestSkipped('`stty` is required to test autocomplete functionality');
  130. }
  131. // Acm<NEWLINE>
  132. // Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
  133. // <NEWLINE>
  134. // <UP ARROW><UP ARROW><NEWLINE>
  135. // <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
  136. // <DOWN ARROW><NEWLINE>
  137. // S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
  138. // F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
  139. $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");
  140. $dialog = new QuestionHelper();
  141. $helperSet = new HelperSet([new FormatterHelper()]);
  142. $dialog->setHelperSet($helperSet);
  143. $question = new Question('Please select a bundle', 'FrameworkBundle');
  144. $question->setAutocompleterValues(['AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle']);
  145. $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  146. $this->assertEquals('AsseticBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  147. $this->assertEquals('FrameworkBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  148. $this->assertEquals('SecurityBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  149. $this->assertEquals('FooBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  150. $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  151. $this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  152. $this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  153. }
  154. public function testAskWithAutocompleteWithNonSequentialKeys()
  155. {
  156. if (!$this->hasSttyAvailable()) {
  157. $this->markTestSkipped('`stty` is required to test autocomplete functionality');
  158. }
  159. // <UP ARROW><UP ARROW><NEWLINE><DOWN ARROW><DOWN ARROW><NEWLINE>
  160. $inputStream = $this->getInputStream("\033[A\033[A\n\033[B\033[B\n");
  161. $dialog = new QuestionHelper();
  162. $dialog->setHelperSet(new HelperSet([new FormatterHelper()]));
  163. $question = new ChoiceQuestion('Please select a bundle', [1 => 'AcmeDemoBundle', 4 => 'AsseticBundle']);
  164. $question->setMaxAttempts(1);
  165. $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  166. $this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  167. }
  168. public function testAskWithAutocompleteWithExactMatch()
  169. {
  170. if (!$this->hasSttyAvailable()) {
  171. $this->markTestSkipped('`stty` is required to test autocomplete functionality');
  172. }
  173. $inputStream = $this->getInputStream("b\n");
  174. $possibleChoices = [
  175. 'a' => 'berlin',
  176. 'b' => 'copenhagen',
  177. 'c' => 'amsterdam',
  178. ];
  179. $dialog = new QuestionHelper();
  180. $dialog->setHelperSet(new HelperSet([new FormatterHelper()]));
  181. $question = new ChoiceQuestion('Please select a city', $possibleChoices);
  182. $question->setMaxAttempts(1);
  183. $this->assertSame('b', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  184. }
  185. public function getInputs()
  186. {
  187. return [
  188. ['$'], // 1 byte character
  189. ['¢'], // 2 bytes character
  190. ['€'], // 3 bytes character
  191. ['𐍈'], // 4 bytes character
  192. ];
  193. }
  194. /**
  195. * @dataProvider getInputs
  196. */
  197. public function testAskWithAutocompleteWithMultiByteCharacter($character)
  198. {
  199. if (!$this->hasSttyAvailable()) {
  200. $this->markTestSkipped('`stty` is required to test autocomplete functionality');
  201. }
  202. $inputStream = $this->getInputStream("$character\n");
  203. $possibleChoices = [
  204. '$' => '1 byte character',
  205. '¢' => '2 bytes character',
  206. '€' => '3 bytes character',
  207. '𐍈' => '4 bytes character',
  208. ];
  209. $dialog = new QuestionHelper();
  210. $dialog->setHelperSet(new HelperSet([new FormatterHelper()]));
  211. $question = new ChoiceQuestion('Please select a character', $possibleChoices);
  212. $question->setMaxAttempts(1);
  213. $this->assertSame($character, $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  214. }
  215. public function testAutocompleteWithTrailingBackslash()
  216. {
  217. if (!$this->hasSttyAvailable()) {
  218. $this->markTestSkipped('`stty` is required to test autocomplete functionality');
  219. }
  220. $inputStream = $this->getInputStream('E');
  221. $dialog = new QuestionHelper();
  222. $helperSet = new HelperSet([new FormatterHelper()]);
  223. $dialog->setHelperSet($helperSet);
  224. $question = new Question('');
  225. $expectedCompletion = 'ExampleNamespace\\';
  226. $question->setAutocompleterValues([$expectedCompletion]);
  227. $output = $this->createOutputInterface();
  228. $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $output, $question);
  229. $outputStream = $output->getStream();
  230. rewind($outputStream);
  231. $actualOutput = stream_get_contents($outputStream);
  232. // Shell control (esc) sequences are not so important: we only care that
  233. // <hl> tag is interpreted correctly and replaced
  234. $irrelevantEscSequences = [
  235. "\0337" => '', // Save cursor position
  236. "\0338" => '', // Restore cursor position
  237. "\033[K" => '', // Clear line from cursor till the end
  238. ];
  239. $importantActualOutput = strtr($actualOutput, $irrelevantEscSequences);
  240. // Remove colors (e.g. "\033[30m", "\033[31;41m")
  241. $importantActualOutput = preg_replace('/\033\[\d+(;\d+)?m/', '', $importantActualOutput);
  242. $this->assertEquals($expectedCompletion, $importantActualOutput);
  243. }
  244. public function testAskHiddenResponse()
  245. {
  246. if ('\\' === \DIRECTORY_SEPARATOR) {
  247. $this->markTestSkipped('This test is not supported on Windows');
  248. }
  249. $dialog = new QuestionHelper();
  250. $question = new Question('What time is it?');
  251. $question->setHidden(true);
  252. $this->assertEquals('8AM', $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("8AM\n")), $this->createOutputInterface(), $question));
  253. }
  254. /**
  255. * @dataProvider getAskConfirmationData
  256. */
  257. public function testAskConfirmation($question, $expected, $default = true)
  258. {
  259. $dialog = new QuestionHelper();
  260. $inputStream = $this->getInputStream($question."\n");
  261. $question = new ConfirmationQuestion('Do you like French fries?', $default);
  262. $this->assertEquals($expected, $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question), 'confirmation question should '.($expected ? 'pass' : 'cancel'));
  263. }
  264. public function getAskConfirmationData()
  265. {
  266. return [
  267. ['', true],
  268. ['', false, false],
  269. ['y', true],
  270. ['yes', true],
  271. ['n', false],
  272. ['no', false],
  273. ];
  274. }
  275. public function testAskConfirmationWithCustomTrueAnswer()
  276. {
  277. $dialog = new QuestionHelper();
  278. $inputStream = $this->getInputStream("j\ny\n");
  279. $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
  280. $this->assertTrue($dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  281. $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
  282. $this->assertTrue($dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  283. }
  284. public function testAskAndValidate()
  285. {
  286. $dialog = new QuestionHelper();
  287. $helperSet = new HelperSet([new FormatterHelper()]);
  288. $dialog->setHelperSet($helperSet);
  289. $error = 'This is not a color!';
  290. $validator = function ($color) use ($error) {
  291. if (!\in_array($color, ['white', 'black'])) {
  292. throw new \InvalidArgumentException($error);
  293. }
  294. return $color;
  295. };
  296. $question = new Question('What color was the white horse of Henry IV?', 'white');
  297. $question->setValidator($validator);
  298. $question->setMaxAttempts(2);
  299. $inputStream = $this->getInputStream("\nblack\n");
  300. $this->assertEquals('white', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  301. $this->assertEquals('black', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  302. try {
  303. $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("green\nyellow\norange\n")), $this->createOutputInterface(), $question);
  304. $this->fail();
  305. } catch (\InvalidArgumentException $e) {
  306. $this->assertEquals($error, $e->getMessage());
  307. }
  308. }
  309. /**
  310. * @dataProvider simpleAnswerProvider
  311. */
  312. public function testSelectChoiceFromSimpleChoices($providedAnswer, $expectedValue)
  313. {
  314. $possibleChoices = [
  315. 'My environment 1',
  316. 'My environment 2',
  317. 'My environment 3',
  318. ];
  319. $dialog = new QuestionHelper();
  320. $helperSet = new HelperSet([new FormatterHelper()]);
  321. $dialog->setHelperSet($helperSet);
  322. $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
  323. $question->setMaxAttempts(1);
  324. $answer = $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream($providedAnswer."\n")), $this->createOutputInterface(), $question);
  325. $this->assertSame($expectedValue, $answer);
  326. }
  327. public function simpleAnswerProvider()
  328. {
  329. return [
  330. [0, 'My environment 1'],
  331. [1, 'My environment 2'],
  332. [2, 'My environment 3'],
  333. ['My environment 1', 'My environment 1'],
  334. ['My environment 2', 'My environment 2'],
  335. ['My environment 3', 'My environment 3'],
  336. ];
  337. }
  338. /**
  339. * @dataProvider specialCharacterInMultipleChoice
  340. */
  341. public function testSpecialCharacterChoiceFromMultipleChoiceList($providedAnswer, $expectedValue)
  342. {
  343. $possibleChoices = [
  344. '.',
  345. 'src',
  346. ];
  347. $dialog = new QuestionHelper();
  348. $inputStream = $this->getInputStream($providedAnswer."\n");
  349. $helperSet = new HelperSet([new FormatterHelper()]);
  350. $dialog->setHelperSet($helperSet);
  351. $question = new ChoiceQuestion('Please select the directory', $possibleChoices);
  352. $question->setMaxAttempts(1);
  353. $question->setMultiselect(true);
  354. $answer = $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question);
  355. $this->assertSame($expectedValue, $answer);
  356. }
  357. public function specialCharacterInMultipleChoice()
  358. {
  359. return [
  360. ['.', ['.']],
  361. ['., src', ['.', 'src']],
  362. ];
  363. }
  364. /**
  365. * @dataProvider mixedKeysChoiceListAnswerProvider
  366. */
  367. public function testChoiceFromChoicelistWithMixedKeys($providedAnswer, $expectedValue)
  368. {
  369. $possibleChoices = [
  370. '0' => 'No environment',
  371. '1' => 'My environment 1',
  372. 'env_2' => 'My environment 2',
  373. 3 => 'My environment 3',
  374. ];
  375. $dialog = new QuestionHelper();
  376. $helperSet = new HelperSet([new FormatterHelper()]);
  377. $dialog->setHelperSet($helperSet);
  378. $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
  379. $question->setMaxAttempts(1);
  380. $answer = $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream($providedAnswer."\n")), $this->createOutputInterface(), $question);
  381. $this->assertSame($expectedValue, $answer);
  382. }
  383. public function mixedKeysChoiceListAnswerProvider()
  384. {
  385. return [
  386. ['0', '0'],
  387. ['No environment', '0'],
  388. ['1', '1'],
  389. ['env_2', 'env_2'],
  390. [3, '3'],
  391. ['My environment 1', '1'],
  392. ];
  393. }
  394. /**
  395. * @dataProvider answerProvider
  396. */
  397. public function testSelectChoiceFromChoiceList($providedAnswer, $expectedValue)
  398. {
  399. $possibleChoices = [
  400. 'env_1' => 'My environment 1',
  401. 'env_2' => 'My environment',
  402. 'env_3' => 'My environment',
  403. ];
  404. $dialog = new QuestionHelper();
  405. $helperSet = new HelperSet([new FormatterHelper()]);
  406. $dialog->setHelperSet($helperSet);
  407. $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
  408. $question->setMaxAttempts(1);
  409. $answer = $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream($providedAnswer."\n")), $this->createOutputInterface(), $question);
  410. $this->assertSame($expectedValue, $answer);
  411. }
  412. /**
  413. * @expectedException \InvalidArgumentException
  414. * @expectedExceptionMessage The provided answer is ambiguous. Value should be one of env_2 or env_3.
  415. */
  416. public function testAmbiguousChoiceFromChoicelist()
  417. {
  418. $possibleChoices = [
  419. 'env_1' => 'My first environment',
  420. 'env_2' => 'My environment',
  421. 'env_3' => 'My environment',
  422. ];
  423. $dialog = new QuestionHelper();
  424. $helperSet = new HelperSet([new FormatterHelper()]);
  425. $dialog->setHelperSet($helperSet);
  426. $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
  427. $question->setMaxAttempts(1);
  428. $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("My environment\n")), $this->createOutputInterface(), $question);
  429. }
  430. public function answerProvider()
  431. {
  432. return [
  433. ['env_1', 'env_1'],
  434. ['env_2', 'env_2'],
  435. ['env_3', 'env_3'],
  436. ['My environment 1', 'env_1'],
  437. ];
  438. }
  439. public function testNoInteraction()
  440. {
  441. $dialog = new QuestionHelper();
  442. $question = new Question('Do you have a job?', 'not yet');
  443. $this->assertEquals('not yet', $dialog->ask($this->createStreamableInputInterfaceMock(null, false), $this->createOutputInterface(), $question));
  444. }
  445. /**
  446. * @requires function mb_strwidth
  447. */
  448. public function testChoiceOutputFormattingQuestionForUtf8Keys()
  449. {
  450. $question = 'Lorem ipsum?';
  451. $possibleChoices = [
  452. 'foo' => 'foo',
  453. 'żółw' => 'bar',
  454. 'łabądź' => 'baz',
  455. ];
  456. $outputShown = [
  457. $question,
  458. ' [<info>foo </info>] foo',
  459. ' [<info>żółw </info>] bar',
  460. ' [<info>łabądź</info>] baz',
  461. ];
  462. $output = $this->getMockBuilder('\Symfony\Component\Console\Output\OutputInterface')->getMock();
  463. $output->method('getFormatter')->willReturn(new OutputFormatter());
  464. $dialog = new QuestionHelper();
  465. $helperSet = new HelperSet([new FormatterHelper()]);
  466. $dialog->setHelperSet($helperSet);
  467. $output->expects($this->once())->method('writeln')->with($this->equalTo($outputShown));
  468. $question = new ChoiceQuestion($question, $possibleChoices, 'foo');
  469. $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("\n")), $output, $question);
  470. }
  471. /**
  472. * @group legacy
  473. */
  474. public function testLegacyAskChoice()
  475. {
  476. $questionHelper = new QuestionHelper();
  477. $helperSet = new HelperSet([new FormatterHelper()]);
  478. $questionHelper->setHelperSet($helperSet);
  479. $heroes = ['Superman', 'Batman', 'Spiderman'];
  480. $questionHelper->setInputStream($this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n"));
  481. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2');
  482. $question->setMaxAttempts(1);
  483. // first answer is an empty answer, we're supposed to receive the default value
  484. $this->assertEquals('Spiderman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  485. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
  486. $question->setMaxAttempts(1);
  487. $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  488. $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  489. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
  490. $question->setErrorMessage('Input "%s" is not a superhero!');
  491. $question->setMaxAttempts(2);
  492. $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
  493. rewind($output->getStream());
  494. $stream = stream_get_contents($output->getStream());
  495. $this->assertContains('Input "Fabien" is not a superhero!', $stream);
  496. try {
  497. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1');
  498. $question->setMaxAttempts(1);
  499. $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question);
  500. $this->fail();
  501. } catch (\InvalidArgumentException $e) {
  502. $this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
  503. }
  504. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
  505. $question->setMaxAttempts(1);
  506. $question->setMultiselect(true);
  507. $this->assertEquals(['Batman'], $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  508. $this->assertEquals(['Superman', 'Spiderman'], $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  509. $this->assertEquals(['Superman', 'Spiderman'], $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  510. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1');
  511. $question->setMaxAttempts(1);
  512. $question->setMultiselect(true);
  513. $this->assertEquals(['Superman', 'Batman'], $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  514. $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 ');
  515. $question->setMaxAttempts(1);
  516. $question->setMultiselect(true);
  517. $this->assertEquals(['Superman', 'Batman'], $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  518. }
  519. /**
  520. * @group legacy
  521. */
  522. public function testLegacyAsk()
  523. {
  524. $dialog = new QuestionHelper();
  525. $dialog->setInputStream($this->getInputStream("\n8AM\n"));
  526. $question = new Question('What time is it?', '2PM');
  527. $this->assertEquals('2PM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  528. $question = new Question('What time is it?', '2PM');
  529. $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
  530. rewind($output->getStream());
  531. $this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
  532. }
  533. /**
  534. * @group legacy
  535. */
  536. public function testLegacyAskWithAutocomplete()
  537. {
  538. if (!$this->hasSttyAvailable()) {
  539. $this->markTestSkipped('`stty` is required to test autocomplete functionality');
  540. }
  541. // Acm<NEWLINE>
  542. // Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
  543. // <NEWLINE>
  544. // <UP ARROW><UP ARROW><NEWLINE>
  545. // <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
  546. // <DOWN ARROW><NEWLINE>
  547. // S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
  548. // F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
  549. $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");
  550. $dialog = new QuestionHelper();
  551. $dialog->setInputStream($inputStream);
  552. $helperSet = new HelperSet([new FormatterHelper()]);
  553. $dialog->setHelperSet($helperSet);
  554. $question = new Question('Please select a bundle', 'FrameworkBundle');
  555. $question->setAutocompleterValues(['AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle']);
  556. $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  557. $this->assertEquals('AsseticBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  558. $this->assertEquals('FrameworkBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  559. $this->assertEquals('SecurityBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  560. $this->assertEquals('FooBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  561. $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  562. $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  563. $this->assertEquals('FooBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  564. }
  565. /**
  566. * @group legacy
  567. */
  568. public function testLegacyAskWithAutocompleteWithNonSequentialKeys()
  569. {
  570. if (!$this->hasSttyAvailable()) {
  571. $this->markTestSkipped('`stty` is required to test autocomplete functionality');
  572. }
  573. // <UP ARROW><UP ARROW><NEWLINE><DOWN ARROW><DOWN ARROW><NEWLINE>
  574. $inputStream = $this->getInputStream("\033[A\033[A\n\033[B\033[B\n");
  575. $dialog = new QuestionHelper();
  576. $dialog->setInputStream($inputStream);
  577. $dialog->setHelperSet(new HelperSet([new FormatterHelper()]));
  578. $question = new ChoiceQuestion('Please select a bundle', [1 => 'AcmeDemoBundle', 4 => 'AsseticBundle']);
  579. $question->setMaxAttempts(1);
  580. $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  581. $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  582. }
  583. /**
  584. * @group legacy
  585. */
  586. public function testLegacyAskHiddenResponse()
  587. {
  588. if ('\\' === \DIRECTORY_SEPARATOR) {
  589. $this->markTestSkipped('This test is not supported on Windows');
  590. }
  591. $dialog = new QuestionHelper();
  592. $dialog->setInputStream($this->getInputStream("8AM\n"));
  593. $question = new Question('What time is it?');
  594. $question->setHidden(true);
  595. $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  596. }
  597. /**
  598. * @group legacy
  599. * @dataProvider getAskConfirmationData
  600. */
  601. public function testLegacyAskConfirmation($question, $expected, $default = true)
  602. {
  603. $dialog = new QuestionHelper();
  604. $dialog->setInputStream($this->getInputStream($question."\n"));
  605. $question = new ConfirmationQuestion('Do you like French fries?', $default);
  606. $this->assertEquals($expected, $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question), 'confirmation question should '.($expected ? 'pass' : 'cancel'));
  607. }
  608. /**
  609. * @group legacy
  610. */
  611. public function testLegacyAskConfirmationWithCustomTrueAnswer()
  612. {
  613. $dialog = new QuestionHelper();
  614. $dialog->setInputStream($this->getInputStream("j\ny\n"));
  615. $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
  616. $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  617. $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
  618. $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  619. }
  620. /**
  621. * @group legacy
  622. */
  623. public function testLegacyAskAndValidate()
  624. {
  625. $dialog = new QuestionHelper();
  626. $helperSet = new HelperSet([new FormatterHelper()]);
  627. $dialog->setHelperSet($helperSet);
  628. $error = 'This is not a color!';
  629. $validator = function ($color) use ($error) {
  630. if (!\in_array($color, ['white', 'black'])) {
  631. throw new \InvalidArgumentException($error);
  632. }
  633. return $color;
  634. };
  635. $question = new Question('What color was the white horse of Henry IV?', 'white');
  636. $question->setValidator($validator);
  637. $question->setMaxAttempts(2);
  638. $dialog->setInputStream($this->getInputStream("\nblack\n"));
  639. $this->assertEquals('white', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  640. $this->assertEquals('black', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
  641. $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n"));
  642. try {
  643. $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
  644. $this->fail();
  645. } catch (\InvalidArgumentException $e) {
  646. $this->assertEquals($error, $e->getMessage());
  647. }
  648. }
  649. /**
  650. * @group legacy
  651. * @dataProvider simpleAnswerProvider
  652. */
  653. public function testLegacySelectChoiceFromSimpleChoices($providedAnswer, $expectedValue)
  654. {
  655. $possibleChoices = [
  656. 'My environment 1',
  657. 'My environment 2',
  658. 'My environment 3',
  659. ];
  660. $dialog = new QuestionHelper();
  661. $dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
  662. $helperSet = new HelperSet([new FormatterHelper()]);
  663. $dialog->setHelperSet($helperSet);
  664. $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
  665. $question->setMaxAttempts(1);
  666. $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
  667. $this->assertSame($expectedValue, $answer);
  668. }
  669. /**
  670. * @group legacy
  671. * @dataProvider mixedKeysChoiceListAnswerProvider
  672. */
  673. public function testLegacyChoiceFromChoicelistWithMixedKeys($providedAnswer, $expectedValue)
  674. {
  675. $possibleChoices = [
  676. '0' => 'No environment',
  677. '1' => 'My environment 1',
  678. 'env_2' => 'My environment 2',
  679. 3 => 'My environment 3',
  680. ];
  681. $dialog = new QuestionHelper();
  682. $dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
  683. $helperSet = new HelperSet([new FormatterHelper()]);
  684. $dialog->setHelperSet($helperSet);
  685. $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
  686. $question->setMaxAttempts(1);
  687. $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
  688. $this->assertSame($expectedValue, $answer);
  689. }
  690. /**
  691. * @group legacy
  692. * @dataProvider answerProvider
  693. */
  694. public function testLegacySelectChoiceFromChoiceList($providedAnswer, $expectedValue)
  695. {
  696. $possibleChoices = [
  697. 'env_1' => 'My environment 1',
  698. 'env_2' => 'My environment',
  699. 'env_3' => 'My environment',
  700. ];
  701. $dialog = new QuestionHelper();
  702. $dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
  703. $helperSet = new HelperSet([new FormatterHelper()]);
  704. $dialog->setHelperSet($helperSet);
  705. $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
  706. $question->setMaxAttempts(1);
  707. $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
  708. $this->assertSame($expectedValue, $answer);
  709. }
  710. /**
  711. * @group legacy
  712. * @expectedException \InvalidArgumentException
  713. * @expectedExceptionMessage The provided answer is ambiguous. Value should be one of env_2 or env_3.
  714. */
  715. public function testLegacyAmbiguousChoiceFromChoicelist()
  716. {
  717. $possibleChoices = [
  718. 'env_1' => 'My first environment',
  719. 'env_2' => 'My environment',
  720. 'env_3' => 'My environment',
  721. ];
  722. $dialog = new QuestionHelper();
  723. $dialog->setInputStream($this->getInputStream("My environment\n"));
  724. $helperSet = new HelperSet([new FormatterHelper()]);
  725. $dialog->setHelperSet($helperSet);
  726. $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
  727. $question->setMaxAttempts(1);
  728. $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
  729. }
  730. /**
  731. * @requires function mb_strwidth
  732. * @group legacy
  733. */
  734. public function testLegacyChoiceOutputFormattingQuestionForUtf8Keys()
  735. {
  736. $question = 'Lorem ipsum?';
  737. $possibleChoices = [
  738. 'foo' => 'foo',
  739. 'żółw' => 'bar',
  740. 'łabądź' => 'baz',
  741. ];
  742. $outputShown = [
  743. $question,
  744. ' [<info>foo </info>] foo',
  745. ' [<info>żółw </info>] bar',
  746. ' [<info>łabądź</info>] baz',
  747. ];
  748. $output = $this->getMockBuilder('\Symfony\Component\Console\Output\OutputInterface')->getMock();
  749. $output->method('getFormatter')->willReturn(new OutputFormatter());
  750. $dialog = new QuestionHelper();
  751. $dialog->setInputStream($this->getInputStream("\n"));
  752. $helperSet = new HelperSet([new FormatterHelper()]);
  753. $dialog->setHelperSet($helperSet);
  754. $output->expects($this->once())->method('writeln')->with($this->equalTo($outputShown));
  755. $question = new ChoiceQuestion($question, $possibleChoices, 'foo');
  756. $dialog->ask($this->createInputInterfaceMock(), $output, $question);
  757. }
  758. /**
  759. * @expectedException \Symfony\Component\Console\Exception\RuntimeException
  760. * @expectedExceptionMessage Aborted.
  761. */
  762. public function testAskThrowsExceptionOnMissingInput()
  763. {
  764. $dialog = new QuestionHelper();
  765. $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), new Question('What\'s your name?'));
  766. }
  767. /**
  768. * @expectedException \Symfony\Component\Console\Exception\RuntimeException
  769. * @expectedExceptionMessage Aborted.
  770. */
  771. public function testAskThrowsExceptionOnMissingInputForChoiceQuestion()
  772. {
  773. $dialog = new QuestionHelper();
  774. $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), new ChoiceQuestion('Choice', ['a', 'b']));
  775. }
  776. /**
  777. * @expectedException \Symfony\Component\Console\Exception\RuntimeException
  778. * @expectedExceptionMessage Aborted.
  779. */
  780. public function testAskThrowsExceptionOnMissingInputWithValidator()
  781. {
  782. $dialog = new QuestionHelper();
  783. $question = new Question('What\'s your name?');
  784. $question->setValidator(function () {
  785. if (!$value) {
  786. throw new \Exception('A value is required.');
  787. }
  788. });
  789. $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), $question);
  790. }
  791. /**
  792. * @expectedException \LogicException
  793. * @expectedExceptionMessage Choice question must have at least 1 choice available.
  794. */
  795. public function testEmptyChoices()
  796. {
  797. new ChoiceQuestion('Question', [], 'irrelevant');
  798. }
  799. public function testTraversableAutocomplete()
  800. {
  801. if (!$this->hasSttyAvailable()) {
  802. $this->markTestSkipped('`stty` is required to test autocomplete functionality');
  803. }
  804. // Acm<NEWLINE>
  805. // Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
  806. // <NEWLINE>
  807. // <UP ARROW><UP ARROW><NEWLINE>
  808. // <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
  809. // <DOWN ARROW><NEWLINE>
  810. // S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
  811. // F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
  812. $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");
  813. $dialog = new QuestionHelper();
  814. $helperSet = new HelperSet([new FormatterHelper()]);
  815. $dialog->setHelperSet($helperSet);
  816. $question = new Question('Please select a bundle', 'FrameworkBundle');
  817. $question->setAutocompleterValues(new AutocompleteValues(['irrelevant' => 'AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle']));
  818. $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  819. $this->assertEquals('AsseticBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  820. $this->assertEquals('FrameworkBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  821. $this->assertEquals('SecurityBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  822. $this->assertEquals('FooBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  823. $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  824. $this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  825. $this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
  826. }
  827. protected function getInputStream($input)
  828. {
  829. $stream = fopen('php://memory', 'r+', false);
  830. fwrite($stream, $input);
  831. rewind($stream);
  832. return $stream;
  833. }
  834. protected function createOutputInterface()
  835. {
  836. return new StreamOutput(fopen('php://memory', 'r+', false));
  837. }
  838. protected function createInputInterfaceMock($interactive = true)
  839. {
  840. $mock = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface')->getMock();
  841. $mock->expects($this->any())
  842. ->method('isInteractive')
  843. ->will($this->returnValue($interactive));
  844. return $mock;
  845. }
  846. private function hasSttyAvailable()
  847. {
  848. exec('stty 2>&1', $output, $exitcode);
  849. return 0 === $exitcode;
  850. }
  851. }
  852. class AutocompleteValues implements \IteratorAggregate
  853. {
  854. private $values;
  855. public function __construct(array $values)
  856. {
  857. $this->values = $values;
  858. }
  859. public function getIterator()
  860. {
  861. return new \ArrayIterator($this->values);
  862. }
  863. }