Completed
Push — master ( 0d42e0...f1e76d )
by Jonathan
10s
created

ConsoleTest::testGenerateIncludeOpenTrue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 15
nc 1
nop 0
dl 0
loc 22
rs 9.7666
c 0
b 0
f 0
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 file_exists;
19
use function sprintf;
20
use function sys_get_temp_dir;
21
use function tempnam;
22
use function uniqid;
23
use function unlink;
24
25
final class ConsoleTest extends TestCase
26
{
27
    /** @var \PHPUnit_Framework_MockObject_MockObject|ChangelogGenerator */
28
    private $changelogGenerator;
29
30
    /** @var \PHPUnit_Framework_MockObject_MockObject|GenerateChangelogCommand */
31
    private $generateChangelogCommand;
32
33
    /** @var Application */
34
    private $application;
35
36
    public function testGenerate() : void
37
    {
38
        $input = new ArrayInput([
39
            'command'       => 'generate',
40
            '--user'        => 'jwage',
41
            '--repository'  => 'changelog-generator',
42
            '--milestone'   => '1.0',
43
        ]);
44
45
        $output = $this->createMock(OutputInterface::class);
46
47
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
48
49
        $this->changelogGenerator->expects($this->once())
50
            ->method('generate')
51
            ->with($changelogConfig, $output);
52
53
        $this->application->run($input, $output);
54
    }
55
56
57
    public function testGenerateInvalidConfig() : void
58
    {
59
        $this->expectException(InvalidArgumentException::class);
60
        $this->expectExceptionMessage('You must pass a config file with the --config option or manually specify the --user --repository and --milestone options.');
61
62
        $input = new ArrayInput(['command' => 'generate']);
63
64
        $output = $this->createMock(OutputInterface::class);
65
66
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
67
68
        $this->changelogGenerator->expects($this->never())
69
            ->method('generate')
70
            ->with($changelogConfig, $output);
71
72
        $this->application->run($input, $output);
73
    }
74
75
    public function testGenerateFile() : void
76
    {
77
        $input = new ArrayInput([
78
            'command'       => 'generate',
79
            '--user'        => 'jwage',
80
            '--repository'  => 'changelog-generator',
81
            '--milestone'   => '1.0',
82
            '--file'        => null,
83
        ]);
84
85
        $output       = $this->createMock(OutputInterface::class);
86
        $streamOutput = $this->createMock(StreamOutput::class);
87
88
        $this->generateChangelogCommand->expects($this->once())
89
            ->method('createOutput')
90
            ->willReturn($streamOutput);
91
92
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
93
94
        $this->changelogGenerator->expects($this->once())
95
            ->method('generate')
96
            ->with($changelogConfig, $streamOutput);
97
98
        $this->application->run($input, $output);
99
    }
100
101
    public function testGenerateFilePathGiven() : void
102
    {
103
        $input = new ArrayInput([
104
            'command'       => 'generate',
105
            '--user'        => 'jwage',
106
            '--repository'  => 'changelog-generator',
107
            '--milestone'   => '1.0',
108
            '--file'        => tempnam(sys_get_temp_dir(), 'CHANGELOG.md'),
109
        ]);
110
111
        $output       = $this->createMock(OutputInterface::class);
112
        $streamOutput = $this->createMock(StreamOutput::class);
113
114
        $this->generateChangelogCommand->expects($this->once())
115
            ->method('createOutput')
116
            ->willReturn($streamOutput);
117
118
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
119
120
        $this->changelogGenerator->expects($this->once())
121
            ->method('generate')
122
            ->with($changelogConfig, $streamOutput);
123
124
        $this->application->run($input, $output);
125
    }
126
127
    public function testGenerateFileAppend() : void
128
    {
129
        $input = new ArrayInput([
130
            'command'       => 'generate',
131
            '--user'        => 'jwage',
132
            '--repository'  => 'changelog-generator',
133
            '--milestone'   => '1.0',
134
            '--file'        => tempnam(sys_get_temp_dir(), 'CHANGELOG.md'),
135
            '--append'      => true,
136
        ]);
137
138
        $output       = $this->createMock(OutputInterface::class);
139
        $streamOutput = $this->createMock(StreamOutput::class);
140
141
        $this->generateChangelogCommand->expects($this->once())
142
            ->method('createOutput')
143
            ->willReturn($streamOutput);
144
145
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
146
147
        $this->changelogGenerator->expects($this->once())
148
            ->method('generate')
149
            ->with($changelogConfig, $streamOutput);
150
151
        $this->application->run($input, $output);
152
    }
153
154
    public function testGenerateFilePrepend() : void
155
    {
156
        $input = new ArrayInput([
157
            'command'       => 'generate',
158
            '--user'        => 'jwage',
159
            '--repository'  => 'changelog-generator',
160
            '--milestone'   => '1.0',
161
            '--file'        => tempnam(sys_get_temp_dir(), 'CHANGELOG.md'),
162
            '--prepend'     => true,
163
        ]);
164
165
        $output         = $this->createMock(OutputInterface::class);
166
        $bufferedOutput = $this->createMock(BufferedOutput::class);
167
168
        $this->generateChangelogCommand->expects($this->once())
169
            ->method('createOutput')
170
            ->willReturn($bufferedOutput);
171
172
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
173
174
        $this->changelogGenerator->expects($this->once())
175
            ->method('generate')
176
            ->with($changelogConfig, $bufferedOutput);
177
178
        $this->application->run($input, $output);
179
    }
180
181
    public function testGenerateFilePrependStreamOutput() : void
182
    {
183
        $input = new ArrayInput([
184
            'command'       => 'generate',
185
            '--user'        => 'jwage',
186
            '--repository'  => 'changelog-generator',
187
            '--milestone'   => '1.0',
188
            '--file'        => tempnam(sys_get_temp_dir(), 'CHANGELOG.md'),
189
            '--prepend'     => true,
190
        ]);
191
192
        $output       = $this->createMock(OutputInterface::class);
193
        $streamOutput = $this->createMock(StreamOutput::class);
194
195
        $this->generateChangelogCommand->expects($this->once())
196
            ->method('createOutput')
197
            ->willReturn($streamOutput);
198
199
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
200
201
        $this->changelogGenerator->expects($this->once())
202
            ->method('generate')
203
            ->with($changelogConfig, $streamOutput);
204
205
        $this->application->run($input, $output);
206
    }
207
208
    public function testGenerateFilePrependCreatesFileThatDoesNotExist() : void
209
    {
210
        $file = sprintf('%s/%sCHANGELOG.md', sys_get_temp_dir(), uniqid());
211
212
        $input = new ArrayInput([
213
            'command'       => 'generate',
214
            '--user'        => 'jwage',
215
            '--repository'  => 'changelog-generator',
216
            '--milestone'   => '1.0',
217
            '--file'        => $file,
218
            '--prepend'     => true,
219
        ]);
220
221
        $output         = $this->createMock(OutputInterface::class);
222
        $bufferedOutput = $this->createMock(BufferedOutput::class);
223
224
        $this->generateChangelogCommand->expects($this->once())
225
            ->method('createOutput')
226
            ->willReturn($bufferedOutput);
227
228
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', []);
229
230
        $this->changelogGenerator->expects($this->once())
231
            ->method('generate')
232
            ->with($changelogConfig, $bufferedOutput);
233
234
        $this->application->run($input, $output);
235
236
        $exists = file_exists($file);
237
238
        unlink($file);
239
240
        self::assertTrue($exists);
241
    }
242
243
    public function testGenerateLabel() : void
244
    {
245
        $input = new ArrayInput([
246
            'command'       => 'generate',
247
            '--user'        => 'jwage',
248
            '--repository'  => 'changelog-generator',
249
            '--milestone'   => '1.0',
250
            '--label'       => ['Enhancement', 'Bug'],
251
        ]);
252
253
        $output = $this->createMock(OutputInterface::class);
254
255
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
256
257
        $this->changelogGenerator->expects($this->once())
258
            ->method('generate')
259
            ->with($changelogConfig, $output);
260
261
        $this->application->run($input, $output);
262
    }
263
264
    public function testGenerateConfig() : void
265
    {
266
        $input = new ArrayInput([
267
            'command'       => 'generate',
268
            '--user'        => 'jwage',
269
            '--repository'  => 'changelog-generator',
270
            '--milestone'   => '1.0',
271
            '--label'       => ['Enhancement', 'Bug'],
272
            '--config'      => __DIR__ . '/_files/config.php',
273
            '--project'     => 'changelog-generator',
274
        ]);
275
276
        $output = $this->createMock(OutputInterface::class);
277
278
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
279
280
        $this->changelogGenerator->expects($this->once())
281
            ->method('generate')
282
            ->with($changelogConfig, $output);
283
284
        $this->application->run($input, $output);
285
    }
286
287
    public function testGenerateConfigDoesNotExist() : void
288
    {
289
        $this->expectException(InvalidArgumentException::class);
290
        $this->expectExceptionMessage('Configuration file "unknown.php" does not exist.');
291
292
        $input = new ArrayInput([
293
            'command'       => 'generate',
294
            '--user'        => 'jwage',
295
            '--repository'  => 'changelog-generator',
296
            '--milestone'   => '1.0',
297
            '--label'       => ['Enhancement', 'Bug'],
298
            '--config'      => 'unknown.php',
299
        ]);
300
301
        $output = $this->createMock(OutputInterface::class);
302
303
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
304
305
        $this->changelogGenerator->expects($this->never())
306
            ->method('generate')
307
            ->with($changelogConfig, $output);
308
309
        $this->application->run($input, $output);
310
    }
311
312
    public function testGenerateConfigEmpty() : void
313
    {
314
        $configFile = __DIR__ . '/_files/empty.php';
315
316
        $this->expectException(InvalidArgumentException::class);
317
        $this->expectExceptionMessage(sprintf('Configuration file "%s" did not return anything.', $configFile));
318
319
        $input = new ArrayInput([
320
            'command'       => 'generate',
321
            '--user'        => 'jwage',
322
            '--repository'  => 'changelog-generator',
323
            '--milestone'   => '1.0',
324
            '--label'       => ['Enhancement', 'Bug'],
325
            '--config'      => $configFile,
326
        ]);
327
328
        $output = $this->createMock(OutputInterface::class);
329
330
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
331
332
        $this->changelogGenerator->expects($this->never())
333
            ->method('generate')
334
            ->with($changelogConfig, $output);
335
336
        $this->application->run($input, $output);
337
    }
338
339
    public function testGenerateConfigInvalidProject() : void
340
    {
341
        $this->expectException(InvalidArgumentException::class);
342
        $this->expectExceptionMessage('Could not find project named "unknown" configured');
343
344
        $input = new ArrayInput([
345
            'command'       => 'generate',
346
            '--user'        => 'jwage',
347
            '--repository'  => 'changelog-generator',
348
            '--milestone'   => '1.0',
349
            '--label'       => ['Enhancement', 'Bug'],
350
            '--config'      => __DIR__ . '/_files/config.php',
351
            '--project'     => 'unknown',
352
        ]);
353
354
        $output = $this->createMock(OutputInterface::class);
355
356
        $changelogConfig = new ChangelogConfig('jwage', 'changelog-generator', '1.0', ['Enhancement', 'Bug']);
357
358
        $this->changelogGenerator->expects($this->never())
359
            ->method('generate')
360
            ->with($changelogConfig, $output);
361
362
        $this->application->run($input, $output);
363
    }
364
365
    public function testGenerateIncludeOpenOptionNotProvided() : void
366
    {
367
        $input = new ArrayInput([
368
            'command'        => 'generate',
369
            '--user'         => 'doctrine',
370
            '--repository'   => 'migrations',
371
            '--milestone'    => '2.0',
372
            '--label'        => ['Improvement', 'Bug'],
373
            '--config'       => __DIR__ . '/_files/config.php',
374
            '--project'      => 'changelog-generator',
375
        ]);
376
377
        $output = $this->createMock(OutputInterface::class);
378
379
        $changelogConfig = new ChangelogConfig('doctrine', 'migrations', '2.0', ['Improvement', 'Bug'], false);
380
381
        $this->changelogGenerator->expects($this->once())
382
            ->method('generate')
383
            ->with($changelogConfig, $output);
384
385
        $this->application->run($input, $output);
386
    }
387
388
    public function testGenerateIncludeOpenDefault() : void
389
    {
390
        $input = new ArrayInput([
391
            'command'        => 'generate',
392
            '--user'         => 'doctrine',
393
            '--repository'   => 'migrations',
394
            '--milestone'    => '2.0',
395
            '--label'        => ['Improvement', 'Bug'],
396
            '--config'       => __DIR__ . '/_files/config.php',
397
            '--project'      => 'changelog-generator',
398
            '--include-open' => null,
399
        ]);
400
401
        $output = $this->createMock(OutputInterface::class);
402
403
        $changelogConfig = new ChangelogConfig('doctrine', 'migrations', '2.0', ['Improvement', 'Bug'], true);
404
405
        $this->changelogGenerator->expects($this->once())
406
            ->method('generate')
407
            ->with($changelogConfig, $output);
408
409
        $this->application->run($input, $output);
410
    }
411
412
    public function testGenerateIncludeOpenTrue() : void
413
    {
414
        $input = new ArrayInput([
415
            'command'        => 'generate',
416
            '--user'         => 'doctrine',
417
            '--repository'   => 'migrations',
418
            '--milestone'    => '2.0',
419
            '--label'        => ['Improvement', 'Bug'],
420
            '--config'       => __DIR__ . '/_files/config.php',
421
            '--project'      => 'changelog-generator',
422
            '--include-open' => '1',
423
        ]);
424
425
        $output = $this->createMock(OutputInterface::class);
426
427
        $changelogConfig = new ChangelogConfig('doctrine', 'migrations', '2.0', ['Improvement', 'Bug'], true);
428
429
        $this->changelogGenerator->expects($this->once())
430
            ->method('generate')
431
            ->with($changelogConfig, $output);
432
433
        $this->application->run($input, $output);
434
    }
435
436
    public function testGenerateIncludeOpenFalse() : void
437
    {
438
        $input = new ArrayInput([
439
            'command'        => 'generate',
440
            '--user'         => 'doctrine',
441
            '--repository'   => 'migrations',
442
            '--milestone'    => '2.0',
443
            '--label'        => ['Improvement', 'Bug'],
444
            '--config'       => __DIR__ . '/_files/config.php',
445
            '--project'      => 'changelog-generator',
446
            '--include-open' => '0',
447
        ]);
448
449
        $output = $this->createMock(OutputInterface::class);
450
451
        $changelogConfig = new ChangelogConfig('doctrine', 'migrations', '2.0', ['Improvement', 'Bug'], false);
452
453
        $this->changelogGenerator->expects($this->once())
454
            ->method('generate')
455
            ->with($changelogConfig, $output);
456
457
        $this->application->run($input, $output);
458
    }
459
460
    public function testGenerateConfigOverrideNoLabels() : void
461
    {
462
        $input = new ArrayInput([
463
            'command'       => 'generate',
464
            '--user'        => 'doctrine',
465
            '--repository'  => 'migrations',
466
            '--milestone'   => '2.0',
467
            '--config'      => __DIR__ . '/_files/config.php',
468
            '--project'     => 'changelog-generator',
469
        ]);
470
471
        $output = $this->createMock(OutputInterface::class);
472
473
        $changelogConfig = new ChangelogConfig('doctrine', 'migrations', '2.0', ['Enhancement', 'Bug']);
474
475
        $this->changelogGenerator->expects($this->once())
476
            ->method('generate')
477
            ->with($changelogConfig, $output);
478
479
        $this->application->run($input, $output);
480
    }
481
482
    public function testCreateOutput() : void
483
    {
484
        $generateChangelogCommand = new GenerateChangelogCommandStub($this->changelogGenerator);
485
486
        $file = sprintf('%s/test.md', sys_get_temp_dir());
487
488
        self::assertInstanceOf(
489
            StreamOutput::class,
490
            $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_APPEND)
491
        );
492
493
        self::assertInstanceOf(
494
            BufferedOutput::class,
495
            $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_PREPEND)
496
        );
497
498
        self::assertInstanceOf(
499
            StreamOutput::class,
500
            $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_REPLACE)
501
        );
502
503
        unlink($file);
504
    }
505
506
    public function testCreateOutputCouldNotOpenHandleInvalidArgumentException() : void
507
    {
508
        $this->expectException(InvalidArgumentException::class);
509
        $this->expectExceptionMessage('Could not open handle for /tmp/test.md');
510
511
        $file = sprintf('%s/test.md', sys_get_temp_dir());
512
513
        /** @var \PHPUnit_Framework_MockObject_MockObject|GenerateChangelogCommandStub $generateChangelogCommand */
514
        $generateChangelogCommand = $this->getMockBuilder(GenerateChangelogCommandStub::class)
515
            ->setConstructorArgs([$this->changelogGenerator])
516
            ->setMethods(['fopen'])
517
            ->getMock();
518
519
        $generateChangelogCommand->expects($this->once())
520
            ->method('fopen')
521
            ->with($file, 'a+')
522
            ->willReturn(false);
523
524
        $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_APPEND);
525
    }
526
527
    protected function setUp() : void
528
    {
529
        $this->changelogGenerator = $this->createMock(ChangelogGenerator::class);
530
531
        $this->application = new Application('Changelog Generator', Versions::getVersion('jwage/changelog-generator'));
532
        $this->application->setAutoExit(false);
533
        $this->application->setCatchExceptions(false);
534
535
        $this->generateChangelogCommand = $this->getMockBuilder(GenerateChangelogCommand::class)
536
            ->setConstructorArgs([$this->changelogGenerator])
537
            ->setMethods(['createOutput'])
538
            ->getMock();
539
540
        $this->application->add($this->generateChangelogCommand);
541
    }
542
}
543
544
class GenerateChangelogCommandStub extends GenerateChangelogCommand
545
{
546
    public function createOutputTest(string $file, string $fileWriteStrategy) : OutputInterface
547
    {
548
        return $this->createOutput($file, $fileWriteStrategy);
549
    }
550
}
551