Failed Conditions
Pull Request — master (#163)
by Guillaume
07:51
created

testFromPsr0()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 8
c 2
b 0
f 0
dl 0
loc 15
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace ComposerRequireCheckerTest\FileLocator;
4
5
use ComposerRequireChecker\FileLocator\LocateComposerPackageSourceFiles;
6
use ComposerRequireChecker\JsonLoader;
7
use org\bovigo\vfs\vfsStream;
8
use org\bovigo\vfs\vfsStreamDirectory;
9
use PHPUnit\Framework\TestCase;
10
11
/**
12
 * @covers \ComposerRequireChecker\FileLocator\LocateComposerPackageSourceFiles
13
 */
14
final class LocateComposerPackageSourceFilesTest extends TestCase
15
{
16
    /** @var LocateComposerPackageSourceFiles */
17
    private $locator;
18
    /** @var vfsStreamDirectory */
19
    private $root;
20
21
    protected function setUp(): void
22
    {
23
        parent::setUp();
24
25
        $this->locator = new LocateComposerPackageSourceFiles();
26
        $this->root = vfsStream::setup();
27
    }
28
29
    public function testFromClassmap(): void
30
    {
31
        vfsStream::create([
32
            'composer.json' => '{"autoload": {"classmap": ["src/MyClassA.php", "MyClassB.php"]}}',
33
            'src' => [
34
                'MyClassA.php' => '<?php class MyClassA {}',
35
            ],
36
            'MyClassB.php' => '<?php class MyClassB {}',
37
        ]);
38
39
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload');
40
41
        $this->assertCount(2, $files);
42
        $this->assertContains($this->root->getChild('src/MyClassA.php')->url(), $files);
43
        $this->assertContains($this->root->getChild('MyClassB.php')->url(), $files);
44
    }
45
46
    public function testFromFiles(): void
47
    {
48
        vfsStream::create([
49
            'composer.json' => '{"autoload": {"files": ["foo.php"]}}',
50
            'foo.php' => '<?php class MyClass {}',
51
        ]);
52
53
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload');
54
55
        $this->assertCount(1, $files);
56
        $this->assertContains($this->root->getChild('foo.php')->url(), $files);
57
    }
58
59
    public function testFromPsr0(): void
60
    {
61
        vfsStream::create([
62
            'composer.json' => '{"autoload": {"psr-0": ["src"]}}',
63
            'src' => [
64
                'MyNamespace' => [
65
                    'MyClass.php' => '<?php namespace MyNamespace; class MyClass {}',
66
                ],
67
            ],
68
        ]);
69
70
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload');
71
72
        $this->assertCount(1, $files);
73
        $this->assertContains($this->root->getChild('src/MyNamespace/MyClass.php')->url(), $files);
74
    }
75
76
    public function testFromPsr4(): void
77
    {
78
        vfsStream::create([
79
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": "src"}}}',
80
            'src' => [
81
                'MyClass.php' => '<?php namespace MyNamespace; class MyClass {}',
82
            ],
83
        ]);
84
85
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload');
86
87
        $this->assertCount(1, $files);
88
        $this->assertContains($this->root->getChild('src/MyClass.php')->url(), $files);
89
    }
90
91
    public function testFromPsr0WithMultipleDirectories(): void
92
    {
93
        vfsStream::create([
94
            'composer.json' => '{"autoload": {"psr-0": {"MyNamespace\\\\": ["src", "lib"]}}}',
95
            'src' => ['MyNamespace' => ['MyClassA.php' => '<?php namespace MyNamespace; class MyClassA {}']],
96
            'lib' => ['MyNamespace' => ['MyClassB.php' => '<?php namespace MyNamespace; class MyClassB {}']],
97
        ]);
98
99
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload');
100
101
        $this->assertCount(2, $files);
102
        $this->assertContains($this->root->getChild('src/MyNamespace/MyClassA.php')->url(), $files);
103
        $this->assertContains($this->root->getChild('lib/MyNamespace/MyClassB.php')->url(), $files);
104
    }
105
106
    public function testFromPsr4WithMultipleDirectories(): void
107
    {
108
        vfsStream::create([
109
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": ["src", "lib"]}}}',
110
            'src' => ['MyClassA.php' => '<?php namespace MyNamespace; class MyClassA {}'],
111
            'lib' => ['MyClassB.php' => '<?php namespace MyNamespace; class MyClassB {}'],
112
        ]);
113
114
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload');
115
116
        $this->assertCount(2, $files);
117
        $this->assertContains($this->root->getChild('src/MyClassA.php')->url(), $files);
118
        $this->assertContains($this->root->getChild('lib/MyClassB.php')->url(), $files);
119
    }
120
121
    public function testFromPsr4WithNestedDirectory(): void
122
    {
123
        vfsStream::create([
124
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": ["src/MyNamespace"]}}}',
125
            'src' => [
126
                'MyNamespace' => ['MyClassA.php' => '<?php namespace MyNamespace; class MyClassA {}'],
127
            ],
128
        ]);
129
130
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload');
131
132
        $this->assertCount(1, $files);
133
        $this->assertContains($this->root->getChild('src/MyNamespace/MyClassA.php')->url(), $files);
134
    }
135
136
    public function testFromPsr4WithNestedDirectoryAlternativeDirectorySeparator(): void
137
    {
138
        vfsStream::create([
139
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": ["src\\\\MyNamespace"]}}}',
140
            'src' => [
141
                'MyNamespace' => ['MyClassA.php' => '<?php namespace MyNamespace; class MyClassA {}'],
142
            ],
143
        ]);
144
145
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload');
146
147
        $this->assertCount(1, $files);
148
        $this->assertContains($this->root->getChild('src/MyNamespace/MyClassA.php')->url(), $files);
149
    }
150
151
    /**
152
     * @dataProvider provideExcludePattern
153
     */
154
    public function testFromPsr4WithExcludeFromClassmap(array $excludedPattern, array $expectedFiles): void
155
    {
156
        $excludedPatternJson = json_encode($excludedPattern);
157
158
        vfsStream::create([
159
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": ""}, "exclude-from-classmap": ' . $excludedPatternJson . '}}',
160
            'ClassA.php' => '<?php namespace MyNamespace; class ClassA {}',
161
            'tests' => [
162
                'ATest.php' => '<?php namespace MyNamespace; class ATest {}',
163
            ],
164
            'foo' => [
165
                'Bar' => [
166
                    'BTest.php' => '<?php namespace MyNamespace; class BTest {}',
167
                ],
168
                'src' => [
169
                    'ClassB.php' => '<?php namespace MyNamespace; class ClassB {}',
170
                    'Bar' => [
171
                        'CTest.php' => '<?php namespace MyNamespace; class CTest {}',
172
                    ],
173
                ],
174
            ],
175
        ]);
176
177
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload');
178
179
        foreach ($expectedFiles as $expectedFile) {
180
            $this->assertContains($this->root->getChild($expectedFile)->url(), $files);
181
        }
182
        $this->assertCount(count($expectedFiles), $files);
183
    }
184
185
    public function testFromDevClassmap(): void
186
    {
187
        vfsStream::create([
188
            'composer.json' => <<<'COMPOSERJSON'
189
{
190
    "autoload": {"classmap": ["src/MyClassA.php"]},
191
    "autoload-dev": {"classmap": ["tests/MyClassATest.php"]}
192
}
193
COMPOSERJSON
194
            ,
195
            'src' => [
196
                'MyClassA.php' => '<?php class MyClassA {}',
197
            ],
198
            'tests' => [
199
                'MyClassATest.php' => '<?php class MyClassATest {}',
200
            ],
201
        ]);
202
203
        $files = $this->files($this->root->getChild('composer.json')->url(), 'autoload-dev');
204
205
        $this->assertCount(1, $files);
206
        $this->assertNotContains($this->root->getChild('src/MyClassA.php')->url(), $files);
207
        $this->assertContains($this->root->getChild('tests/MyClassATest.php')->url(), $files);
208
    }
209
210
    /**
211
     * @return array[]
212
     */
213
    public function provideExcludePattern(): array
214
    {
215
        return [
216
            'No exclude pattern' => [
217
                [],
218
                [
219
                    'ClassA.php',
220
                    'tests/ATest.php',
221
                    'foo/Bar/BTest.php',
222
                    'foo/src/ClassB.php',
223
                    'foo/src/Bar/CTest.php',
224
                ],
225
            ],
226
            'Exclude single directory by pattern' => [
227
                ['/tests/'],
228
                [
229
                    'ClassA.php',
230
                    'foo/Bar/BTest.php',
231
                    'foo/src/ClassB.php',
232
                    'foo/src/Bar/CTest.php',
233
                ],
234
            ],
235
            'Exclude all subdirectories by pattern' => [
236
                ['**/Bar/'],
237
                [
238
                    'ClassA.php',
239
                    'tests/ATest.php',
240
                    'foo/src/ClassB.php',
241
                ],
242
            ],
243
            'Combine multiple patterns' => [
244
                ['/tests/', '**/Bar/'],
245
                [
246
                    'ClassA.php',
247
                    'foo/src/ClassB.php',
248
                ],
249
            ],
250
        ];
251
    }
252
253
    /**
254
     * @return string[]
255
     */
256
    private function files(string $composerJson, string $autoloadKey): array
257
    {
258
        $composerData = (new JsonLoader($composerJson))->getData();
259
        $files = [];
260
        $filesGenerator = ($this->locator)($composerData, dirname($composerJson), $autoloadKey);
261
        foreach ($filesGenerator as $file) {
262
            $files[] = str_replace('\\', '/', $file);
263
        }
264
        return $files;
265
    }
266
}
267