25 yield [ $prefix, $dir,
$file ];
31 return (
new File_Iterator_Facade() )->getFilesAsArray( $dir, [
'.php' ] );
39 $contents = file_get_contents(
$file );
41 $classes = array_keys( $classesInFile );
46 "Only one class per file in PSR-4 autoloaded classes ($file)"
52 $abbrFileName = substr( substr(
$file, strlen( $dir ) ), 0, -4 );
53 $expectedClassName = $prefix . str_replace(
'/',
'\\', $abbrFileName );
58 "Class not autoloaded properly"
64 $this->assertCount( 0, $classes );
67 if ( $aliasesInFile ) {
69 foreach ( $aliasesInFile
as $alias => $class ) {
70 $this->assertArrayHasKey( $alias, $otherClasses,
71 'Alias must be in the classmap autoloader'
83 (?:final\s+)? (?:abstract\s+)? (?:class|interface|trait) \s+
86 class_alias \s* \( \s*
87 ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
88 ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
91 class_alias \s* \( \s*
92 (?P<originalStatic> [\w\\\\]+)::class \s* , \s*
93 ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
96 /imx', $contents,
$matches, PREG_SET_ORDER );
104 /imx', $contents, $namespaceMatch );
105 $fileNamespace = $namespaceMatch ? $namespaceMatch[1] .
'\\' :
'';
111 if ( !empty( $match[
'class'] ) ) {
113 $class = $fileNamespace . $match[
'class'];
114 $classesInFile[$class] =
true;
115 } elseif ( !empty( $match[
'original'] ) ) {
117 $aliasesInFile[$match[
'alias']] = $match[
'original'];
120 $aliasesInFile[$match[
'aliasString']] = $fileNamespace . $match[
'originalStatic'];
124 return [ $classesInFile, $aliasesInFile ];
134 $psr4Namespaces = [];
136 $psr4Namespaces[rtrim( $ns,
'\\' ) .
'\\'] = rtrim(
$path,
'/' );
139 foreach ( $expected
as $class =>
$file ) {
142 if ( substr(
$file, 0, 1 ) !=
'/' && substr(
$file, 1, 1 ) !=
':' ) {
143 $filePath =
"$IP/$file";
148 if ( !file_exists( $filePath ) ) {
149 $actual[$class] =
"[file '$filePath' does not exist]";
153 Wikimedia\suppressWarnings();
154 $contents = file_get_contents( $filePath );
155 Wikimedia\restoreWarnings();
157 if ( $contents ===
false ) {
158 $actual[$class] =
"[couldn't read file '$filePath']";
164 foreach ( $classesInFile
as $className => $ignore ) {
166 $parts = explode(
'\\', $className );
167 for ( $i =
count( $parts ) - 1; $i > 0; $i-- ) {
168 $ns = implode(
'\\', array_slice( $parts, 0, $i ) ) .
'\\';
169 if ( isset( $psr4Namespaces[$ns] ) ) {
170 $expectedPath = $psr4Namespaces[$ns] .
'/'
171 . implode(
'/', array_slice( $parts, $i ) )
173 if ( $filePath === $expectedPath ) {
180 $actual[$className] =
$file;
186 foreach ( $aliasesInFile
as $alias => $class ) {
187 if ( isset( $classesInFile[$class] ) ) {
188 $actual[$alias] =
$file;
190 $actual[$alias] =
"[original class not in $file]";
196 'expected' => $expected,
202 $path = realpath( __DIR__ .
'/../../..' );
203 $oldAutoload = file_get_contents(
$path .
'/autoload.php' );
207 $newAutoload =
$generator->getAutoload(
'maintenance/generateLocalAutoload.php' );
209 $this->assertEquals( $oldAutoload, $newAutoload,
'autoload.php does not match' .
210 ' output of generateLocalAutoload.php script.' );