[BUGFIX] Fatal errors for interfaces with PHP version < 5.3.7
[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 * Copyright notice
6 *
7 * (c) 2011 Andreas Wolf <andreas.wolf@ikt-werk.de>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26
27 /**
28 * Testcase for TYPO3\CMS\Core\Core\ClassLoader
29 *
30 * @package TYPO3
31 * @subpackage t3lib
32 * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
33 */
34 class ClassLoaderTest extends \Tx_Phpunit_TestCase {
35
36 /**
37 * @var boolean Enable backup of global and system variables
38 */
39 protected $backupGlobals = TRUE;
40
41 /**
42 * Exclude TYPO3_DB from backup/ restore of $GLOBALS
43 * because resource types cannot be handled during serializing
44 *
45 * @var array
46 */
47 protected $backupGlobalsBlacklist = array('TYPO3_DB');
48
49 /**
50 * @var array Backup of typo3CacheManager
51 */
52 protected $typo3CacheManager = NULL;
53
54 /**
55 * @var array Register of temporary extensions in typo3temp
56 */
57 protected $fakedExtensions = array();
58
59 /**
60 * Fix a race condition that t3lib_div is not available
61 * during tearDown if fiddling with the autoloader where
62 * backupGlobals is not set up again yet
63 */
64 public function setUp() {
65 $this->typo3CacheManager = $GLOBALS['typo3CacheManager'];
66 }
67
68 /**
69 * Clean up
70 * Warning: Since phpunit itself is php and we are fiddling with php
71 * autoloader code here, the tests are a bit fragile. This tearDown
72 * method ensures that all main classes are available again during
73 * tear down of a testcase.
74 * This construct will fail if the class under test is changed and
75 * not compatible anymore. Make sure to always run the whole test
76 * suite if fiddling with the autoloader unit tests to ensure that
77 * there is no fatal error thrown in other unit test classes triggered
78 * by errors in this one.
79 */
80 public function tearDown() {
81 $GLOBALS['typo3CacheManager'] = $this->typo3CacheManager;
82 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
83 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
84 foreach ($this->fakedExtensions as $extension) {
85 \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir(PATH_site . 'typo3temp/' . $extension, TRUE);
86 }
87 }
88
89 /**
90 * Creates a fake extension inside typo3temp/. No configuration is created,
91 * just the folder, plus the extension is registered in $TYPO3_LOADED_EXT
92 *
93 * @return string The extension key
94 */
95 protected function createFakeExtension() {
96 $extKey = strtolower(uniqid('testing'));
97 $absExtPath = PATH_site . 'typo3temp/' . $extKey . '/';
98 $relPath = 'typo3temp/' . $extKey . '/';
99 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($absExtPath);
100 $GLOBALS['TYPO3_LOADED_EXT'][$extKey] = array(
101 'siteRelPath' => $relPath
102 );
103 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extListArray'][] = $extKey;
104 $this->fakedExtensions[] = $extKey;
105 \TYPO3\CMS\Core\Extension\ExtensionManager::clearExtensionKeyMap();
106 return $extKey;
107 }
108
109 /**
110 * @test
111 */
112 public function unregisterAndRegisterAgainDoesNotFatal() {
113 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
114 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
115 // If this fatals the autoload re registering went wrong
116 \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\TimeTracker\\NullTimeTracker');
117 }
118
119 /**
120 * @test
121 */
122 public function unregisterAutoloaderSetsCacheEntryWithT3libNoTags() {
123 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
124 // Expect the mock cache set method to be called
125 // once with t3lib_autoloader as third parameter
126 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), array());
127 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
128 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
129 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
130 }
131
132 /**
133 * @test
134 * @expectedException \RuntimeException
135 */
136 public function autoloadFindsClassFileDefinedInExtAutoloadFile() {
137 $extKey = $this->createFakeExtension();
138 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
139 $autoloaderFile = $extPath . 'ext_autoload.php';
140 $class = strtolower("tx_{$extKey}_" . uniqid(''));
141 $file = $extPath . uniqid('') . '.php';
142 file_put_contents($file, '<?php' . LF . 'throw new \\RuntimeException(\'\', 1310203812);' . LF . '?>');
143 file_put_contents($autoloaderFile, '<?php' . LF . 'return array(\'' . $class . '\' => \'' . $file . '\');' . LF . '?>');
144 // Inject a dummy for the core_phpcode cache to force the autoloader
145 // to re calculate the registry
146 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
147 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
148 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
149 // Re-initialize autoloader registry to force it to recognize the new extension
150 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
151 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
152 // Expect the exception of the file to be thrown
153 \TYPO3\CMS\Core\Core\ClassLoader::autoload($class);
154 }
155
156 /**
157 * @test
158 */
159 public function unregisterAutoloaderWritesLowerCasedClassFileToCache() {
160 $extKey = $this->createFakeExtension();
161 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
162 $autoloaderFile = $extPath . 'ext_autoload.php';
163 // A case sensitive key (FooBar) in ext_autoload file
164 $class = "tx_{$extKey}_" . uniqid('FooBar');
165 $file = $extPath . uniqid('') . '.php';
166 file_put_contents($autoloaderFile, '<?php' . LF . 'return array(\'' . $class . '\' => \'' . $file . '\');' . LF . '?>');
167 // Inject a dummy for the core_phpcode cache to force the autoloader
168 // to re calculate the registry
169 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
170 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
171 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
172 // Expect that the lower case version of the class name is written to cache
173 $mockCache->expects($this->at(2))->method('set')->with($this->anything(), $this->stringContains(strtolower($class), FALSE));
174 // Re-initialize autoloader registry to force it to recognize the new extension
175 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
176 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
177 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
178 }
179
180 /**
181 * @test
182 * @expectedException \RuntimeException
183 */
184 public function autoloadFindsClassFileIfExtAutoloadEntryIsCamelCased() {
185 $extKey = $this->createFakeExtension();
186 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
187 // A case sensitive key (FooBar) in ext_autoload file
188 $class = "tx_{$extKey}_" . uniqid('FooBar');
189 $file = $extPath . uniqid('') . '.php';
190 file_put_contents($file, '<?php' . LF . 'throw new \\RuntimeException(\'\', 1336756850);' . LF . '?>');
191 $extAutoloadFile = $extPath . 'ext_autoload.php';
192 file_put_contents($extAutoloadFile, '<?php' . LF . 'return array(\'' . $class . '\' => \'' . $file . '\');' . LF . '?>');
193 // Inject cache and return false, so autoloader is forced to read ext_autoloads from extensions
194 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
195 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
196 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
197 $mockCache->expects($this->any())->method('has')->will($this->returnValue(FALSE));
198 // Re-initialize autoloader registry to force it to recognize the new extension
199 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
200 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
201 \TYPO3\CMS\Core\Core\ClassLoader::autoload($class);
202 }
203
204 /**
205 * @test
206 * @expectedException \RuntimeException
207 */
208 public function autoloadFindsCamelCasedClassFileIfExtAutoloadEntryIsReadLowerCasedFromCache() {
209 $extKey = $this->createFakeExtension();
210 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
211 // A case sensitive key (FooBar) in ext_autoload file
212 $class = "tx_{$extKey}_" . uniqid('FooBar');
213 $file = $extPath . uniqid('') . '.php';
214 file_put_contents($file, '<?php' . LF . 'throw new \RuntimeException(\'\', 1336756850);' . LF . '?>');
215 // Inject cache mock and let the cache entry return the lowercased class name as key
216 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
217 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
218 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
219 $mockCache->expects($this->any())->method('has')->will($this->returnValue(TRUE));
220 $mockCache->expects($this->once())->method('requireOnce')->will($this->returnValue(array(strtolower($class) => $file)));
221 // Re-initialize autoloader registry to force it to recognize the new extension
222 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
223 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
224 \TYPO3\CMS\Core\Core\ClassLoader::autoload($class);
225 }
226
227 /**
228 * @test
229 * @expectedException \RuntimeException
230 */
231 public function autoloadFindsClassFileThatRespectsExtbaseNamingSchemeWithoutExtAutoloadFile() {
232 $extKey = $this->createFakeExtension();
233 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
234 // Create a class named Tx_Extension_Foo123_Bar456
235 // to find file extension/Classes/Foo123/Bar456.php
236 $pathSegment = 'Foo' . uniqid();
237 $fileName = 'Bar' . uniqid();
238 $class = 'Tx_' . ucfirst($extKey) . '_' . $pathSegment . '_' . $fileName;
239
240 $file = $extPath . 'Classes/' . $pathSegment . '/' . $fileName . '.php';
241 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep($extPath . 'Classes/' . $pathSegment);
242 file_put_contents($file, '<?php' . LF . 'throw new \\RuntimeException(\'\', 1310203813);' . LF . '?>');
243 // Inject a dummy for the core_phpcode cache to cache
244 // the calculated cache entry to a dummy cache
245 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
246 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
247 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
248 // Expect the exception of the file to be thrown
249 \TYPO3\CMS\Core\Core\ClassLoader::autoload($class);
250 }
251
252 /**
253 * @test
254 */
255 public function unregisterAutoloaderWritesClassFileThatRespectsExtbaseNamingSchemeToCacheFile() {
256 $extKey = $this->createFakeExtension();
257 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
258 $pathSegment = 'Foo' . uniqid();
259 $fileName = 'Bar' . uniqid();
260 $class = 'Tx_' . $extKey . '_' . $pathSegment . '_' . $fileName;
261 $file = $extPath . 'Classes/' . $pathSegment . '/' . $fileName . '.php';
262 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep($extPath . 'Classes/' . $pathSegment);
263 file_put_contents($file, '<?php' . LF . '$foo = \'bar\';' . LF . '?>');
264 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
265 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
266 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
267 // Expect that an entry to the cache is written containing the newly found class
268 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains(strtolower($class), $this->anything()));
269 \TYPO3\CMS\Core\Core\ClassLoader::autoload($class);
270 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
271 }
272
273 /**
274 * @test
275 */
276 public function unregisterAutoloaderWritesClassFileLocationOfClassRespectingExtbaseNamingSchemeToCacheFile() {
277 $extKey = $this->createFakeExtension();
278 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
279 $pathSegment = 'Foo' . uniqid();
280 $fileName = 'Bar' . uniqid();
281 $class = 'Tx_' . $extKey . '_' . $pathSegment . '_' . $fileName;
282 $file = $extPath . 'Classes/' . $pathSegment . '/' . $fileName . '.php';
283 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep($extPath . 'Classes/' . $pathSegment);
284 file_put_contents($file, '<?php' . LF . '$foo = \'bar\';' . LF . '?>');
285 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
286 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
287 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
288 // Expect that an entry to the cache is written containing the newly found class
289 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains(strtolower($file), $this->anything()));
290 \TYPO3\CMS\Core\Core\ClassLoader::autoload($class);
291 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
292 }
293
294 /**
295 * @test
296 */
297 public function getClassPathByRegistryLookupFindsClassPrefixedWithUxRegisteredInExtAutoloadFile() {
298 // Create a dummy extension with a path to a 'ux_' prefixed php file
299 $extKey = $this->createFakeExtension();
300 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
301 $autoloaderFile = $extPath . 'ext_autoload.php';
302 $class = strtolower("ux_tx_{$extKey}_" . uniqid(''));
303 $file = $extPath . uniqid('') . '.php';
304 file_put_contents($autoloaderFile, '<?php' . LF . 'return array(\'' . $class . '\' => \'' . $file . '\');' . LF . '?>');
305 // Inject a dummy for the core_phpcode cache to force the autoloader
306 // to re calculate the registry
307 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
308 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
309 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
310 // Re-initialize autoloader registry to force it to recognize the new extension with the ux_ autoload definition
311 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
312 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
313 $this->assertSame($file, \TYPO3\CMS\Core\Core\ClassLoader::getClassPathByRegistryLookup($class));
314 }
315
316 /**
317 * @test
318 */
319 public function unregisterAutoloaderWritesNotExistingUxCLassLookupFromGetClassPathByRegistryLookupToCache() {
320 $uxClassName = 'ux_Tx_Foo' . uniqid();
321 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
322 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
323 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
324 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
325 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
326 // Class is not found by returning NULL
327 $this->assertSame(NULL, \TYPO3\CMS\Core\Core\ClassLoader::getClassPathByRegistryLookup($uxClassName));
328 // Expect NULL lookup is cached
329 $expectedCacheString = '\'' . strtolower($uxClassName) . '\' => NULL,';
330 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($expectedCacheString));
331 // Trigger writing new cache file
332 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
333 }
334
335 /**
336 * @test
337 */
338 public function unregisterAutoloaderWritesDeprecatedTypo3ConfVarsRegisteredXclassClassFoundByGetClassPathByRegistryLookupToCache() {
339 // Create a fake extension
340 $extKey = $this->createFakeExtension();
341 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
342 $autoloaderFile = $extPath . 'ext_autoload.php';
343 // Feed ext_autoload with a base file and the class file
344 $class = strtolower("tx_{$extKey}_" . uniqid(''));
345 $fileName = uniqid('') . '.php';
346 $file = $extPath . $fileName;
347 $xClassFile = 'typo3temp/' . $extKey . '/xclassFile';
348 file_put_contents($autoloaderFile, '<?php' . LF . 'return array(\'' . $class . '\' => \'' . $file . '\');' . LF . '?>');
349 file_put_contents(PATH_site . $xClassFile, '<?php' . LF . 'die();' . LF . '?>');
350 // Register a xclass for the base file
351 $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3temp/' . $extKey . '/' . $fileName] = $xClassFile;
352 // Inject a dummy for the core_phpcode cache to force the autoloader
353 // to re calculate the registry
354 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
355 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
356 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
357 // Excpect the cache entry to be called once with the new class name
358 $mockCache->expects($this->at(2))->method('set')->with($this->anything(), $this->stringContains('ux_' . $class));
359 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
360 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
361 \TYPO3\CMS\Core\Core\ClassLoader::getClassPathByRegistryLookup('ux_' . $class);
362 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
363 }
364
365 /**
366 * @test
367 * @expectedException \RuntimeException
368 */
369 public function autoloadFindsClassFileThatRespectsExtbaseNamingSchemeWithNamespace() {
370 $extKey = $this->createFakeExtension();
371 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
372 // Create a class named \Tx\Extension\Foo123\Bar456
373 // to find file extension/Classes/Foo123/Bar456.php
374 $pathSegment = 'Foo' . uniqid();
375 $fileName = 'Bar' . uniqid();
376 $namespacedClass = '\\Vendor\\' . ucfirst($extKey) . '\\' . $pathSegment . '\\' . $fileName;
377 $file = $extPath . 'Classes/' . $pathSegment . '/' . $fileName . '.php';
378 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep($extPath . 'Classes/' . $pathSegment);
379 file_put_contents($file, '<?php' . LF . 'throw new \\RuntimeException(\'\', 1342800577);' . LF . '?>');
380 // Re-initialize autoloader registry to force it to recognize the new extension
381 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
382 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
383 // Expect the exception of the file to be thrown
384 \TYPO3\CMS\Core\Core\ClassLoader::autoload($namespacedClass);
385 }
386
387 /**
388 * @test
389 */
390 public function unregisterAutoloaderWritesClassFileLocationOfClassRespectingExtbaseNamingSchemeWithNamespaceToCacheFile() {
391 $extKey = $this->createFakeExtension();
392 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
393 $pathSegment = 'Foo' . uniqid();
394 $fileName = 'Bar' . uniqid();
395 $namespacedClass = '\\Tx\\' . $extKey . '\\' . $pathSegment . '\\' . $fileName;
396 $file = $extPath . 'Classes/' . $pathSegment . '/' . $fileName . '.php';
397 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep($extPath . 'Classes/' . $pathSegment);
398 file_put_contents($file, "<?php\n\n\$foo = 'bar';\n\n?>");
399 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
400 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
401 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
402 // Expect that an entry to the cache is written containing the newly found class
403 $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains(strtolower($file), $this->anything()));
404 \TYPO3\CMS\Core\Core\ClassLoader::autoload($namespacedClass);
405 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
406 }
407
408 /**
409 * @test
410 */
411 public function checkClassNamesNotExtbaseSchemePassAutoloaderUntouched() {
412 $class = '\\Symfony\\Foo\\Bar';
413 $this->assertNull(\TYPO3\CMS\Core\Core\ClassLoader::getClassPathByRegistryLookup($class));
414 }
415
416 /**
417 * @test
418 */
419 public function checkAutoloaderSetsNamespacedClassnamesInExtAutoloadAreWrittenToCache() {
420 $extKey = $this->createFakeExtension();
421 $extPath = PATH_site . 'typo3temp/' . $extKey . '/';
422 $pathSegment = 'Foo' . uniqid();
423 $fileName = 'Bar' . uniqid();
424 $autoloaderFile = $extPath . 'ext_autoload.php';
425 // A case sensitive key (FooBar) in ext_autoload file
426 $namespacedClass = '\\Tx\\' . $extKey . '\\' . $pathSegment . '\\' . $fileName;
427 file_put_contents($autoloaderFile, '<?php' . LF . 'return array(\'' . $namespacedClass . '\' => \'EXT:someExt/Classes/Foo/bar.php\');' . LF . '?>');
428 // Inject a dummy for the core_phpcode cache to force the autoloader
429 // to re calculate the registry
430 $mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'), array(), '', FALSE);
431 $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array('getCache'));
432 $GLOBALS['typo3CacheManager']->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
433 // Expect that the lower case version of the class name is written to cache
434 $mockCache->expects($this->at(2))->method('set')->with($this->anything(), $this->stringContains(strtolower($namespacedClass), FALSE));
435 // Re-initialize autoloader registry to force it to recognize the new extension
436 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
437 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
438 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
439 }
440
441 }
442
443 ?>