Currently we invalidate module caches based on timestamps from various places (including message blob, file mtimes and more). This meant that when a module changes such that the maximum detectable timestamp is still the same, the cache would not invalidate. Module classes can now implement a method to build a summary. In most cases this should be (a normalised version of) the definition array originally given to ResourceLoader::register (such as $wgResourceModules items). The most common scenarios this addresses: * File lists (scripts, styles) being re-ordered. * Files being removed when more recently changed files remain part of the module (e.g. removing an older file). * Files or messages being added to a module while other more recently changed things are already part of the module. E.g. you create a message and use it in a js file, but forget to add the message to the module. Then later you add the msg key. This last update would be ignored, because the mtime of the message is no newer than the total which already included the (same) mtime of the js file added in the previous update. * Change the concatenation order of pages in a Gadget definition. Bug: 37812 Change-Id: I00cf086c981a84235623bf58fb83c9c23aa2d619
87 lines
2.3 KiB
PHP
87 lines
2.3 KiB
PHP
<?php
|
|
|
|
class ResourceLoaderModuleTest extends MediaWikiTestCase {
|
|
|
|
protected static function getResourceLoaderContext() {
|
|
$resourceLoader = new ResourceLoader();
|
|
$request = new FauxRequest( array(
|
|
'debug' => 'false',
|
|
'lang' => 'en',
|
|
'modules' => 'startup',
|
|
'only' => 'scripts',
|
|
'skin' => 'vector',
|
|
) );
|
|
return new ResourceLoaderContext( $resourceLoader, $request );
|
|
}
|
|
|
|
/**
|
|
* @covers ResourceLoaderModule::getDefinitionSummary
|
|
* @covers ResourceLoaderFileModule::getDefinitionSummary
|
|
*/
|
|
public function testDefinitionSummary() {
|
|
$context = self::getResourceLoaderContext();
|
|
|
|
$baseParams = array(
|
|
'scripts' => array( 'foo.js', 'bar.js' ),
|
|
'dependencies' => array( 'jquery', 'mediawiki' ),
|
|
'messages' => array( 'hello', 'world' ),
|
|
);
|
|
|
|
$module = new ResourceLoaderFileModule( $baseParams );
|
|
|
|
$jsonSummary = json_encode( $module->getDefinitionSummary( $context ) );
|
|
|
|
// Exactly the same
|
|
$module = new ResourceLoaderFileModule( $baseParams );
|
|
|
|
$this->assertEquals(
|
|
$jsonSummary,
|
|
json_encode( $module->getDefinitionSummary( $context ) ),
|
|
'Instance is insignificant'
|
|
);
|
|
|
|
// Re-order dependencies
|
|
$module = new ResourceLoaderFileModule( array(
|
|
'dependencies' => array( 'mediawiki', 'jquery' ),
|
|
) + $baseParams );
|
|
|
|
$this->assertEquals(
|
|
$jsonSummary,
|
|
json_encode( $module->getDefinitionSummary( $context ) ),
|
|
'Order of dependencies is insignificant'
|
|
);
|
|
|
|
// Re-order messages
|
|
$module = new ResourceLoaderFileModule( array(
|
|
'messages' => array( 'world', 'hello' ),
|
|
) + $baseParams );
|
|
|
|
$this->assertEquals(
|
|
$jsonSummary,
|
|
json_encode( $module->getDefinitionSummary( $context ) ),
|
|
'Order of messages is insignificant'
|
|
);
|
|
|
|
// Re-order scripts
|
|
$module = new ResourceLoaderFileModule( array(
|
|
'scripts' => array( 'bar.js', 'foo.js' ),
|
|
) + $baseParams );
|
|
|
|
$this->assertNotEquals(
|
|
$jsonSummary,
|
|
json_encode( $module->getDefinitionSummary( $context ) ),
|
|
'Order of scripts is significant'
|
|
);
|
|
|
|
// Subclass
|
|
$module = new ResourceLoaderFileModuleTestModule( $baseParams );
|
|
|
|
$this->assertNotEquals(
|
|
$jsonSummary,
|
|
json_encode( $module->getDefinitionSummary( $context ) ),
|
|
'Class is significant'
|
|
);
|
|
}
|
|
}
|
|
|
|
class ResourceLoaderFileModuleTestModule extends ResourceLoaderFileModule {}
|