Being a raw module means that when it is requested from load.php with "only=scripts" set, then the output is *not* wrapped in an 'mw.loader.implement' closure *and* there no 'mw.loader.state()' appendix. Instead, it is served "raw". Before 2018, the modules 'mediawiki' and 'jquery' were raw modules. They were needed before the client could define 'mw.loader.implement', and could never be valid dependencies. Module 'mediawiki' merged to 'startup', and 'jquery' became a regular module (T192623). Based on the architecture of modules being deliverable bundles, it doesn't make sense for there to ever be raw modules again. Anything that 'startup' needs should be bundled with it. Anything else is a regular module. On top of that, we never actually needed this feature because specifying the 'only=scripts' and 'raw=1' parameters does the same thing. The only special bit about marking modules (not requests) as "raw" was that it allowed the client to forget to specify "raw=1" and the server would automatically omit the 'mw.loader.state()' appendix based on whether the module is marked as raw. As of Ie4564ec8e26ad53f2, the two remaining use cases for raw responses now specify the 'raw=1' request parameter, and we can get rid of the "raw module" feature and all the complexity around it. == Startup module In the startup module there was an interesting use of isRaw() that has little to do with the above. The "ATTENTION" warning there applies to the startup module only, not raw modules in general. This is now fixed by explicitly checking for StartupModule. Above that warning, it talked about saving bytes, which was an optimisation given that "raw" modules don't communicate with mw.loader, they also don't need to be registered there because even if mw.loader would try to load them, the server would never inform mw.loader about the module having arrived. There are now no longer any such modules. Bug: T201483 Change-Id: I8839036e7b2b76919b6cd3aa42ccfde4d1247899
797 lines
18 KiB
PHP
797 lines
18 KiB
PHP
<?php
|
|
|
|
class ResourceLoaderStartUpModuleTest extends ResourceLoaderTestCase {
|
|
|
|
protected static function expandPlaceholders( $text ) {
|
|
return strtr( $text, [
|
|
'{blankVer}' => self::BLANK_VERSION
|
|
] );
|
|
}
|
|
|
|
public function provideGetModuleRegistrations() {
|
|
return [
|
|
[ [
|
|
'msg' => 'Empty registry',
|
|
'modules' => [],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [] );'
|
|
] ],
|
|
[ [
|
|
'msg' => 'Basic registry',
|
|
'modules' => [
|
|
'test.blank' => new ResourceLoaderTestModule(),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.blank",
|
|
"{blankVer}"
|
|
]
|
|
] );',
|
|
] ],
|
|
[ [
|
|
'msg' => 'Optimise the dependency tree (basic case)',
|
|
'modules' => [
|
|
'a' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'b', 'c', 'd' ] ] ),
|
|
'b' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'c' ] ] ),
|
|
'c' => new ResourceLoaderTestModule( [ 'dependencies' => [] ] ),
|
|
'd' => new ResourceLoaderTestModule( [ 'dependencies' => [] ] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"a",
|
|
"{blankVer}",
|
|
[
|
|
1,
|
|
3
|
|
]
|
|
],
|
|
[
|
|
"b",
|
|
"{blankVer}",
|
|
[
|
|
2
|
|
]
|
|
],
|
|
[
|
|
"c",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"d",
|
|
"{blankVer}"
|
|
]
|
|
] );',
|
|
] ],
|
|
[ [
|
|
'msg' => 'Optimise the dependency tree (tolerate unknown deps)',
|
|
'modules' => [
|
|
'a' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'b', 'c', 'x' ] ] ),
|
|
'b' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'c', 'x' ] ] ),
|
|
'c' => new ResourceLoaderTestModule( [ 'dependencies' => [] ] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"a",
|
|
"{blankVer}",
|
|
[
|
|
1,
|
|
"x"
|
|
]
|
|
],
|
|
[
|
|
"b",
|
|
"{blankVer}",
|
|
[
|
|
2,
|
|
"x"
|
|
]
|
|
],
|
|
[
|
|
"c",
|
|
"{blankVer}"
|
|
]
|
|
] );',
|
|
] ],
|
|
[ [
|
|
// Regression test for T223402.
|
|
'msg' => 'Optimise the dependency tree (indirect circular dependency)',
|
|
'modules' => [
|
|
'top' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'middle1', 'util' ] ] ),
|
|
'middle1' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'middle2', 'util' ] ] ),
|
|
'middle2' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'bottom' ] ] ),
|
|
'bottom' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'top' ] ] ),
|
|
'util' => new ResourceLoaderTestModule( [ 'dependencies' => [] ] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"top",
|
|
"{blankVer}",
|
|
[
|
|
1,
|
|
4
|
|
]
|
|
],
|
|
[
|
|
"middle1",
|
|
"{blankVer}",
|
|
[
|
|
2,
|
|
4
|
|
]
|
|
],
|
|
[
|
|
"middle2",
|
|
"{blankVer}",
|
|
[
|
|
3
|
|
]
|
|
],
|
|
[
|
|
"bottom",
|
|
"{blankVer}",
|
|
[
|
|
0
|
|
]
|
|
],
|
|
[
|
|
"util",
|
|
"{blankVer}"
|
|
]
|
|
] );',
|
|
] ],
|
|
[ [
|
|
// Regression test for T223402.
|
|
'msg' => 'Optimise the dependency tree (direct circular dependency)',
|
|
'modules' => [
|
|
'top' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'util', 'top' ] ] ),
|
|
'util' => new ResourceLoaderTestModule( [ 'dependencies' => [] ] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"top",
|
|
"{blankVer}",
|
|
[
|
|
1,
|
|
0
|
|
]
|
|
],
|
|
[
|
|
"util",
|
|
"{blankVer}"
|
|
]
|
|
] );',
|
|
] ],
|
|
[ [
|
|
'msg' => 'Version falls back gracefully if getVersionHash throws',
|
|
'modules' => [
|
|
'test.fail' => (
|
|
( $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
|
|
->setMethods( [ 'getVersionHash' ] )->getMock() )
|
|
&& $mock->method( 'getVersionHash' )->will(
|
|
$this->throwException( new Exception )
|
|
)
|
|
) ? $mock : $mock
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.fail",
|
|
""
|
|
]
|
|
] );
|
|
mw.loader.state( {
|
|
"test.fail": "error"
|
|
} );',
|
|
] ],
|
|
[ [
|
|
'msg' => 'Use version from getVersionHash',
|
|
'modules' => [
|
|
'test.version' => (
|
|
( $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
|
|
->setMethods( [ 'getVersionHash' ] )->getMock() )
|
|
&& $mock->method( 'getVersionHash' )->willReturn( '1234567' )
|
|
) ? $mock : $mock
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.version",
|
|
"1234567"
|
|
]
|
|
] );',
|
|
] ],
|
|
[ [
|
|
'msg' => 'Re-hash version from getVersionHash if too long',
|
|
'modules' => [
|
|
'test.version' => (
|
|
( $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
|
|
->setMethods( [ 'getVersionHash' ] )->getMock() )
|
|
&& $mock->method( 'getVersionHash' )->willReturn( '12345678' )
|
|
) ? $mock : $mock
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.version",
|
|
"016es8l"
|
|
]
|
|
] );',
|
|
] ],
|
|
[ [
|
|
'msg' => 'Group signature',
|
|
'modules' => [
|
|
'test.blank' => new ResourceLoaderTestModule(),
|
|
'test.group.foo' => new ResourceLoaderTestModule( [ 'group' => 'x-foo' ] ),
|
|
'test.group.bar' => new ResourceLoaderTestModule( [ 'group' => 'x-bar' ] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.blank",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"test.group.foo",
|
|
"{blankVer}",
|
|
[],
|
|
"x-foo"
|
|
],
|
|
[
|
|
"test.group.bar",
|
|
"{blankVer}",
|
|
[],
|
|
"x-bar"
|
|
]
|
|
] );'
|
|
] ],
|
|
[ [
|
|
'msg' => 'Different target (non-test should not be registered)',
|
|
'modules' => [
|
|
'test.blank' => new ResourceLoaderTestModule(),
|
|
'test.target.foo' => new ResourceLoaderTestModule( [ 'targets' => [ 'x-foo' ] ] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.blank",
|
|
"{blankVer}"
|
|
]
|
|
] );'
|
|
] ],
|
|
[ [
|
|
'msg' => 'Safemode disabled (default; register all modules)',
|
|
'modules' => [
|
|
// Default origin: ORIGIN_CORE_SITEWIDE
|
|
'test.blank' => new ResourceLoaderTestModule(),
|
|
'test.core-generated' => new ResourceLoaderTestModule( [
|
|
'origin' => ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL
|
|
] ),
|
|
'test.sitewide' => new ResourceLoaderTestModule( [
|
|
'origin' => ResourceLoaderModule::ORIGIN_USER_SITEWIDE
|
|
] ),
|
|
'test.user' => new ResourceLoaderTestModule( [
|
|
'origin' => ResourceLoaderModule::ORIGIN_USER_INDIVIDUAL
|
|
] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.blank",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"test.core-generated",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"test.sitewide",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"test.user",
|
|
"{blankVer}"
|
|
]
|
|
] );'
|
|
] ],
|
|
[ [
|
|
'msg' => 'Safemode enabled (filter modules with user/site origin)',
|
|
'extraQuery' => [ 'safemode' => '1' ],
|
|
'modules' => [
|
|
// Default origin: ORIGIN_CORE_SITEWIDE
|
|
'test.blank' => new ResourceLoaderTestModule(),
|
|
'test.core-generated' => new ResourceLoaderTestModule( [
|
|
'origin' => ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL
|
|
] ),
|
|
'test.sitewide' => new ResourceLoaderTestModule( [
|
|
'origin' => ResourceLoaderModule::ORIGIN_USER_SITEWIDE
|
|
] ),
|
|
'test.user' => new ResourceLoaderTestModule( [
|
|
'origin' => ResourceLoaderModule::ORIGIN_USER_INDIVIDUAL
|
|
] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.blank",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"test.core-generated",
|
|
"{blankVer}"
|
|
]
|
|
] );'
|
|
] ],
|
|
[ [
|
|
'msg' => 'Foreign source',
|
|
'sources' => [
|
|
'example' => [
|
|
'loadScript' => 'http://example.org/w/load.php',
|
|
'apiScript' => 'http://example.org/w/api.php',
|
|
],
|
|
],
|
|
'modules' => [
|
|
'test.blank' => new ResourceLoaderTestModule( [ 'source' => 'example' ] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php",
|
|
"example": "http://example.org/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.blank",
|
|
"{blankVer}",
|
|
[],
|
|
null,
|
|
"example"
|
|
]
|
|
] );'
|
|
] ],
|
|
[ [
|
|
'msg' => 'Conditional dependency function',
|
|
'modules' => [
|
|
'test.x.core' => new ResourceLoaderTestModule(),
|
|
'test.x.polyfill' => new ResourceLoaderTestModule( [
|
|
'skipFunction' => 'return true;'
|
|
] ),
|
|
'test.y.polyfill' => new ResourceLoaderTestModule( [
|
|
'skipFunction' =>
|
|
'return !!(' .
|
|
' window.JSON &&' .
|
|
' JSON.parse &&' .
|
|
' JSON.stringify' .
|
|
');'
|
|
] ),
|
|
'test.z.foo' => new ResourceLoaderTestModule( [
|
|
'dependencies' => [
|
|
'test.x.core',
|
|
'test.x.polyfill',
|
|
'test.y.polyfill',
|
|
],
|
|
] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.x.core",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"test.x.polyfill",
|
|
"{blankVer}",
|
|
[],
|
|
null,
|
|
null,
|
|
"return true;"
|
|
],
|
|
[
|
|
"test.y.polyfill",
|
|
"{blankVer}",
|
|
[],
|
|
null,
|
|
null,
|
|
"return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
|
|
],
|
|
[
|
|
"test.z.foo",
|
|
"{blankVer}",
|
|
[
|
|
0,
|
|
1,
|
|
2
|
|
]
|
|
]
|
|
] );',
|
|
] ],
|
|
[ [
|
|
// This may seem like an edge case, but a plain MediaWiki core install
|
|
// with a few extensions installed is likely far more complex than this
|
|
// even, not to mention an install like Wikipedia.
|
|
// TODO: Make this even more realistic.
|
|
'msg' => 'Advanced (everything combined)',
|
|
'sources' => [
|
|
'example' => [
|
|
'loadScript' => 'http://example.org/w/load.php',
|
|
'apiScript' => 'http://example.org/w/api.php',
|
|
],
|
|
],
|
|
'modules' => [
|
|
'test.blank' => new ResourceLoaderTestModule(),
|
|
'test.x.core' => new ResourceLoaderTestModule(),
|
|
'test.x.util' => new ResourceLoaderTestModule( [
|
|
'dependencies' => [
|
|
'test.x.core',
|
|
],
|
|
] ),
|
|
'test.x.foo' => new ResourceLoaderTestModule( [
|
|
'dependencies' => [
|
|
'test.x.core',
|
|
],
|
|
] ),
|
|
'test.x.bar' => new ResourceLoaderTestModule( [
|
|
'dependencies' => [
|
|
'test.x.core',
|
|
'test.x.util',
|
|
],
|
|
] ),
|
|
'test.x.quux' => new ResourceLoaderTestModule( [
|
|
'dependencies' => [
|
|
'test.x.foo',
|
|
'test.x.bar',
|
|
'test.x.util',
|
|
'test.x.unknown',
|
|
],
|
|
] ),
|
|
'test.group.foo.1' => new ResourceLoaderTestModule( [
|
|
'group' => 'x-foo',
|
|
] ),
|
|
'test.group.foo.2' => new ResourceLoaderTestModule( [
|
|
'group' => 'x-foo',
|
|
] ),
|
|
'test.group.bar.1' => new ResourceLoaderTestModule( [
|
|
'group' => 'x-bar',
|
|
] ),
|
|
'test.group.bar.2' => new ResourceLoaderTestModule( [
|
|
'group' => 'x-bar',
|
|
'source' => 'example',
|
|
] ),
|
|
'test.target.foo' => new ResourceLoaderTestModule( [
|
|
'targets' => [ 'x-foo' ],
|
|
] ),
|
|
'test.target.bar' => new ResourceLoaderTestModule( [
|
|
'source' => 'example',
|
|
'targets' => [ 'x-foo' ],
|
|
] ),
|
|
],
|
|
'out' => '
|
|
mw.loader.addSource( {
|
|
"local": "/w/load.php",
|
|
"example": "http://example.org/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.blank",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"test.x.core",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"test.x.util",
|
|
"{blankVer}",
|
|
[
|
|
1
|
|
]
|
|
],
|
|
[
|
|
"test.x.foo",
|
|
"{blankVer}",
|
|
[
|
|
1
|
|
]
|
|
],
|
|
[
|
|
"test.x.bar",
|
|
"{blankVer}",
|
|
[
|
|
2
|
|
]
|
|
],
|
|
[
|
|
"test.x.quux",
|
|
"{blankVer}",
|
|
[
|
|
3,
|
|
4,
|
|
"test.x.unknown"
|
|
]
|
|
],
|
|
[
|
|
"test.group.foo.1",
|
|
"{blankVer}",
|
|
[],
|
|
"x-foo"
|
|
],
|
|
[
|
|
"test.group.foo.2",
|
|
"{blankVer}",
|
|
[],
|
|
"x-foo"
|
|
],
|
|
[
|
|
"test.group.bar.1",
|
|
"{blankVer}",
|
|
[],
|
|
"x-bar"
|
|
],
|
|
[
|
|
"test.group.bar.2",
|
|
"{blankVer}",
|
|
[],
|
|
"x-bar",
|
|
"example"
|
|
]
|
|
] );'
|
|
] ],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideGetModuleRegistrations
|
|
* @covers ResourceLoaderStartUpModule
|
|
* @covers ResourceLoader::makeLoaderRegisterScript
|
|
*/
|
|
public function testGetModuleRegistrations( $case ) {
|
|
$extraQuery = $case['extraQuery'] ?? [];
|
|
$context = $this->getResourceLoaderContext( $extraQuery );
|
|
$rl = $context->getResourceLoader();
|
|
if ( isset( $case['sources'] ) ) {
|
|
$rl->addSource( $case['sources'] );
|
|
}
|
|
$rl->register( $case['modules'] );
|
|
$module = new ResourceLoaderStartUpModule();
|
|
$out = ltrim( $case['out'], "\n" );
|
|
|
|
// Disable log from getModuleRegistrations via MWExceptionHandler
|
|
// for case where getVersionHash() is expected to throw.
|
|
$this->setLogger( 'exception', new Psr\Log\NullLogger() );
|
|
|
|
$this->assertEquals(
|
|
self::expandPlaceholders( $out ),
|
|
$module->getModuleRegistrations( $context ),
|
|
$case['msg']
|
|
);
|
|
}
|
|
|
|
public static function provideRegistrations() {
|
|
return [
|
|
[ [
|
|
'test.blank' => new ResourceLoaderTestModule(),
|
|
'test.min' => new ResourceLoaderTestModule( [
|
|
'skipFunction' =>
|
|
'return !!(' .
|
|
' window.JSON &&' .
|
|
' JSON.parse &&' .
|
|
' JSON.stringify' .
|
|
');',
|
|
'dependencies' => [
|
|
'test.blank',
|
|
],
|
|
] ),
|
|
] ]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @covers ResourceLoaderStartUpModule::getModuleRegistrations
|
|
* @dataProvider provideRegistrations
|
|
*/
|
|
public function testRegistrationsMinified( $modules ) {
|
|
$this->setMwGlobals( 'wgResourceLoaderDebug', false );
|
|
|
|
$context = $this->getResourceLoaderContext();
|
|
$rl = $context->getResourceLoader();
|
|
$rl->register( $modules );
|
|
$module = new ResourceLoaderStartUpModule();
|
|
$out = 'mw.loader.addSource({"local":"/w/load.php"});' . "\n"
|
|
. 'mw.loader.register(['
|
|
. '["test.blank","{blankVer}"],'
|
|
. '["test.min","{blankVer}",[0],null,null,'
|
|
. '"return!!(window.JSON\u0026\u0026JSON.parse\u0026\u0026JSON.stringify);"'
|
|
. ']]);';
|
|
|
|
$this->assertEquals(
|
|
self::expandPlaceholders( $out ),
|
|
$module->getModuleRegistrations( $context ),
|
|
'Minified output'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers ResourceLoaderStartUpModule::getModuleRegistrations
|
|
* @dataProvider provideRegistrations
|
|
*/
|
|
public function testRegistrationsUnminified( $modules ) {
|
|
$context = $this->getResourceLoaderContext();
|
|
$rl = $context->getResourceLoader();
|
|
$rl->register( $modules );
|
|
$module = new ResourceLoaderStartUpModule();
|
|
$out =
|
|
'mw.loader.addSource( {
|
|
"local": "/w/load.php"
|
|
} );
|
|
mw.loader.register( [
|
|
[
|
|
"test.blank",
|
|
"{blankVer}"
|
|
],
|
|
[
|
|
"test.min",
|
|
"{blankVer}",
|
|
[
|
|
0
|
|
],
|
|
null,
|
|
null,
|
|
"return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
|
|
]
|
|
] );';
|
|
|
|
$this->assertEquals(
|
|
self::expandPlaceholders( $out ),
|
|
$module->getModuleRegistrations( $context ),
|
|
'Unminified output'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers ResourceLoaderStartupModule::getDefinitionSummary
|
|
*/
|
|
public function testGetVersionHash_varyConfig() {
|
|
$context = $this->getResourceLoaderContext();
|
|
|
|
$this->setMwGlobals( 'wgArticlePath', '/w1' );
|
|
$module = new ResourceLoaderStartupModule();
|
|
$version1 = $module->getVersionHash( $context );
|
|
$module = new ResourceLoaderStartupModule();
|
|
$version2 = $module->getVersionHash( $context );
|
|
|
|
$this->setMwGlobals( 'wgArticlePath', '/w3' );
|
|
$module = new ResourceLoaderStartupModule();
|
|
$version3 = $module->getVersionHash( $context );
|
|
|
|
$this->assertEquals(
|
|
$version1,
|
|
$version2,
|
|
'Deterministic version hash'
|
|
);
|
|
|
|
$this->assertNotEquals(
|
|
$version1,
|
|
$version3,
|
|
'Config change impacts version hash'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers ResourceLoaderStartupModule
|
|
*/
|
|
public function testGetVersionHash_varyModule() {
|
|
$context1 = $this->getResourceLoaderContext();
|
|
$rl1 = $context1->getResourceLoader();
|
|
$rl1->register( [
|
|
'test.a' => new ResourceLoaderTestModule(),
|
|
'test.b' => new ResourceLoaderTestModule(),
|
|
] );
|
|
$module = new ResourceLoaderStartupModule();
|
|
$version1 = $module->getVersionHash( $context1 );
|
|
|
|
$context2 = $this->getResourceLoaderContext();
|
|
$rl2 = $context2->getResourceLoader();
|
|
$rl2->register( [
|
|
'test.b' => new ResourceLoaderTestModule(),
|
|
'test.c' => new ResourceLoaderTestModule(),
|
|
] );
|
|
$module = new ResourceLoaderStartupModule();
|
|
$version2 = $module->getVersionHash( $context2 );
|
|
|
|
$context3 = $this->getResourceLoaderContext();
|
|
$rl3 = $context3->getResourceLoader();
|
|
$rl3->register( [
|
|
'test.a' => new ResourceLoaderTestModule(),
|
|
'test.b' => new ResourceLoaderTestModule( [ 'script' => 'different' ] ),
|
|
] );
|
|
$module = new ResourceLoaderStartupModule();
|
|
$version3 = $module->getVersionHash( $context3 );
|
|
|
|
// Module name *is* significant (T201686)
|
|
$this->assertNotEquals(
|
|
$version1,
|
|
$version2,
|
|
'Module name is significant'
|
|
);
|
|
|
|
$this->assertNotEquals(
|
|
$version1,
|
|
$version3,
|
|
'Hash change of any module impacts startup hash'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers ResourceLoaderStartupModule
|
|
*/
|
|
public function testGetVersionHash_varyDeps() {
|
|
$context = $this->getResourceLoaderContext();
|
|
$rl = $context->getResourceLoader();
|
|
$rl->register( [
|
|
'test.a' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'x', 'y' ] ] ),
|
|
] );
|
|
$module = new ResourceLoaderStartupModule();
|
|
$version1 = $module->getVersionHash( $context );
|
|
|
|
$context = $this->getResourceLoaderContext();
|
|
$rl = $context->getResourceLoader();
|
|
$rl->register( [
|
|
'test.a' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'x', 'z' ] ] ),
|
|
] );
|
|
$module = new ResourceLoaderStartupModule();
|
|
$version2 = $module->getVersionHash( $context );
|
|
|
|
// Dependencies *are* significant (T201686)
|
|
$this->assertNotEquals(
|
|
$version1,
|
|
$version2,
|
|
'Dependencies are significant'
|
|
);
|
|
}
|
|
|
|
}
|