Completed
Pull Request — master (#35)
by James
02:21
created

testProvidingMarkdownOptionWritesMarkdownOutput()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 50
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 50
rs 9.3333
c 0
b 0
f 0
cc 1
eloc 39
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace RoaveTest\ApiCompare\Command;
6
7
use Assert\InvalidArgumentException;
8
use PHPUnit\Framework\MockObject\MockObject;
9
use PHPUnit\Framework\TestCase;
10
use Roave\ApiCompare\Change;
11
use Roave\ApiCompare\Changes;
12
use Roave\ApiCompare\Command\ApiCompare;
13
use Roave\ApiCompare\Comparator;
14
use Roave\ApiCompare\Factory\DirectoryReflectorFactory;
15
use Roave\ApiCompare\Git\CheckedOutRepository;
16
use Roave\ApiCompare\Git\GetVersionCollection;
17
use Roave\ApiCompare\Git\ParseRevision;
18
use Roave\ApiCompare\Git\PerformCheckoutOfRevision;
19
use Roave\ApiCompare\Git\PickVersionFromVersionCollection;
20
use Roave\ApiCompare\Git\Revision;
21
use Symfony\Component\Console\Input\InputInterface;
22
use Symfony\Component\Console\Output\ConsoleOutputInterface;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use Version\Version;
25
use Version\VersionsCollection;
26
use function chdir;
27
use function realpath;
28
use function sha1;
29
use function uniqid;
30
31
/**
32
 * @covers \Roave\ApiCompare\Command\ApiCompare
33
 */
34
final class ApiCompareTest extends TestCase
35
{
36
    /** @var CheckedOutRepository */
37
    private $sourceRepository;
38
39
    /** @var InputInterface|MockObject */
40
    private $input;
41
42
    /** @var ConsoleOutputInterface|MockObject */
43
    private $output;
44
45
    /** @var OutputInterface|MockObject */
46
    private $stdErr;
47
48
    /** @var PerformCheckoutOfRevision|MockObject */
49
    private $performCheckout;
50
51
    /** @var ParseRevision|MockObject */
52
    private $parseRevision;
53
54
    /** @var GetVersionCollection|MockObject */
55
    private $getVersions;
56
57
    /** @var PickVersionFromVersionCollection|MockObject */
58
    private $pickVersion;
59
60
    /** @var Comparator|MockObject */
61
    private $comparator;
62
63
    /** @var ApiCompare */
64
    private $compare;
65
66
    public function setUp() : void
67
    {
68
        $this->sourceRepository = CheckedOutRepository::fromPath(realpath(__DIR__ . '/../../../'));
69
        chdir((string) $this->sourceRepository);
70
71
        $this->input   = $this->createMock(InputInterface::class);
72
        $this->output  = $this->createMock(ConsoleOutputInterface::class);
73
        $this->stdErr  = $this->createMock(OutputInterface::class);
74
        $this->output->expects(self::any())->method('getErrorOutput')->willReturn($this->stdErr);
75
76
        $this->performCheckout = $this->createMock(PerformCheckoutOfRevision::class);
77
        $this->parseRevision   = $this->createMock(ParseRevision::class);
78
        $this->getVersions     = $this->createMock(GetVersionCollection::class);
79
        $this->pickVersion     = $this->createMock(PickVersionFromVersionCollection::class);
80
        $this->comparator      = $this->createMock(Comparator::class);
81
        $this->compare         = new ApiCompare(
82
            $this->performCheckout,
83
            new DirectoryReflectorFactory(),
84
            $this->parseRevision,
85
            $this->getVersions,
86
            $this->pickVersion,
87
            $this->comparator
88
        );
89
    }
90
91
    public function testExecuteWhenRevisionsAreProvidedAsOptions() : void
92
    {
93
        $fromSha = sha1('fromRevision', false);
94
        $toSha   = sha1('toRevision', false);
95
96
        $this->input->expects(self::any())->method('hasOption')->willReturn(true);
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Symfony\Component\Console\Input\InputInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

96
        $this->input->/** @scrutinizer ignore-call */ 
97
                      expects(self::any())->method('hasOption')->willReturn(true);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
97
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
98
            ['from', $fromSha],
99
            ['to', $toSha],
100
        ]);
101
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
102
            ['sources-path', 'src'],
103
        ]);
104
105
        $this->performCheckout->expects(self::at(0))
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Roave\ApiCompare\Git\PerformCheckoutOfRevision. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

105
        $this->performCheckout->/** @scrutinizer ignore-call */ 
106
                                expects(self::at(0))

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
106
            ->method('checkout')
107
            ->with($this->sourceRepository, $fromSha)
108
            ->willReturn($this->sourceRepository);
109
        $this->performCheckout->expects(self::at(1))
110
            ->method('checkout')
111
            ->with($this->sourceRepository, $toSha)
112
            ->willReturn($this->sourceRepository);
113
        $this->performCheckout->expects(self::at(2))
114
            ->method('remove')
115
            ->with($this->sourceRepository);
116
        $this->performCheckout->expects(self::at(3))
117
            ->method('remove')
118
            ->with($this->sourceRepository);
119
120
        $this->parseRevision->expects(self::at(0))
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Roave\ApiCompare\Git\ParseRevision. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

120
        $this->parseRevision->/** @scrutinizer ignore-call */ 
121
                              expects(self::at(0))

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
121
            ->method('fromStringForRepository')
122
            ->with($fromSha)
123
            ->willReturn(Revision::fromSha1($fromSha));
124
        $this->parseRevision->expects(self::at(1))
125
            ->method('fromStringForRepository')
126
            ->with($toSha)
127
            ->willReturn(Revision::fromSha1($toSha));
128
129
        $this->comparator->expects(self::once())->method('compare')->willReturn(Changes::new());
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Roave\ApiCompare\Comparator. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

129
        $this->comparator->/** @scrutinizer ignore-call */ 
130
                           expects(self::once())->method('compare')->willReturn(Changes::new());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
130
131
        self::assertSame(0, $this->compare->execute($this->input, $this->output));
132
    }
133
134
    public function testExecuteReturnsNonZeroExitCodeWhenChangesAreDetected() : void
135
    {
136
        $fromSha = sha1('fromRevision', false);
137
        $toSha   = sha1('toRevision', false);
138
139
        $this->input->expects(self::any())->method('hasOption')->willReturn(true);
140
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
141
            ['from', $fromSha],
142
            ['to', $toSha],
143
        ]);
144
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
145
            ['sources-path', 'src'],
146
        ]);
147
148
        $this->performCheckout->expects(self::at(0))
149
            ->method('checkout')
150
            ->with($this->sourceRepository, $fromSha)
151
            ->willReturn($this->sourceRepository);
152
        $this->performCheckout->expects(self::at(1))
153
            ->method('checkout')
154
            ->with($this->sourceRepository, $toSha)
155
            ->willReturn($this->sourceRepository);
156
        $this->performCheckout->expects(self::at(2))
157
            ->method('remove')
158
            ->with($this->sourceRepository);
159
        $this->performCheckout->expects(self::at(3))
160
            ->method('remove')
161
            ->with($this->sourceRepository);
162
163
        $this->parseRevision->expects(self::at(0))
164
            ->method('fromStringForRepository')
165
            ->with($fromSha)
166
            ->willReturn(Revision::fromSha1($fromSha));
167
        $this->parseRevision->expects(self::at(1))
168
            ->method('fromStringForRepository')
169
            ->with($toSha)
170
            ->willReturn(Revision::fromSha1($toSha));
171
172
        $this->comparator->expects(self::once())->method('compare')->willReturn(Changes::fromArray([
173
            Change::added(uniqid('added', true), true),
174
            Change::removed(uniqid('removed', true), true),
175
        ]));
176
177
        self::assertSame(2, $this->compare->execute($this->input, $this->output));
178
    }
179
180
    public function testProvidingMarkdownOptionWritesMarkdownOutput() : void
181
    {
182
        $fromSha = sha1('fromRevision', false);
183
        $toSha = sha1('toRevision', false);
184
185
        $this->input->expects(self::any())->method('hasOption')->willReturn(true);
186
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
187
            ['from', $fromSha],
188
            ['to', $toSha],
189
            ['format', ['markdown']]
190
        ]);
191
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
192
            ['sources-path', 'src'],
193
        ]);
194
195
        $this->performCheckout->expects(self::at(0))
196
            ->method('checkout')
197
            ->with($this->sourceRepository, $fromSha)
198
            ->willReturn($this->sourceRepository);
199
        $this->performCheckout->expects(self::at(1))
200
            ->method('checkout')
201
            ->with($this->sourceRepository, $toSha)
202
            ->willReturn($this->sourceRepository);
203
        $this->performCheckout->expects(self::at(2))
204
            ->method('remove')
205
            ->with($this->sourceRepository);
206
        $this->performCheckout->expects(self::at(3))
207
            ->method('remove')
208
            ->with($this->sourceRepository);
209
210
        $this->parseRevision->expects(self::at(0))
211
            ->method('fromStringForRepository')
212
            ->with($fromSha)
213
            ->willReturn(Revision::fromSha1($fromSha));
214
        $this->parseRevision->expects(self::at(1))
215
            ->method('fromStringForRepository')
216
            ->with($toSha)
217
            ->willReturn(Revision::fromSha1($toSha));
218
219
        $changeToExpect = uniqid('changeToExpect', true);
220
        $this->comparator->expects(self::once())->method('compare')->willReturn(Changes::fromArray([
221
            Change::removed($changeToExpect, true),
222
        ]));
223
224
        $this->compare->execute($this->input, $this->output);
225
226
        $this->output->expects(self::any())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Symfony\Component\Consol...\ConsoleOutputInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

226
        $this->output->/** @scrutinizer ignore-call */ 
227
                       expects(self::any())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
227
            ->method('writeln')
228
            ->willReturnCallback(function (string $output) use ($changeToExpect) {
229
                self::assertContains($changeToExpect, $output);
230
            });
231
    }
232
233
    public function testExecuteWithDefaultRevisionsNotProvided() : void
234
    {
235
        $fromSha       = sha1('fromRevision', false);
236
        $toSha         = sha1('toRevision', false);
237
        $versions      = VersionsCollection::fromArray(['1.0.0', '1.0.1']);
238
        $pickedVersion = Version::fromString('1.0.0');
239
240
        $this->input->expects(self::any())->method('hasOption')->willReturn(false);
241
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
242
            ['from', null],
243
            ['to', 'HEAD'],
244
        ]);
245
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
246
            ['sources-path', 'src'],
247
        ]);
248
249
        $this->performCheckout->expects(self::at(0))
250
            ->method('checkout')
251
            ->with($this->sourceRepository, $fromSha)
252
            ->willReturn($this->sourceRepository);
253
        $this->performCheckout->expects(self::at(1))
254
            ->method('checkout')
255
            ->with($this->sourceRepository, $toSha)
256
            ->willReturn($this->sourceRepository);
257
        $this->performCheckout->expects(self::at(2))
258
            ->method('remove')
259
            ->with($this->sourceRepository);
260
        $this->performCheckout->expects(self::at(3))
261
            ->method('remove')
262
            ->with($this->sourceRepository);
263
264
        $this->parseRevision->expects(self::at(0))
265
            ->method('fromStringForRepository')
266
            ->with((string) $pickedVersion)
267
            ->willReturn(Revision::fromSha1($fromSha));
268
        $this->parseRevision->expects(self::at(1))
269
            ->method('fromStringForRepository')
270
            ->with('HEAD')
271
            ->willReturn(Revision::fromSha1($toSha));
272
273
        $this->getVersions->expects(self::once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Roave\ApiCompare\Git\GetVersionCollection. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

273
        $this->getVersions->/** @scrutinizer ignore-call */ 
274
                            expects(self::once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
274
            ->method('fromRepository')
275
            ->with(self::callback(function (CheckedOutRepository $checkedOutRepository) : bool {
276
                self::assertEquals($this->sourceRepository, $checkedOutRepository);
277
                return true;
278
            }))
279
            ->willReturn($versions);
280
        $this->pickVersion->expects(self::once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Roave\ApiCompare\Git\Pic...onFromVersionCollection. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

280
        $this->pickVersion->/** @scrutinizer ignore-call */ 
281
                            expects(self::once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
281
            ->method('forVersions')
282
            ->with($versions)
283
            ->willReturn($pickedVersion);
284
285
        $this->comparator->expects(self::once())->method('compare')->willReturn(Changes::new());
286
287
        self::assertSame(0, $this->compare->execute($this->input, $this->output));
288
    }
289
290
    public function testExecuteFailsIfCheckedOutRepositoryDoesNotExist() : void
291
    {
292
        $fromSha = sha1('fromRevision', false);
293
        $toSha   = sha1('toRevision', false);
294
295
        $this->input->expects(self::any())->method('hasOption')->willReturn(true);
296
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
297
            ['from', $fromSha],
298
            ['to', $toSha],
299
        ]);
300
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
301
            ['sources-path', uniqid('src', true)],
302
        ]);
303
304
        $this->performCheckout->expects(self::at(0))
305
            ->method('checkout')
306
            ->with($this->sourceRepository, $fromSha)
307
            ->willReturn($this->sourceRepository);
308
        $this->performCheckout->expects(self::at(1))
309
            ->method('checkout')
310
            ->with($this->sourceRepository, $toSha)
311
            ->willReturn($this->sourceRepository);
312
        $this->performCheckout->expects(self::at(2))
313
            ->method('remove')
314
            ->with($this->sourceRepository);
315
        $this->performCheckout->expects(self::at(3))
316
            ->method('remove')
317
            ->with($this->sourceRepository);
318
319
        $this->parseRevision->expects(self::at(0))
320
            ->method('fromStringForRepository')
321
            ->with($fromSha)
322
            ->willReturn(Revision::fromSha1($fromSha));
323
        $this->parseRevision->expects(self::at(1))
324
            ->method('fromStringForRepository')
325
            ->with($toSha)
326
            ->willReturn(Revision::fromSha1($toSha));
327
328
        $this->comparator->expects(self::never())->method('compare');
329
330
        $this->expectException(InvalidArgumentException::class);
331
        $this->compare->execute($this->input, $this->output);
332
    }
333
}
334