Completed
Push — master ( a6be25...7dec61 )
by Jonathan
9s
created

ConsoleTest   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 410
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 410
rs 10
c 0
b 0
f 0
wmc 17

17 Methods

Rating   Name   Duplication   Size   Complexity  
A testGenerate() 0 18 1
A testCreateOutputCouldNotOpenHandleInvalidArgumentException() 0 19 1
A testGenerateConfigOverride() 0 21 1
B testGenerateConfigInvalidProject() 0 24 1
A testCreateOutput() 0 22 1
B testGenerateConfigEmpty() 0 25 1
A testGenerateConfig() 0 21 1
B testGenerateFile() 0 24 1
B testGenerateFilePrependStreamOutput() 0 25 1
A testGenerateLabel() 0 19 1
A testGenerateConfigOverrideNoLabels() 0 20 1
B testGenerateFilePathGiven() 0 24 1
B testGenerateFileAppend() 0 25 1
A setUp() 0 14 1
A testGenerateInvalidConfig() 0 16 1
B testGenerateFilePrepend() 0 25 1
A testGenerateConfigDoesNotExist() 0 23 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ChangelogGenerator\Tests\Functional;
6
7
use ChangelogGenerator\ChangelogConfig;
8
use ChangelogGenerator\ChangelogGenerator;
9
use ChangelogGenerator\Command\GenerateChangelogCommand;
10
use InvalidArgumentException;
11
use PackageVersions\Versions;
12
use PHPUnit\Framework\TestCase;
13
use Symfony\Component\Console\Application;
14
use Symfony\Component\Console\Input\ArrayInput;
15
use Symfony\Component\Console\Output\BufferedOutput;
16
use Symfony\Component\Console\Output\OutputInterface;
17
use Symfony\Component\Console\Output\StreamOutput;
18
use function sprintf;
19
use function sys_get_temp_dir;
20
use function unlink;
21
22
final class ConsoleTest extends TestCase
23
{
24
    /** @var \PHPUnit_Framework_MockObject_MockObject|ChangelogGenerator */
25
    private $changelogGenerator;
26
27
    /** @var \PHPUnit_Framework_MockObject_MockObject|GenerateChangelogCommand */
28
    private $generateChangelogCommand;
29
30
    /** @var Application */
31
    private $application;
32
33
    public function testGenerate() : void
34
    {
35
        $input = new ArrayInput([
36
            'command'       => 'generate',
37
            '--user'        => 'jwage',
38
            '--repository'  => 'changelog-generator',
39
            '--milestone'   => '1.0',
40
        ]);
41
42
        $output = $this->createMock(OutputInterface::class);
43
44
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
45
46
        $this->changelogGenerator->expects($this->once())
47
            ->method('generate')
48
            ->with($changelogConfig, $output);
49
50
        $this->application->run($input, $output);
51
    }
52
53
54
    public function testGenerateInvalidConfig() : void
55
    {
56
        $this->expectException(InvalidArgumentException::class);
57
        $this->expectExceptionMessage('You must pass a config file with the --config option or manually specify the --user --repository and --milestone options.');
58
59
        $input = new ArrayInput(['command' => 'generate']);
60
61
        $output = $this->createMock(OutputInterface::class);
62
63
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
64
65
        $this->changelogGenerator->expects($this->never())
66
            ->method('generate')
67
            ->with($changelogConfig, $output);
68
69
        $this->application->run($input, $output);
70
    }
71
72
    public function testGenerateFile() : void
73
    {
74
        $input = new ArrayInput([
75
            'command'       => 'generate',
76
            '--user'        => 'jwage',
77
            '--repository'  => 'changelog-generator',
78
            '--milestone'   => '1.0',
79
            '--file'        => null,
80
        ]);
81
82
        $output       = $this->createMock(OutputInterface::class);
83
        $streamOutput = $this->createMock(StreamOutput::class);
84
85
        $this->generateChangelogCommand->expects($this->once())
86
            ->method('createOutput')
87
            ->willReturn($streamOutput);
88
89
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
90
91
        $this->changelogGenerator->expects($this->once())
92
            ->method('generate')
93
            ->with($changelogConfig, $streamOutput);
94
95
        $this->application->run($input, $output);
96
    }
97
98
    public function testGenerateFilePathGiven() : void
99
    {
100
        $input = new ArrayInput([
101
            'command'       => 'generate',
102
            '--user'        => 'jwage',
103
            '--repository'  => 'changelog-generator',
104
            '--milestone'   => '1.0',
105
            '--file'        => 'CHANGELOG.md',
106
        ]);
107
108
        $output       = $this->createMock(OutputInterface::class);
109
        $streamOutput = $this->createMock(StreamOutput::class);
110
111
        $this->generateChangelogCommand->expects($this->once())
112
            ->method('createOutput')
113
            ->willReturn($streamOutput);
114
115
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
116
117
        $this->changelogGenerator->expects($this->once())
118
            ->method('generate')
119
            ->with($changelogConfig, $streamOutput);
120
121
        $this->application->run($input, $output);
122
    }
123
124
    public function testGenerateFileAppend() : void
125
    {
126
        $input = new ArrayInput([
127
            'command'       => 'generate',
128
            '--user'        => 'jwage',
129
            '--repository'  => 'changelog-generator',
130
            '--milestone'   => '1.0',
131
            '--file'        => 'CHANGELOG.md',
132
            '--append'      => true,
133
        ]);
134
135
        $output       = $this->createMock(OutputInterface::class);
136
        $streamOutput = $this->createMock(StreamOutput::class);
137
138
        $this->generateChangelogCommand->expects($this->once())
139
            ->method('createOutput')
140
            ->willReturn($streamOutput);
141
142
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
143
144
        $this->changelogGenerator->expects($this->once())
145
            ->method('generate')
146
            ->with($changelogConfig, $streamOutput);
147
148
        $this->application->run($input, $output);
149
    }
150
151
    public function testGenerateFilePrepend() : void
152
    {
153
        $input = new ArrayInput([
154
            'command'       => 'generate',
155
            '--user'        => 'jwage',
156
            '--repository'  => 'changelog-generator',
157
            '--milestone'   => '1.0',
158
            '--file'        => 'CHANGELOG.md',
159
            '--prepend'     => true,
160
        ]);
161
162
        $output         = $this->createMock(OutputInterface::class);
163
        $bufferedOutput = $this->createMock(BufferedOutput::class);
164
165
        $this->generateChangelogCommand->expects($this->once())
166
            ->method('createOutput')
167
            ->willReturn($bufferedOutput);
168
169
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
170
171
        $this->changelogGenerator->expects($this->once())
172
            ->method('generate')
173
            ->with($changelogConfig, $bufferedOutput);
174
175
        $this->application->run($input, $output);
176
    }
177
178
    public function testGenerateFilePrependStreamOutput() : void
179
    {
180
        $input = new ArrayInput([
181
            'command'       => 'generate',
182
            '--user'        => 'jwage',
183
            '--repository'  => 'changelog-generator',
184
            '--milestone'   => '1.0',
185
            '--file'        => 'CHANGELOG.md',
186
            '--prepend'     => true,
187
        ]);
188
189
        $output       = $this->createMock(OutputInterface::class);
190
        $streamOutput = $this->createMock(StreamOutput::class);
191
192
        $this->generateChangelogCommand->expects($this->once())
193
            ->method('createOutput')
194
            ->willReturn($streamOutput);
195
196
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
197
198
        $this->changelogGenerator->expects($this->once())
199
            ->method('generate')
200
            ->with($changelogConfig, $streamOutput);
201
202
        $this->application->run($input, $output);
203
    }
204
205
    public function testGenerateLabel() : void
206
    {
207
        $input = new ArrayInput([
208
            'command'       => 'generate',
209
            '--user'        => 'jwage',
210
            '--repository'  => 'changelog-generator',
211
            '--milestone'   => '1.0',
212
            '--label'       => ['Enhancement', 'Bug'],
213
        ]);
214
215
        $output = $this->createMock(OutputInterface::class);
216
217
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
218
219
        $this->changelogGenerator->expects($this->once())
220
            ->method('generate')
221
            ->with($changelogConfig, $output);
222
223
        $this->application->run($input, $output);
224
    }
225
226
    public function testGenerateConfig() : void
227
    {
228
        $input = new ArrayInput([
229
            'command'       => 'generate',
230
            '--user'        => 'jwage',
231
            '--repository'  => 'changelog-generator',
232
            '--milestone'   => '1.0',
233
            '--label'       => ['Enhancement', 'Bug'],
234
            '--config'      => __DIR__ . '/_files/config.php',
235
            '--project'     => 'changelog-generator',
236
        ]);
237
238
        $output = $this->createMock(OutputInterface::class);
239
240
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
241
242
        $this->changelogGenerator->expects($this->once())
243
            ->method('generate')
244
            ->with($changelogConfig, $output);
245
246
        $this->application->run($input, $output);
247
    }
248
249
    public function testGenerateConfigDoesNotExist() : void
250
    {
251
        $this->expectException(InvalidArgumentException::class);
252
        $this->expectExceptionMessage('Configuration file "unknown.php" does not exist.');
253
254
        $input = new ArrayInput([
255
            'command'       => 'generate',
256
            '--user'        => 'jwage',
257
            '--repository'  => 'changelog-generator',
258
            '--milestone'   => '1.0',
259
            '--label'       => ['Enhancement', 'Bug'],
260
            '--config'      => 'unknown.php',
261
        ]);
262
263
        $output = $this->createMock(OutputInterface::class);
264
265
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
266
267
        $this->changelogGenerator->expects($this->never())
268
            ->method('generate')
269
            ->with($changelogConfig, $output);
270
271
        $this->application->run($input, $output);
272
    }
273
274
    public function testGenerateConfigEmpty() : void
275
    {
276
        $configFile = __DIR__ . '/_files/empty.php';
277
278
        $this->expectException(InvalidArgumentException::class);
279
        $this->expectExceptionMessage(sprintf('Configuration file "%s" did not return anything.', $configFile));
280
281
        $input = new ArrayInput([
282
            'command'       => 'generate',
283
            '--user'        => 'jwage',
284
            '--repository'  => 'changelog-generator',
285
            '--milestone'   => '1.0',
286
            '--label'       => ['Enhancement', 'Bug'],
287
            '--config'      => $configFile,
288
        ]);
289
290
        $output = $this->createMock(OutputInterface::class);
291
292
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
293
294
        $this->changelogGenerator->expects($this->never())
295
            ->method('generate')
296
            ->with($changelogConfig, $output);
297
298
        $this->application->run($input, $output);
299
    }
300
301
    public function testGenerateConfigInvalidProject() : void
302
    {
303
        $this->expectException(InvalidArgumentException::class);
304
        $this->expectExceptionMessage('Could not find project named "unknown" configured');
305
306
        $input = new ArrayInput([
307
            'command'       => 'generate',
308
            '--user'        => 'jwage',
309
            '--repository'  => 'changelog-generator',
310
            '--milestone'   => '1.0',
311
            '--label'       => ['Enhancement', 'Bug'],
312
            '--config'      => __DIR__ . '/_files/config.php',
313
            '--project'     => 'unknown',
314
        ]);
315
316
        $output = $this->createMock(OutputInterface::class);
317
318
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
319
320
        $this->changelogGenerator->expects($this->never())
321
            ->method('generate')
322
            ->with($changelogConfig, $output);
323
324
        $this->application->run($input, $output);
325
    }
326
327
    public function testGenerateConfigOverride() : void
328
    {
329
        $input = new ArrayInput([
330
            'command'       => 'generate',
331
            '--user'        => 'doctrine',
332
            '--repository'  => 'migrations',
333
            '--milestone'   => '2.0',
334
            '--label'       => ['Improvement', 'Bug'],
335
            '--config'      => __DIR__ . '/_files/config.php',
336
            '--project'     => 'changelog-generator',
337
        ]);
338
339
        $output = $this->createMock(OutputInterface::class);
340
341
        $changelogConfig = new ChangelogConfig('doctrine', 'migrations', '2.0', ['Improvement', 'Bug']);
342
343
        $this->changelogGenerator->expects($this->once())
344
            ->method('generate')
345
            ->with($changelogConfig, $output);
346
347
        $this->application->run($input, $output);
348
    }
349
350
351
    public function testGenerateConfigOverrideNoLabels() : void
352
    {
353
        $input = new ArrayInput([
354
            'command'       => 'generate',
355
            '--user'        => 'doctrine',
356
            '--repository'  => 'migrations',
357
            '--milestone'   => '2.0',
358
            '--config'      => __DIR__ . '/_files/config.php',
359
            '--project'     => 'changelog-generator',
360
        ]);
361
362
        $output = $this->createMock(OutputInterface::class);
363
364
        $changelogConfig = new ChangelogConfig('doctrine', 'migrations', '2.0', ['Enhancement', 'Bug']);
365
366
        $this->changelogGenerator->expects($this->once())
367
            ->method('generate')
368
            ->with($changelogConfig, $output);
369
370
        $this->application->run($input, $output);
371
    }
372
373
    public function testCreateOutput() : void
374
    {
375
        $generateChangelogCommand = new GenerateChangelogCommandStub($this->changelogGenerator);
376
377
        $file = sprintf('%s/test.md', sys_get_temp_dir());
378
379
        self::assertInstanceOf(
380
            StreamOutput::class,
381
            $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_APPEND)
382
        );
383
384
        self::assertInstanceOf(
385
            BufferedOutput::class,
386
            $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_PREPEND)
387
        );
388
389
        self::assertInstanceOf(
390
            StreamOutput::class,
391
            $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_REPLACE)
392
        );
393
394
        unlink($file);
395
    }
396
397
    public function testCreateOutputCouldNotOpenHandleInvalidArgumentException() : void
398
    {
399
        $this->expectException(InvalidArgumentException::class);
400
        $this->expectExceptionMessage('Could not open handle for /tmp/test.md');
401
402
        $file = sprintf('%s/test.md', sys_get_temp_dir());
403
404
        /** @var \PHPUnit_Framework_MockObject_MockObject|GenerateChangelogCommandStub $generateChangelogCommand */
405
        $generateChangelogCommand = $this->getMockBuilder(GenerateChangelogCommandStub::class)
406
            ->setConstructorArgs([$this->changelogGenerator])
407
            ->setMethods(['fopen'])
408
            ->getMock();
409
410
        $generateChangelogCommand->expects($this->once())
411
            ->method('fopen')
412
            ->with($file, 'a+')
413
            ->willReturn(false);
414
415
        $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_APPEND);
416
    }
417
418
    protected function setUp() : void
419
    {
420
        $this->changelogGenerator = $this->createMock(ChangelogGenerator::class);
421
422
        $this->application = new Application('Changelog Generator', Versions::getVersion('jwage/changelog-generator'));
423
        $this->application->setAutoExit(false);
424
        $this->application->setCatchExceptions(false);
425
426
        $this->generateChangelogCommand = $this->getMockBuilder(GenerateChangelogCommand::class)
427
            ->setConstructorArgs([$this->changelogGenerator])
428
            ->setMethods(['createOutput'])
429
            ->getMock();
430
431
        $this->application->add($this->generateChangelogCommand);
432
    }
433
}
434
435
class GenerateChangelogCommandStub extends GenerateChangelogCommand
436
{
437
    public function createOutputTest(string $file, string $fileWriteStrategy) : OutputInterface
438
    {
439
        return $this->createOutput($file, $fileWriteStrategy);
440
    }
441
}
442