3 class ResourceLoaderStartUpModuleTest
extends ResourceLoaderTestCase
{
5 protected static function expandPlaceholders( $text ) {
7 '{blankVer}' => self
::BLANK_VERSION
11 public function provideGetModuleRegistrations() {
14 'msg' => 'Empty registry',
17 mw.loader.addSource( {
18 "local": "/w/load.php"
20 mw.loader.register( [] );'
23 'msg' => 'Basic registry',
25 'test.blank' => new ResourceLoaderTestModule(),
28 mw.loader.addSource( {
29 "local": "/w/load.php"
39 'msg' => 'Omit raw modules from registry',
41 'test.raw' => new ResourceLoaderTestModule( [ 'isRaw' => true ] ),
42 'test.blank' => new ResourceLoaderTestModule(),
45 mw.loader.addSource( {
46 "local": "/w/load.php"
56 'msg' => 'Version falls back gracefully if getVersionHash throws',
59 ( $mock = $this->getMockBuilder( ResourceLoaderTestModule
::class )
60 ->setMethods( [ 'getVersionHash' ] )->getMock() )
61 && $mock->method( 'getVersionHash' )->will(
62 $this->throwException( new Exception
)
67 mw.loader.addSource( {
68 "local": "/w/load.php"
81 'msg' => 'Use version from getVersionHash',
84 ( $mock = $this->getMockBuilder( ResourceLoaderTestModule
::class )
85 ->setMethods( [ 'getVersionHash' ] )->getMock() )
86 && $mock->method( 'getVersionHash' )->willReturn( '1234567' )
90 mw.loader.addSource( {
91 "local": "/w/load.php"
101 'msg' => 'Re-hash version from getVersionHash if too long',
104 ( $mock = $this->getMockBuilder( ResourceLoaderTestModule
::class )
105 ->setMethods( [ 'getVersionHash' ] )->getMock() )
106 && $mock->method( 'getVersionHash' )->willReturn( '12345678' )
110 mw.loader.addSource( {
111 "local": "/w/load.php"
113 mw.loader.register( [
121 'msg' => 'Group signature',
123 'test.blank' => new ResourceLoaderTestModule(),
124 'test.group.foo' => new ResourceLoaderTestModule( [ 'group' => 'x-foo' ] ),
125 'test.group.bar' => new ResourceLoaderTestModule( [ 'group' => 'x-bar' ] ),
128 mw.loader.addSource( {
129 "local": "/w/load.php"
131 mw.loader.register( [
151 'msg' => 'Different target (non-test should not be registered)',
153 'test.blank' => new ResourceLoaderTestModule(),
154 'test.target.foo' => new ResourceLoaderTestModule( [ 'targets' => [ 'x-foo' ] ] ),
157 mw.loader.addSource( {
158 "local": "/w/load.php"
160 mw.loader.register( [
168 'msg' => 'Safemode disabled (default; register all modules)',
170 // Default origin: ORIGIN_CORE_SITEWIDE
171 'test.blank' => new ResourceLoaderTestModule(),
172 'test.core-generated' => new ResourceLoaderTestModule( [
173 'origin' => ResourceLoaderModule
::ORIGIN_CORE_INDIVIDUAL
175 'test.sitewide' => new ResourceLoaderTestModule( [
176 'origin' => ResourceLoaderModule
::ORIGIN_USER_SITEWIDE
178 'test.user' => new ResourceLoaderTestModule( [
179 'origin' => ResourceLoaderModule
::ORIGIN_USER_INDIVIDUAL
183 mw.loader.addSource( {
184 "local": "/w/load.php"
186 mw.loader.register( [
192 "test.core-generated",
206 'msg' => 'Safemode enabled (filter modules with user/site origin)',
207 'extraQuery' => [ 'safemode' => '1' ],
209 // Default origin: ORIGIN_CORE_SITEWIDE
210 'test.blank' => new ResourceLoaderTestModule(),
211 'test.core-generated' => new ResourceLoaderTestModule( [
212 'origin' => ResourceLoaderModule
::ORIGIN_CORE_INDIVIDUAL
214 'test.sitewide' => new ResourceLoaderTestModule( [
215 'origin' => ResourceLoaderModule
::ORIGIN_USER_SITEWIDE
217 'test.user' => new ResourceLoaderTestModule( [
218 'origin' => ResourceLoaderModule
::ORIGIN_USER_INDIVIDUAL
222 mw.loader.addSource( {
223 "local": "/w/load.php"
225 mw.loader.register( [
231 "test.core-generated",
237 'msg' => 'Foreign source',
240 'loadScript' => 'http://example.org/w/load.php',
241 'apiScript' => 'http://example.org/w/api.php',
245 'test.blank' => new ResourceLoaderTestModule( [ 'source' => 'example' ] ),
248 mw.loader.addSource( {
249 "local": "/w/load.php",
250 "example": "http://example.org/w/load.php"
252 mw.loader.register( [
263 'msg' => 'Conditional dependency function',
265 'test.x.core' => new ResourceLoaderTestModule(),
266 'test.x.polyfill' => new ResourceLoaderTestModule( [
267 'skipFunction' => 'return true;'
269 'test.y.polyfill' => new ResourceLoaderTestModule( [
277 'test.z.foo' => new ResourceLoaderTestModule( [
286 mw.loader.addSource( {
287 "local": "/w/load.php"
289 mw.loader.register( [
308 "return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
322 // This may seem like an edge case, but a plain MediaWiki core install
323 // with a few extensions installed is likely far more complex than this
324 // even, not to mention an install like Wikipedia.
325 // TODO: Make this even more realistic.
326 'msg' => 'Advanced (everything combined)',
329 'loadScript' => 'http://example.org/w/load.php',
330 'apiScript' => 'http://example.org/w/api.php',
334 'test.blank' => new ResourceLoaderTestModule(),
335 'test.x.core' => new ResourceLoaderTestModule(),
336 'test.x.util' => new ResourceLoaderTestModule( [
341 'test.x.foo' => new ResourceLoaderTestModule( [
346 'test.x.bar' => new ResourceLoaderTestModule( [
352 'test.x.quux' => new ResourceLoaderTestModule( [
360 'test.group.foo.1' => new ResourceLoaderTestModule( [
363 'test.group.foo.2' => new ResourceLoaderTestModule( [
366 'test.group.bar.1' => new ResourceLoaderTestModule( [
369 'test.group.bar.2' => new ResourceLoaderTestModule( [
371 'source' => 'example',
373 'test.target.foo' => new ResourceLoaderTestModule( [
374 'targets' => [ 'x-foo' ],
376 'test.target.bar' => new ResourceLoaderTestModule( [
377 'source' => 'example',
378 'targets' => [ 'x-foo' ],
382 mw.loader.addSource( {
383 "local": "/w/load.php",
384 "example": "http://example.org/w/load.php"
386 mw.loader.register( [
456 * @dataProvider provideGetModuleRegistrations
457 * @covers ResourceLoaderStartUpModule::getModuleRegistrations
458 * @covers ResourceLoaderStartUpModule::compileUnresolvedDependencies
459 * @covers ResourceLoader::makeLoaderRegisterScript
461 public function testGetModuleRegistrations( $case ) {
462 if ( isset( $case['sources'] ) ) {
463 $this->setMwGlobals( 'wgResourceLoaderSources', $case['sources'] );
466 $extraQuery = $case['extraQuery'] ??
[];
467 $context = $this->getResourceLoaderContext( $extraQuery );
468 $rl = $context->getResourceLoader();
469 $rl->register( $case['modules'] );
470 $module = new ResourceLoaderStartUpModule();
471 $out = ltrim( $case['out'], "\n" );
473 // Disable log from getModuleRegistrations via MWExceptionHandler
474 // for case where getVersionHash() is expected to throw.
475 $this->setLogger( 'exception', new Psr\Log\
NullLogger() );
478 self
::expandPlaceholders( $out ),
479 $module->getModuleRegistrations( $context ),
484 public static function provideRegistrations() {
487 'test.blank' => new ResourceLoaderTestModule(),
488 'test.min' => new ResourceLoaderTestModule( [
504 * @covers ResourceLoaderStartUpModule::getModuleRegistrations
505 * @dataProvider provideRegistrations
507 public function testRegistrationsMinified( $modules ) {
508 $this->setMwGlobals( 'wgResourceLoaderDebug', false );
510 $context = $this->getResourceLoaderContext();
511 $rl = $context->getResourceLoader();
512 $rl->register( $modules );
513 $module = new ResourceLoaderStartUpModule();
514 $out = 'mw.loader.addSource({"local":"/w/load.php"});' . "\n"
515 . 'mw.loader.register(['
516 . '["test.blank","{blankVer}"],'
517 . '["test.min","{blankVer}",[0],null,null,'
518 . '"return!!(window.JSON\u0026\u0026JSON.parse\u0026\u0026JSON.stringify);"'
522 self
::expandPlaceholders( $out ),
523 $module->getModuleRegistrations( $context ),
529 * @covers ResourceLoaderStartUpModule::getModuleRegistrations
530 * @dataProvider provideRegistrations
532 public function testRegistrationsUnminified( $modules ) {
533 $context = $this->getResourceLoaderContext();
534 $rl = $context->getResourceLoader();
535 $rl->register( $modules );
536 $module = new ResourceLoaderStartUpModule();
538 'mw.loader.addSource( {
539 "local": "/w/load.php"
541 mw.loader.register( [
554 "return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
559 self
::expandPlaceholders( $out ),
560 $module->getModuleRegistrations( $context ),
566 * @covers ResourceLoaderStartupModule::getDefinitionSummary
568 public function testGetVersionHash_varyConfig() {
569 $context = $this->getResourceLoaderContext();
571 $this->setMwGlobals( 'wgArticlePath', '/w1' );
572 $module = new ResourceLoaderStartupModule();
573 $version1 = $module->getVersionHash( $context );
574 $module = new ResourceLoaderStartupModule();
575 $version2 = $module->getVersionHash( $context );
577 $this->setMwGlobals( 'wgArticlePath', '/w3' );
578 $module = new ResourceLoaderStartupModule();
579 $version3 = $module->getVersionHash( $context );
584 'Deterministic version hash'
587 $this->assertNotEquals(
590 'Config change impacts version hash'
595 * @covers ResourceLoaderStartupModule
597 public function testGetVersionHash_varyModule() {
598 $context1 = $this->getResourceLoaderContext();
599 $rl1 = $context1->getResourceLoader();
601 'test.a' => new ResourceLoaderTestModule(),
602 'test.b' => new ResourceLoaderTestModule(),
604 $module = new ResourceLoaderStartupModule();
605 $version1 = $module->getVersionHash( $context1 );
607 $context2 = $this->getResourceLoaderContext();
608 $rl2 = $context2->getResourceLoader();
610 'test.b' => new ResourceLoaderTestModule(),
611 'test.c' => new ResourceLoaderTestModule(),
613 $module = new ResourceLoaderStartupModule();
614 $version2 = $module->getVersionHash( $context2 );
616 $context3 = $this->getResourceLoaderContext();
617 $rl3 = $context3->getResourceLoader();
619 'test.a' => new ResourceLoaderTestModule(),
620 'test.b' => new ResourceLoaderTestModule( [ 'script' => 'different' ] ),
622 $module = new ResourceLoaderStartupModule();
623 $version3 = $module->getVersionHash( $context3 );
625 // Module name *is* significant (T201686)
626 $this->assertNotEquals(
629 'Module name is significant'
632 $this->assertNotEquals(
635 'Hash change of any module impacts startup hash'
640 * @covers ResourceLoaderStartupModule
642 public function testGetVersionHash_varyDeps() {
643 $context = $this->getResourceLoaderContext();
644 $rl = $context->getResourceLoader();
646 'test.a' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'x', 'y' ] ] ),
648 $module = new ResourceLoaderStartupModule();
649 $version1 = $module->getVersionHash( $context );
651 $context = $this->getResourceLoaderContext();
652 $rl = $context->getResourceLoader();
654 'test.a' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'x', 'z' ] ] ),
656 $module = new ResourceLoaderStartupModule();
657 $version2 = $module->getVersionHash( $context );
659 // Dependencies *are* significant (T201686)
660 $this->assertNotEquals(
663 'Dependencies are significant'