Passed
Pull Request — master (#117)
by Dave
02:53
created

RemoveBaseLineCommandTest::testCleanUpOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 11
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 18
rs 9.9
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\LineNumber;
10
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\Location;
11
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\ProjectRoot;
12
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\Type;
13
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\OutputFormatter\OutputFormatter;
14
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Pruner\PrunedResults;
15
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\AnalysisResult;
16
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\AnalysisResults;
17
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\AnalysisResultsBuilder;
18
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command\RemoveBaseLineFromResultsCommand;
19
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Container\OutputFormatterRegistry;
20
use DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\GitDiffHistoryAnalyser\GitCommit;
21
use DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\OutputFormatters\TableOutputFormatter;
22
use DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\ResultsParsers\SarbJsonResultsParser\SarbJsonResultsParser;
23
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\Helpers\BaseLineResultsBuilder;
24
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\TestDoubles\HistoryFactoryStub;
25
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\TestDoubles\MockResultsPruner;
26
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\TestDoubles\OutputFormatterStub;
27
use Exception;
28
use PHPUnit\Framework\TestCase;
29
use Symfony\Component\Console\Tester\CommandTester;
30
use Throwable;
31
32
class RemoveBaseLineCommandTest extends TestCase
33
{
34
    private const INPUT_STRING_1 = <<<EOF
35
This is
36
a multiline
37
string
38
EOF;
39
    public const BASELINE_FILENAME = 'baseline1.sarb';
40
    public const BASELINE_FILE_ARGUMENT = 'baseline-file';
41
    public const OUTPUT_FORMAT_OPTION = '--output-format';
42
    public const PROJECT_ROOT = '--project-root';
43
    public const CLEAN_UP = '--clean-up';
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 = ProjectRoot::fromProjectRoot('/tmp', '/tmp/foo/bar');
74
    }
75
76
    public function testNoNewIssues(): void
77
    {
78
        $commandTester = $this->createCommandTester(
79
            $this->getAnalysisResultsWithXResults(0),
80
            null,
81
            null
82
        );
83
84
        $commandTester->execute([
85
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
86
        ]);
87
88
        $this->assertReturnCode(0, $commandTester);
89
        $this->assertResponseContains('Latest analysis issue count: 2', $commandTester);
90
        $this->assertResponseContains('Baseline issue count: 4', $commandTester);
91
        $this->assertResponseContains('Issue count with baseline removed: 0', $commandTester);
92
    }
93
94
    public function test1NewIssues(): void
95
    {
96
        $commandTester = $this->createCommandTester(
97
            $this->getAnalysisResultsWithXResults(1),
98
            null,
99
            null
100
        );
101
102
        $commandTester->execute([
103
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
104
        ]);
105
106
        $this->assertReturnCode(1, $commandTester);
107
        $this->assertResponseContains('Issue count with baseline removed: 1', $commandTester);
108
    }
109
110
    public function testPickNonDefaultOutputFormatter(): void
111
    {
112
        $commandTester = $this->createCommandTester(
113
            $this->getAnalysisResultsWithXResults(0),
114
            null,
115
            null
116
        );
117
118
        $commandTester->execute([
119
            self::OUTPUT_FORMAT_OPTION => OutputFormatterStub::CODE,
120
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
121
        ]);
122
123
        $this->assertReturnCode(0, $commandTester);
124
        $this->assertResponseContains(
125
            '[stub output formatter: Issues since baseline 0]',
126
            $commandTester
127
        );
128
    }
129
130
    public function testPickNonDefaultOutputFormatterWithIssues(): void
131
    {
132
        $commandTester = $this->createCommandTester(
133
            $this->getAnalysisResultsWithXResults(8),
134
            null,
135
            null
136
        );
137
138
        $commandTester->execute([
139
            self::OUTPUT_FORMAT_OPTION => OutputFormatterStub::CODE,
140
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
141
        ]);
142
143
        $this->assertReturnCode(1, $commandTester);
144
        $this->assertResponseContains(
145
            '[stub output formatter: Issues since baseline 8]',
146
            $commandTester
147
        );
148
    }
149
150
    public function testInvalidResultsParser(): void
151
    {
152
        $commandTester = $this->createCommandTester(
153
            $this->getAnalysisResultsWithXResults(0),
154
            null,
155
            null
156
        );
157
158
        $commandTester->execute([
159
            self::OUTPUT_FORMAT_OPTION => 'rubbish',
160
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
161
        ]);
162
163
        $this->assertReturnCode(11, $commandTester);
164
        $this->assertResponseContains(
165
            'Invalid value [rubbish] for option [output-format]. Pick one of: table|stub',
166
            $commandTester
167
        );
168
    }
169
170
    public function testSpecifyProjectRoot(): void
171
    {
172
        $commandTester = $this->createCommandTester(
173
            $this->getAnalysisResultsWithXResults(0),
174
            $this->projectRoot,
175
            null
176
        );
177
178
        $commandTester->execute([
179
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
180
            self::PROJECT_ROOT => '/tmp',
181
        ]);
182
183
        $this->assertReturnCode(0, $commandTester);
184
    }
185
186
    public function testException(): void
187
    {
188
        $commandTester = $this->createCommandTester(
189
            $this->getAnalysisResultsWithXResults(1),
190
            null,
191
            new Exception()
192
        );
193
194
        $commandTester->execute([
195
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
196
        ]);
197
198
        $this->assertReturnCode(100, $commandTester);
199
    }
200
201
202
    public function testCleanUpOptions(): void
203
    {
204
        $commandTester = $this->createCommandTester(
205
            $this->getAnalysisResultsWithXResults(0),
206
            $this->projectRoot,
207
            null
208
        );
209
210
        $commandTester->execute([
211
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
212
            self::CLEAN_UP => true,
213
        ]);
214
215
        var_dump($commandTester->getDisplay());
0 ignored issues
show
Security Debugging Code introduced by
var_dump($commandTester->getDisplay()) looks like debug code. Are you sure you do not want to remove it?
Loading history...
216
217
        $this->assertResponseContains(
218
            'Random 2 issues in the baseline to fix...',
219
            $commandTester
220
        );
221
    }
222
223
    private function createCommandTester(
224
        AnalysisResults $expectedAnalysisResults,
225
        ?ProjectRoot $projectRoot,
226
        ?Throwable $exception
227
    ): CommandTester {
228
        $baseLineResultsBuilder = new BaseLineResultsBuilder();
229
        $baseLineResultsBuilder->add('file1', 1, 'type1');
230
        $baseLineResultsBuilder->add('file2', 2, 'type2');
231
        $baseLineResultsBuilder->add('file3', 3, 'type3');
232
        $baseLineResultsBuilder->add('file4', 4, 'type4');
233
234
        $baseLine = new BaseLine(
235
            new HistoryFactoryStub(),
236
            $baseLineResultsBuilder->build(),
237
            new SarbJsonResultsParser(),
238
            new GitCommit('fae40b3d596780ffd746dbd2300d05dcfbd09033')
239
        );
240
241
        $prunedResults = new PrunedResults(
242
            $baseLine,
243
            $expectedAnalysisResults,
244
            $this->getAnalysisResultsWithXResults(2)
245
        );
246
247
        $mockResultsPruner = new MockResultsPruner(
248
            self::INPUT_STRING_1,
249
            $prunedResults,
250
            $projectRoot,
251
            $exception
252
        );
253
254
        $command = new RemoveBaseLineFromResultsCommand(
255
            $mockResultsPruner,
256
            $this->outputFormatterRegistry,
257
            new TableOutputFormatter(),
258
        );
259
260
        $commandTester = new CommandTester($command);
261
        $commandTester->setInputs([self::INPUT_STRING_1]);
262
263
        return $commandTester;
264
    }
265
266
267
268
    private function assertReturnCode(int $expectedReturnCode, CommandTester $commandTester): void
269
    {
270
        $this->assertSame($expectedReturnCode, $commandTester->getStatusCode(), $commandTester->getDisplay());
271
    }
272
273
    private function assertResponseContains(string $expectedMessage, CommandTester $commandTester): void
274
    {
275
        $output = $commandTester->getDisplay();
276
        $position = strpos($output, $expectedMessage);
277
        $this->assertNotFalse($position, "Can't find message [$expectedMessage] in [$output]");
278
    }
279
280
    private function getAnalysisResultsWithXResults(int $count): AnalysisResults
281
    {
282
        $projectRoot = ProjectRoot::fromCurrentWorkingDirectory('/');
283
284
        $analysisResultsBuilder = new AnalysisResultsBuilder();
285
        for ($i = 0; $i < $count; ++$i) {
286
            $analysisResult = new AnalysisResult(
287
                Location::fromAbsoluteFileName(
288
                    new AbsoluteFileName("/FILE_$count"),
289
                    $projectRoot,
290
                    new LineNumber($count)
291
                ),
292
                new Type("TYPE_$i"),
293
                "MESSAGE_$i",
294
                []
295
            );
296
            $analysisResultsBuilder->addAnalysisResult($analysisResult);
297
        }
298
299
        return $analysisResultsBuilder->build();
300
    }
301
}
302