Selaa lähdekoodia

[Console] implemented output formatter style class for defining custom styles

ever.zet 14 vuotta sitten
vanhempi
commit
e5700b817b

+ 207 - 0
src/Symfony/Component/Console/Formatter/OutputFormatterStyle.php

@@ -0,0 +1,207 @@
+<?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;
+
+/**
+ * Formatter style class for defining styles.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class OutputFormatterStyle implements OutputFormatterStyleInterface
+{
+    static private $availableForegroundColors = array(
+        'black'     => 30,
+        'red'       => 31,
+        'green'     => 32,
+        'yellow'    => 33,
+        'blue'      => 34,
+        'magenta'   => 35,
+        'cyan'      => 36,
+        'white'     => 37
+    );
+    static private $availableBackgroundColors = array(
+        'black'     => 40,
+        'red'       => 41,
+        'green'     => 42,
+        'yellow'    => 43,
+        'blue'      => 44,
+        'magenta'   => 45,
+        'cyan'      => 46,
+        'white'     => 47
+    );
+    static private $availableOptions = array(
+        'bold'          => 1,
+        'underscore'    => 4,
+        'blink'         => 5,
+        'reverse'       => 7,
+        'conceal'       => 8
+    );
+
+    private $foreground;
+    private $background;
+    private $options = array();
+
+    /**
+     * Initializes output formatter style.
+     *
+     * @param   string  $foreground     style foreground color name
+     * @param   string  $background     style background color name
+     * @param   array   $options        style options
+     */
+    public function __construct($foreground = null, $background = null, array $options = array())
+    {
+        if (null !== $foreground) {
+            $this->setForeground($foreground);
+        }
+        if (null !== $background) {
+            $this->setBackground($background);
+        }
+        if (count($options)) {
+            $this->setOptions($options);
+        }
+    }
+
+    /**
+     * Sets style foreground color.
+     *
+     * @param   string  $color  color name
+     */
+    public function setForeground($color = null)
+    {
+        if (null === $color) {
+            $this->foreground = null;
+
+            return;
+        }
+
+        if (!isset(static::$availableForegroundColors[$color])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid foreground color specified: "%s". Expected one of (%s)',
+                $color,
+                implode(', ', array_keys(static::$availableForegroundColors))
+            ));
+        }
+
+        $this->foreground = static::$availableForegroundColors[$color];
+    }
+
+    /**
+     * Sets style background color.
+     *
+     * @param   string  $color  color name
+     */
+    public function setBackground($color = null)
+    {
+        if (null === $color) {
+            $this->background = null;
+
+            return;
+        }
+
+        if (!isset(static::$availableBackgroundColors[$color])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid background color specified: "%s". Expected one of (%s)',
+                $color,
+                implode(', ', array_keys(static::$availableBackgroundColors))
+            ));
+        }
+
+        $this->background = static::$availableBackgroundColors[$color];
+    }
+
+    /**
+     * Sets some specific style option.
+     *
+     * @param   string  $option     option name
+     */
+    public function setOption($option)
+    {
+        if (!isset(static::$availableOptions[$option])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid option specified: "%s". Expected one of (%s)',
+                $option,
+                implode(', ', array_keys(static::$availableOptions))
+            ));
+        }
+
+        if (false === array_search(static::$availableOptions[$option], $this->options)) {
+            $this->options[] = static::$availableOptions[$option];
+        }
+    }
+
+    /**
+     * Unsets some specific style option.
+     *
+     * @param   string  $option     option name
+     */
+    public function unsetOption($option)
+    {
+        if (!isset(static::$availableOptions[$option])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid option specified: "%s". Expected one of (%s)',
+                $option,
+                implode(', ', array_keys(static::$availableOptions))
+            ));
+        }
+
+        $pos = array_search(static::$availableOptions[$option], $this->options);
+        if (false !== $pos) {
+            unset($this->options[$pos]);
+        }
+    }
+
+    /**
+     * Set multiple style options at once.
+     *
+     * @param   array   $options
+     */
+    public function setOptions(array $options)
+    {
+        $this->options = array();
+
+        foreach ($options as $option) {
+            $this->setOption($option);
+        }
+    }
+
+    /**
+     * Returns begin style code.
+     *
+     * @return  string
+     */
+    public function getBeginStyle()
+    {
+        $codes = array();
+
+        if (null !== $this->foreground) {
+            $codes[] = $this->foreground;
+        }
+        if (null !== $this->background) {
+            $codes[] = $this->background;
+        }
+        if (count($this->options)) {
+            $codes = array_merge($codes, $this->options);
+        }
+
+        return "\033[" . implode(';', $codes) . 'm';
+    }
+
+    /**
+     * Returns end style code.
+     *
+     * @return  string
+     */
+    public function getEndStyle()
+    {
+        return "\033[0m";
+    }
+}

+ 97 - 0
tests/Symfony/Tests/Component/Console/Formatter/OutputFormatterStyleTest.php

@@ -0,0 +1,97 @@
+<?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\OutputFormatterStyle;
+
+class OutputFormatterStyleTest extends \PHPUnit_Framework_TestCase
+{
+    public function testConstructor()
+    {
+        $style = new OutputFormatterStyle('green', 'black', array('bold', 'underscore'));
+
+        $this->assertEquals("\033[32;40;1;4m", $style->getBeginStyle());
+        $this->assertEquals("\033[0m", $style->getEndStyle());
+
+        $style = new OutputFormatterStyle('red', null, array('blink'));
+
+        $this->assertEquals("\033[31;5m", $style->getBeginStyle());
+        $this->assertEquals("\033[0m", $style->getEndStyle());
+
+        $style = new OutputFormatterStyle(null, 'white');
+
+        $this->assertEquals("\033[47m", $style->getBeginStyle());
+        $this->assertEquals("\033[0m", $style->getEndStyle());
+    }
+
+    public function testForeground()
+    {
+        $style = new OutputFormatterStyle();
+
+        $style->setForeground('black');
+
+        $this->assertEquals("\033[30m", $style->getBeginStyle());
+        $this->assertEquals("\033[0m", $style->getEndStyle());
+
+        $style->setForeground('blue');
+
+        $this->assertEquals("\033[34m", $style->getBeginStyle());
+        $this->assertEquals("\033[0m", $style->getEndStyle());
+
+        $this->setExpectedException('InvalidArgumentException');
+
+        $style->setForeground('undefined-color');
+    }
+
+    public function testBackground()
+    {
+        $style = new OutputFormatterStyle();
+
+        $style->setBackground('black');
+
+        $this->assertEquals("\033[40m", $style->getBeginStyle());
+        $this->assertEquals("\033[0m", $style->getEndStyle());
+
+        $style->setBackground('yellow');
+
+        $this->assertEquals("\033[43m", $style->getBeginStyle());
+
+        $this->setExpectedException('InvalidArgumentException');
+
+        $style->setBackground('undefined-color');
+    }
+
+    public function testOptions()
+    {
+        $style = new OutputFormatterStyle();
+
+        $style->setOptions(array('reverse', 'conceal'));
+
+        $this->assertEquals("\033[7;8m", $style->getBeginStyle());
+
+        $style->setOption('bold');
+
+        $this->assertEquals("\033[7;8;1m", $style->getBeginStyle());
+
+        $style->unsetOption('reverse');
+
+        $this->assertEquals("\033[8;1m", $style->getBeginStyle());
+
+        $style->setOption('bold');
+
+        $this->assertEquals("\033[8;1m", $style->getBeginStyle());
+
+        $style->setOptions(array('bold'));
+
+        $this->assertEquals("\033[1m", $style->getBeginStyle());
+    }
+}