MediaWiki  REL1_24
ResourcesTest.php
Go to the documentation of this file.
00001 <?php
00017 class ResourcesTest extends MediaWikiTestCase {
00018 
00022     public function testFileExistence( $filename, $module, $resource ) {
00023         $this->assertFileExists( $filename,
00024             "File '$resource' referenced by '$module' must exist."
00025         );
00026     }
00027 
00031     public function testStyleMedia( $moduleName, $media, $filename, $css ) {
00032         $cssText = CSSMin::minify( $css->cssText );
00033 
00034         $this->assertTrue(
00035             strpos( $cssText, '@media' ) === false,
00036             'Stylesheets should not both specify "media" and contain @media'
00037         );
00038     }
00039 
00044     public function testIllegalDependencies() {
00045         $data = self::getAllModules();
00046         $illegalDeps = array( 'jquery', 'mediawiki' );
00047 
00049         foreach ( $data['modules'] as $moduleName => $module ) {
00050             foreach ( $illegalDeps as $illegalDep ) {
00051                 $this->assertNotContains(
00052                     $illegalDep,
00053                     $module->getDependencies(),
00054                     "Module '$moduleName' must not depend on '$illegalDep'"
00055                 );
00056             }
00057         }
00058     }
00059 
00063     public function testMissingDependencies() {
00064         $data = self::getAllModules();
00065         $validDeps = array_keys( $data['modules'] );
00066 
00068         foreach ( $data['modules'] as $moduleName => $module ) {
00069             foreach ( $module->getDependencies() as $dep ) {
00070                 $this->assertContains(
00071                     $dep,
00072                     $validDeps,
00073                     "The module '$dep' required by '$moduleName' must exist"
00074                 );
00075             }
00076         }
00077     }
00078 
00086     public function testUnsatisfiableDependencies() {
00087         $data = self::getAllModules();
00088         $validDeps = array_keys( $data['modules'] );
00089 
00091         foreach ( $data['modules'] as $moduleName => $module ) {
00092             $moduleTargets = $module->getTargets();
00093             foreach ( $module->getDependencies() as $dep ) {
00094                 $targets = $data['modules'][$dep]->getTargets();
00095                 foreach ( $moduleTargets as $moduleTarget ) {
00096                     $this->assertContains(
00097                         $moduleTarget,
00098                         $targets,
00099                         "The module '$moduleName' must not have target '$moduleTarget' "
00100                             . "because its dependency '$dep' does not have it"
00101                     );
00102                 }
00103             }
00104         }
00105     }
00106 
00111     protected static function getAllModules() {
00112         global $wgEnableJavaScriptTest;
00113 
00114         // Test existance of test suite files as well
00115         // (can't use setUp or setMwGlobals because providers are static)
00116         $org_wgEnableJavaScriptTest = $wgEnableJavaScriptTest;
00117         $wgEnableJavaScriptTest = true;
00118 
00119         // Initialize ResourceLoader
00120         $rl = new ResourceLoader();
00121 
00122         $modules = array();
00123 
00124         foreach ( $rl->getModuleNames() as $moduleName ) {
00125             $modules[$moduleName] = $rl->getModule( $moduleName );
00126         }
00127 
00128         // Restore settings
00129         $wgEnableJavaScriptTest = $org_wgEnableJavaScriptTest;
00130 
00131         return array(
00132             'modules' => $modules,
00133             'resourceloader' => $rl,
00134             'context' => new ResourceLoaderContext( $rl, new FauxRequest() )
00135         );
00136     }
00137 
00142     public static function provideMediaStylesheets() {
00143         $data = self::getAllModules();
00144         $cases = array();
00145 
00146         foreach ( $data['modules'] as $moduleName => $module ) {
00147             if ( !$module instanceof ResourceLoaderFileModule ) {
00148                 continue;
00149             }
00150 
00151             $reflectedModule = new ReflectionObject( $module );
00152 
00153             $getStyleFiles = $reflectedModule->getMethod( 'getStyleFiles' );
00154             $getStyleFiles->setAccessible( true );
00155 
00156             $readStyleFile = $reflectedModule->getMethod( 'readStyleFile' );
00157             $readStyleFile->setAccessible( true );
00158 
00159             $styleFiles = $getStyleFiles->invoke( $module, $data['context'] );
00160 
00161             $flip = $module->getFlip( $data['context'] );
00162 
00163             foreach ( $styleFiles as $media => $files ) {
00164                 if ( $media && $media !== 'all' ) {
00165                     foreach ( $files as $file ) {
00166                         $cases[] = array(
00167                             $moduleName,
00168                             $media,
00169                             $file,
00170                             // XXX: Wrapped in an object to keep it out of PHPUnit output
00171                             (object)array( 'cssText' => $readStyleFile->invoke( $module, $file, $flip ) ),
00172                         );
00173                     }
00174                 }
00175             }
00176         }
00177 
00178         return $cases;
00179     }
00180 
00188     public static function provideResourceFiles() {
00189         $data = self::getAllModules();
00190         $cases = array();
00191 
00192         // See also ResourceLoaderFileModule::__construct
00193         $filePathProps = array(
00194             // Lists of file paths
00195             'lists' => array(
00196                 'scripts',
00197                 'debugScripts',
00198                 'loaderScripts',
00199                 'styles',
00200             ),
00201 
00202             // Collated lists of file paths
00203             'nested-lists' => array(
00204                 'languageScripts',
00205                 'skinScripts',
00206                 'skinStyles',
00207             ),
00208         );
00209 
00210         foreach ( $data['modules'] as $moduleName => $module ) {
00211             if ( !$module instanceof ResourceLoaderFileModule ) {
00212                 continue;
00213             }
00214 
00215             $reflectedModule = new ReflectionObject( $module );
00216 
00217             $files = array();
00218 
00219             foreach ( $filePathProps['lists'] as $propName ) {
00220                 $property = $reflectedModule->getProperty( $propName );
00221                 $property->setAccessible( true );
00222                 $list = $property->getValue( $module );
00223                 foreach ( $list as $key => $value ) {
00224                     // 'scripts' are numeral arrays.
00225                     // 'styles' can be numeral or associative.
00226                     // In case of associative the key is the file path
00227                     // and the value is the 'media' attribute.
00228                     if ( is_int( $key ) ) {
00229                         $files[] = $value;
00230                     } else {
00231                         $files[] = $key;
00232                     }
00233                 }
00234             }
00235 
00236             foreach ( $filePathProps['nested-lists'] as $propName ) {
00237                 $property = $reflectedModule->getProperty( $propName );
00238                 $property->setAccessible( true );
00239                 $lists = $property->getValue( $module );
00240                 foreach ( $lists as $list ) {
00241                     foreach ( $list as $key => $value ) {
00242                         // We need the same filter as for 'lists',
00243                         // due to 'skinStyles'.
00244                         if ( is_int( $key ) ) {
00245                             $files[] = $value;
00246                         } else {
00247                             $files[] = $key;
00248                         }
00249                     }
00250                 }
00251             }
00252 
00253             // Get method for resolving the paths to full paths
00254             $method = $reflectedModule->getMethod( 'getLocalPath' );
00255             $method->setAccessible( true );
00256 
00257             // Populate cases
00258             foreach ( $files as $file ) {
00259                 $cases[] = array(
00260                     $method->invoke( $module, $file ),
00261                     $moduleName,
00262                     ( $file instanceof ResourceLoaderFilePath ? $file->getPath() : $file ),
00263                 );
00264             }
00265         }
00266 
00267         return $cases;
00268     }
00269 }