bluetree-service/clover-reporter

View on GitHub
src/Console/Style.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php

declare(strict_types=1);

namespace CloverReporter\Console;

use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

use function mb_strlen;

class Style extends SymfonyStyle
{
    /**
     * @var \Symfony\Component\Console\Helper\FormatterHelper
     */
    protected $formatter;

    /**
     * @var int
     */
    protected $align = 20;

    /**
     * Style constructor.
     *
     * @param InputInterface $input
     * @param OutputInterface $output
     * @param Command $command
     */
    public function __construct(InputInterface $input, OutputInterface $output, Command $command)
    {
        $this->formatter = $command->getHelper('formatter');

        parent::__construct($input, $output);
    }

    /**
     * @param int $align
     * @return $this
     */
    public function setAlign(int $align): self
    {
        $this->align = $align;

        return $this;
    }

    /**
     * @return int
     */
    public function getAlign(): int
    {
        return $this->align;
    }

    /**
     * @param string $section
     * @param string $message
     * @param string $style
     * @throws \InvalidArgumentException
     * @return $this
     */
    public function formatSection(string $section, string $message, string $style = 'info'): self
    {
        $this->writeln(
            $this->formatter->formatSection(
                $section,
                $message,
                $style
            )
        );

        return $this;
    }

    /**
     * @param string|array $messages
     * @param string $style
     * @param bool $large
     * @throws \InvalidArgumentException
     * @return $this
     */
    public function formatBlock($messages, string $style, bool $large = false): self
    {
        $this->writeln(
            $this->formatter->formatBlock(
                $messages,
                $style,
                $large
            )
        );

        return $this;
    }

    /**
     * @param array $message
     * @throws \InvalidArgumentException
     * @return $this
     */
    public function errorLine(array $message): self
    {
        $this->writeln(
            $this->formatBlock($message, 'error')
        );

        return $this;
    }

    /**
     * @param int $strLength
     * @param int $align
     * @return string
     */
    public function align(int $strLength, int $align): string
    {
        $newAlign = ' ';
        $spaces = $align - $strLength;

        for ($i = 1; $i <= $spaces; $i++) {
            $newAlign .= ' ';
        }

        return $newAlign;
    }

    /**
     * @param mixed $message
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function okMessage($message): self
    {
        $alignment = $this->align(4, $this->align);
        $this->write('<info>[OK]</info>');
        $this->write($alignment);
        $this->writeln($message);

        return $this;
    }

    /**
     * @param mixed $message
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function errorMessage($message): self
    {
        $alignment = $this->align(7, $this->align);
        $this->write('<fg=red>[ERROR]</>');
        $this->write($alignment);
        $this->writeln($message);

        return $this;
    }

    /**
     * @param mixed $message
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function warningMessage($message): self
    {
        $alignment = $this->align(9, $this->align);
        $this->write('<comment>[WARNING]</comment>');
        $this->write($alignment);
        $this->writeln($message);

        return $this;
    }

    /**
     * @param string $message
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function note($message): self
    {
        return $this->genericBlock($message, 'blue', 'note');
    }

    /**
     * @param string $message
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function caution($message): self
    {
        return $this->genericBlock($message, 'magenta', 'caution');
    }

    /**
     * @param string $message
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function success($message): self
    {
        return $this->genericBlock($message, 'green', 'success');
    }

    /**
     * @param string $message
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function warning($message): self
    {
        return $this->genericBlock($message, 'yellow', 'warning');
    }

    /**
     * @param string $message
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function error($message): self
    {
        return $this->genericBlock($message, 'red', 'error');
    }

    /**
     * @param string $message
     * @param string $background
     * @param string $type
     * @param int $length
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function genericBlock(string $message, string $background, string $type, int $length = 100): self
    {
        $type = \strtoupper($type);
        $alignment = $this->align(0, $length);
        $alignmentMessage = $this->align(mb_strlen($message), $length - (mb_strlen($type) + 5));

        $this->writeln("<bg=$background>$alignment</>");
        $this->writeln("<fg=white;bg=$background>  [$type] $message$alignmentMessage</>");
        $this->writeln("<bg=$background>$alignment</>");
        $this->newLine();

        return $this;
    }

    /**
     * @param int $lineNumber
     * @param string $line
     * @param string $coverage
     * @throws \InvalidArgumentException
     * @return $this
     */
    public function formatUncoveredLine(int $lineNumber, string $line, string $coverage = ''): self
    {
        $endAlign = $this->align(mb_strlen($line), 120);
        $this->writeln(
            "     <comment>$lineNumber</comment>:"
            . ($coverage === '' ? $coverage : "<fg=red>$coverage</>:")
            . $this->align(mb_strlen((string) $lineNumber), 6)
            . "<error>$line$endAlign</error>"
        );

        return $this;
    }

    /**
     * @param float $coverage
     * @param string $namespace
     * @return $this
     * @throws \InvalidArgumentException
     */
    public function formatCoverage(float $coverage, string $namespace): self
    {
        $coverage = \round($coverage, 3);

        $align = $this->align(mb_strlen((string) $coverage), 10);

        $this->write('  - ');
        $this->write($this->formatCoveragePercent($coverage));
        $this->write('%');
        $this->write($align);
        $this->writeln($namespace);

        return $this;
    }

    /**
     * @param int $lineNumber
     * @param int|string $lineCoverage
     * @param string $line
     * @throws \InvalidArgumentException
     * @return $this
     */
    public function formatCoveredLine(int $lineNumber, $lineCoverage, string $line): self
    {
        $lineColor = 'info';
        if ($lineCoverage === '-') {
            $lineColor = 'comment';
        }

        $endAlign = $this->align(mb_strlen($line), 120);
        $this->writeln(
            "     <comment>$lineNumber</comment>:"
            . "<$lineColor>$lineCoverage</$lineColor>:"
            . $this->align(mb_strlen((string) $lineNumber), 6)
            . "<$lineColor>$line$endAlign</$lineColor>"
        );

        return $this;
    }

    /**
     * @param float $coverage
     * @return string
     */
    public function formatCoveragePercent(float $coverage): string
    {
        switch (true) {
            case $coverage < 40:
                return "<fg=red>$coverage</>";

            case $coverage < 90:
                return "<comment>$coverage</comment>";

            default:
                return "<info>$coverage</info>";
        }
    }
}