Completed
Pull Request — master (#95)
by Marco
04:36
created

testWillLocateDependencies()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 50
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 32
nc 1
nop 0
dl 0
loc 50
rs 9.408
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 stdClass;
19
use function getcwd;
20
use function realpath;
21
22
/**
23
 * @covers \Roave\BackwardCompatibility\LocateDependencies\LocateDependenciesViaComposer
24
 */
25
final class LocateDependenciesViaComposerTest extends TestCase
26
{
27
    /** @var string */
28
    private $originalCwd;
29
30
    /** @var callable */
31
    private $makeInstaller;
32
33
    /** @var Installer|MockObject */
34
    private $composerInstaller;
35
36
    /** @var string|null */
37
    private $expectedInstallatonPath;
38
39
    /** @var Locator */
40
    private $astLocator;
41
42
    /** @var LocateDependenciesViaComposer */
43
    private $locateDependencies;
44
45
    protected function setUp() : void
46
    {
47
        parent::setUp();
48
49
        $originalCwd = getcwd();
50
51
        self::assertInternalType('string', $originalCwd);
52
53
        $this->originalCwd       = $originalCwd;
54
        $this->composerInstaller = $this->createMock(Installer::class);
55
        $this->astLocator        = (new BetterReflection())->astLocator();
56
        $this->makeInstaller     = function (string $installationPath) : Installer {
57
            self::assertSame($this->expectedInstallatonPath, $installationPath);
58
59
            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...
60
        };
61
62
        $this
63
            ->composerInstaller
64
            ->expects(self::atLeastOnce())
65
            ->method('setDevMode')
66
            ->with(false);
67
        $this
68
            ->composerInstaller
69
            ->expects(self::atLeastOnce())
70
            ->method('setDumpAutoloader')
71
            ->with(true);
72
        $this
73
            ->composerInstaller
74
            ->expects(self::atLeastOnce())
75
            ->method('setRunScripts')
76
            ->with(false);
77
        $this
78
            ->composerInstaller
79
            ->expects(self::atLeastOnce())
80
            ->method('setOptimizeAutoloader')
81
            ->with(true);
82
        $this
83
            ->composerInstaller
84
            ->expects(self::atLeastOnce())
85
            ->method('setClassMapAuthoritative')
86
            ->with(true);
87
        $this
88
            ->composerInstaller
89
            ->expects(self::atLeastOnce())
90
            ->method('setIgnorePlatformRequirements')
91
            ->with(true);
92
93
        $this->locateDependencies = new LocateDependenciesViaComposer($this->makeInstaller, $this->astLocator);
94
    }
95
96
    protected function tearDown() : void
97
    {
98
        self::assertSame($this->originalCwd, getcwd());
99
100
        parent::tearDown();
101
    }
102
103
    public function testWillLocateDependencies() : void
104
    {
105
        $this->expectedInstallatonPath = $this->realpath(__DIR__ . '/../../asset/composer-installation-structure');
106
107
        $this
108
            ->composerInstaller
109
            ->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

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