[Console] Fix traversable autocomplete values
This commit is contained in:
parent
6fe8435c6f
commit
965b5b5f8d
@ -134,7 +134,7 @@ class QuestionHelper extends Helper
|
|||||||
$ret = trim($ret);
|
$ret = trim($ret);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$ret = trim($this->autocomplete($output, $question, $inputStream));
|
$ret = trim($this->autocomplete($output, $question, $inputStream, is_array($autocomplete) ? $autocomplete : iterator_to_array($autocomplete, false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$ret = strlen($ret) > 0 ? $ret : $question->getDefault();
|
$ret = strlen($ret) > 0 ? $ret : $question->getDefault();
|
||||||
@ -190,12 +190,12 @@ class QuestionHelper extends Helper
|
|||||||
* @param OutputInterface $output
|
* @param OutputInterface $output
|
||||||
* @param Question $question
|
* @param Question $question
|
||||||
* @param resource $inputStream
|
* @param resource $inputStream
|
||||||
|
* @param array $autocomplete
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function autocomplete(OutputInterface $output, Question $question, $inputStream)
|
private function autocomplete(OutputInterface $output, Question $question, $inputStream, array $autocomplete)
|
||||||
{
|
{
|
||||||
$autocomplete = $question->getAutocompleterValues();
|
|
||||||
$ret = '';
|
$ret = '';
|
||||||
|
|
||||||
$i = 0;
|
$i = 0;
|
||||||
|
@ -137,10 +137,8 @@ class Question
|
|||||||
$values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
|
$values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $values && !is_array($values)) {
|
if (null !== $values && !is_array($values) && !$values instanceof \Traversable) {
|
||||||
if (!$values instanceof \Traversable || !$values instanceof \Countable) {
|
throw new \InvalidArgumentException('Autocompleter values can be either an array, `null` or a `Traversable` object.');
|
||||||
throw new \InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->hidden) {
|
if ($this->hidden) {
|
||||||
|
@ -514,6 +514,40 @@ class QuestionHelperTest extends TestCase
|
|||||||
new ChoiceQuestion('Question', array(), 'irrelevant');
|
new ChoiceQuestion('Question', array(), 'irrelevant');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTraversableAutocomplete()
|
||||||
|
{
|
||||||
|
if (!$this->hasSttyAvailable()) {
|
||||||
|
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acm<NEWLINE>
|
||||||
|
// Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
|
||||||
|
// <NEWLINE>
|
||||||
|
// <UP ARROW><UP ARROW><NEWLINE>
|
||||||
|
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
|
||||||
|
// <DOWN ARROW><NEWLINE>
|
||||||
|
// S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
|
||||||
|
// F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
|
||||||
|
$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");
|
||||||
|
|
||||||
|
$dialog = new QuestionHelper();
|
||||||
|
$dialog->setInputStream($inputStream);
|
||||||
|
$helperSet = new HelperSet(array(new FormatterHelper()));
|
||||||
|
$dialog->setHelperSet($helperSet);
|
||||||
|
|
||||||
|
$question = new Question('Please select a bundle', 'FrameworkBundle');
|
||||||
|
$question->setAutocompleterValues(new AutocompleteValues(array('irrelevant' => 'AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle')));
|
||||||
|
|
||||||
|
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
|
||||||
|
$this->assertEquals('AsseticBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
|
||||||
|
$this->assertEquals('FrameworkBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
|
||||||
|
$this->assertEquals('SecurityBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
|
||||||
|
$this->assertEquals('FooBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
|
||||||
|
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
|
||||||
|
$this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
|
||||||
|
$this->assertEquals('FooBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
|
||||||
|
}
|
||||||
|
|
||||||
protected function getInputStream($input)
|
protected function getInputStream($input)
|
||||||
{
|
{
|
||||||
$stream = fopen('php://memory', 'r+', false);
|
$stream = fopen('php://memory', 'r+', false);
|
||||||
@ -545,3 +579,18 @@ class QuestionHelperTest extends TestCase
|
|||||||
return 0 === $exitcode;
|
return 0 === $exitcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AutocompleteValues implements \IteratorAggregate
|
||||||
|
{
|
||||||
|
private $values;
|
||||||
|
|
||||||
|
public function __construct(array $values)
|
||||||
|
{
|
||||||
|
$this->values = $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return new \ArrayIterator($this->values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user