LocateComposerPackageSourceFilesTest   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 226
Duplicated Lines 0 %

Importance

Changes 11
Bugs 1 Features 0
Metric Value
wmc 14
eloc 111
c 11
b 1
f 0
dl 0
loc 226
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A testFromClassmap() 0 15 1
A testFromFiles() 0 11 1
A setUp() 0 6 1
A testFromPsr4WithNestedDirectoryAlternativeDirectorySeparator() 0 13 1
A testFromPsr0() 0 15 1
A testFromPsr4WithNestedDirectory() 0 13 1
A testFromPsr0WithMultipleDirectories() 0 13 1
A files() 0 9 2
A testFromPsr4WithExcludeFromClassmap() 0 28 2
A testFromPsr4() 0 13 1
A testFromPsr4WithMultipleDirectories() 0 13 1
A provideExcludePattern() 0 35 1
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());
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
        $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());
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());
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());
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());
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());
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());
178
179
        $this->assertCount(count($expectedFiles), $files);
180
        foreach ($expectedFiles as $expectedFile) {
181
            $this->assertContains($this->root->getChild($expectedFile)->url(), $files);
182
        }
183
    }
184
185
    /**
186
     * @return array[]
187
     */
188
    public function provideExcludePattern(): array
189
    {
190
        return [
191
            'No exclude pattern' => [
192
                [],
193
                [
194
                    'ClassA.php',
195
                    'tests/ATest.php',
196
                    'foo/Bar/BTest.php',
197
                    'foo/src/ClassB.php',
198
                    'foo/src/Bar/CTest.php',
199
                ],
200
            ],
201
            'Exclude single directory by pattern' => [
202
                ['/tests/'],
203
                [
204
                    'ClassA.php',
205
                    'foo/Bar/BTest.php',
206
                    'foo/src/ClassB.php',
207
                    'foo/src/Bar/CTest.php',
208
                ],
209
            ],
210
            'Exclude all subdirectories by pattern' => [
211
                ['**/Bar/'],
212
                [
213
                    'ClassA.php',
214
                    'tests/ATest.php',
215
                    'foo/src/ClassB.php',
216
                ],
217
            ],
218
            'Combine multiple patterns' => [
219
                ['/tests/', '**/Bar/'],
220
                [
221
                    'ClassA.php',
222
                    'foo/src/ClassB.php',
223
                ],
224
            ],
225
        ];
226
    }
227
228
    /**
229
     * @return string[]
230
     */
231
    private function files(string $composerJson): array
232
    {
233
        $composerData = (new JsonLoader($composerJson))->getData();
234
        $files = [];
235
        $filesGenerator = ($this->locator)($composerData, dirname($composerJson));
236
        foreach ($filesGenerator as $file) {
237
            $files[] = str_replace('\\', '/', $file);
238
        }
239
        return $files;
240
    }
241
}
242