Skip to content

Commit

Permalink
Merge pull request #7 from kbond/console-output
Browse files Browse the repository at this point in the history
Always use `ConsoleOutput` for tests
  • Loading branch information
kbond authored Oct 19, 2021
2 parents c68f9bd + 12b200c commit ba07fa5
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 86 deletions.
10 changes: 4 additions & 6 deletions src/CommandResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,15 @@
final class CommandResult
{
private int $statusCode;
private string $output;
private string $errorOutput;
private TestOutput $output;

/**
* @internal
*/
public function __construct(int $statusCode, string $output, string $errorOutput)
public function __construct(int $statusCode, TestOutput $output)
{
$this->statusCode = $statusCode;
$this->output = $output;
$this->errorOutput = $errorOutput;
}

public function statusCode(): int
Expand All @@ -31,12 +29,12 @@ public function statusCode(): int

public function output(): string
{
return $this->output;
return $this->output->getDisplay();
}

public function errorOutput(): string
{
return $this->errorOutput;
return $this->output->getErrorDisplay();
}

public function assertOutputContains(string $expected): self
Expand Down
72 changes: 0 additions & 72 deletions src/CommandTester.php

This file was deleted.

11 changes: 5 additions & 6 deletions src/TestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\StringInput;

/**
* @author Kevin Bond <kevinbond@gmail.com>
Expand Down Expand Up @@ -91,11 +90,11 @@ public function withInput(array $inputs): self

public function execute(?string $cli = null): CommandResult
{
$cli = $cli ? \sprintf('%s %s', $this->cli, $cli) : $this->cli;
$status = $this->command->run(
$input = new TestInput($cli ? \sprintf('%s %s', $this->cli, $cli) : $this->cli, $this->inputs),
$output = new TestOutput($this->splitOutputStreams, $input)
);

$tester = new CommandTester($this->command, new StringInput($cli));
$tester->setInputs($this->inputs);

return $tester->execute($this->splitOutputStreams);
return new CommandResult($status, $output);
}
}
64 changes: 64 additions & 0 deletions src/TestInput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Zenstruck\Console\Test;

use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\OutputInterface;

/**
* @internal
*
* @author Kevin Bond <kevinbond@gmail.com>
*/
final class TestInput extends StringInput
{
public function __construct(string $input, array $inputs)
{
parent::__construct($input);

$this->setInteractive(false);

if ($inputs) {
$stream = \fopen('php://memory', 'r+', false);

foreach ($inputs as $value) {
\fwrite($stream, $value.\PHP_EOL);
}

\rewind($stream);

$this->setStream($stream);
$this->setInteractive(true);
}

if (true === $this->hasParameterOption(['--no-interaction', '-n'], true)) {
$this->setInteractive(false);
}
}

public function isDecorated(): bool
{
return true === $this->hasParameterOption(['--ansi'], true);
}

public function getVerbosity(): int
{
if (true === $this->hasParameterOption(['--quiet', '-q'], true)) {
return OutputInterface::VERBOSITY_QUIET;
}

if ($this->hasParameterOption('-vvv', true) || $this->hasParameterOption('--verbose=3', true) || 3 === $this->getParameterOption('--verbose', false, true)) {
return OutputInterface::VERBOSITY_DEBUG;
}

if ($this->hasParameterOption('-vv', true) || $this->hasParameterOption('--verbose=2', true) || 2 === $this->getParameterOption('--verbose', false, true)) {
return OutputInterface::VERBOSITY_VERY_VERBOSE;
}

if ($this->hasParameterOption('-v', true) || $this->hasParameterOption('--verbose=1', true) || $this->hasParameterOption('--verbose', true) || $this->getParameterOption('--verbose', false, true)) {
return OutputInterface::VERBOSITY_VERBOSE;
}

return OutputInterface::VERBOSITY_NORMAL;
}
}
68 changes: 68 additions & 0 deletions src/TestOutput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Zenstruck\Console\Test;

use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;

/**
* @internal
*
* @author Kevin Bond <kevinbond@gmail.com>
*/
final class TestOutput extends StreamOutput implements ConsoleOutputInterface
{
private ?OutputInterface $error = null;
private array $sections = [];

public function __construct(bool $splitStreams, TestInput $input)
{
parent::__construct(
\fopen('php://memory', 'w', false),
$input->getVerbosity(),
$input->isDecorated()
);

if ($splitStreams) {
$this->error = new StreamOutput(\fopen('php://memory', 'w', false));
$this->error->setFormatter($this->getFormatter());
$this->error->setVerbosity($this->getVerbosity());
$this->error->setDecorated($this->isDecorated());
}
}

public function getErrorOutput(): OutputInterface
{
return $this->error ?? $this;
}

public function setErrorOutput(OutputInterface $error): void
{
$this->error = $error;
}

public function section(): ConsoleSectionOutput
{
return new ConsoleSectionOutput($this->getStream(), $this->sections, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter());
}

public function getDisplay(): string
{
\rewind($this->getStream());

return \stream_get_contents($this->getStream());
}

public function getErrorDisplay(): string
{
if (!$this->error instanceof StreamOutput) {
return '';
}

\rewind($this->error->getStream());

return \stream_get_contents($this->error->getStream());
}
}
9 changes: 7 additions & 2 deletions tests/Fixture/FixtureCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
namespace Zenstruck\Console\Test\Tests\Fixture;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
Expand All @@ -33,7 +33,7 @@ protected function configure(): void

protected function execute(InputInterface $input, OutputInterface $output): int
{
$errOutput = $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output;
$errOutput = $output->getErrorOutput();

$output->writeln('Executing <info>command</info>...');
$output->writeln("verbosity: {$output->getVerbosity()}");
Expand Down Expand Up @@ -62,6 +62,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int

(new SymfonyStyle($input, $output))->success('Long link: https://github.com/zenstruck/console-test/blob/997ee1f66743342ffd9cd00a77613ebfa2efd2b8/src/CommandResult.php');

$table = new Table($output->section());
$table->addRow(['table row 1']);
$table->render();
$table->appendRow(['table row 2']);

return (int) $input->getOption('code');
}

Expand Down
12 changes: 12 additions & 0 deletions tests/UnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,16 @@ public function terminal_width_is_standardized(): void
->assertOutputContains(' https://github.com/zenstruck/console-test/blob/997ee1f66743342ffd9cd00a77613ebfa2efd2b8/src/CommandResult.php ')
;
}

/**
* @test
*/
public function always_executes_with_console_output(): void
{
TestCommand::for(new FixtureCommand())
->execute()
->assertOutputContains('table row 1')
->assertOutputContains('table row 2')
;
}
}

0 comments on commit ba07fa5

Please sign in to comment.