Completed
Push — master ( b13ea3...fb1b03 )
by Dave
18s queued 15s
created

testSimulateStaticAnalysisToolFailed()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 18
rs 9.8666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DaveLiddament\StaticAnalysisResultsBaseliner\Tests\Unit\Framework\Command;
6
7
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\BaseLineFileName;
8
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\ProjectRoot;
9
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\HistoryAnalyser\HistoryFactory;
10
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\HistoryAnalyser\UnifiedDiffParser\Parser;
11
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\ErrorReportedByStaticAnalysisTool;
12
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\ResultsParser;
13
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command\CreateBaseLineCommand;
14
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Container\HistoryFactoryRegistry;
15
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Container\ResultsParsersRegistry;
16
use DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\GitDiffHistoryAnalyser\GitDiffHistoryFactory;
17
use DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\ResultsParsers\SarbJsonResultsParser\SarbJsonResultsParser;
18
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\TestDoubles\HistoryFactoryStub;
19
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\TestDoubles\ResultsParserStub;
20
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\TestDoubles\ResultsParserStubIdentifier;
21
use DaveLiddament\StaticAnalysisResultsBaseliner\Tests\Unit\Plugins\GitDiffHistoryAnalyser\internal\StubGitWrapper;
22
use PHPUnit\Framework\TestCase;
23
use Symfony\Component\Console\Tester\CommandTester;
24
25
class CreateBaseLineCommandTest extends TestCase
26
{
27
    private const INPUT_STRING_1 = <<<EOF
28
This is
29
a multiline
30
string
31
EOF;
32
    public const BASELINE_FILENAME = 'baseline1.sarb';
33
    public const BASELINE_FILE_ARGUMENT = 'baseline-file';
34
    public const INPUT_FORMAT_OPTION = '--input-format';
35
    public const HISTORY_ANALYSER = '--history-analyser';
36
    public const PROJECT_ROOT = '--project-root';
37
38
    /**
39
     * @var ResultsParser
40
     */
41
    private $defaultResultsParser;
42
    /**
43
     * @var ResultsParser
44
     */
45
    private $resultsParser2;
46
    /**
47
     * @var HistoryFactory
48
     */
49
    private $defaultHistoryFactory;
50
    /**
51
     * @var HistoryFactory
52
     */
53
    private $historyFactoryStub;
54
    /**
55
     * @var ProjectRoot
56
     */
57
    private $projectRoot;
58
    /**
59
     * @var ResultsParsersRegistry
60
     */
61
    private $resultsParserRegistry;
62
    /**
63
     * @var HistoryFactoryRegistry
64
     */
65
    private $historyFactoryRegistry;
66
67
    protected function setUp(): void
68
    {
69
        $this->defaultResultsParser = new SarbJsonResultsParser();
70
        $this->resultsParser2 = new ResultsParserStub();
71
72
        $this->resultsParserRegistry = new ResultsParsersRegistry([
73
            $this->defaultResultsParser,
74
            $this->resultsParser2,
75
        ]);
76
77
        $this->defaultHistoryFactory = new GitDiffHistoryFactory(new StubGitWrapper('123', ''), new Parser());
78
        $this->historyFactoryStub = new HistoryFactoryStub();
79
80
        $this->historyFactoryRegistry = new HistoryFactoryRegistry([
81
            $this->defaultHistoryFactory,
82
            $this->historyFactoryStub,
83
        ]);
84
85
        $this->projectRoot = ProjectRoot::fromProjectRoot('/tmp', '/tmp/foo/bar');
86
    }
87
88
    public function testHappyPath(): void
89
    {
90
        $commandTester = $this->createCommandTester(
91
            $this->defaultHistoryFactory,
92
            $this->defaultResultsParser,
93
            self::BASELINE_FILENAME,
94
            null,
95
            null
96
        );
97
98
        $commandTester->execute([
99
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
100
        ]);
101
102
        $this->assertReturnCode(0, $commandTester);
103
        $this->assertResponseContains('Baseline created', $commandTester);
104
    }
105
106
    public function testPickNonDefaultResultsParserWithGuessTypesSet(): void
107
    {
108
        $commandTester = $this->createCommandTester(
109
            $this->defaultHistoryFactory,
110
            $this->resultsParser2,
111
            self::BASELINE_FILENAME,
112
            null,
113
            null
114
        );
115
116
        $commandTester->execute([
117
            self::INPUT_FORMAT_OPTION => ResultsParserStubIdentifier::CODE,
118
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
119
        ]);
120
121
        $this->assertReturnCode(0, $commandTester);
122
        $this->assertResponseContains(
123
            '[results-parser-stub] guesses the classification of violations. This means results might not be 100% accurate.',
124
            $commandTester
125
        );
126
    }
127
128
    public function testPickNonDefaultHistoryAnalyser(): void
129
    {
130
        $commandTester = $this->createCommandTester(
131
            $this->historyFactoryStub,
132
            $this->defaultResultsParser,
133
            self::BASELINE_FILENAME,
134
            null,
135
            null
136
        );
137
138
        $commandTester->execute([
139
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
140
            self::HISTORY_ANALYSER => HistoryFactoryStub::CODE,
141
        ]);
142
143
        $this->assertReturnCode(0, $commandTester);
144
    }
145
146
    public function testInvalidResultsParser(): void
147
    {
148
        $commandTester = $this->createCommandTester(
149
            $this->defaultHistoryFactory,
150
            $this->defaultResultsParser,
151
            self::BASELINE_FILENAME,
152
            null,
153
            null
154
        );
155
156
        $commandTester->execute([
157
            self::INPUT_FORMAT_OPTION => 'rubbish',
158
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
159
        ]);
160
161
        $this->assertReturnCode(11, $commandTester);
162
        $this->assertResponseContains(
163
            'Invalid value [rubbish] for option [input-format]. Pick one of: sarb-json|results-parser-stub',
164
            $commandTester
165
        );
166
    }
167
168
    public function testInvalidHistoryAnalyser(): void
169
    {
170
        $commandTester = $this->createCommandTester(
171
            $this->defaultHistoryFactory,
172
            $this->defaultResultsParser,
173
            self::BASELINE_FILENAME,
174
            null,
175
            null
176
        );
177
178
        $commandTester->execute([
179
            self::HISTORY_ANALYSER => 'rubbish',
180
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
181
        ]);
182
183
        $this->assertReturnCode(11, $commandTester);
184
        $this->assertResponseContains(
185
            'Invalid value [rubbish] for option [history-analyser]. Pick one of: git|history-factory-stub',
186
            $commandTester
187
        );
188
    }
189
190
    public function testSpecifyProjectRoot(): void
191
    {
192
        $commandTester = $this->createCommandTester(
193
            $this->historyFactoryStub,
194
            $this->defaultResultsParser,
195
            self::BASELINE_FILENAME,
196
            $this->projectRoot,
197
            null
198
        );
199
200
        $commandTester->execute([
201
            self::HISTORY_ANALYSER => HistoryFactoryStub::CODE,
202
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
203
            self::PROJECT_ROOT => '/tmp',
204
        ]);
205
206
        $this->assertReturnCode(0, $commandTester);
207
    }
208
209
    public function testSimulateThrowable(): void
210
    {
211
        $commandTester = $this->createCommandTester(
212
            $this->historyFactoryStub,
213
            $this->defaultResultsParser,
214
            self::BASELINE_FILENAME,
215
            null,
216
            new \Exception()
217
        );
218
219
        $commandTester->execute([
220
            self::HISTORY_ANALYSER => HistoryFactoryStub::CODE,
221
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
222
            self::PROJECT_ROOT => '/tmp',
223
        ]);
224
225
        $this->assertReturnCode(100, $commandTester);
226
    }
227
228
    public function testSimulateStaticAnalysisToolFailed(): void
229
    {
230
        $commandTester = $this->createCommandTester(
231
            $this->historyFactoryStub,
232
            $this->defaultResultsParser,
233
            self::BASELINE_FILENAME,
234
            null,
235
            new ErrorReportedByStaticAnalysisTool('Tool failed'),
236
        );
237
238
        $commandTester->execute([
239
            self::HISTORY_ANALYSER => HistoryFactoryStub::CODE,
240
            self::BASELINE_FILE_ARGUMENT => self::BASELINE_FILENAME,
241
            self::PROJECT_ROOT => '/tmp',
242
        ]);
243
244
        $this->assertReturnCode(16, $commandTester);
245
        $this->assertResponseContains('Tool failed', $commandTester);
246
    }
247
248
    private function createCommandTester(
249
        HistoryFactory $expectedHistoryFactory,
250
        ResultsParser $expectedResultsParser,
251
        string $baselineFileName,
252
        ?ProjectRoot $projectRoot,
253
        ?\Throwable $exception
254
    ): CommandTester {
255
        $mockBaseLineCreator = new MockBaseLineCreator(
256
            $expectedHistoryFactory,
257
            $expectedResultsParser,
258
            new BaseLineFileName($baselineFileName),
259
            $projectRoot,
260
            self::INPUT_STRING_1, // CommandTest adds line end
261
            $exception
262
        );
263
264
        $command = new CreateBaseLineCommand(
265
            $this->resultsParserRegistry,
266
            $this->historyFactoryRegistry,
267
            $mockBaseLineCreator
268
        );
269
270
        $commandTester = new CommandTester($command);
271
        $commandTester->setInputs([self::INPUT_STRING_1]);
272
273
        return $commandTester;
274
    }
275
276
    private function assertReturnCode(int $expectedReturnCode, CommandTester $commandTester): void
277
    {
278
        $this->assertSame($expectedReturnCode, $commandTester->getStatusCode(), $commandTester->getDisplay());
279
    }
280
281
    private function assertResponseContains(string $expectedMessage, CommandTester $commandTester): void
282
    {
283
        $output = $commandTester->getDisplay();
284
        $position = strpos($output, $expectedMessage);
285
        $this->assertNotFalse($position, "Can't find message [$expectedMessage] in [$output]");
286
    }
287
}
288