[Console] Added formatter style stack.
This commit is contained in:
parent
93ffe54886
commit
4f298dd7c7
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Formatter;
|
||||
|
||||
/**
|
||||
* @author: Jean-François Simon <contact@jfsimon.fr>
|
||||
*/
|
||||
class OutputFormatterStyleStack
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $foregrounds;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $backgrounds;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets stack (ie. empty internal arrays).
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->foregrounds = array();
|
||||
$this->backgrounds = array();
|
||||
$this->options = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a style in the stack.
|
||||
*
|
||||
* @param OutputFormatterStyleInterface $style
|
||||
*/
|
||||
public function pushStyle(OutputFormatterStyleInterface $style)
|
||||
{
|
||||
$foreground = $style->getForeground();
|
||||
if (null !== $foreground) {
|
||||
$this->foregrounds[] = $foreground;
|
||||
}
|
||||
|
||||
$background = $style->getBackground();
|
||||
if (null !== $background) {
|
||||
$this->backgrounds[] = $background;
|
||||
}
|
||||
|
||||
foreach ($style->getOptions() as $option) {
|
||||
if (!isset($this->options[$option])) {
|
||||
$this->options[$option] = 0;
|
||||
}
|
||||
$this->options[$option] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops a style from the stack.
|
||||
*
|
||||
* @param OutputFormatterStyleInterface $style
|
||||
*
|
||||
* @throws \InvalidArgumentException When style tags incorrectly nested
|
||||
*/
|
||||
public function popStyle(OutputFormatterStyleInterface $style)
|
||||
{
|
||||
$this->popArrayCode($this->foregrounds, $style->getForeground());
|
||||
$this->popArrayCode($this->backgrounds, $style->getBackground());
|
||||
|
||||
foreach ($style->getOptions() as $option) {
|
||||
if (!isset($this->options[$option])) {
|
||||
throw new \InvalidArgumentException('Unexpected style "'.$option.'" option end.');
|
||||
}
|
||||
|
||||
$this->options[$option] -= 1;
|
||||
if (0 === $this->options[$option]) {
|
||||
unset($this->options[$option]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes current style with stacks top codes.
|
||||
*
|
||||
* @return OutputFormatterStyle
|
||||
*/
|
||||
public function getCurrentStyle()
|
||||
{
|
||||
return new OutputFormatterStyle(
|
||||
end($this->foregrounds) ?: null,
|
||||
end($this->backgrounds) ?: null,
|
||||
array_keys($this->options)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops a color from a stack.
|
||||
*
|
||||
* @param array $stack An array of color names
|
||||
* @param int $color A color name
|
||||
*
|
||||
* @throws \InvalidArgumentException When poped color is not the expected one
|
||||
*/
|
||||
private function popArrayCode(&$stack, $color)
|
||||
{
|
||||
if (null === $color) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current = end($stack);
|
||||
if ($current !== $color) {
|
||||
throw new \InvalidArgumentException('Expected style "'.$current.'" color end but "'.$color.'" end found.');
|
||||
}
|
||||
|
||||
array_pop($stack);
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Tests\Component\Console\Formatter;
|
||||
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyleStack;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
|
||||
class OutputFormatterStyleStackTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testPush()
|
||||
{
|
||||
$stack = new OutputFormatterStyleStack();
|
||||
$stack->pushStyle(new OutputFormatterStyle('white'));
|
||||
$stack->pushStyle(new OutputFormatterStyle(null, 'black'));
|
||||
$stack->pushStyle(new OutputFormatterStyle(null, null, array('bold')));
|
||||
|
||||
$style = $stack->getCurrentStyle();
|
||||
$this->assertEquals('white', $style->getForeground());
|
||||
$this->assertEquals('black', $style->getBackground());
|
||||
$this->assertEquals(array('bold'), $style->getOptions());
|
||||
|
||||
$stack->pushStyle(new OutputFormatterStyle('yellow', null, array('blink')));
|
||||
|
||||
$style = $stack->getCurrentStyle();
|
||||
$this->assertEquals('yellow', $style->getForeground());
|
||||
$this->assertEquals('black', $style->getBackground());
|
||||
$this->assertEquals(array('bold', 'blink'), $style->getOptions());
|
||||
}
|
||||
|
||||
public function testPop()
|
||||
{
|
||||
$stack = new OutputFormatterStyleStack();
|
||||
$stack->pushStyle(new OutputFormatterStyle('white', 'black', array('blink', 'bold')));
|
||||
$stack->pushStyle(new OutputFormatterStyle('yellow', 'blue'));
|
||||
|
||||
$style = $stack->getCurrentStyle();
|
||||
$this->assertEquals('yellow', $style->getForeground());
|
||||
$this->assertEquals('blue', $style->getBackground());
|
||||
$this->assertEquals(array('blink', 'bold'), $style->getOptions());
|
||||
|
||||
$stack->popStyle(new OutputFormatterStyle(null, 'blue', array('blink')));
|
||||
|
||||
$style = $stack->getCurrentStyle();
|
||||
$this->assertEquals('yellow', $style->getForeground());
|
||||
$this->assertEquals('black', $style->getBackground());
|
||||
$this->assertEquals(array('bold'), $style->getOptions());
|
||||
|
||||
$stack->popStyle(new OutputFormatterStyle('yellow', 'black', array('bold')));
|
||||
|
||||
$style = $stack->getCurrentStyle();
|
||||
$this->assertEquals('white', $style->getForeground());
|
||||
$this->assertEquals(null, $style->getBackground());
|
||||
$this->assertEquals(array(), $style->getOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testInvalidPop()
|
||||
{
|
||||
$stack = new OutputFormatterStyleStack();
|
||||
$stack->pushStyle(new OutputFormatterStyle('white', 'black', array('blink', 'bold')));
|
||||
$stack->popStyle(new OutputFormatterStyle('yellow'));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user