Completed
Push — master ( 41ae82...437c90 )
by Dave
13s queued 11s
created

RemoveBaseLineCommandTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
eloc 6
c 2
b 0
f 1
nc 1
nop 0
dl 0
loc 11
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DaveLiddament\StaticAnalysisResultsBaseliner\Tests\Unit\Framework\Command;
6
7
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\AbsoluteFileName;
8
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\BaseLine;
9
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\BaseLineFileName;
10
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\LineNumber;
11
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\Location;
12
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\ProjectRoot;
13
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\Type;
14
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\OutputFormatter\OutputFormatter;
15
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Pruner\PrunedResults;
16
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\AnalysisResult;
17
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\AnalysisResults;
18
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\AnalysisResultsBuilder;
19
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command\RemoveBaseLineFromResultsCommand;
20
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Container\OutputFormatterRegistry;
21
use DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\GitDiffHistoryAnalyser\GitCommit;
22
use DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\OutputFormatters\TableOutputFormatter;
23
use DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\ResultsParsers\SarbJsonResultsParser\SarbJsonResultsParser;
24
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\Helpers\BaseLineResultsBuilder;
25
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\TestDoubles\HistoryFactoryStub;
26
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\TestDoubles\MockResultsPruner;
27
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\TestDoubles\OutputFormatterStub;
28
use Exception;
29
use PHPUnit\Framework\TestCase;
30
use Symfony\Component\Console\Tester\CommandTester;
31
use Throwable;
32
33
class RemoveBaseLineCommandTest extends TestCase
34
{
35
    private const INPUT_STRING_1 = <<<EOF
36
This is
37
a multiline
38
string
39
EOF;
40
    public const BASELINE_FILENAME = 'baseline1.sarb';
41
    public const BASELINE_FILE_ARGUMENT = 'baseline-file';
42
    public const OUTPUT_FORMAT_OPTION = '--output-format';
43
    public const PROJECT_ROOT = '--project-root';
44
45
    /**
46
     * @var ProjectRoot
47
     */
48
    private $projectRoot;
49
50
    /**
51
     * @var OutputFormatterRegistry
52
     */
53
    private $outputFormatterRegistry;
54
    /**
55
     * @var OutputFormatter
56
     */
57
    private $defaultOutputFormater;
58
    /**
59
     * @var OutputFormatter
60
     */
61
    private $stubOutputFormatter;
62
63
    protected function setUp(): void
64
    {
65
        $this->defaultOutputFormater = new TableOutputFormatter();
66
        $this->stubOutputFormatter = new OutputFormatterStub();
67
68
        $this->outputFormatterRegistry = new OutputFormatterRegistry([
69
            $this->defaultOutputFormater,
70
            $this->stubOutputFormatter,
71
        ]);
72
73
        $this->projectRoot = new ProjectRoot('/tmp', '/tmp/foo/bar');
74
    }
75
76
    public function testNoNewIssues(): void
77
    {
78
        $commandTester = $this->createCommandTester(
79
            $this->defaultOutputFormater,
80
            $this->getAnalysisResultsWithXResults(0),
81
            self::BASELINE_FILENAME,
82
            null,
83
            null
84
        );
85
86
        $commandTester->execute([
87
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
88
        ]);
89
90
        $this->assertReturnCode(0, $commandTester);
91
        $this->assertResponseContains('Latest analysis issue count: 2', $commandTester);
92
        $this->assertResponseContains('Baseline issue count: 4', $commandTester);
93
        $this->assertResponseContains('Issue count with baseline removed: 0', $commandTester);
94
    }
95
96
    public function test1NewIssues(): void
97
    {
98
        $commandTester = $this->createCommandTester(
99
            $this->defaultOutputFormater,
100
            $this->getAnalysisResultsWithXResults(1),
101
            self::BASELINE_FILENAME,
102
            null,
103
            null
104
        );
105
106
        $commandTester->execute([
107
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
108
        ]);
109
110
        $this->assertReturnCode(1, $commandTester);
111
        $this->assertResponseContains('Issue count with baseline removed: 1', $commandTester);
112
    }
113
114
    public function testPickNonDefaultOutputFormatter(): void
115
    {
116
        $commandTester = $this->createCommandTester(
117
            $this->stubOutputFormatter,
118
            $this->getAnalysisResultsWithXResults(0),
119
            self::BASELINE_FILENAME,
120
            null,
121
            null
122
        );
123
124
        $commandTester->execute([
125
            self::OUTPUT_FORMAT_OPTION => OutputFormatterStub::CODE,
126
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
127
        ]);
128
129
        $this->assertReturnCode(0, $commandTester);
130
        $this->assertResponseContains(
131
            '[stub output formatter: Issues since baseline 0]',
132
            $commandTester
133
        );
134
    }
135
136
    public function testPickNonDefaultOutputFormatterWithIssues(): void
137
    {
138
        $commandTester = $this->createCommandTester(
139
            $this->stubOutputFormatter,
140
            $this->getAnalysisResultsWithXResults(8),
141
            self::BASELINE_FILENAME,
142
            null,
143
            null
144
        );
145
146
        $commandTester->execute([
147
            self::OUTPUT_FORMAT_OPTION => OutputFormatterStub::CODE,
148
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
149
        ]);
150
151
        $this->assertReturnCode(1, $commandTester);
152
        $this->assertResponseContains(
153
            '[stub output formatter: Issues since baseline 8]',
154
            $commandTester
155
        );
156
    }
157
158
    public function testInvalidResultsParser(): void
159
    {
160
        $commandTester = $this->createCommandTester(
161
            $this->defaultOutputFormater,
162
            $this->getAnalysisResultsWithXResults(0),
163
            self::BASELINE_FILENAME,
164
            null,
165
            null
166
        );
167
168
        $commandTester->execute([
169
            self::OUTPUT_FORMAT_OPTION => 'rubbish',
170
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
171
        ]);
172
173
        $this->assertReturnCode(11, $commandTester);
174
        $this->assertResponseContains(
175
            'Invalid value [rubbish] for option [output-format]. Pick one of: table|stub',
176
            $commandTester
177
        );
178
    }
179
180
    public function testSpecifyProjectRoot(): void
181
    {
182
        $commandTester = $this->createCommandTester(
183
            $this->defaultOutputFormater,
184
            $this->getAnalysisResultsWithXResults(0),
185
            self::BASELINE_FILENAME,
186
            $this->projectRoot,
187
            null
188
        );
189
190
        $commandTester->execute([
191
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
192
            self::PROJECT_ROOT => '/tmp',
193
        ]);
194
195
        $this->assertReturnCode(0, $commandTester);
196
    }
197
198
    public function testException(): void
199
    {
200
        $commandTester = $this->createCommandTester(
201
            $this->defaultOutputFormater,
202
            $this->getAnalysisResultsWithXResults(1),
203
            self::BASELINE_FILENAME,
204
            null,
205
            new Exception()
206
        );
207
208
        $commandTester->execute([
209
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
210
        ]);
211
212
        $this->assertReturnCode(100, $commandTester);
213
    }
214
215
    private function createCommandTester(
216
        OutputFormatter $expectedOutputFormatter,
0 ignored issues
show
Unused Code introduced by
The parameter $expectedOutputFormatter is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

216
        /** @scrutinizer ignore-unused */ OutputFormatter $expectedOutputFormatter,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
217
        AnalysisResults $expectedAnalysisResults,
218
        string $baselineFileName,
219
        ?ProjectRoot $projectRoot,
220
        ?Throwable $exception
221
    ): CommandTester {
222
        $baseLineResultsBuilder = new BaseLineResultsBuilder();
223
        $baseLineResultsBuilder->add('file1', 1, 'type1');
224
        $baseLineResultsBuilder->add('file2', 2, 'type2');
225
        $baseLineResultsBuilder->add('file3', 3, 'type3');
226
        $baseLineResultsBuilder->add('file4', 4, 'type4');
227
228
        $baseLine = new BaseLine(
229
            new HistoryFactoryStub(),
230
            $baseLineResultsBuilder->build(),
231
            new SarbJsonResultsParser(),
232
            new GitCommit('fae40b3d596780ffd746dbd2300d05dcfbd09033')
233
        );
234
235
        $prunedResults = new PrunedResults(
236
            $baseLine,
237
            $expectedAnalysisResults,
238
            2
239
        );
240
241
        $mockResultsPruner = new MockResultsPruner(
242
            new BaseLineFileName($baselineFileName),
243
            self::INPUT_STRING_1,
244
            $prunedResults,
245
            $projectRoot,
246
            $exception
247
        );
248
249
        $command = new RemoveBaseLineFromResultsCommand(
250
            $mockResultsPruner,
251
            $this->outputFormatterRegistry
252
        );
253
254
        $commandTester = new CommandTester($command);
255
        $commandTester->setInputs([self::INPUT_STRING_1]);
256
257
        return $commandTester;
258
    }
259
260
    private function assertReturnCode(int $expectedReturnCode, CommandTester $commandTester): void
261
    {
262
        $this->assertSame($expectedReturnCode, $commandTester->getStatusCode(), $commandTester->getDisplay());
263
    }
264
265
    private function assertResponseContains(string $expectedMessage, CommandTester $commandTester): void
266
    {
267
        $output = $commandTester->getDisplay();
268
        $position = strpos($output, $expectedMessage);
269
        $this->assertNotFalse($position, "Can't find message [$expectedMessage] in [$output]");
270
    }
271
272
    private function getAnalysisResultsWithXResults(int $count): AnalysisResults
273
    {
274
        $projectRoot = new ProjectRoot('/', '/');
275
276
        $analysisResultsBuilder = new AnalysisResultsBuilder();
277
        for ($i = 0; $i < $count; ++$i) {
278
            $analysisResult = new AnalysisResult(
279
                Location::fromAbsoluteFileName(
280
                    new AbsoluteFileName("/FILE_$count"),
281
                    $projectRoot,
282
                    new LineNumber($count)
283
                ),
284
                new Type("TYPE_$i"),
285
                "MESSAGE_$i",
286
                []
287
            );
288
            $analysisResultsBuilder->addAnalysisResult($analysisResult);
289
        }
290
291
        return $analysisResultsBuilder->build();
292
    }
293
}
294