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