Skip to content

[Console] Add SymfonyStyle::setInputStream() to ease command testing #18902

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/Symfony/Component/Console/Style/SymfonyStyle.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class SymfonyStyle extends OutputStyle
private $progressBar;
private $lineLength;
private $bufferedOutput;
private $inputStream;

/**
* @param InputInterface $input
Expand Down Expand Up @@ -350,6 +351,10 @@ public function askQuestion(Question $question)

if (!$this->questionHelper) {
$this->questionHelper = new SymfonyQuestionHelper();

if ($this->inputStream) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be possible to set after creating the SymfonyQuestionHelper instance.
What about detecting in setInputStream() if $this->questionHelper is not null and then calling setInputStream() on the SymfonyQuestionHelper object?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch @sstok, but I think it needs to keep an additional check in ask() because in most cases the helper will not be set when calling setInputStream, because it is set in ask()

Copy link
Contributor

@sstok sstok May 30, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, that's actually what I thought (but forgot to clearly communicate) :)

One check (the current one) in askQuestion() to set it initially, and then in setInputStream() detect if questionHelper is already created and set the inputStream for the questionHelper instance (overwriting what was already set).

$this->questionHelper->setInputStream($this->inputStream);
}
}

$answer = $this->questionHelper->ask($this->input, $this, $question);
Expand Down Expand Up @@ -389,6 +394,22 @@ public function newLine($count = 1)
$this->bufferedOutput->write(str_repeat("\n", $count));
}

/**
* Sets the input stream to read from when interacting with the user.
*
* This is mainly useful for testing purpose.
*
* @param resource $stream The input stream
*/
public function setInputStream($stream)
{
$this->inputStream = $stream;

if ($this->questionHelper) {
$this->questionHelper->setInputStream($stream);
}
}

/**
* @return ProgressBar
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;

//Ensure that questions have the expected outputs
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$questions = array(
'What\'s your name?',
'How are you?',
'Where do you come from?',
);
$inputs = array('Foo', 'Bar', 'Baz');
$stream = fopen('php://memory', 'r+', false);

fputs($stream, implode(PHP_EOL, $inputs));
rewind($stream);

$output->setInputStream($stream);
$output->ask($questions[0]);
$output->ask($questions[1]);
$output->ask($questions[2]);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

What's your name?:
>
How are you?:
>
Where do you come from?:
>
40 changes: 40 additions & 0 deletions src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,24 @@ public function inputCommandToOutputFilesProvider()
return array_map(null, glob($baseDir.'/command/command_*.php'), glob($baseDir.'/output/output_*.txt'));
}

/**
* @dataProvider inputInteractiveCommandToOutputFilesProvider
*/
public function testInteractiveOutputs($inputCommandFilepath, $outputFilepath)
{
$code = require $inputCommandFilepath;
$this->command->setCode($code);
$this->tester->execute(array(), array('interactive' => true, 'decorated' => false));
$this->assertStringEqualsFile($outputFilepath, $this->tester->getDisplay(true));
}

public function inputInteractiveCommandToOutputFilesProvider()
{
$baseDir = __DIR__.'/../Fixtures/Style/SymfonyStyle';

return array_map(null, glob($baseDir.'/command/interactive_command_*.php'), glob($baseDir.'/output/interactive_output_*.txt'));
}

public function testLongWordsBlockWrapping()
{
$word = 'Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygovgollhjvhvljfezefeqifzeiqgiqzhrsdgihqzridghqridghqirshdghdghieridgheirhsdgehrsdvhqrsidhqshdgihrsidvqhneriqsdvjzergetsrfhgrstsfhsetsfhesrhdgtesfhbzrtfbrztvetbsdfbrsdfbrn';
Expand All @@ -70,6 +88,28 @@ public function testLongWordsBlockWrapping()
$expectedCount = (int) ceil($wordLength / ($maxLineLength)) + (int) ($wordLength > $maxLineLength - 5);
$this->assertSame($expectedCount, substr_count($this->tester->getDisplay(true), ' § '));
}

public function testSetInputStream()
{
$command = $this->command;
$inputs = array('Foo', 'Bar', 'Baz');
$stream = fopen('php://memory', 'r+', false);

fputs($stream, implode(PHP_EOL, $inputs));
rewind($stream);

$command->setCode(function ($input, $output) use ($command, $stream) {
$sfStyle = new SymfonyStyle($input, $output);

$sfStyle->setInputStream($stream);
$sfStyle->ask('What\'s your name?');
$sfStyle->ask('How are you?');
$sfStyle->ask('Where do you come from?');
});

$this->tester->execute(array());
$this->assertSame(0, $this->tester->getStatusCode());
}
}

/**
Expand Down