AutoLoaderTest: Add support for class aliases
authorKevin Israel <pleasestand@live.com>
Thu, 23 Jan 2014 20:49:39 +0000 (15:49 -0500)
committerKevin Israel <pleasestand@live.com>
Thu, 23 Jan 2014 21:31:42 +0000 (16:31 -0500)
* Changed the regex to match class aliases, and added a check to
  also ensure that all aliases for a class are in the same file as
  the class (see cb77e59f7c99 for explanation).
* Removed support for the seemingly unmaintained Parsekit extension
  (no release since 2009, and known not to compile against PHP 5.4).
  The test would currently fail if Parsekit were used anyway because
  the class MyLocalSettingsGenerator is commented out.

Change-Id: I7be2352f4659abc7b4952a9f74a14d0cef911614

tests/phpunit/structure/AutoLoaderTest.php

index d8b90d5..be18a49 100644 (file)
@@ -38,7 +38,6 @@ class AutoLoaderTest extends MediaWikiTestCase {
 
        protected static function checkAutoLoadConf() {
                global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP;
-               $supportsParsekit = function_exists( 'parsekit_compile_file' );
 
                // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php
                $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses;
@@ -54,17 +53,44 @@ class AutoLoaderTest extends MediaWikiTestCase {
                        } else {
                                $filePath = $file;
                        }
-                       if ( $supportsParsekit ) {
-                               $parseInfo = parsekit_compile_file( "$filePath" );
-                               $classes = array_keys( $parseInfo['class_table'] );
-                       } else {
-                               $contents = file_get_contents( "$filePath" );
-                               $m = array();
-                               preg_match_all( '/\n\s*(?:final)?\s*(?:abstract)?\s*(?:class|interface)\s+([a-zA-Z0-9_]+)/', $contents, $m, PREG_PATTERN_ORDER );
-                               $classes = $m[1];
+
+                       $contents = file_get_contents( $filePath );
+
+                       // We could use token_get_all() here, but this is faster
+                       $matches = array();
+                       preg_match_all( '/
+                               ^ [\t ]* (?:
+                                       (?:final\s+)? (?:abstract\s+)? (?:class|interface) \s+
+                                       (?P<class> [a-zA-Z0-9_]+)
+                               |
+                                       class_alias \s* \( \s*
+                                               ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
+                                               ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
+                                       \) \s* ;
+                               )
+                       /imx', $contents, $matches, PREG_SET_ORDER );
+
+                       $classesInFile = array();
+                       $aliasesInFile = array();
+
+                       foreach ( $matches as $match ) {
+                               if ( !empty( $match['class'] ) ) {
+                                       $actual[$match['class']] = $file;
+                                       $classesInFile[$match['class']] = true;
+                               } else {
+                                       $aliasesInFile[$match['alias']] = $match['original'];
+                               }
                        }
-                       foreach ( $classes as $class ) {
-                               $actual[$class] = $file;
+
+                       // Only accept aliases for classes in the same file, because for correct
+                       // behavior, all aliases for a class must be set up when the class is loaded
+                       // (see <https://bugs.php.net/bug.php?id=61422>).
+                       foreach ( $aliasesInFile as $alias => $class ) {
+                               if ( isset( $classesInFile[$class] ) ) {
+                                       $actual[$alias] = $file;
+                               } else {
+                                       $actual[$alias] = "[original class not in $file]";
+                               }
                        }
                }