MediaWiki
REL1_24
|
00001 <?php 00002 00003 class AutoLoaderTest extends MediaWikiTestCase { 00004 protected function setUp() { 00005 global $wgAutoloadLocalClasses, $wgAutoloadClasses; 00006 00007 parent::setUp(); 00008 00009 // Fancy dance to trigger a rebuild of AutoLoader::$autoloadLocalClassesLower 00010 $this->testLocalClasses = array( 00011 'TestAutoloadedLocalClass' => __DIR__ . '/../data/autoloader/TestAutoloadedLocalClass.php', 00012 'TestAutoloadedCamlClass' => __DIR__ . '/../data/autoloader/TestAutoloadedCamlClass.php', 00013 'TestAutoloadedSerializedClass' => 00014 __DIR__ . '/../data/autoloader/TestAutoloadedSerializedClass.php', 00015 ); 00016 $this->setMwGlobals( 00017 'wgAutoloadLocalClasses', 00018 $this->testLocalClasses + $wgAutoloadLocalClasses 00019 ); 00020 AutoLoader::resetAutoloadLocalClassesLower(); 00021 00022 $this->testExtensionClasses = array( 00023 'TestAutoloadedClass' => __DIR__ . '/../data/autoloader/TestAutoloadedClass.php', 00024 ); 00025 $this->setMwGlobals( 'wgAutoloadClasses', $this->testExtensionClasses + $wgAutoloadClasses ); 00026 } 00027 00034 public function testAutoLoadConfig() { 00035 $results = self::checkAutoLoadConf(); 00036 00037 $this->assertEquals( 00038 $results['expected'], 00039 $results['actual'] 00040 ); 00041 } 00042 00043 protected static function checkAutoLoadConf() { 00044 global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP; 00045 00046 // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php 00047 $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses; 00048 $actual = array(); 00049 00050 $files = array_unique( $expected ); 00051 00052 foreach ( $files as $file ) { 00053 // Only prefix $IP if it doesn't have it already. 00054 // Generally local classes don't have it, and those from extensions and test suites do. 00055 if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) { 00056 $filePath = "$IP/$file"; 00057 } else { 00058 $filePath = $file; 00059 } 00060 00061 $contents = file_get_contents( $filePath ); 00062 00063 // We could use token_get_all() here, but this is faster 00064 $matches = array(); 00065 preg_match_all( '/ 00066 ^ [\t ]* (?: 00067 (?:final\s+)? (?:abstract\s+)? (?:class|interface) \s+ 00068 (?P<class> [a-zA-Z0-9_]+) 00069 | 00070 class_alias \s* \( \s* 00071 ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s* 00072 ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s* 00073 \) \s* ; 00074 ) 00075 /imx', $contents, $matches, PREG_SET_ORDER ); 00076 00077 $namespaceMatch = array(); 00078 preg_match( '/ 00079 ^ [\t ]* 00080 namespace \s+ 00081 ([a-zA-Z0-9_]+(\\\\[a-zA-Z0-9_]+)*) 00082 \s* ; 00083 /imx', $contents, $namespaceMatch ); 00084 $fileNamespace = $namespaceMatch ? $namespaceMatch[1] . '\\' : ''; 00085 00086 $classesInFile = array(); 00087 $aliasesInFile = array(); 00088 00089 foreach ( $matches as $match ) { 00090 if ( !empty( $match['class'] ) ) { 00091 $class = $fileNamespace . $match['class']; 00092 $actual[$class] = $file; 00093 $classesInFile[$class] = true; 00094 } else { 00095 $aliasesInFile[$match['alias']] = $match['original']; 00096 } 00097 } 00098 00099 // Only accept aliases for classes in the same file, because for correct 00100 // behavior, all aliases for a class must be set up when the class is loaded 00101 // (see <https://bugs.php.net/bug.php?id=61422>). 00102 foreach ( $aliasesInFile as $alias => $class ) { 00103 if ( isset( $classesInFile[$class] ) ) { 00104 $actual[$alias] = $file; 00105 } else { 00106 $actual[$alias] = "[original class not in $file]"; 00107 } 00108 } 00109 } 00110 00111 return array( 00112 'expected' => $expected, 00113 'actual' => $actual, 00114 ); 00115 } 00116 00117 function testCoreClass() { 00118 $this->assertTrue( class_exists( 'TestAutoloadedLocalClass' ) ); 00119 } 00120 00121 function testExtensionClass() { 00122 $this->assertTrue( class_exists( 'TestAutoloadedClass' ) ); 00123 } 00124 00125 function testWrongCaseClass() { 00126 $this->assertTrue( class_exists( 'testautoLoadedcamlCLASS' ) ); 00127 } 00128 00129 function testWrongCaseSerializedClass() { 00130 $dummyCereal = 'O:29:"testautoloadedserializedclass":0:{}'; 00131 $uncerealized = unserialize( $dummyCereal ); 00132 $this->assertFalse( $uncerealized instanceof __PHP_Incomplete_Class, 00133 "unserialize() can load classes case-insensitively." ); 00134 } 00135 }