Completed
Pull Request — master (#76)
by Marco
08:32
created

testWillPickTaggedVersionOnNoGivenFrom()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 42
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 26
nc 1
nop 0
dl 0
loc 42
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace RoaveE2ETest\BackwardCompatibility\Command;
6
7
use PHPUnit\Framework\TestCase;
8
use Symfony\Component\Process\Process;
9
10
/**
11
 * @coversNothing
12
 */
13
final class AssertBackwardsCompatibleTest extends TestCase
14
{
15
    private const COMPOSER_MANIFEST = <<<'JSON'
16
{
17
    "autoload": {
18
        "psr-4": {
19
            "TestArtifact\\": "src/"
20
        }
21
    },
22
    "repositories": [
23
        {
24
            "packagist.org": false
25
        }
26
    ]
27
}
28
29
JSON;
30
31
    private const CLASS_V1 = <<<'PHP'
32
<?php
33
34
namespace TestArtifact;
35
36
final class TheClass
37
{
38
    public function method(A $a)
39
    {
40
    }
41
}
42
43
PHP;
44
45
    private const CLASS_V2 = <<<'PHP'
46
<?php
47
48
namespace TestArtifact;
49
50
final class TheClass
51
{
52
    public function method(B $a)
53
    {
54
    }
55
}
56
57
PHP;
58
59
    private const CLASS_V3 = <<<'PHP'
60
<?php
61
62
namespace TestArtifact;
63
64
final class TheClass
65
{
66
    public function method(C $a)
67
    {
68
    }
69
}
70
71
PHP;
72
73
    private const CLASS_V4 = <<<'PHP'
74
<?php
75
76
namespace TestArtifact;
77
78
final class TheClass
79
{
80
    public function method(A $a)
81
    {
82
    }
83
}
84
85
PHP;
86
87
    /** @var string path to the sources that should be checked */
88
    private $sourcesRepository;
89
90
    /** @var string[] sha1 of the source versions */
91
    private $versions = [];
92
93
    protected function setUp() : void
94
    {
95
        parent::setUp();
96
97
        $this->sourcesRepository = tempnam(sys_get_temp_dir(), 'roave-backward-compatibility-e2e-test');
98
99
        self::assertInternalType('string', $this->sourcesRepository);
100
        self::assertNotEmpty($this->sourcesRepository);
101
        self::assertFileExists($this->sourcesRepository);
102
103
        unlink($this->sourcesRepository);
104
        mkdir($this->sourcesRepository);
105
        mkdir($this->sourcesRepository . '/src');
106
107
        self::assertDirectoryExists($this->sourcesRepository);
108
        self::assertDirectoryExists($this->sourcesRepository . '/src');
109
110
        (new Process('git init', $this->sourcesRepository))->mustRun();
111
112
        file_put_contents($this->sourcesRepository . '/composer.json', self::COMPOSER_MANIFEST);
113
114
        (new Process('git add -A', $this->sourcesRepository))->mustRun();
115
        (new Process('git commit -am "Initial commit with composer manifest"', $this->sourcesRepository))->mustRun();
116
117
        foreach ([self::CLASS_V1, self::CLASS_V2, self::CLASS_V3, self::CLASS_V4] as $key => $classCode) {
118
            file_put_contents($this->sourcesRepository . '/src/TheClass.php', $classCode);
119
120
            (new Process('git add -A', $this->sourcesRepository))->mustRun();
121
            (new Process(sprintf('git commit -am "Class sources v%d"', $key + 1), $this->sourcesRepository))->mustRun();
122
            $this->versions[$key] = trim((new Process('git rev-parse HEAD', $this->sourcesRepository))->mustRun()
123
                                                                                                      ->getOutput());
124
        }
125
    }
126
127
    protected function tearDown() : void
128
    {
129
        self::assertInternalType('string', $this->sourcesRepository);
130
        self::assertNotEmpty($this->sourcesRepository);
131
        self::assertDirectoryExists($this->sourcesRepository);
132
133
        // Need to be extremely careful with this stuff - skipping it for now
134
//        (new Process(['rm', '-r', $this->sourcesRepository]))->mustRun();
135
136
        parent::tearDown();
137
    }
138
139
    public function testWillAllowSpecifyingGitRevision() : void
140
    {
141
        $check = new Process(
142
            [
143
                __DIR__ . '/../../../bin/roave-backward-compatibility-check',
144
                '--from=' . $this->versions[0],
145
                '--to=' . $this->versions[1],
146
            ],
147
            $this->sourcesRepository
148
        );
149
150
        self::assertSame(3, $check->run());
151
        self::assertStringEndsWith(
152
            <<<'EXPECTED'
153
[BC] CHANGED: The parameter $a of TestArtifact\TheClass#method() changed from TestArtifact\A to a non-contravariant TestArtifact\B
154
1 backwards-incompatible changes detected
155
156
EXPECTED
157
            ,
158
            $check->getErrorOutput() // @TODO this looks like a symfony bug - we shouldn't check STDERR, but STDOUT
159
        );
160
    }
161
162
    public function testWillNotRunWithoutTagsNorSpecifiedVersions() : void
163
    {
164
        $check = new Process(
165
            __DIR__ . '/../../../bin/roave-backward-compatibility-check',
166
            $this->sourcesRepository
167
        );
168
169
        self::assertSame(212, $check->run());
170
        self::assertContains(
171
            'Could not detect any released versions for the given repository',
172
            $check->getErrorOutput()
173
        );
174
    }
175
176
    public function testWillRunSuccessfullyOnNoBcBreaks() : void
177
    {
178
        $check = new Process(
179
            [
180
                __DIR__ . '/../../../bin/roave-backward-compatibility-check',
181
                '--from=' . $this->versions[0],
182
                '--to=' . $this->versions[3],
183
            ],
184
            $this->sourcesRepository
185
        );
186
187
        self::assertSame(0, $check->run());
188
        self::assertContains(
189
            'No backwards-incompatible changes detected',
190
            $check->getErrorOutput()
191
        );
192
    }
193
194
    public function testWillPickTaggedVersionOnNoGivenFrom() : void
195
    {
196
        (new Process(
197
            [
198
                'git',
199
                'checkout',
200
                $this->versions[1],
201
            ],
202
            $this->sourcesRepository
203
        ))->mustRun();
204
        (new Process(
205
            [
206
                'git',
207
                'tag',
208
                '1.2.3',
209
                '-m',
210
                'First tag',
211
            ],
212
            $this->sourcesRepository
213
        ))->mustRun();
214
215
        $check = new Process(
216
            [
217
                __DIR__ . '/../../../bin/roave-backward-compatibility-check',
218
                '--to=' . $this->versions[2],
219
            ],
220
            $this->sourcesRepository
221
        );
222
223
        self::assertSame(3, $check->run());
224
225
        $errorOutput = $check->getErrorOutput();
226
227
        self::assertContains('Detected last minor version: 1.2.3', $errorOutput);
228
        self::assertStringEndsWith(
229
            <<<'EXPECTED'
230
[BC] CHANGED: The parameter $a of TestArtifact\TheClass#method() changed from TestArtifact\B to a non-contravariant TestArtifact\C
231
1 backwards-incompatible changes detected
232
233
EXPECTED
234
            ,
235
            $errorOutput // @TODO this looks like a symfony bug - we shouldn't check STDERR, but STDOUT
236
        );
237
    }
238
239
    public function testWillPickLatestTaggedVersionOnNoGivenFrom() : void
240
    {
241
        (new Process(
242
            [
243
                'git',
244
                'checkout',
245
                $this->versions[1],
246
            ],
247
            $this->sourcesRepository
248
        ))->mustRun();
249
        (new Process(
250
            [
251
                'git',
252
                'tag',
253
                '2.2.3',
254
                '-m',
255
                'First tag',
256
            ],
257
            $this->sourcesRepository
258
        ))->mustRun();
259
        (new Process(
260
            [
261
                'git',
262
                'checkout',
263
                $this->versions[3],
264
            ],
265
            $this->sourcesRepository
266
        ))->mustRun();
267
        (new Process(
268
            [
269
                'git',
270
                'tag',
271
                '1.2.3',
272
                '-m',
273
                'First tag',
274
            ],
275
            $this->sourcesRepository
276
        ))->mustRun();
277
278
        $check = new Process(
279
            [
280
                __DIR__ . '/../../../bin/roave-backward-compatibility-check',
281
                '--to=' . $this->versions[2],
282
            ],
283
            $this->sourcesRepository
284
        );
285
286
        self::assertSame(3, $check->run());
287
288
        $errorOutput = $check->getErrorOutput();
289
290
        self::assertContains('Detected last minor version: 2.2.3', $errorOutput);
291
        self::assertStringEndsWith(
292
            <<<'EXPECTED'
293
[BC] CHANGED: The parameter $a of TestArtifact\TheClass#method() changed from TestArtifact\B to a non-contravariant TestArtifact\C
294
1 backwards-incompatible changes detected
295
296
EXPECTED
297
            ,
298
            $errorOutput // @TODO this looks like a symfony bug - we shouldn't check STDERR, but STDOUT
299
        );
300
    }
301
}
302