Completed
Push — master ( 4905fa...027eeb )
by Jonathan
10s
created

testGenerateFilePrependCreatesFileThatDoesNotExist()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 21
nc 1
nop 0
dl 0
loc 33
rs 8.8571
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 testGenerateConfigOverride() : 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']);
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 testGenerateConfigOverrideNoLabels() : void
389
    {
390
        $input = new ArrayInput([
391
            'command'       => 'generate',
392
            '--user'        => 'doctrine',
393
            '--repository'  => 'migrations',
394
            '--milestone'   => '2.0',
395
            '--config'      => __DIR__ . '/_files/config.php',
396
            '--project'     => 'changelog-generator',
397
        ]);
398
399
        $output = $this->createMock(OutputInterface::class);
400
401
        $changelogConfig = new ChangelogConfig('doctrine', 'migrations', '2.0', ['Enhancement', 'Bug']);
402
403
        $this->changelogGenerator->expects($this->once())
404
            ->method('generate')
405
            ->with($changelogConfig, $output);
406
407
        $this->application->run($input, $output);
408
    }
409
410
    public function testCreateOutput() : void
411
    {
412
        $generateChangelogCommand = new GenerateChangelogCommandStub($this->changelogGenerator);
413
414
        $file = sprintf('%s/test.md', sys_get_temp_dir());
415
416
        self::assertInstanceOf(
417
            StreamOutput::class,
418
            $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_APPEND)
419
        );
420
421
        self::assertInstanceOf(
422
            BufferedOutput::class,
423
            $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_PREPEND)
424
        );
425
426
        self::assertInstanceOf(
427
            StreamOutput::class,
428
            $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_REPLACE)
429
        );
430
431
        unlink($file);
432
    }
433
434
    public function testCreateOutputCouldNotOpenHandleInvalidArgumentException() : void
435
    {
436
        $this->expectException(InvalidArgumentException::class);
437
        $this->expectExceptionMessage('Could not open handle for /tmp/test.md');
438
439
        $file = sprintf('%s/test.md', sys_get_temp_dir());
440
441
        /** @var \PHPUnit_Framework_MockObject_MockObject|GenerateChangelogCommandStub $generateChangelogCommand */
442
        $generateChangelogCommand = $this->getMockBuilder(GenerateChangelogCommandStub::class)
443
            ->setConstructorArgs([$this->changelogGenerator])
444
            ->setMethods(['fopen'])
445
            ->getMock();
446
447
        $generateChangelogCommand->expects($this->once())
448
            ->method('fopen')
449
            ->with($file, 'a+')
450
            ->willReturn(false);
451
452
        $generateChangelogCommand->createOutputTest($file, GenerateChangelogCommand::WRITE_STRATEGY_APPEND);
453
    }
454
455
    protected function setUp() : void
456
    {
457
        $this->changelogGenerator = $this->createMock(ChangelogGenerator::class);
458
459
        $this->application = new Application('Changelog Generator', Versions::getVersion('jwage/changelog-generator'));
460
        $this->application->setAutoExit(false);
461
        $this->application->setCatchExceptions(false);
462
463
        $this->generateChangelogCommand = $this->getMockBuilder(GenerateChangelogCommand::class)
464
            ->setConstructorArgs([$this->changelogGenerator])
465
            ->setMethods(['createOutput'])
466
            ->getMock();
467
468
        $this->application->add($this->generateChangelogCommand);
469
    }
470
}
471
472
class GenerateChangelogCommandStub extends GenerateChangelogCommand
473
{
474
    public function createOutputTest(string $file, string $fileWriteStrategy) : OutputInterface
475
    {
476
        return $this->createOutput($file, $fileWriteStrategy);
477
    }
478
}
479