wiki.techinc.nl/tests/phpunit/ResourceLoaderTestCase.php
Timo Tijhof 9d390a09cd resourceloader: Condition-wrap the HTML tag instead of JS response
Follows-up 9272bc6c47, 03c503da22, 1e063f6078.

One can't wrap arbitrary JavaScript in an if-statement and have
its inner-body mean exactly the same.

Certain statements are only allowed in the top of a scope (such
as hoisted function declarations). These are not allowed inside
a block. They're fine in both global scope and local function
scope, but not inside an if-block of any scope.

The ECMAScript spec only describes what is an allowed token.
Any unexpected token should result in a SyntaxError.

Chrome's implementation (V8) allows function declarations in
blocks and hoists them to *outside* the condition. Firefox's
SpiderMonkey silently ignores the statement. Neither throw a
SyntaxError.

Rgular ResourceLoader responses only contain mw.loader.implement()
and mw.loader.state() call which could be wrapped without issues.
However such responses don't need wrapping as they're only made
by mediawiki.js (in which case mw is obviously loaded). The
wrapping is for legacy scripts that execute in the global scope.

For those, let's wrap the script tag itself (instead of the
response). That seems like the most water-tight and semantically
correct solution.

Had to bring in $isRaw from ResourceLoader.php, else the startup
module would have been wrapped as well (added regression test).

Bug: 69924
Change-Id: Iedda0464f734ba5f7a884726487f6c7e07d444f1
2014-09-09 15:54:16 +00:00

95 lines
2.2 KiB
PHP

<?php
abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
protected static function getResourceLoaderContext( $lang = 'en' ) {
$resourceLoader = new ResourceLoader();
$request = new FauxRequest( array(
'lang' => $lang,
'modules' => 'startup',
'only' => 'scripts',
'skin' => 'vector',
'target' => 'test',
) );
return new ResourceLoaderContext( $resourceLoader, $request );
}
protected function setUp() {
parent::setUp();
ResourceLoader::clearCache();
$this->setMwGlobals( array(
// For ResourceLoader::inDebugMode since it doesn't have context
'wgResourceLoaderDebug' => true,
// Avoid influence from wgInvalidateCacheOnLocalSettingsChange
'wgCacheEpoch' => '20140101000000',
// For ResourceLoader::__construct()
'wgResourceLoaderSources' => array(),
// For wfScript()
'wgScriptPath' => '/w',
'wgScriptExtension' => '.php',
'wgScript' => '/w/index.php',
'wgLoadScript' => '/w/load.php',
) );
}
}
/* Stubs */
class ResourceLoaderTestModule extends ResourceLoaderModule {
protected $dependencies = array();
protected $group = null;
protected $source = 'local';
protected $script = '';
protected $styles = '';
protected $skipFunction = null;
protected $isRaw = false;
protected $targets = array( 'test' );
public function __construct( $options = array() ) {
foreach ( $options as $key => $value ) {
$this->$key = $value;
}
}
public function getScript( ResourceLoaderContext $context ) {
return $this->script;
}
public function getStyles( ResourceLoaderContext $context ) {
return array( '' => $this->styles );
}
public function getDependencies() {
return $this->dependencies;
}
public function getGroup() {
return $this->group;
}
public function getSource() {
return $this->source;
}
public function getSkipFunction() {
return $this->skipFunction;
}
public function isRaw() {
return $this->isRaw;
}
}
class ResourceLoaderFileModuleTestModule extends ResourceLoaderFileModule {
}
class ResourceLoaderWikiModuleTestModule extends ResourceLoaderWikiModule {
// Override expected via PHPUnit mocks and stubs
protected function getPages( ResourceLoaderContext $context ) {
return array();
}
}