Skip to content

Commit 1973be2

Browse files
committed
Roave#66 Roave#72 Roave#73 added an end-to-end test setup that works with real repositories
The reasoning behind this is that `symfony/console` has a very squishy API, and that can lead to a lot of headaches in upgrades or implicit API changes. Having an E2E test will ensure that the implementation details of `symfony/console` are also considered, since the interfaces really just lie.
1 parent c30e153 commit 1973be2

File tree

2 files changed

+306
-0
lines changed

2 files changed

+306
-0
lines changed

phpunit.xml.dist

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
<testsuite name="unit">
1010
<directory>./test/unit</directory>
1111
</testsuite>
12+
<testsuite name="end to end">
13+
<directory>./test/e2e</directory>
14+
</testsuite>
1215
</testsuites>
1316
<filter>
1417
<whitelist processUncoveredFilesFromWhitelist="true">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
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+
$check->run();
287+
// self::assertSame(3, $check->run());
288+
289+
var_dump($check->getOutput());
290+
$errorOutput = $check->getErrorOutput();
291+
292+
self::assertContains('Detected last minor version: 2.2.3', $errorOutput);
293+
self::assertStringEndsWith(
294+
<<<'EXPECTED'
295+
[BC] CHANGED: The parameter $a of TestArtifact\TheClass#method() changed from TestArtifact\B to a non-contravariant TestArtifact\C
296+
1 backwards-incompatible changes detected
297+
298+
EXPECTED
299+
,
300+
$errorOutput // @TODO this looks like a symfony bug - we shouldn't check STDERR, but STDOUT
301+
);
302+
}
303+
}

0 commit comments

Comments
 (0)