Completed
Push — master ( ffa9df...a6be25 )
by Jonathan
10s
created

ConsoleTest::testCreateOutput()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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