Completed
Push — master ( 4beb48...a3896f )
by Jefersson
02:02
created

InstallerTest::rmDir()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 20
rs 9.4285
c 1
b 0
f 0
cc 2
eloc 11
nc 2
nop 1
1
<?php
2
3
namespace PackageVersionsTest;
4
5
use Composer\Autoload\AutoloadGenerator;
6
use Composer\Composer;
7
use Composer\Config;
8
use Composer\EventDispatcher\EventDispatcher;
9
use Composer\Installer\InstallationManager;
10
use Composer\IO\IOInterface;
11
use Composer\Package\Locker;
12
use Composer\Package\RootAliasPackage;
13
use Composer\Package\RootPackage;
14
use Composer\Package\RootPackageInterface;
15
use Composer\Repository\InstalledRepositoryInterface;
16
use Composer\Repository\RepositoryManager;
17
use Composer\Script\Event;
18
use PackageVersions\Installer;
19
use PHPUnit_Framework_TestCase;
20
21
/**
22
 * @covers \PackageVersions\Installer
23
 */
24
final class InstallerTest extends PHPUnit_Framework_TestCase
25
{
26
    /**
27
     * @var Composer|\PHPUnit_Framework_MockObject_MockObject
28
     */
29
    private $composer;
30
31
    /**
32
     * @var EventDispatcher|\PHPUnit_Framework_MockObject_MockObject
33
     */
34
    private $eventDispatcher;
35
36
    /**
37
     * @var IOInterface|\PHPUnit_Framework_MockObject_MockObject
38
     */
39
    private $io;
40
41
    /**
42
     * @var Installer
43
     */
44
    private $installer;
45
46
    /**
47
     * {@inheritDoc}
48
     */
49
    protected function setUp()
50
    {
51
        parent::setUp();
52
53
        $this->installer       = new Installer();
54
        $this->io              = $this->getMock(IOInterface::class);
55
        $this->composer        = $this->getMock(Composer::class);
56
        $this->eventDispatcher = $this->getMockBuilder(EventDispatcher::class)->disableOriginalConstructor()->getMock();
57
58
        $this->composer->expects(self::any())->method('getEventDispatcher')->willReturn($this->eventDispatcher);
59
    }
60
61
    public function testActivate()
62
    {
63
        $this->eventDispatcher->expects(self::once())->method('addSubscriber')->with($this->installer);
64
65
        $this->installer->activate($this->composer, $this->io);
66
    }
67
68
    public function testGetSubscribedEvents()
69
    {
70
        $events = Installer::getSubscribedEvents();
71
72
        self::assertSame(
73
            [
74
                'post-install-cmd' => 'dumpVersionsClass',
75
                'post-update-cmd'  => 'dumpVersionsClass',
76
            ],
77
            $events
78
        );
79
80
        foreach ($events as $callback) {
81
            self::assertInternalType('callable', [$this->installer, $callback]);
82
        }
83
    }
84
85
    public function testDumpVersionsClass()
86
    {
87
        $config            = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
88
        $locker            = $this->getMockBuilder(Locker::class)->disableOriginalConstructor()->getMock();
89
        $autoloadGenerator = $this->getMockBuilder(AutoloadGenerator::class)->disableOriginalConstructor()->getMock();
90
        $repositoryManager = $this->getMockBuilder(RepositoryManager::class)->disableOriginalConstructor()->getMock();
91
        $installManager    = $this->getMockBuilder(InstallationManager::class)->disableOriginalConstructor()->getMock();
92
        $repository        = $this->getMock(InstalledRepositoryInterface::class);
93
        $package           = $this->getMock(RootPackageInterface::class);
94
95
        $vendorDir = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true);
96
97
        $expectedPath = $vendorDir . '/ocramius/package-versions/src/PackageVersions';
98
99
        mkdir($expectedPath, 0777, true);
100
101
        $locker
102
            ->expects(self::any())
103
            ->method('getLockData')
104
            ->willReturn([
105
                'packages' => [
106
                    [
107
                        'name'    => 'foo/bar',
108
                        'version' => '1.2.3',
109
                        'source'  => [
110
                            'reference' => 'abc123',
111
                        ],
112
                    ],
113
                    [
114
                        'name'    => 'baz/tab',
115
                        'version' => '4.5.6',
116
                        'source'  => [
117
                            'reference' => 'def456',
118
                        ],
119
                    ],
120
                ],
121
                'packages-dev' => [
122
                    [
123
                        'name'    => 'tar/taz',
124
                        'version' => '7.8.9',
125
                        'source'  => [
126
                            'reference' => 'ghi789',
127
                        ],
128
                    ]
129
                ],
130
            ]);
131
132
        $autoloadGenerator->expects(self::once())->method('dump');
133
        $repositoryManager->expects(self::any())->method('getLocalRepository')->willReturn($repository);
134
135
        $this->composer->expects(self::any())->method('getConfig')->willReturn($config);
136
        $this->composer->expects(self::any())->method('getLocker')->willReturn($locker);
137
        $this->composer->expects(self::any())->method('getAutoloadGenerator')->willReturn($autoloadGenerator);
138
        $this->composer->expects(self::any())->method('getRepositoryManager')->willReturn($repositoryManager);
139
        $this->composer->expects(self::any())->method('getPackage')->willReturn($package);
140
        $this->composer->expects(self::any())->method('getInstallationManager')->willReturn($installManager);
141
142
        $package->expects(self::any())->method('getName')->willReturn('root/package');
143
        $package->expects(self::any())->method('getVersion')->willReturn('1.3.5');
144
        $package->expects(self::any())->method('getSourceReference')->willReturn('aaabbbcccddd');
145
146
        $config->expects(self::any())->method('get')->with('vendor-dir')->willReturn($vendorDir);
147
148
        Installer::dumpVersionsClass(new Event(
149
            'post-install-cmd',
150
            $this->composer,
151
            $this->io
152
        ));
153
154
        $expectedSource = <<<'PHP'
155
<?php
156
157
namespace PackageVersions;
158
159
/**
160
 * This class is generated by ocramius/package-versions, specifically by
161
 * @see \PackageVersions\Installer
162
 *
163
 * This file is overwritten at every run of `composer install` or `composer update`.
164
 */
165
final class Versions
166
{
167
    const VERSIONS = array (
168
  'foo/bar' => '1.2.3@abc123',
169
  'baz/tab' => '4.5.6@def456',
170
  'tar/taz' => '7.8.9@ghi789',
171
  'root/package' => '1.3.5@aaabbbcccddd',
172
);
173
174
    private function __construct()
175
    {
176
    }
177
178
    /**
179
     * @throws \OutOfBoundsException if a version cannot be located
180
     */
181
    public static function getVersion(string $packageName) : string
182
    {
183
        if (! isset(self::VERSIONS[$packageName])) {
184
            throw new \OutOfBoundsException(
185
                'Required package "' . $packageName . '" is not installed: cannot detect its version'
186
            );
187
        }
188
189
        return self::VERSIONS[$packageName];
190
    }
191
}
192
193
PHP;
194
195
        self::assertSame($expectedSource, file_get_contents($expectedPath . '/Versions.php'));
196
197
        $this->rmDir($vendorDir);
198
    }
199
200
    /**
201
     * @dataProvider rootPackageProvider
202
     *
203
     * @param RootPackageInterface $rootPackage
204
     * @param bool                 $inVendor
205
     */
206
    public function testDumpsVersionsClassToSpecificLocation(RootPackageInterface $rootPackage, bool $inVendor)
207
    {
208
        $config            = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
209
        $locker            = $this->getMockBuilder(Locker::class)->disableOriginalConstructor()->getMock();
210
        $autoloadGenerator = $this->getMockBuilder(AutoloadGenerator::class)->disableOriginalConstructor()->getMock();
211
        $repositoryManager = $this->getMockBuilder(RepositoryManager::class)->disableOriginalConstructor()->getMock();
212
        $installManager    = $this->getMockBuilder(InstallationManager::class)->disableOriginalConstructor()->getMock();
213
        $repository        = $this->getMock(InstalledRepositoryInterface::class);
214
215
        $vendorDir = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/vendor';
216
217
        mkdir($vendorDir, 0777, true);
218
219
        $expectedPath = $inVendor
220
            ? $vendorDir . '/ocramius/package-versions/src/PackageVersions'
221
            : realpath($vendorDir . '/..') . '/src/PackageVersions';
222
223
        mkdir($expectedPath, 0777, true);
224
225
        $locker
226
            ->expects(self::any())
227
            ->method('getLockData')
228
            ->willReturn([
229
                'packages' => [],
230
                'packages-dev' => [],
231
            ]);
232
233
        $autoloadGenerator->expects(self::once())->method('dump');
234
        $repositoryManager->expects(self::any())->method('getLocalRepository')->willReturn($repository);
235
236
        $this->composer->expects(self::any())->method('getConfig')->willReturn($config);
237
        $this->composer->expects(self::any())->method('getLocker')->willReturn($locker);
238
        $this->composer->expects(self::any())->method('getAutoloadGenerator')->willReturn($autoloadGenerator);
239
        $this->composer->expects(self::any())->method('getRepositoryManager')->willReturn($repositoryManager);
240
        $this->composer->expects(self::any())->method('getPackage')->willReturn($rootPackage);
241
        $this->composer->expects(self::any())->method('getInstallationManager')->willReturn($installManager);
242
243
        $config->expects(self::any())->method('get')->with('vendor-dir')->willReturn($vendorDir);
244
245
        Installer::dumpVersionsClass(new Event(
246
            'post-install-cmd',
247
            $this->composer,
248
            $this->io
249
        ));
250
251
        self::assertStringMatchesFormat(
252
            '%Aclass Versions%A1.2.3@%A',
253
            file_get_contents($expectedPath . '/Versions.php')
254
        );
255
256
        $this->rmDir($vendorDir);
257
    }
258
259
    /**
260
     * @return bool[][]|RootPackageInterface[][] the root package and whether the versions class is to be generated in
261
     *                                           the vendor dir or not
262
     */
263
    public function rootPackageProvider() : array
264
    {
265
        $baseRootPackage                         = new RootPackage('root/package', '1.2.3', '1.2.3');
266
        $aliasRootPackage                        = new RootAliasPackage($baseRootPackage, '1.2.3', '1.2.3');
267
        $indirectAliasRootPackage                = new RootAliasPackage($aliasRootPackage, '1.2.3', '1.2.3');
268
        $packageVersionsRootPackage              = new RootPackage('ocramius/package-versions', '1.2.3', '1.2.3');
269
        $aliasPackageVersionsRootPackage         = new RootAliasPackage($packageVersionsRootPackage, '1.2.3', '1.2.3');
270
        $indirectAliasPackageVersionsRootPackage = new RootAliasPackage(
271
            $aliasPackageVersionsRootPackage,
272
            '1.2.3',
273
            '1.2.3'
274
        );
275
276
        return [
277
            'root package is not ocramius/package-versions' => [
278
                $baseRootPackage,
279
                true
280
            ],
281
            'alias root package is not ocramius/package-versions' => [
282
                $aliasRootPackage,
283
                true
284
            ],
285
            'indirect alias root package is not ocramius/package-versions' => [
286
                $indirectAliasRootPackage,
287
                true
288
            ],
289
            'root package is ocramius/package-versions' => [
290
                $packageVersionsRootPackage,
291
                false
292
            ],
293
            'alias root package is ocramius/package-versions' => [
294
                $aliasPackageVersionsRootPackage,
295
                false
296
            ],
297
            'indirect alias root package is ocramius/package-versions' => [
298
                $indirectAliasPackageVersionsRootPackage,
299
                false
300
            ],
301
        ];
302
    }
303
304
    /**
305
     * @param string $directory
306
     *
307
     * @return void
308
     */
309
    private function rmDir(string $directory)
310
    {
311
        if (! is_dir($directory)) {
312
            unlink($directory);
313
314
            return;
315
        }
316
317
        array_map(
318
            function ($item) use ($directory) {
319
                $this->rmDir($directory . '/' . $item);
320
            },
321
            array_filter(
322
                scandir($directory),
323
                function (string $dirItem) {
324
                    return ! in_array($dirItem, ['.', '..'], true);
325
                }
326
            )
327
        );
328
    }
329
}
330