Completed
Push — master ( ba85a6...34f627 )
by Marco
12s queued 10s
created

LocateDependenciesViaComposerTest::realpath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace RoaveTest\BackwardCompatibility\LocateDependencies;
6
7
use Composer\Installer;
8
use PHPUnit\Framework\MockObject\MockObject;
9
use PHPUnit\Framework\TestCase;
10
use Roave\BackwardCompatibility\LocateDependencies\LocateDependenciesViaComposer;
11
use Roave\BackwardCompatibility\SourceLocator\StaticClassMapSourceLocator;
12
use Roave\BackwardCompatibility\SourceLocator\StubClassSourceLocator;
13
use Roave\BetterReflection\BetterReflection;
14
use Roave\BetterReflection\SourceLocator\Ast\Locator;
15
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
16
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
17
use Roave\BetterReflection\SourceLocator\Type\SingleFileSourceLocator;
18
use function getcwd;
19
use function realpath;
20
21
/**
22
 * @covers \Roave\BackwardCompatibility\LocateDependencies\LocateDependenciesViaComposer
23
 */
24
final class LocateDependenciesViaComposerTest extends TestCase
25
{
26
    /** @var string */
27
    private $originalCwd;
28
29
    /** @var callable */
30
    private $makeInstaller;
31
32
    /** @var Installer|MockObject */
33
    private $composerInstaller;
34
35
    /** @var string|null */
36
    private $expectedInstallatonPath;
37
38
    /** @var Locator */
39
    private $astLocator;
40
41
    /** @var LocateDependenciesViaComposer */
42
    private $locateDependencies;
43
44
    protected function setUp() : void
45
    {
46
        parent::setUp();
47
48
        $originalCwd = getcwd();
49
50
        self::assertInternalType('string', $originalCwd);
51
52
        $this->originalCwd       = $originalCwd;
53
        $this->composerInstaller = $this->createMock(Installer::class);
54
        $this->astLocator        = (new BetterReflection())->astLocator();
55
        $this->makeInstaller     = function (string $installationPath) : Installer {
56
            self::assertSame($this->expectedInstallatonPath, $installationPath);
57
58
            return $this->composerInstaller;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->composerInstaller could return the type PHPUnit\Framework\MockObject\MockObject which is incompatible with the type-hinted return Composer\Installer. Consider adding an additional type-check to rule them out.
Loading history...
59
        };
60
61
        $this
62
            ->composerInstaller
63
            ->expects(self::atLeastOnce())
64
            ->method('setDevMode')
65
            ->with(false);
66
        $this
67
            ->composerInstaller
68
            ->expects(self::atLeastOnce())
69
            ->method('setDumpAutoloader')
70
            ->with(true);
71
        $this
72
            ->composerInstaller
73
            ->expects(self::atLeastOnce())
74
            ->method('setRunScripts')
75
            ->with(false);
76
        $this
77
            ->composerInstaller
78
            ->expects(self::atLeastOnce())
79
            ->method('setOptimizeAutoloader')
80
            ->with(true);
81
        $this
82
            ->composerInstaller
83
            ->expects(self::atLeastOnce())
84
            ->method('setClassMapAuthoritative')
85
            ->with(true);
86
        $this
87
            ->composerInstaller
88
            ->expects(self::atLeastOnce())
89
            ->method('setIgnorePlatformRequirements')
90
            ->with(true);
91
92
        $this->locateDependencies = new LocateDependenciesViaComposer($this->makeInstaller, $this->astLocator);
93
    }
94
95
    protected function tearDown() : void
96
    {
97
        self::assertSame($this->originalCwd, getcwd());
98
99
        parent::tearDown();
100
    }
101
102
    public function testWillLocateDependencies() : void
103
    {
104
        $this->expectedInstallatonPath = $this->realpath(__DIR__ . '/../../asset/composer-installation-structure');
105
106
        $this
107
            ->composerInstaller
108
            ->expects(self::once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Composer\Installer. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

108
            ->/** @scrutinizer ignore-call */ 
109
              expects(self::once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
109
            ->method('run')
110
            ->willReturnCallback(function () : void {
111
                self::assertSame($this->expectedInstallatonPath, getcwd());
112
            });
113
114
        $locator = $this
115
            ->locateDependencies
116
            ->__invoke($this->expectedInstallatonPath);
117
118
        self::assertInstanceOf(AggregateSourceLocator::class, $locator);
119
120
        $reflectionLocators = new \ReflectionProperty(AggregateSourceLocator::class, 'sourceLocators');
121
122
        $reflectionLocators->setAccessible(true);
123
124
        $locators = $reflectionLocators->getValue($locator);
125
126
        self::assertCount(4, $locators);
127
        self::assertEquals(
128
            new StaticClassMapSourceLocator(
129
                [
130
                    'A\\ClassName' => $this->realpath(__DIR__ . '/../../asset/composer-installation-structure/AClassName.php'),
131
                    'B\\ClassName' => $this->realpath(__DIR__ . '/../../asset/composer-installation-structure/BClassName.php'),
132
                ],
133
                $this->astLocator
134
            ),
135
            $locators[0]
136
        );
137
        self::assertEquals(
138
            new AggregateSourceLocator([
139
                new SingleFileSourceLocator(
140
                    $this->realpath(__DIR__ . '/../../asset/composer-installation-structure/included-file-1.php'),
141
                    $this->astLocator
142
                ),
143
                new SingleFileSourceLocator(
144
                    $this->realpath(__DIR__ . '/../../asset/composer-installation-structure/included-file-2.php'),
145
                    $this->astLocator
146
                ),
147
            ]),
148
            $locators[1]
149
        );
150
        self::assertInstanceOf(PhpInternalSourceLocator::class, $locators[2]);
151
        self::assertInstanceOf(StubClassSourceLocator::class, $locators[3]);
152
    }
153
154
    public function testWillLocateDependenciesEvenWithoutAutoloadFiles() : void
155
    {
156
        $this->expectedInstallatonPath = $this->realpath(__DIR__ . '/../../asset/composer-installation-structure-without-autoload-files');
157
158
        $this
159
            ->composerInstaller
160
            ->expects(self::once())
161
            ->method('run')
162
            ->willReturnCallback(function () : void {
163
                self::assertSame($this->expectedInstallatonPath, getcwd());
164
            });
165
166
        $locator = $this
167
            ->locateDependencies
168
            ->__invoke($this->expectedInstallatonPath);
169
170
        self::assertInstanceOf(AggregateSourceLocator::class, $locator);
171
172
        $reflectionLocators = new \ReflectionProperty(AggregateSourceLocator::class, 'sourceLocators');
173
174
        $reflectionLocators->setAccessible(true);
175
176
        $locators = $reflectionLocators->getValue($locator);
177
178
        self::assertCount(4, $locators);
179
        self::assertEquals(
180
            new StaticClassMapSourceLocator(
181
                [
182
                    'A\\ClassName' => $this->realpath(__DIR__ . '/../../asset/composer-installation-structure-without-autoload-files/AClassName.php'),
183
                    'B\\ClassName' => $this->realpath(__DIR__ . '/../../asset/composer-installation-structure-without-autoload-files/BClassName.php'),
184
                ],
185
                $this->astLocator
186
            ),
187
            $locators[0]
188
        );
189
        self::assertEquals(new AggregateSourceLocator(), $locators[1]);
190
        self::assertInstanceOf(PhpInternalSourceLocator::class, $locators[2]);
191
        self::assertInstanceOf(StubClassSourceLocator::class, $locators[3]);
192
    }
193
194
    private function realpath(string $path) : string
195
    {
196
        $realPath = realpath($path);
197
198
        self::assertInternalType('string', $realPath);
199
200
        return $realPath;
201
    }
202
}
203