wiki.techinc.nl/tests/phpunit/includes/ResourceLoaderModuleTest.php
Timo Tijhof d3bdda3221 resourceloader: Add definition hashing to improve cache invalidation
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
2013-12-02 21:45:33 -08:00

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 {}