Completed
Pull Request — master (#163)
by Guillaume
04:49
created

testFromClassmapWithDev()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 25
rs 9.7333
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(false);
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());
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());
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());
71
72
        $this->assertCount(1, $files);
73
    }
74
75
    public function testFromPsr4(): void
76
    {
77
        vfsStream::create([
78
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": "src"}}}',
79
            'src' => [
80
                'MyClass.php' => '<?php namespace MyNamespace; class MyClass {}',
81
            ],
82
        ]);
83
84
        $files = $this->files($this->root->getChild('composer.json')->url());
85
86
        $this->assertCount(1, $files);
87
    }
88
89
    public function testFromPsr0WithMultipleDirectories(): void
90
    {
91
        vfsStream::create([
92
            'composer.json' => '{"autoload": {"psr-0": {"MyNamespace\\\\": ["src", "lib"]}}}',
93
            'src' => ['MyNamespace' => ['MyClassA.php' => '<?php namespace MyNamespace; class MyClassA {}']],
94
            'lib' => ['MyNamespace' => ['MyClassB.php' => '<?php namespace MyNamespace; class MyClassB {}']],
95
        ]);
96
97
        $files = $this->files($this->root->getChild('composer.json')->url());
98
99
        $this->assertCount(2, $files);
100
        $this->assertContains($this->root->getChild('src/MyNamespace/MyClassA.php')->url(), $files);
101
        $this->assertContains($this->root->getChild('lib/MyNamespace/MyClassB.php')->url(), $files);
102
    }
103
104
    public function testFromPsr4WithMultipleDirectories(): void
105
    {
106
        vfsStream::create([
107
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": ["src", "lib"]}}}',
108
            'src' => ['MyClassA.php' => '<?php namespace MyNamespace; class MyClassA {}'],
109
            'lib' => ['MyClassB.php' => '<?php namespace MyNamespace; class MyClassB {}'],
110
        ]);
111
112
        $files = $this->files($this->root->getChild('composer.json')->url());
113
114
        $this->assertCount(2, $files);
115
        $this->assertContains($this->root->getChild('src/MyClassA.php')->url(), $files);
116
        $this->assertContains($this->root->getChild('lib/MyClassB.php')->url(), $files);
117
    }
118
119
    public function testFromPsr4WithNestedDirectory(): void
120
    {
121
        vfsStream::create([
122
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": ["src/MyNamespace"]}}}',
123
            'src' => [
124
                'MyNamespace' => ['MyClassA.php' => '<?php namespace MyNamespace; class MyClassA {}']
125
            ],
126
        ]);
127
128
        $files = $this->files($this->root->getChild('composer.json')->url());
129
130
        $this->assertCount(1, $files);
131
        $this->assertContains($this->root->getChild('src/MyNamespace/MyClassA.php')->url(), $files);
132
    }
133
134
    public function testFromPsr4WithNestedDirectoryAlternativeDirectorySeparator(): void
135
    {
136
        vfsStream::create([
137
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": ["src\\\\MyNamespace"]}}}',
138
            'src' => [
139
                'MyNamespace' => ['MyClassA.php' => '<?php namespace MyNamespace; class MyClassA {}']
140
            ],
141
        ]);
142
143
        $files = $this->files($this->root->getChild('composer.json')->url());
144
145
        $this->assertCount(1, $files);
146
        $this->assertContains($this->root->getChild('src/MyNamespace/MyClassA.php')->url(), $files);
147
    }
148
149
    /**
150
     * @dataProvider provideExcludePattern
151
     */
152
    public function testFromPsr4WithExcludeFromClassmap(array $excludedPattern, array $expectedFiles): void
153
    {
154
        $excludedPatternJson = json_encode($excludedPattern);
155
156
        vfsStream::create([
157
            'composer.json' => '{"autoload": {"psr-4": {"MyNamespace\\\\": ""}, "exclude-from-classmap": ' . $excludedPatternJson . '}}',
158
            'ClassA.php' => '<?php namespace MyNamespace; class ClassA {}',
159
            'tests' => [
160
                'ATest.php' => '<?php namespace MyNamespace; class ATest {}',
161
            ],
162
            'foo' => [
163
                'Tests' => [
164
                    'BTest.php' => '<?php namespace MyNamespace; class BTest {}',
165
                ],
166
                'src' => [
167
                    'ClassB.php' => '<?php namespace MyNamespace; class ClassB {}',
168
                    'Tests' => [
169
                        'CTest.php' => '<?php namespace MyNamespace; class CTest {}',
170
                    ],
171
                ],
172
            ],
173
        ]);
174
175
        $files = $this->files($this->root->getChild('composer.json')->url());
176
177
        $this->assertCount(count($expectedFiles), $files);
178
        foreach ($expectedFiles as $expectedFile) {
179
            $this->assertContains($this->root->getChild($expectedFile)->url(), $files);
180
        }
181
    }
182
183
    public function testFromClassmapWithoutDev(): void
184
    {
185
        vfsStream::create([
186
            'composer.json' => <<<'COMPOSERJSON'
187
{
188
    "autoload": {"classmap": ["src/MyClassA.php"]},
189
    "autoload-dev": {"classmap": ["tests/MyClassATest.php"]}
190
}
191
COMPOSERJSON
192
            ,
193
            'src' => [
194
                'MyClassA.php' => '<?php class MyClassA {}',
195
            ],
196
            'tests' => [
197
                'MyClassATest.php' => '<?php class MyClassATest {}',
198
            ]
199
        ]);
200
201
        $files = $this->files($this->root->getChild('composer.json')->url());
202
203
        $this->assertCount(1, $files);
204
        $this->assertContains($this->root->getChild('src/MyClassA.php')->url(), $files);
205
    }
206
207
    public function testFromClassmapWithDev(): void
208
    {
209
        $this->locator = new LocateComposerPackageSourceFiles(true);
210
211
        vfsStream::create([
212
            'composer.json' => <<<'COMPOSERJSON'
213
{
214
    "autoload": {"classmap": ["src/MyClassA.php"]},
215
    "autoload-dev": {"classmap": ["tests/MyClassATest.php"]}
216
}
217
COMPOSERJSON
218
,
219
            'src' => [
220
                'MyClassA.php' => '<?php class MyClassA {}',
221
            ],
222
            'tests' => [
223
                'MyClassATest.php' => '<?php class MyClassATest {}',
224
            ]
225
        ]);
226
227
        $files = $this->files($this->root->getChild('composer.json')->url());
228
229
        $this->assertCount(2, $files);
230
        $this->assertContains($this->root->getChild('src/MyClassA.php')->url(), $files);
231
        $this->assertContains($this->root->getChild('tests/MyClassATest.php')->url(), $files);
232
    }
233
234
    /**
235
     * @return array[]
236
     */
237
    public function provideExcludePattern(): array
238
    {
239
        return [
240
            'No exclude pattern' => [
241
                [],
242
                [
243
                    'ClassA.php',
244
                    'tests/ATest.php',
245
                    'foo/Tests/BTest.php',
246
                    'foo/src/ClassB.php',
247
                    'foo/src/Tests/CTest.php',
248
249
                ],
250
            ],
251
            'Exclude single directory by pattern' => [
252
                ['/tests/'],
253
                [
254
                    'ClassA.php',
255
                    'foo/Tests/BTest.php',
256
                    'foo/src/ClassB.php',
257
                    'foo/src/Tests/CTest.php',
258
                ],
259
            ],
260
            'Exclude all subdirectories by pattern' => [
261
                ['**/Tests/'],
262
                [
263
                    'ClassA.php',
264
                    'tests/ATest.php',
265
                    'foo/src/ClassB.php',
266
                ],
267
            ],
268
            'Combine multiple patterns' => [
269
                ['/tests/', '**/Tests/'],
270
                [
271
                    'ClassA.php',
272
                    'foo/src/ClassB.php',
273
                ],
274
            ],
275
        ];
276
    }
277
278
    /**
279
     * @return string[]
280
     */
281
    private function files(string $composerJson): array
282
    {
283
        $composerData = (new JsonLoader($composerJson))->getData();
284
        $files = [];
285
        $filesGenerator = ($this->locator)($composerData, dirname($composerJson));
286
        foreach ($filesGenerator as $file) {
287
            $files[] = $file;
288
        }
289
        return $files;
290
    }
291
}
292