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

ApiCompareTest   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 291
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 6
dl 0
loc 291
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
B testExecuteReturnsNonZeroExitCodeWhenChangesAreDetected() 0 44 1
A setUp() 0 19 1
B testExecuteWhenRevisionsAreProvidedAsOptions() 0 41 1
B testExecuteFailsIfCheckedOutRepositoryDoesNotExist() 0 42 1
A testExecuteWithDefaultRevisionsNotProvided() 0 55 1
A testProvidingMarkdownOptionWritesMarkdownOutput() 0 50 1
1
<?php
2
declare(strict_types=1);
3
4
namespace RoaveTest\ApiCompare\Command;
5
6
use Assert\InvalidArgumentException;
7
use PHPUnit\Framework\MockObject\MockObject;
8
use Roave\ApiCompare\Change;
9
use Roave\ApiCompare\Changes;
10
use Roave\ApiCompare\Command\ApiCompare;
11
use PHPUnit\Framework\TestCase;
12
use Roave\ApiCompare\Comparator;
13
use Roave\ApiCompare\Factory\DirectoryReflectorFactory;
14
use Roave\ApiCompare\Git\CheckedOutRepository;
15
use Roave\ApiCompare\Git\GetVersionCollection;
16
use Roave\ApiCompare\Git\ParseRevision;
17
use Roave\ApiCompare\Git\PerformCheckoutOfRevision;
18
use Roave\ApiCompare\Git\PickVersionFromVersionCollection;
19
use Roave\ApiCompare\Git\Revision;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Output\OutputInterface;
22
use Version\Version;
23
use Version\VersionsCollection;
24
25
/**
26
 * @covers \Roave\ApiCompare\Command\ApiCompare
27
 */
28
final class ApiCompareTest extends TestCase
29
{
30
    /** @var CheckedOutRepository */
31
    private $sourceRepository;
32
33
    /** @var InputInterface|MockObject */
34
    private $input;
35
36
    /** @var OutputInterface|MockObject */
37
    private $output;
38
39
    /** @var PerformCheckoutOfRevision|MockObject */
40
    private $performCheckout;
41
42
    /** @var ParseRevision|MockObject */
43
    private $parseRevision;
44
45
    /** @var GetVersionCollection|MockObject */
46
    private $getVersions;
47
48
    /** @var PickVersionFromVersionCollection|MockObject */
49
    private $pickVersion;
50
51
    /** @var Comparator|MockObject */
52
    private $comparator;
53
54
    /** @var ApiCompare */
55
    private $compare;
56
57
    public function setUp() : void
58
    {
59
        $this->sourceRepository = CheckedOutRepository::fromPath(realpath(__DIR__ . '/../../../'));
60
        chdir((string)$this->sourceRepository);
61
62
        $this->input = $this->createMock(InputInterface::class);
63
        $this->output = $this->createMock(OutputInterface::class);
64
        $this->performCheckout = $this->createMock(PerformCheckoutOfRevision::class);
65
        $this->parseRevision = $this->createMock(ParseRevision::class);
66
        $this->getVersions = $this->createMock(GetVersionCollection::class);
67
        $this->pickVersion = $this->createMock(PickVersionFromVersionCollection::class);
68
        $this->comparator = $this->createMock(Comparator::class);
69
        $this->compare = new ApiCompare(
70
            $this->performCheckout,
71
            new DirectoryReflectorFactory(),
72
            $this->parseRevision,
73
            $this->getVersions,
74
            $this->pickVersion,
75
            $this->comparator
76
        );
77
    }
78
79
    public function testExecuteWhenRevisionsAreProvidedAsOptions() : void
80
    {
81
        $fromSha = sha1('fromRevision', false);
82
        $toSha = sha1('toRevision', false);
83
84
        $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

84
        $this->input->/** @scrutinizer ignore-call */ 
85
                      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...
85
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
86
            ['from', $fromSha],
87
            ['to', $toSha],
88
        ]);
89
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
90
            ['sources-path', 'src'],
91
        ]);
92
93
        $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

93
        $this->performCheckout->/** @scrutinizer ignore-call */ 
94
                                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...
94
            ->method('checkout')
95
            ->with($this->sourceRepository, $fromSha)
96
            ->willReturn($this->sourceRepository);
97
        $this->performCheckout->expects(self::at(1))
98
            ->method('checkout')
99
            ->with($this->sourceRepository, $toSha)
100
            ->willReturn($this->sourceRepository);
101
        $this->performCheckout->expects(self::at(2))
102
            ->method('remove')
103
            ->with($this->sourceRepository);
104
        $this->performCheckout->expects(self::at(3))
105
            ->method('remove')
106
            ->with($this->sourceRepository);
107
108
        $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

108
        $this->parseRevision->/** @scrutinizer ignore-call */ 
109
                              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...
109
            ->method('fromStringForRepository')
110
            ->with($fromSha)
111
            ->willReturn(Revision::fromSha1($fromSha));
112
        $this->parseRevision->expects(self::at(1))
113
            ->method('fromStringForRepository')
114
            ->with($toSha)
115
            ->willReturn(Revision::fromSha1($toSha));
116
117
        $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

117
        $this->comparator->/** @scrutinizer ignore-call */ 
118
                           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...
118
119
        self::assertSame(0, $this->compare->execute($this->input, $this->output));
120
    }
121
122
    public function testExecuteReturnsNonZeroExitCodeWhenChangesAreDetected() : void
123
    {
124
        $fromSha = sha1('fromRevision', false);
125
        $toSha = sha1('toRevision', false);
126
127
        $this->input->expects(self::any())->method('hasOption')->willReturn(true);
128
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
129
            ['from', $fromSha],
130
            ['to', $toSha],
131
        ]);
132
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
133
            ['sources-path', 'src'],
134
        ]);
135
136
        $this->performCheckout->expects(self::at(0))
137
            ->method('checkout')
138
            ->with($this->sourceRepository, $fromSha)
139
            ->willReturn($this->sourceRepository);
140
        $this->performCheckout->expects(self::at(1))
141
            ->method('checkout')
142
            ->with($this->sourceRepository, $toSha)
143
            ->willReturn($this->sourceRepository);
144
        $this->performCheckout->expects(self::at(2))
145
            ->method('remove')
146
            ->with($this->sourceRepository);
147
        $this->performCheckout->expects(self::at(3))
148
            ->method('remove')
149
            ->with($this->sourceRepository);
150
151
        $this->parseRevision->expects(self::at(0))
152
            ->method('fromStringForRepository')
153
            ->with($fromSha)
154
            ->willReturn(Revision::fromSha1($fromSha));
155
        $this->parseRevision->expects(self::at(1))
156
            ->method('fromStringForRepository')
157
            ->with($toSha)
158
            ->willReturn(Revision::fromSha1($toSha));
159
160
        $this->comparator->expects(self::once())->method('compare')->willReturn(Changes::fromArray([
161
            Change::added(uniqid('added', true), true),
162
            Change::removed(uniqid('removed', true), true)
163
        ]));
164
165
        self::assertSame(2, $this->compare->execute($this->input, $this->output));
166
    }
167
168
    public function testProvidingMarkdownOptionWritesMarkdownOutput() : void
169
    {
170
        $fromSha = sha1('fromRevision', false);
171
        $toSha = sha1('toRevision', false);
172
173
        $markdownFilename = tempnam(sys_get_temp_dir(), uniqid('api-compare-', true)) . '.md';
174
175
        $this->input->expects(self::any())->method('hasOption')->willReturn(true);
176
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
177
            ['from', $fromSha],
178
            ['to', $toSha],
179
            ['markdown', $markdownFilename]
180
        ]);
181
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
182
            ['sources-path', 'src'],
183
        ]);
184
185
        $this->performCheckout->expects(self::at(0))
186
            ->method('checkout')
187
            ->with($this->sourceRepository, $fromSha)
188
            ->willReturn($this->sourceRepository);
189
        $this->performCheckout->expects(self::at(1))
190
            ->method('checkout')
191
            ->with($this->sourceRepository, $toSha)
192
            ->willReturn($this->sourceRepository);
193
        $this->performCheckout->expects(self::at(2))
194
            ->method('remove')
195
            ->with($this->sourceRepository);
196
        $this->performCheckout->expects(self::at(3))
197
            ->method('remove')
198
            ->with($this->sourceRepository);
199
200
        $this->parseRevision->expects(self::at(0))
201
            ->method('fromStringForRepository')
202
            ->with($fromSha)
203
            ->willReturn(Revision::fromSha1($fromSha));
204
        $this->parseRevision->expects(self::at(1))
205
            ->method('fromStringForRepository')
206
            ->with($toSha)
207
            ->willReturn(Revision::fromSha1($toSha));
208
209
        $changeToExpect = uniqid('changeToExpect', true);
210
        $this->comparator->expects(self::once())->method('compare')->willReturn(Changes::fromArray([
211
            Change::removed($changeToExpect, true),
212
        ]));
213
214
        $this->compare->execute($this->input, $this->output);
215
216
        self::assertContains($changeToExpect, file_get_contents($markdownFilename));
217
        unlink($markdownFilename);
218
    }
219
220
    public function testExecuteWithDefaultRevisionsNotProvided() : void
221
    {
222
        $fromSha = sha1('fromRevision', false);
223
        $toSha = sha1('toRevision', false);
224
        $versions = VersionsCollection::fromArray(['1.0.0', '1.0.1']);
225
        $pickedVersion = Version::fromString('1.0.0');
226
227
        $this->input->expects(self::any())->method('hasOption')->willReturn(false);
228
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
229
            ['from', null],
230
            ['to', 'HEAD'],
231
        ]);
232
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
233
            ['sources-path', 'src'],
234
        ]);
235
236
        $this->performCheckout->expects(self::at(0))
237
            ->method('checkout')
238
            ->with($this->sourceRepository, $fromSha)
239
            ->willReturn($this->sourceRepository);
240
        $this->performCheckout->expects(self::at(1))
241
            ->method('checkout')
242
            ->with($this->sourceRepository, $toSha)
243
            ->willReturn($this->sourceRepository);
244
        $this->performCheckout->expects(self::at(2))
245
            ->method('remove')
246
            ->with($this->sourceRepository);
247
        $this->performCheckout->expects(self::at(3))
248
            ->method('remove')
249
            ->with($this->sourceRepository);
250
251
        $this->parseRevision->expects(self::at(0))
252
            ->method('fromStringForRepository')
253
            ->with((string)$pickedVersion)
254
            ->willReturn(Revision::fromSha1($fromSha));
255
        $this->parseRevision->expects(self::at(1))
256
            ->method('fromStringForRepository')
257
            ->with('HEAD')
258
            ->willReturn(Revision::fromSha1($toSha));
259
260
        $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

260
        $this->getVersions->/** @scrutinizer ignore-call */ 
261
                            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...
261
            ->method('fromRepository')
262
            ->with(self::callback(function (CheckedOutRepository $checkedOutRepository) : bool {
263
                self::assertEquals($this->sourceRepository, $checkedOutRepository);
264
                return true;
265
            }))
266
            ->willReturn($versions);
267
        $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

267
        $this->pickVersion->/** @scrutinizer ignore-call */ 
268
                            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...
268
            ->method('forVersions')
269
            ->with($versions)
270
            ->willReturn($pickedVersion);
271
272
        $this->comparator->expects(self::once())->method('compare')->willReturn(Changes::new());
273
274
        self::assertSame(0, $this->compare->execute($this->input, $this->output));
275
    }
276
277
    public function testExecuteFailsIfCheckedOutRepositoryDoesNotExist() : void
278
    {
279
        $fromSha = sha1('fromRevision', false);
280
        $toSha = sha1('toRevision', false);
281
282
        $this->input->expects(self::any())->method('hasOption')->willReturn(true);
283
        $this->input->expects(self::any())->method('getOption')->willReturnMap([
284
            ['from', $fromSha],
285
            ['to', $toSha],
286
        ]);
287
        $this->input->expects(self::any())->method('getArgument')->willReturnMap([
288
            ['sources-path', uniqid('src', true)],
289
        ]);
290
291
        $this->performCheckout->expects(self::at(0))
292
            ->method('checkout')
293
            ->with($this->sourceRepository, $fromSha)
294
            ->willReturn($this->sourceRepository);
295
        $this->performCheckout->expects(self::at(1))
296
            ->method('checkout')
297
            ->with($this->sourceRepository, $toSha)
298
            ->willReturn($this->sourceRepository);
299
        $this->performCheckout->expects(self::at(2))
300
            ->method('remove')
301
            ->with($this->sourceRepository);
302
        $this->performCheckout->expects(self::at(3))
303
            ->method('remove')
304
            ->with($this->sourceRepository);
305
306
        $this->parseRevision->expects(self::at(0))
307
            ->method('fromStringForRepository')
308
            ->with($fromSha)
309
            ->willReturn(Revision::fromSha1($fromSha));
310
        $this->parseRevision->expects(self::at(1))
311
            ->method('fromStringForRepository')
312
            ->with($toSha)
313
            ->willReturn(Revision::fromSha1($toSha));
314
315
        $this->comparator->expects(self::never())->method('compare');
316
317
        $this->expectException(InvalidArgumentException::class);
318
        $this->compare->execute($this->input, $this->output);
319
    }
320
}
321