Completed
Pull Request — master (#39)
by Aydin
06:11
created

testGloballyInstalledPluginDoesNotGenerateVersionsForLocalProject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 50
Code Lines 25

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 25
nc 1
nop 0
1
<?php
2
3
namespace PackageVersionsTest;
4
5
use PHPUnit_Framework_TestCase;
6
use RecursiveCallbackFilterIterator;
7
use RecursiveDirectoryIterator;
8
use RecursiveIteratorIterator;
9
use SplFileInfo;
10
use ZipArchive;
11
12
/**
13
 * @coversNothing
14
 */
15
class E2EInstaller extends PHPUnit_Framework_TestCase
16
{
17
    /**
18
     * @var string
19
     */
20
    private $tempGlobalComposerHome;
21
22
    /**
23
     * @var string
24
     */
25
    private $tempLocalComposerHome;
26
27
    /**
28
     * @var string
29
     */
30
    private $tempArtifact;
31
32
    public function setUp()
33
    {
34
        $this->tempGlobalComposerHome = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/global';
35
        $this->tempLocalComposerHome = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/local';
36
        $this->tempArtifact = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/artifacts';
37
        mkdir($this->tempGlobalComposerHome, 0777, true);
38
        mkdir($this->tempLocalComposerHome, 0777, true);
39
        mkdir($this->tempArtifact, 0777, true);
40
41
        putenv('COMPOSER_HOME=' . $this->tempGlobalComposerHome);
42
    }
43
44
    public function tearDown()
45
    {
46
        $this->rmDir($this->tempGlobalComposerHome);
47
        $this->rmDir($this->tempLocalComposerHome);
48
        $this->rmDir($this->tempArtifact);
49
    }
50
51
    public function testGloballyInstalledPluginDoesNotGenerateVersionsForLocalProject()
52
    {
53
        $this->createPackageVersionsArtifact();
54
55
        $this->writeComposerJsonFile(
56
            [
57
                'name'         => 'package-versions/e2e-global',
58
                'require'      => [
59
                    'ocramius/package-versions' => '1.0.0'
60
                ],
61
                'repositories' => [
62
                    [
63
                        'packagist' => false,
64
                    ],
65
                    [
66
                        'type' => 'artifact',
67
                        'url' => $this->tempArtifact,
68
                    ]
69
                ]
70
            ],
71
            $this->tempGlobalComposerHome
72
        );
73
74
        $this->execComposerInDir('global update', $this->tempGlobalComposerHome);
75
76
        $this->createArtifact();
77
        $this->writeComposerJsonFile(
78
            [
79
                'name'         => 'package-versions/e2e-local',
80
                'require'      => [
81
                    'test/package' => '2.0.0'
82
                ],
83
                'repositories' => [
84
                    [
85
                        'packagist' => false,
86
                    ],
87
                    [
88
                        'type' => 'artifact',
89
                        'url' => $this->tempArtifact,
90
                    ]
91
                ]
92
            ],
93
            $this->tempLocalComposerHome
94
        );
95
96
        $this->execComposerInDir('update', $this->tempLocalComposerHome);
97
        $this->assertFileNotExists(
98
            $this->tempLocalComposerHome . '/vendor/ocramius/package-versions/src/PackageVersions/Versions.php'
99
        );
100
    }
101
102
    public function testRemovingPluginDoesNotAttemptToGenerateVersions()
103
    {
104
        $this->createPackageVersionsArtifact();
105
        $this->createArtifact();
106
107
        $this->writeComposerJsonFile(
108
            [
109
                'name'         => 'package-versions/e2e-local',
110
                'require'      => [
111
                    'test/package' => '2.0.0',
112
                    'ocramius/package-versions' => '1.0.0'
113
                ],
114
                'repositories' => [
115
                    [
116
                        'packagist' => false,
117
                    ],
118
                    [
119
                        'type' => 'artifact',
120
                        'url' => $this->tempArtifact,
121
                    ]
122
                ]
123
            ],
124
            $this->tempLocalComposerHome
125
        );
126
127
        $this->execComposerInDir('update', $this->tempLocalComposerHome);
128
        $this->assertFileExists(
129
            $this->tempLocalComposerHome . '/vendor/ocramius/package-versions/src/PackageVersions/Versions.php'
130
        );
131
132
        $this->execComposerInDir('remove ocramius/package-versions', $this->tempLocalComposerHome);
133
134
        $this->assertFileNotExists(
135
            $this->tempLocalComposerHome . '/vendor/ocramius/package-versions/src/PackageVersions/Versions.php'
136
        );
137
    }
138
139
    private function createPackageVersionsArtifact()
140
    {
141
        $zip = new ZipArchive();
142
143
        $zip->open($this->tempArtifact . '/ocramius-package-versions-1.0.0.zip', ZipArchive::CREATE);
144
145
        $files = array_filter(
146
            iterator_to_array(new RecursiveIteratorIterator(
147
                new RecursiveCallbackFilterIterator(
148
                    new RecursiveDirectoryIterator(realpath(__DIR__ . '/../../'), RecursiveDirectoryIterator::SKIP_DOTS),
149
                    function (SplFileInfo $file, $key, RecursiveDirectoryIterator $iterator) {
150
                        return $iterator->getSubPathname()[0]  !== '.' && $iterator->getSubPathname() !== 'vendor';
151
                    }
152
                ),
153
                RecursiveIteratorIterator::LEAVES_ONLY
154
            )),
155
            function (SplFileInfo $file) {
156
                return !$file->isDir();
157
            }
158
        );
159
160
        array_walk(
161
            $files,
162
            function (SplFileInfo $file) use ($zip) {
163
                if ($file->getFilename() === 'composer.json') {
164
                    $contents = json_decode(file_get_contents($file->getRealPath()), true);
165
                    $contents['version'] = '1.0.0';
166
167
                    return $zip->addFromString('composer.json', json_encode($contents));
168
                }
169
170
                $zip->addFile(
171
                    $file->getRealPath(),
172
                    substr($file->getRealPath(), strlen(realpath(__DIR__ . '/../../')) + 1)
173
                );
174
            }
175
        );
176
177
        $zip->close();
178
    }
179
180
    private function createArtifact()
181
    {
182
        $zip = new ZipArchive();
183
184
        $zip->open($this->tempArtifact . '/test-package-2.0.0.zip', ZipArchive::CREATE);
185
        $zip->addFromString(
186
            'composer.json',
187
            json_encode(
188
                [
189
                    'name'    => 'test/package',
190
                    'version' => '2.0.0'
191
                ],
192
                JSON_PRETTY_PRINT
193
            )
194
        );
195
        $zip->close();
196
    }
197
198
    private function writeComposerJsonFile(array $config, string $directory)
199
    {
200
        file_put_contents(
201
            $directory . '/composer.json',
202
            json_encode($config, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)
203
        );
204
    }
205
206
    private function execComposerInDir(string $command, string $dir) : array
207
    {
208
        $currentDir = getcwd();
209
        chdir($dir);
210
        exec(__DIR__ . '/../../vendor/bin/composer ' . $command . ' 2> /dev/null', $output, $exitCode);
211
        $this->assertEquals(0, $exitCode);
212
        chdir($currentDir);
213
        return $output;
214
    }
215
216
    /**
217
     * @param string $directory
218
     *
219
     * @return void
220
     */
221
    private function rmDir(string $directory)
222
    {
223
        if (! is_dir($directory)) {
224
            unlink($directory);
225
226
            return;
227
        }
228
229
        array_map(
230
            function ($item) use ($directory) {
231
                $this->rmDir($directory . '/' . $item);
232
            },
233
            array_filter(
234
                scandir($directory),
235
                function (string $dirItem) {
236
                    return ! in_array($dirItem, ['.', '..'], true);
237
                }
238
            )
239
        );
240
241
        rmdir($directory);
242
    }
243
}
244