06972fd4c6ae613d50693dd07105811cc4ef971c
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Core / ClassLoadingInformationGeneratorTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Core;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Composer\Autoload\ClassLoader;
18 use TYPO3\CMS\Core\Core\ClassLoadingInformationGenerator;
19 use TYPO3\CMS\Core\Package\PackageInterface;
20
21 /**
22 * Testcase for the ClassLoadingInformationGenerator class
23 */
24 class ClassLoadingInformationGeneratorTest extends \TYPO3\Components\TestingFramework\Core\UnitTestCase
25 {
26 /**
27 * @test
28 */
29 public function buildClassAliasMapForPackageThrowsExceptionForWrongComposerManifestInformation()
30 {
31 $this->expectException(\TYPO3\CMS\Core\Error\Exception::class);
32 $this->expectExceptionCode(1444142481);
33
34 $packageMock = $this->createPackageMock([
35 'extra' => [
36 'typo3/class-alias-loader' => [
37 'class-alias-maps' => [
38 'foo' => Fixtures\test_extension\Resources\PHP\Test::class,
39 'bar' => Fixtures\test_extension\Resources\PHP\AnotherTestFile::class,
40 ],
41 ],
42 ],
43 ]);
44 /** @var ClassLoader|\PHPUnit_Framework_MockObject_MockObject $classLoaderMock */
45 $classLoaderMock = $this->createMock(ClassLoader::class);
46 $generator = new ClassLoadingInformationGenerator($classLoaderMock, [], __DIR__);
47 $generator->buildClassAliasMapForPackage($packageMock);
48 }
49
50 /**
51 * @test
52 */
53 public function buildClassAliasMapForPackageThrowsExceptionForWrongClassAliasMapFile()
54 {
55 $this->expectException(\TYPO3\CMS\Core\Error\Exception::class);
56 $this->expectExceptionCode(1422625075);
57
58 $packageMock = $this->createPackageMock([
59 'extra' => [
60 'typo3/class-alias-loader' => [
61 'class-alias-maps' => [
62 'Migrations/Code/WrongClassAliasMap.php',
63 ],
64 ],
65 ],
66 ]);
67 /** @var ClassLoader|\PHPUnit_Framework_MockObject_MockObject $classLoaderMock */
68 $classLoaderMock = $this->createMock(ClassLoader::class);
69 $generator = new ClassLoadingInformationGenerator($classLoaderMock, [], __DIR__);
70 $generator->buildClassAliasMapForPackage($packageMock);
71 }
72
73 /**
74 * @test
75 */
76 public function buildClassAliasMapForPackageReturnsClassAliasMapForClassAliasMapFile()
77 {
78 $expectedClassMap = [
79 'aliasToClassNameMapping' => [
80 'foo' => Fixtures\test_extension\Resources\PHP\Test::class,
81 'bar' => Fixtures\test_extension\Resources\PHP\AnotherTestFile::class,
82 ],
83 'classNameToAliasMapping' => [
84 Fixtures\test_extension\Resources\PHP\Test::class => [
85 'foo' => 'foo',
86 ],
87 Fixtures\test_extension\Resources\PHP\AnotherTestFile::class => [
88 'bar' => 'bar',
89 ]
90 ],
91 ];
92 $packageMock = $this->createPackageMock([]);
93 /** @var ClassLoader|\PHPUnit_Framework_MockObject_MockObject $classLoaderMock */
94 $classLoaderMock = $this->createMock(ClassLoader::class);
95 $generator = new ClassLoadingInformationGenerator($classLoaderMock, [], __DIR__);
96 $this->assertEquals($expectedClassMap, $generator->buildClassAliasMapForPackage($packageMock));
97 }
98
99 /**
100 * @test
101 */
102 public function buildClassAliasMapForPackageReturnsClassAliasMapForComposerManifestInformation()
103 {
104 $expectedClassMap = [
105 'aliasToClassNameMapping' => [
106 'foo' => Fixtures\test_extension\Resources\PHP\Test::class,
107 'bar' => Fixtures\test_extension\Resources\PHP\AnotherTestFile::class,
108 ],
109 'classNameToAliasMapping' => [
110 Fixtures\test_extension\Resources\PHP\Test::class => [
111 'foo' => 'foo',
112 ],
113 Fixtures\test_extension\Resources\PHP\AnotherTestFile::class => [
114 'bar' => 'bar',
115 ]
116 ],
117 ];
118 $packageMock = $this->createPackageMock([
119 'extra' => [
120 'typo3/class-alias-loader' => [
121 'class-alias-maps' => [
122 'Resources/PHP/ClassAliasMap.php',
123 ],
124 ],
125 ],
126 ]);
127 /** @var ClassLoader|\PHPUnit_Framework_MockObject_MockObject $classLoaderMock */
128 $classLoaderMock = $this->createMock(ClassLoader::class);
129 $generator = new ClassLoadingInformationGenerator($classLoaderMock, [], __DIR__);
130 $this->assertEquals($expectedClassMap, $generator->buildClassAliasMapForPackage($packageMock));
131 }
132
133 /**
134 * Data provider for different autoload information
135 *
136 * @return array
137 */
138 public function autoloadFilesAreBuildCorrectlyDataProvider()
139 {
140 return [
141 'Psr-4 section' => [
142 [
143 'autoload' => [
144 'psr-4' => [
145 'TYPO3\\CMS\\TestExtension\\' => 'Classes/',
146 ],
147 ],
148 ],
149 [
150 '\'TYPO3\\\\CMS\\\\TestExtension\\\\\' => array($typo3InstallDir . \'/Fixtures/test_extension/Classes\')',
151 ],
152 [],
153 ],
154 'Psr-4 section with array' => [
155 [
156 'autoload' => [
157 'psr-4' => [
158 'TYPO3\\CMS\\TestExtension\\' => ['Classes/', 'Resources/PHP/'],
159 ],
160 ],
161 ],
162 [
163 '\'TYPO3\\\\CMS\\\\TestExtension\\\\\' => array($typo3InstallDir . \'/Fixtures/test_extension/Classes\',$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP\')',
164 ],
165 [],
166 ],
167 'Psr-4 section without trailing slash' => [
168 [
169 'autoload' => [
170 'psr-4' => [
171 'TYPO3\\CMS\\TestExtension\\' => 'Classes',
172 ],
173 ],
174 ],
175 [
176 '\'TYPO3\\\\CMS\\\\TestExtension\\\\\' => array($typo3InstallDir . \'/Fixtures/test_extension/Classes\')',
177 ],
178 [],
179 ],
180 'Classmap section' => [
181 [
182 'autoload' => [
183 'classmap' => [
184 'Resources/PHP/',
185 ],
186 ],
187 ],
188 [],
189 [
190 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Test.php\'',
191 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/AnotherTestFile.php\'',
192 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Subdirectory/SubdirectoryTest.php\'',
193 ],
194 ],
195 'Classmap section without trailing slash' => [
196 [
197 'autoload' => [
198 'classmap' => [
199 'Resources/PHP',
200 ],
201 ],
202 ],
203 [],
204 [
205 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Test.php\'',
206 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/AnotherTestFile.php\'',
207 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Subdirectory/SubdirectoryTest.php\'',
208 ],
209 ],
210 'Classmap section pointing to a file' => [
211 [
212 'autoload' => [
213 'classmap' => [
214 'Resources/PHP/Test.php',
215 ],
216 ],
217 ],
218 [],
219 [
220 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Test.php\'',
221 '!$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/AnotherTestFile.php\'',
222 '!$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Subdirectory/SubdirectoryTest.php\'',
223 ],
224 ],
225 'No autoload section' => [
226 [],
227 [],
228 [
229 '!$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Test.php\'',
230 '!$typo3InstallDir . \'/Fixtures/test_extension/Tests/TestClass.php\'',
231 '!$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/AnotherTestFile.php\'',
232 '!$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Subdirectory/SubdirectoryTest.php\'',
233 '!$typo3InstallDir . \'/Fixtures/test_extension/class.ext_update.php\'',
234 ],
235 ],
236 'Classmap section pointing to two files' => [
237 [
238 'autoload' => [
239 'classmap' => [
240 'Resources/PHP/Test.php',
241 'Resources/PHP/AnotherTestFile.php',
242 ],
243 ],
244 ],
245 [],
246 [
247 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Test.php\'',
248 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/AnotherTestFile.php\'',
249 '!$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Subdirectory/SubdirectoryTest.php\'',
250 ],
251 ],
252 ];
253 }
254
255 /**
256 * @test
257 * @dataProvider autoloadFilesAreBuildCorrectlyDataProvider
258 *
259 * @param string $packageManifest
260 * @param array $expectedPsr4Files
261 * @param array $expectedClassMapFiles
262 */
263 public function autoloadFilesAreBuildCorrectly($packageManifest, $expectedPsr4Files, $expectedClassMapFiles)
264 {
265 /** @var ClassLoader|\PHPUnit_Framework_MockObject_MockObject $classLoaderMock */
266 $classLoaderMock = $this->createMock(ClassLoader::class);
267 $generator = new ClassLoadingInformationGenerator($classLoaderMock, [$this->createPackageMock($packageManifest)], __DIR__);
268 $files = $generator->buildAutoloadInformationFiles();
269
270 $this->assertArrayHasKey('psr-4File', $files);
271 $this->assertArrayHasKey('classMapFile', $files);
272 foreach ($expectedPsr4Files as $expectation) {
273 if ($expectation[0] === '!') {
274 $expectedCount = 0;
275 $expectation = substr($expectation, 1);
276 $message = sprintf('File "%s" is NOT expected to be in psr-4, but is.', $expectation);
277 } else {
278 $expectedCount = 1;
279 $message = sprintf('File "%s" is expected to be in psr-4, but is not.', $expectation);
280 }
281 $this->assertSame($expectedCount, substr_count($files['psr-4File'], $expectation), $message);
282 }
283 foreach ($expectedClassMapFiles as $expectation) {
284 if ($expectation[0] === '!') {
285 $expectedCount = 0;
286 $expectation = substr($expectation, 1);
287 $message = sprintf('File "%s" is NOT expected to be in class map, but is.', $expectation);
288 } else {
289 $expectedCount = 1;
290 $message = sprintf('File "%s" is expected to be in class map, but is not.', $expectation);
291 }
292 $this->assertSame($expectedCount, substr_count($files['classMapFile'], $expectation), $message);
293 }
294 }
295
296 /**
297 * Data provider for different autoload information
298 *
299 * @return array
300 */
301 public function autoloadDevFilesAreBuildCorrectlyDataProvider()
302 {
303 return [
304 'Psr-4 sections' => [
305 [
306 'autoload' => [
307 'psr-4' => [
308 'TYPO3\\CMS\\TestExtension\\' => 'Classes',
309 ],
310 ],
311 'autoload-dev' => [
312 'psr-4' => [
313 'TYPO3\\CMS\\TestExtension\\Tests\\' => 'Tests',
314 ],
315 ],
316 ],
317 [
318 '\'TYPO3\\\\CMS\\\\TestExtension\\\\\' => array($typo3InstallDir . \'/Fixtures/test_extension/Classes\')',
319 '\'TYPO3\\\\CMS\\\\TestExtension\\\\Tests\\\\\' => array($typo3InstallDir . \'/Fixtures/test_extension/Tests\')',
320 ],
321 [],
322 ],
323 'Psr-4 sections with override' => [
324 [
325 'autoload' => [
326 'psr-4' => [
327 'TYPO3\\CMS\\TestExtension\\' => 'Classes',
328 ],
329 ],
330 'autoload-dev' => [
331 'psr-4' => [
332 'TYPO3\\CMS\\TestExtension\\' => 'Tests',
333 ],
334 ],
335 ],
336 [
337 '!\'TYPO3\\\\CMS\\\\TestExtension\\\\\' => array($typo3InstallDir . \'/Fixtures/test_extension/Classes\')',
338 '\'TYPO3\\\\CMS\\\\TestExtension\\\\\' => array($typo3InstallDir . \'/Fixtures/test_extension/Tests\')',
339 ],
340 [],
341 ],
342 'Classmap section pointing to two files, one in dev and one not' => [
343 [
344 'autoload' => [
345 'classmap' => [
346 'Resources/PHP/Test.php',
347 ],
348 ],
349 'autoload-dev' => [
350 'classmap' => [
351 'Resources/PHP/AnotherTestFile.php',
352 ],
353 ],
354 ],
355 [],
356 [
357 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Test.php\'',
358 '$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/AnotherTestFile.php\'',
359 '!$typo3InstallDir . \'/Fixtures/test_extension/Resources/PHP/Subdirectory/SubdirectoryTest.php\'',
360 ],
361 ],
362 ];
363 }
364
365 /**
366 * @test
367 * @dataProvider autoloadDevFilesAreBuildCorrectlyDataProvider
368 *
369 * @param array $packageManifest
370 * @param array $expectedPsr4Files
371 * @param array $expectedClassMapFiles
372 */
373 public function autoloadDevFilesAreBuildCorrectly($packageManifest, $expectedPsr4Files, $expectedClassMapFiles)
374 {
375 /** @var ClassLoader|\PHPUnit_Framework_MockObject_MockObject $classLoaderMock */
376 $classLoaderMock = $this->createMock(ClassLoader::class);
377 $generator = new ClassLoadingInformationGenerator($classLoaderMock, [$this->createPackageMock($packageManifest)], __DIR__, true);
378 $files = $generator->buildAutoloadInformationFiles();
379
380 $this->assertArrayHasKey('psr-4File', $files);
381 $this->assertArrayHasKey('classMapFile', $files);
382 foreach ($expectedPsr4Files as $expectation) {
383 if ($expectation[0] === '!') {
384 $expectedCount = 0;
385 } else {
386 $expectedCount = 1;
387 }
388 $this->assertSame($expectedCount, substr_count($files['psr-4File'], $expectation), '' . $expectation);
389 }
390 foreach ($expectedClassMapFiles as $expectation) {
391 if ($expectation[0] === '!') {
392 $expectedCount = 0;
393 } else {
394 $expectedCount = 1;
395 }
396 $this->assertSame($expectedCount, substr_count($files['classMapFile'], $expectation), '' . $expectation);
397 }
398 }
399
400 /**
401 * @param array Array which should be returned as composer manifest
402 * @return PackageInterface
403 */
404 protected function createPackageMock($packageManifest)
405 {
406 $packageMock = $this->createMock(PackageInterface::class);
407 $packageMock->expects($this->any())->method('getPackagePath')->willReturn(__DIR__ . '/Fixtures/test_extension/');
408 $packageMock->expects($this->any())->method('getValueFromComposerManifest')->willReturn(
409 json_decode(json_encode($packageManifest))
410 );
411
412 return $packageMock;
413 }
414 }