Completed
Pull Request — master (#39)
by Aydin
02:28
created

E2EInstaller::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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