Improved and simplified ListShortcodesCommand with SymfonyStyle

This commit is contained in:
Alejandro Celaya 2017-12-31 18:37:39 +01:00
parent 3e2c5abaa4
commit a6c547c4da
2 changed files with 21 additions and 53 deletions

View File

@ -7,12 +7,10 @@ use Shlinkio\Shlink\Common\Paginator\Adapter\PaginableRepositoryAdapter;
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface; use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Style\SymfonyStyle;
use Zend\I18n\Translator\TranslatorInterface; use Zend\I18n\Translator\TranslatorInterface;
class ListShortcodesCommand extends Command class ListShortcodesCommand extends Command
@ -34,7 +32,7 @@ class ListShortcodesCommand extends Command
{ {
$this->shortUrlService = $shortUrlService; $this->shortUrlService = $shortUrlService;
$this->translator = $translator; $this->translator = $translator;
parent::__construct(null); parent::__construct();
} }
public function configure() public function configure()
@ -83,19 +81,16 @@ class ListShortcodesCommand extends Command
public function execute(InputInterface $input, OutputInterface $output) public function execute(InputInterface $input, OutputInterface $output)
{ {
$io = new SymfonyStyle($input, $output);
$page = (int) $input->getOption('page'); $page = (int) $input->getOption('page');
$searchTerm = $input->getOption('searchTerm'); $searchTerm = $input->getOption('searchTerm');
$tags = $input->getOption('tags'); $tags = $input->getOption('tags');
$tags = ! empty($tags) ? explode(',', $tags) : []; $tags = ! empty($tags) ? \explode(',', $tags) : [];
$showTags = $input->getOption('showTags'); $showTags = $input->getOption('showTags');
/** @var QuestionHelper $helper */
$helper = $this->getHelper('question');
do { do {
$result = $this->shortUrlService->listShortUrls($page, $searchTerm, $tags, $this->processOrderBy($input)); $result = $this->shortUrlService->listShortUrls($page, $searchTerm, $tags, $this->processOrderBy($input));
$page++; $page++;
$table = new Table($output);
$headers = [ $headers = [
$this->translator->translate('Short code'), $this->translator->translate('Short code'),
@ -106,8 +101,8 @@ class ListShortcodesCommand extends Command
if ($showTags) { if ($showTags) {
$headers[] = $this->translator->translate('Tags'); $headers[] = $this->translator->translate('Tags');
} }
$table->setHeaders($headers);
$rows = [];
foreach ($result as $row) { foreach ($result as $row) {
$shortUrl = $row->jsonSerialize(); $shortUrl = $row->jsonSerialize();
if ($showTags) { if ($showTags) {
@ -120,27 +115,23 @@ class ListShortcodesCommand extends Command
unset($shortUrl['tags']); unset($shortUrl['tags']);
} }
$table->addRow(array_values($shortUrl)); $rows[] = \array_values($shortUrl);
} }
$table->render(); $io->table($headers, $rows);
if ($this->isLastPage($result)) { if ($this->isLastPage($result)) {
$continue = false; $continue = false;
$output->writeln( $io->success($this->translator->translate('Short codes properly listed'));
sprintf('<info>%s</info>', $this->translator->translate('You have reached last page'))
);
} else { } else {
$continue = $helper->ask($input, $output, new ConfirmationQuestion( $continue = $io->confirm(
sprintf('<question>' . $this->translator->translate( \sprintf($this->translator->translate('Continue with page') . ' <options=bold>%s</>?', $page),
'Continue with page'
) . ' <bg=cyan;options=bold>%s</>? (y/N)</question> ', $page),
false false
)); );
} }
} while ($continue); } while ($continue);
} }
protected function processOrderBy(InputInterface $input) private function processOrderBy(InputInterface $input)
{ {
$orderBy = $input->getOption('orderBy'); $orderBy = $input->getOption('orderBy');
if (empty($orderBy)) { if (empty($orderBy)) {

View File

@ -10,7 +10,6 @@ use Shlinkio\Shlink\CLI\Command\Shortcode\ListShortcodesCommand;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface; use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
use Symfony\Component\Console\Application; use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
use Zend\I18n\Translator\Translator; use Zend\I18n\Translator\Translator;
use Zend\Paginator\Adapter\ArrayAdapter; use Zend\Paginator\Adapter\ArrayAdapter;
@ -22,10 +21,6 @@ class ListShortcodesCommandTest extends TestCase
* @var CommandTester * @var CommandTester
*/ */
protected $commandTester; protected $commandTester;
/**
* @var QuestionHelper
*/
protected $questionHelper;
/** /**
* @var ObjectProphecy * @var ObjectProphecy
*/ */
@ -37,8 +32,6 @@ class ListShortcodesCommandTest extends TestCase
$app = new Application(); $app = new Application();
$command = new ListShortcodesCommand($this->shortUrlService->reveal(), Translator::factory([])); $command = new ListShortcodesCommand($this->shortUrlService->reveal(), Translator::factory([]));
$app->add($command); $app->add($command);
$this->questionHelper = $command->getHelper('question');
$this->commandTester = new CommandTester($command); $this->commandTester = new CommandTester($command);
} }
@ -47,10 +40,10 @@ class ListShortcodesCommandTest extends TestCase
*/ */
public function noInputCallsListJustOnce() public function noInputCallsListJustOnce()
{ {
$this->questionHelper->setInputStream($this->getInputStream('\n'));
$this->shortUrlService->listShortUrls(1, null, [], null)->willReturn(new Paginator(new ArrayAdapter())) $this->shortUrlService->listShortUrls(1, null, [], null)->willReturn(new Paginator(new ArrayAdapter()))
->shouldBeCalledTimes(1); ->shouldBeCalledTimes(1);
$this->commandTester->setInputs(['n']);
$this->commandTester->execute(['command' => 'shortcode:list']); $this->commandTester->execute(['command' => 'shortcode:list']);
} }
@ -61,22 +54,15 @@ class ListShortcodesCommandTest extends TestCase
{ {
// The paginator will return more than one page for the first 3 times // The paginator will return more than one page for the first 3 times
$data = []; $data = [];
for ($i = 0; $i < 30; $i++) { for ($i = 0; $i < 50; $i++) {
$data[] = new ShortUrl(); $data[] = new ShortUrl();
} }
$data = array_chunk($data, 11);
$questionHelper = $this->questionHelper; $this->shortUrlService->listShortUrls(Argument::cetera())->will(function () use (&$data) {
$that = $this; return new Paginator(new ArrayAdapter($data));
$this->shortUrlService->listShortUrls(Argument::cetera())->will(function () use (
&$data,
$questionHelper,
$that
) {
$questionHelper->setInputStream($that->getInputStream('y'));
return new Paginator(new ArrayAdapter(array_shift($data)));
})->shouldBeCalledTimes(3); })->shouldBeCalledTimes(3);
$this->commandTester->setInputs(['y', 'y', 'n']);
$this->commandTester->execute(['command' => 'shortcode:list']); $this->commandTester->execute(['command' => 'shortcode:list']);
} }
@ -91,10 +77,10 @@ class ListShortcodesCommandTest extends TestCase
$data[] = new ShortUrl(); $data[] = new ShortUrl();
} }
$this->questionHelper->setInputStream($this->getInputStream('n'));
$this->shortUrlService->listShortUrls(Argument::cetera())->willReturn(new Paginator(new ArrayAdapter($data))) $this->shortUrlService->listShortUrls(Argument::cetera())->willReturn(new Paginator(new ArrayAdapter($data)))
->shouldBeCalledTimes(1); ->shouldBeCalledTimes(1);
$this->commandTester->setInputs(['n']);
$this->commandTester->execute(['command' => 'shortcode:list']); $this->commandTester->execute(['command' => 'shortcode:list']);
} }
@ -104,10 +90,10 @@ class ListShortcodesCommandTest extends TestCase
public function passingPageWillMakeListStartOnThatPage() public function passingPageWillMakeListStartOnThatPage()
{ {
$page = 5; $page = 5;
$this->questionHelper->setInputStream($this->getInputStream('\n'));
$this->shortUrlService->listShortUrls($page, null, [], null)->willReturn(new Paginator(new ArrayAdapter())) $this->shortUrlService->listShortUrls($page, null, [], null)->willReturn(new Paginator(new ArrayAdapter()))
->shouldBeCalledTimes(1); ->shouldBeCalledTimes(1);
$this->commandTester->setInputs(['y']);
$this->commandTester->execute([ $this->commandTester->execute([
'command' => 'shortcode:list', 'command' => 'shortcode:list',
'--page' => $page, '--page' => $page,
@ -119,24 +105,15 @@ class ListShortcodesCommandTest extends TestCase
*/ */
public function ifTagsFlagIsProvidedTagsColumnIsIncluded() public function ifTagsFlagIsProvidedTagsColumnIsIncluded()
{ {
$this->questionHelper->setInputStream($this->getInputStream('\n'));
$this->shortUrlService->listShortUrls(1, null, [], null)->willReturn(new Paginator(new ArrayAdapter())) $this->shortUrlService->listShortUrls(1, null, [], null)->willReturn(new Paginator(new ArrayAdapter()))
->shouldBeCalledTimes(1); ->shouldBeCalledTimes(1);
$this->commandTester->setInputs(['y']);
$this->commandTester->execute([ $this->commandTester->execute([
'command' => 'shortcode:list', 'command' => 'shortcode:list',
'--showTags' => true, '--showTags' => true,
]); ]);
$output = $this->commandTester->getDisplay(); $output = $this->commandTester->getDisplay();
$this->assertTrue(strpos($output, 'Tags') > 0); $this->assertContains('Tags', $output);
}
protected function getInputStream($inputData)
{
$stream = fopen('php://memory', 'r+', false);
fputs($stream, $inputData);
rewind($stream);
return $stream;
} }
} }