Completed
Pull Request — master (#11)
by
unknown
02:24
created

InstallerTest::testGetSubscribedEvents()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 16
rs 9.4285
c 1
b 0
f 0
cc 2
eloc 8
nc 2
nop 0
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
    public function testDumpVersionsClassNoDev()
201
    {
202
        $config            = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
203
        $locker            = $this->getMockBuilder(Locker::class)->disableOriginalConstructor()->getMock();
204
        $autoloadGenerator = $this->getMockBuilder(AutoloadGenerator::class)->disableOriginalConstructor()->getMock();
205
        $repositoryManager = $this->getMockBuilder(RepositoryManager::class)->disableOriginalConstructor()->getMock();
206
        $installManager    = $this->getMockBuilder(InstallationManager::class)->disableOriginalConstructor()->getMock();
207
        $repository        = $this->getMock(InstalledRepositoryInterface::class);
208
        $package           = $this->getMock(RootPackageInterface::class);
209
210
        $vendorDir = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true);
211
212
        $expectedPath = $vendorDir . '/ocramius/package-versions/src/PackageVersions';
213
214
        mkdir($expectedPath, 0777, true);
215
216
        $locker
217
            ->expects(self::any())
218
            ->method('getLockData')
219
            ->willReturn([
220
                'packages' => [
221
                    [
222
                        'name'    => 'foo/bar',
223
                        'version' => '1.2.3',
224
                        'source'  => [
225
                            'reference' => 'abc123',
226
                        ],
227
                    ],
228
                    [
229
                        'name'    => 'baz/tab',
230
                        'version' => '4.5.6',
231
                        'source'  => [
232
                            'reference' => 'def456',
233
                        ],
234
                    ],
235
                ],
236
            ]);
237
238
        $autoloadGenerator->expects(self::once())->method('dump');
239
        $repositoryManager->expects(self::any())->method('getLocalRepository')->willReturn($repository);
240
241
        $this->composer->expects(self::any())->method('getConfig')->willReturn($config);
242
        $this->composer->expects(self::any())->method('getLocker')->willReturn($locker);
243
        $this->composer->expects(self::any())->method('getAutoloadGenerator')->willReturn($autoloadGenerator);
244
        $this->composer->expects(self::any())->method('getRepositoryManager')->willReturn($repositoryManager);
245
        $this->composer->expects(self::any())->method('getPackage')->willReturn($package);
246
        $this->composer->expects(self::any())->method('getInstallationManager')->willReturn($installManager);
247
248
        $package->expects(self::any())->method('getName')->willReturn('root/package');
249
        $package->expects(self::any())->method('getVersion')->willReturn('1.3.5');
250
        $package->expects(self::any())->method('getSourceReference')->willReturn('aaabbbcccddd');
251
252
        $config->expects(self::any())->method('get')->with('vendor-dir')->willReturn($vendorDir);
253
254
        Installer::dumpVersionsClass(new Event(
255
            'post-install-cmd',
256
            $this->composer,
257
            $this->io
258
        ));
259
260
        $expectedSource = <<<'PHP'
261
<?php
262
263
namespace PackageVersions;
264
265
/**
266
 * This class is generated by ocramius/package-versions, specifically by
267
 * @see \PackageVersions\Installer
268
 *
269
 * This file is overwritten at every run of `composer install` or `composer update`.
270
 */
271
final class Versions
272
{
273
    const VERSIONS = array (
274
  'foo/bar' => '1.2.3@abc123',
275
  'baz/tab' => '4.5.6@def456',
276
  'root/package' => '1.3.5@aaabbbcccddd',
277
);
278
279
    private function __construct()
280
    {
281
    }
282
283
    /**
284
     * @throws \OutOfBoundsException if a version cannot be located
285
     */
286
    public static function getVersion(string $packageName) : string
287
    {
288
        if (! isset(self::VERSIONS[$packageName])) {
289
            throw new \OutOfBoundsException(
290
                'Required package "' . $packageName . '" is not installed: cannot detect its version'
291
            );
292
        }
293
294
        return self::VERSIONS[$packageName];
295
    }
296
}
297
298
PHP;
299
300
        self::assertSame($expectedSource, file_get_contents($expectedPath . '/Versions.php'));
301
302
        $this->rmDir($vendorDir);
303
    }
304
305
    /**
306
     * @dataProvider rootPackageProvider
307
     *
308
     * @param RootPackageInterface $rootPackage
309
     * @param bool                 $inVendor
310
     */
311
    public function testDumpsVersionsClassToSpecificLocation(RootPackageInterface $rootPackage, bool $inVendor)
312
    {
313
        $config            = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
314
        $locker            = $this->getMockBuilder(Locker::class)->disableOriginalConstructor()->getMock();
315
        $autoloadGenerator = $this->getMockBuilder(AutoloadGenerator::class)->disableOriginalConstructor()->getMock();
316
        $repositoryManager = $this->getMockBuilder(RepositoryManager::class)->disableOriginalConstructor()->getMock();
317
        $installManager    = $this->getMockBuilder(InstallationManager::class)->disableOriginalConstructor()->getMock();
318
        $repository        = $this->getMock(InstalledRepositoryInterface::class);
319
320
        $vendorDir = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/vendor';
321
322
        mkdir($vendorDir, 0777, true);
323
324
        $expectedPath = $inVendor
325
            ? $vendorDir . '/ocramius/package-versions/src/PackageVersions'
326
            : realpath($vendorDir . '/..') . '/src/PackageVersions';
327
328
        mkdir($expectedPath, 0777, true);
329
330
        $locker
331
            ->expects(self::any())
332
            ->method('getLockData')
333
            ->willReturn([
334
                'packages' => [],
335
                'packages-dev' => [],
336
            ]);
337
338
        $autoloadGenerator->expects(self::once())->method('dump');
339
        $repositoryManager->expects(self::any())->method('getLocalRepository')->willReturn($repository);
340
341
        $this->composer->expects(self::any())->method('getConfig')->willReturn($config);
342
        $this->composer->expects(self::any())->method('getLocker')->willReturn($locker);
343
        $this->composer->expects(self::any())->method('getAutoloadGenerator')->willReturn($autoloadGenerator);
344
        $this->composer->expects(self::any())->method('getRepositoryManager')->willReturn($repositoryManager);
345
        $this->composer->expects(self::any())->method('getPackage')->willReturn($rootPackage);
346
        $this->composer->expects(self::any())->method('getInstallationManager')->willReturn($installManager);
347
348
        $config->expects(self::any())->method('get')->with('vendor-dir')->willReturn($vendorDir);
349
350
        Installer::dumpVersionsClass(new Event(
351
            'post-install-cmd',
352
            $this->composer,
353
            $this->io
354
        ));
355
356
        self::assertStringMatchesFormat(
357
            '%Aclass Versions%A1.2.3@%A',
358
            file_get_contents($expectedPath . '/Versions.php')
359
        );
360
361
        $this->rmDir($vendorDir);
362
    }
363
364
    /**
365
     * @return bool[][]|RootPackageInterface[][] the root package and whether the versions class is to be generated in
366
     *                                           the vendor dir or not
367
     */
368
    public function rootPackageProvider() : array
369
    {
370
        $baseRootPackage                         = new RootPackage('root/package', '1.2.3', '1.2.3');
371
        $aliasRootPackage                        = new RootAliasPackage($baseRootPackage, '1.2.3', '1.2.3');
372
        $indirectAliasRootPackage                = new RootAliasPackage($aliasRootPackage, '1.2.3', '1.2.3');
373
        $packageVersionsRootPackage              = new RootPackage('ocramius/package-versions', '1.2.3', '1.2.3');
374
        $aliasPackageVersionsRootPackage         = new RootAliasPackage($packageVersionsRootPackage, '1.2.3', '1.2.3');
375
        $indirectAliasPackageVersionsRootPackage = new RootAliasPackage(
376
            $aliasPackageVersionsRootPackage,
377
            '1.2.3',
378
            '1.2.3'
379
        );
380
381
        return [
382
            'root package is not ocramius/package-versions' => [
383
                $baseRootPackage,
384
                true
385
            ],
386
            'alias root package is not ocramius/package-versions' => [
387
                $aliasRootPackage,
388
                true
389
            ],
390
            'indirect alias root package is not ocramius/package-versions' => [
391
                $indirectAliasRootPackage,
392
                true
393
            ],
394
            'root package is ocramius/package-versions' => [
395
                $packageVersionsRootPackage,
396
                false
397
            ],
398
            'alias root package is ocramius/package-versions' => [
399
                $aliasPackageVersionsRootPackage,
400
                false
401
            ],
402
            'indirect alias root package is ocramius/package-versions' => [
403
                $indirectAliasPackageVersionsRootPackage,
404
                false
405
            ],
406
        ];
407
    }
408
409
    /**
410
     * @param string $directory
411
     *
412
     * @return void
413
     */
414
    private function rmDir(string $directory)
415
    {
416
        if (! is_dir($directory)) {
417
            unlink($directory);
418
419
            return;
420
        }
421
422
        array_map(
423
            function ($item) use ($directory) {
424
                $this->rmDir($directory . '/' . $item);
425
            },
426
            array_filter(
427
                scandir($directory),
428
                function (string $dirItem) {
429
                    return ! in_array($dirItem, ['.', '..'], true);
430
                }
431
            )
432
        );
433
    }
434
}
435