[TASK] Re-work/simplify copyright header in PHP files - Part 4
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Core / ClassLoaderTest.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 org\bovigo\vfs\vfsStream;
18
19 /**
20 * Testcase for TYPO3\CMS\Core\Core\ClassLoader
21 *
22 * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
23 */
24 class ClassLoaderTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
25
26 /**
27 * @var array Backup of typo3CacheManager
28 */
29 protected $typo3CacheManager = NULL;
30
31 /**
32 * @var array Register of temporary extensions in typo3temp
33 */
34 protected $fakedExtensions = array();
35
36 /**
37 * @var \TYPO3\CMS\Core\Core\ClassLoader
38 */
39 protected $classLoader;
40
41 /**
42 * @var \TYPO3\CMS\Core\Core\ClassAliasMap
43 */
44 protected $orinalClassAliasMap;
45
46 /**
47 * Test flag used in in this test case
48 *
49 * @var boolean
50 */
51 public static $testClassWasLoaded = FALSE;
52
53 /**
54 * Fix a race condition that GeneralUtility is not available
55 * during tearDown if fiddling with the autoloader where
56 * backupGlobals is not set up again yet
57 */
58 public function setUp() {
59 vfsStream::setup('Test');
60
61 mkdir('vfs://Test/Packages/Application/Acme.MyApp/Classes/', 0770, TRUE);
62 file_put_contents('vfs://Test/Packages/Application/Acme.MyApp/composer.json', '{"name": "acme/myapp", "type": "flow-test"}');
63 $package1 = new \TYPO3\Flow\Package\Package($this->getMock('TYPO3\Flow\Package\PackageManager'), 'Acme.MyApp', 'vfs://Test/Packages/Application/Acme.MyApp/', 'Classes');
64
65 mkdir('vfs://Test/Packages/Application/Acme.MyAppAddon/Classes/', 0770, TRUE);
66 file_put_contents('vfs://Test/Packages/Application/Acme.MyAppAddon/composer.json', '{"name": "acme/myappaddon", "type": "flow-test"}');
67 $package2 = new \TYPO3\Flow\Package\Package($this->getMock('TYPO3\Flow\Package\PackageManager'), 'Acme.MyAppAddon', 'vfs://Test/Packages/Application/Acme.MyAppAddon/', 'Classes');
68
69 $mockClassAliasMap = $this->getMock('TYPO3\\CMS\\Core\\Core\\ClassAliasMap', array('setPackagesButDontBuildMappingFilesReturnClassNameToAliasMappingInstead', 'buildMappingFiles'), array(), '', FALSE);
70 $mockClassAliasMap->expects($this->any())->method('setPackagesButDontBuildMappingFilesReturnClassNameToAliasMappingInstead')->will($this->returnValue(array()));
71
72 $this->orinalClassAliasMap = \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->getEarlyInstance('TYPO3\\CMS\\Core\\Core\\ClassAliasMap');
73 $this->classLoader = new \TYPO3\CMS\Core\Core\ClassLoader(\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->getApplicationContext());
74 $this->classLoader->injectClassAliasMap($mockClassAliasMap);
75 $this->classLoader->setPackages(array('Acme.MyApp' => $package1, 'Acme.MyAppAddon' => $package2));
76 }
77
78 /**
79 * The class alias map is kept static in the class loader for legacy reasons
80 * and has to be reset after mocking.
81 */
82 public function tearDown() {
83 $this->classLoader->injectClassAliasMap($this->orinalClassAliasMap);
84 parent::tearDown();
85 }
86
87 /**
88 * Creates a fake extension inside typo3temp/. No configuration is created,
89 * just the folder, plus the extension is registered in $TYPO3_LOADED_EXT
90 *
91 * @return string The extension key
92 */
93 protected function createFakeExtension() {
94 $extKey = strtolower(uniqid('testing'));
95 $absExtPath = PATH_site . 'typo3temp/' . $extKey . '/';
96 $relPath = 'typo3temp/' . $extKey . '/';
97 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($absExtPath);
98 $GLOBALS['TYPO3_LOADED_EXT'][$extKey] = array(
99 'siteRelPath' => $relPath
100 );
101 $this->fakedExtensions[] = $extKey;
102 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::clearExtensionKeyMap();
103 return $extKey;
104 }
105
106 /**
107 * Checks if the package autoloader loads classes from subdirectories.
108 *
109 * @test
110 */
111 public function classesFromSubDirectoriesAreLoaded() {
112 mkdir('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp/SubDirectory', 0770, TRUE);
113 file_put_contents('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp/SubDirectory/ClassInSubDirectory.php', '<?php ' . __CLASS__ . '::$testClassWasLoaded = TRUE; ?>');
114
115 self::$testClassWasLoaded = FALSE;
116 $this->classLoader->loadClass('Acme\MyApp\SubDirectory\ClassInSubDirectory');
117 $this->assertTrue(self::$testClassWasLoaded);
118 }
119
120 /**
121 * @test
122 */
123 public function classesFromDeeplyNestedSubDirectoriesAreLoaded() {
124 mkdir('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp/SubDirectory/A/B/C/D', 0770, TRUE);
125 file_put_contents('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp/SubDirectory/A/B/C/D/E.php', '<?php ' . __CLASS__ . '::$testClassWasLoaded = TRUE; ?>');
126
127 self::$testClassWasLoaded = FALSE;
128 $this->classLoader->loadClass('Acme\MyApp\SubDirectory\A\B\C\D\E');
129 $this->assertTrue(self::$testClassWasLoaded);
130 }
131
132 /**
133 * Checks if the package autoloader loads classes from packages that match a
134 * substring of another package (e.g. TYPO3CR vs TYPO3).
135 *
136 * @test
137 */
138 public function classesFromSubMatchingPackagesAreLoaded() {
139 mkdir('vfs://Test/Packages/Application/Acme.MyAppAddon/Classes/Acme/MyAppAddon', 0770, TRUE);
140 file_put_contents('vfs://Test/Packages/Application/Acme.MyAppAddon/Classes/Acme/MyAppAddon/Class.php', '<?php ' . __CLASS__ . '::$testClassWasLoaded = TRUE; ?>');
141
142 self::$testClassWasLoaded = FALSE;
143 $this->classLoader->loadClass('Acme\MyAppAddon\Class');
144 $this->assertTrue(self::$testClassWasLoaded);
145 }
146
147 /**
148 * Checks if the package autoloader loads classes from subdirectories.
149 *
150 * @test
151 */
152 public function classesWithUnderscoresAreLoaded() {
153 mkdir('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp', 0770, TRUE);
154 file_put_contents('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp/Foo.php', '<?php ' . __CLASS__ . '::$testClassWasLoaded = TRUE; ?>');
155
156 self::$testClassWasLoaded = FALSE;
157 $this->classLoader->loadClass('Acme\MyApp_Foo');
158 $this->assertTrue(self::$testClassWasLoaded);
159 }
160
161 /**
162 * Checks if the package autoloader loads classes from subdirectories with underscores.
163 *
164 * @test
165 */
166 public function namespaceWithUnderscoresAreLoaded() {
167 mkdir('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp/My_Underscore', 0770, TRUE);
168 file_put_contents('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp/My_Underscore/Foo.php', '<?php ' . __CLASS__ . '::$testClassWasLoaded = TRUE; ?>');
169
170 self::$testClassWasLoaded = FALSE;
171 $this->classLoader->loadClass('Acme\MyApp\My_Underscore\Foo');
172 $this->assertTrue(self::$testClassWasLoaded);
173 }
174
175 /**
176 * Checks if the package autoloader loads classes from subdirectories.
177 *
178 * @test
179 */
180 public function classesWithOnlyUnderscoresAreLoaded() {
181 mkdir('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp', 0770, TRUE);
182 file_put_contents('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp/UnderscoredOnly.php', '<?php ' . __CLASS__ . '::$testClassWasLoaded = TRUE; ?>');
183
184 self::$testClassWasLoaded = FALSE;
185 $this->classLoader->loadClass('Acme_MyApp_UnderscoredOnly');
186 $this->assertTrue(self::$testClassWasLoaded);
187 }
188
189 /**
190 * @test
191 */
192 public function classesWithLeadingBackslashAreLoaded() {
193 mkdir('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp', 0770, TRUE);
194 file_put_contents('vfs://Test/Packages/Application/Acme.MyApp/Classes/Acme/MyApp/WithLeadingBackslash.php', '<?php ' . __CLASS__ . '::$testClassWasLoaded = TRUE; ?>');
195
196 self::$testClassWasLoaded = FALSE;
197 $this->classLoader->loadClass('\Acme\MyApp\WithLeadingBackslash');
198 $this->assertTrue(self::$testClassWasLoaded);
199 }
200
201 }