Completed
Push — master ( 1806e5...ab9baf )
by Jefersson
04:58
created

src/Command/CheckGherkinCodeStyle.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license.
17
 */
18
19
namespace KawaiiGherkin\Command;
20
21
use Behat\Gherkin\Parser;
22
use KawaiiGherkin\Formatter\Background;
23
use KawaiiGherkin\Formatter\FeatureDescription;
24
use KawaiiGherkin\Formatter\Scenario;
25
use KawaiiGherkin\Formatter\Step;
26
use KawaiiGherkin\Formatter\Tags;
27
use SebastianBergmann\Diff\Differ;
28
use Symfony\Component\Console\Command\Command;
29
use Symfony\Component\Console\Input\InputArgument;
30
use Symfony\Component\Console\Input\InputInterface;
31
use Symfony\Component\Console\Input\InputOption;
32
use Symfony\Component\Console\Output\OutputInterface;
33
use Symfony\Component\Finder\Finder;
34
35
/**
36
 * @author  Jefersson Nathan  <[email protected]>
37
 * @license MIT
38
 */
39
final class CheckGherkinCodeStyle extends Command
0 ignored issues
show
The class CheckGherkinCodeStyle has a coupling between objects value of 13. Consider to reduce the number of dependencies under 13.
Loading history...
40
{
41
    /**
42
     * @var Parser
43
     */
44
    private $parser;
45
46
    /**
47
     * {@inheritDoc}
48
     *
49
     * @param Parser $parser
50
     */
51 2
    public function __construct($name, $parser)
52
    {
53 2
        parent::__construct('Kawaii Gherkin');
54 2
        $this->parser = $parser;
55 2
    }
56
57
    /**
58
     * {@inheritDoc}
59
     */
60 2
    protected function configure()
61
    {
62
        $this
63 2
            ->setName('gherkin:check')
64 2
            ->setDescription('Find wrong gherkin code styled')
65 2
            ->addArgument(
66 2
                'directory',
67 2
                InputArgument::REQUIRED,
68 2
                'Path to find *.feature files'
69
            )
70 2
            ->addOption(
71 2
                'align',
72 2
                null,
73 2
                InputOption::VALUE_OPTIONAL,
74 2
                'Side to align statement (right or left). Default right',
75 2
                'left'
76
            );
77 2
    }
78
79
    /**
80
     * {@inheritDoc}
81
     */
82 2
    protected function execute(InputInterface $input, OutputInterface $output)
0 ignored issues
show
This operation has 3760 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
83
    {
84 2
        $align = $input->getOption('align') === Step::ALIGN_TO_LEFT
85 2
            ? Step::ALIGN_TO_LEFT
86 2
            : Step::ALIGN_TO_RIGHT;
87
88 2
        $directory = $input->getArgument('directory');
89 2
        $finder    = new Finder();
90
        $finder
91 2
            ->files()
92 2
            ->in($directory)
93 2
            ->name('*.feature');
94
95 2
        $output->writeln("\nFinding files on <info>" . $directory . "</info>\n");
96
97
        /* @var $file \Symfony\Component\Finder\SplFileInfo */
98 2
        foreach ($finder as $file) {
99
100 1
            $fileContent            = $file->getContents();
101 1
            $contentWithoutComments = $this->removeComments($fileContent);
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $contentWithoutComments exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
102
103 1
            $feature            = $this->parser->parse($fileContent);
104 1
            $tagFormatter       = new Tags();
105 1
            $featureDescription = new FeatureDescription();
106 1
            $background         = new Background($align);
107 1
            $scenario           = new Scenario($align);
108
109 1
            $formatted = $feature->hasTags() ? $tagFormatter->format($feature->getTags()) . PHP_EOL : '';
110 1
            $formatted .= $featureDescription->format($feature->getTitle(), explode(PHP_EOL, $feature->getDescription())) . PHP_EOL . PHP_EOL;
111 1
            $formatted .= $feature->hasBackground() ? $background->format($feature->getBackground()) . PHP_EOL : '';
112 1
            $formatted .= $feature->hasScenarios() ? $scenario->format($feature->getScenarios()) : '';
113
114 1
            if ($formatted !== $contentWithoutComments) {
115
116 1
                if (! defined('FAILED')) {
117 1
                    define('FAILED', true);
118
                }
119
120 1
                $diff = new Differ("--- Original\n+++ Expected\n", false);
121
122 1
                $output->writeln('<error>Wrong style: ' . $file->getRealPath() . '</error>');
123 1
                $output->writeln($diff->diff($contentWithoutComments, $formatted));
124
            }
125
        }
126
127 2
        if (defined('FAILED')) {
128 1
            return 1;
129
        }
130
131 1
        $output->writeln('<bg=green;fg=white>     Everything is OK!     </>');
132 1
    }
133
134
    /**
135
     * @param string $fileContent
136
     *
137
     * @return string
138
     */
139 1
    private function removeComments($fileContent)
140
    {
141 1
        return rtrim(
142
            implode(
143
                array_filter(
144
                    array_map(
145 1
                        function ($line) {
146 1
                            if (0 === mb_strpos(ltrim($line), '#')) {
147 1
                                return '';
148
                            }
149
150 1
                            return rtrim($line) . PHP_EOL;
151 1
                        },
152 1
                        explode("\n", $fileContent)
153
                    )
154
                )
155
            )
156 1
        ) . PHP_EOL;
157
    }
158
}
159