Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6cef233

Browse files
committed
[Console] allow answer to be trimmed by adding a flag
1 parent 5dba412 commit 6cef233

File tree

4 files changed

+101
-9
lines changed

4 files changed

+101
-9
lines changed

src/Symfony/Component/Console/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
4.4.0
5+
-----
6+
7+
* added `Question::setTrimmable` default to true to allow the anwser to be trimmed or not
8+
49
4.3.0
510
-----
611

src/Symfony/Component/Console/Helper/QuestionHelper.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public function ask(InputInterface $input, OutputInterface $output, Question $qu
6464

6565
$default = explode(',', $default);
6666
foreach ($default as $k => $v) {
67-
$v = trim($v);
67+
$v = $question->isTrimmable() ? trim($v) : $v;
6868
$default[$k] = isset($choices[$v]) ? $choices[$v] : $v;
6969
}
7070
}
@@ -121,7 +121,8 @@ private function doAsk(OutputInterface $output, Question $question)
121121
$ret = false;
122122
if ($question->isHidden()) {
123123
try {
124-
$ret = trim($this->getHiddenResponse($output, $inputStream));
124+
$hiddenResponse = $this->getHiddenResponse($output, $inputStream, $question->isTrimmable());
125+
$ret = $question->isTrimmable() ? trim($hiddenResponse) : $hiddenResponse;
125126
} catch (RuntimeException $e) {
126127
if (!$question->isHiddenFallback()) {
127128
throw $e;
@@ -134,10 +135,13 @@ private function doAsk(OutputInterface $output, Question $question)
134135
if (false === $ret) {
135136
throw new RuntimeException('Aborted.');
136137
}
137-
$ret = trim($ret);
138+
if ($question->isTrimmable()) {
139+
$ret = trim($ret);
140+
}
138141
}
139142
} else {
140-
$ret = trim($this->autocomplete($output, $question, $inputStream, $autocomplete));
143+
$autocomplete = $this->autocomplete($output, $question, $inputStream, $autocomplete);
144+
$ret = $question->isTrimmable() ? trim($autocomplete) : $autocomplete;
141145
}
142146

143147
if ($output instanceof ConsoleSectionOutput) {
@@ -351,10 +355,11 @@ private function mostRecentlyEnteredValue($entered)
351355
*
352356
* @param OutputInterface $output An Output instance
353357
* @param resource $inputStream The handler resource
358+
* @param bool $trimmable Is the answer trimmable
354359
*
355360
* @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
356361
*/
357-
private function getHiddenResponse(OutputInterface $output, $inputStream): string
362+
private function getHiddenResponse(OutputInterface $output, $inputStream, $trimmable = true): string
358363
{
359364
if ('\\' === \DIRECTORY_SEPARATOR) {
360365
$exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
@@ -366,7 +371,8 @@ private function getHiddenResponse(OutputInterface $output, $inputStream): strin
366371
$exe = $tmpExe;
367372
}
368373

369-
$value = rtrim(shell_exec($exe));
374+
$sExec = shell_exec($exe);
375+
$value = $trimmable ? rtrim($sExec) : $sExec;
370376
$output->writeln('');
371377

372378
if (isset($tmpExe)) {
@@ -386,8 +392,9 @@ private function getHiddenResponse(OutputInterface $output, $inputStream): strin
386392
if (false === $value) {
387393
throw new RuntimeException('Aborted.');
388394
}
389-
390-
$value = trim($value);
395+
if ($trimmable) {
396+
$value = trim($value);
397+
}
391398
$output->writeln('');
392399

393400
return $value;
@@ -396,7 +403,8 @@ private function getHiddenResponse(OutputInterface $output, $inputStream): strin
396403
if (false !== $shell = $this->getShell()) {
397404
$readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword';
398405
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
399-
$value = rtrim(shell_exec($command));
406+
$sCommand = shell_exec($command);
407+
$value = $trimmable ? rtrim($sCommand) : $sCommand;
400408
$output->writeln('');
401409

402410
return $value;

src/Symfony/Component/Console/Question/Question.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class Question
2929
private $validator;
3030
private $default;
3131
private $normalizer;
32+
private $trimmable = true;
3233

3334
/**
3435
* @param string $question The question to ask to the user
@@ -274,4 +275,19 @@ protected function isAssoc($array)
274275
{
275276
return (bool) \count(array_filter(array_keys($array), 'is_string'));
276277
}
278+
279+
public function isTrimmable(): bool
280+
{
281+
return $this->trimmable;
282+
}
283+
284+
/**
285+
* @return $this
286+
*/
287+
public function setTrimmable(bool $trimmable): self
288+
{
289+
$this->trimmable = $trimmable;
290+
291+
return $this;
292+
}
277293
}

src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ public function testAsk()
165165
$this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
166166
}
167167

168+
public function testAskNonTrimmed()
169+
{
170+
$dialog = new QuestionHelper();
171+
172+
$inputStream = $this->getInputStream(' 8AM ');
173+
174+
$question = new Question('What time is it?', '2PM');
175+
$question->setTrimmable(false);
176+
$this->assertEquals(' 8AM ', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $output = $this->createOutputInterface(), $question));
177+
178+
rewind($output->getStream());
179+
$this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
180+
}
181+
168182
public function testAskWithAutocomplete()
169183
{
170184
if (!$this->hasSttyAvailable()) {
@@ -198,6 +212,40 @@ public function testAskWithAutocomplete()
198212
$this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
199213
}
200214

215+
public function testAskWithAutocompleteTrimmable()
216+
{
217+
if (!$this->hasSttyAvailable()) {
218+
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
219+
}
220+
221+
// Acm<NEWLINE>
222+
// Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
223+
// <NEWLINE>
224+
// <UP ARROW><UP ARROW><NEWLINE>
225+
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
226+
// <DOWN ARROW><NEWLINE>
227+
// S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
228+
// F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
229+
$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");
230+
231+
$dialog = new QuestionHelper();
232+
$helperSet = new HelperSet([new FormatterHelper()]);
233+
$dialog->setHelperSet($helperSet);
234+
235+
$question = new Question('Please select a bundle', 'FrameworkBundle');
236+
$question->setAutocompleterValues(['AcmeDemoBundle ', 'AsseticBundle', ' SecurityBundle ', 'FooBundle']);
237+
$question->setTrimmable(false);
238+
239+
$this->assertEquals('AcmeDemoBundle ', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
240+
$this->assertEquals('AsseticBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
241+
$this->assertEquals('FrameworkBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
242+
$this->assertEquals(' SecurityBundle ', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
243+
$this->assertEquals('FooBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
244+
$this->assertEquals('AcmeDemoBundle ', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
245+
$this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
246+
$this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
247+
}
248+
201249
public function testAskWithAutocompleteCallback()
202250
{
203251
if (!$this->hasSttyAvailable()) {
@@ -373,6 +421,21 @@ public function testAskHiddenResponse()
373421
$this->assertEquals('8AM', $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("8AM\n")), $this->createOutputInterface(), $question));
374422
}
375423

424+
public function testAskHiddenResponseTrimmed()
425+
{
426+
if ('\\' === \DIRECTORY_SEPARATOR) {
427+
$this->markTestSkipped('This test is not supported on Windows');
428+
}
429+
430+
$dialog = new QuestionHelper();
431+
432+
$question = new Question('What time is it?');
433+
$question->setHidden(true);
434+
$question->setTrimmable(false);
435+
436+
$this->assertEquals(' 8AM', $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream(' 8AM')), $this->createOutputInterface(), $question));
437+
}
438+
376439
/**
377440
* @dataProvider getAskConfirmationData
378441
*/

0 commit comments

Comments
 (0)