Merge "Revert "selenium: add new message banner test to user spec""
[lhc/web/wiklou.git] / tests / phpunit / includes / resourceloader / ResourceLoaderStartUpModuleTest.php
1 <?php
2
3 class ResourceLoaderStartUpModuleTest extends ResourceLoaderTestCase {
4
5 protected static function expandPlaceholders( $text ) {
6 return strtr( $text, [
7 '{blankVer}' => self::BLANK_VERSION
8 ] );
9 }
10
11 public function provideGetModuleRegistrations() {
12 return [
13 [ [
14 'msg' => 'Empty registry',
15 'modules' => [],
16 'out' => '
17 mw.loader.addSource( {
18 "local": "/w/load.php"
19 } );
20 mw.loader.register( [] );'
21 ] ],
22 [ [
23 'msg' => 'Basic registry',
24 'modules' => [
25 'test.blank' => new ResourceLoaderTestModule(),
26 ],
27 'out' => '
28 mw.loader.addSource( {
29 "local": "/w/load.php"
30 } );
31 mw.loader.register( [
32 [
33 "test.blank",
34 "{blankVer}"
35 ]
36 ] );',
37 ] ],
38 [ [
39 'msg' => 'Omit raw modules from registry',
40 'modules' => [
41 'test.raw' => new ResourceLoaderTestModule( [ 'isRaw' => true ] ),
42 'test.blank' => new ResourceLoaderTestModule(),
43 ],
44 'out' => '
45 mw.loader.addSource( {
46 "local": "/w/load.php"
47 } );
48 mw.loader.register( [
49 [
50 "test.blank",
51 "{blankVer}"
52 ]
53 ] );',
54 ] ],
55 [ [
56 'msg' => 'Version falls back gracefully if getVersionHash throws',
57 'modules' => [
58 'test.fail' => (
59 ( $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
60 ->setMethods( [ 'getVersionHash' ] )->getMock() )
61 && $mock->method( 'getVersionHash' )->will(
62 $this->throwException( new Exception )
63 )
64 ) ? $mock : $mock
65 ],
66 'out' => '
67 mw.loader.addSource( {
68 "local": "/w/load.php"
69 } );
70 mw.loader.register( [
71 [
72 "test.fail",
73 ""
74 ]
75 ] );
76 mw.loader.state( {
77 "test.fail": "error"
78 } );',
79 ] ],
80 [ [
81 'msg' => 'Use version from getVersionHash',
82 'modules' => [
83 'test.version' => (
84 ( $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
85 ->setMethods( [ 'getVersionHash' ] )->getMock() )
86 && $mock->method( 'getVersionHash' )->willReturn( '1234567' )
87 ) ? $mock : $mock
88 ],
89 'out' => '
90 mw.loader.addSource( {
91 "local": "/w/load.php"
92 } );
93 mw.loader.register( [
94 [
95 "test.version",
96 "1234567"
97 ]
98 ] );',
99 ] ],
100 [ [
101 'msg' => 'Re-hash version from getVersionHash if too long',
102 'modules' => [
103 'test.version' => (
104 ( $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
105 ->setMethods( [ 'getVersionHash' ] )->getMock() )
106 && $mock->method( 'getVersionHash' )->willReturn( '12345678' )
107 ) ? $mock : $mock
108 ],
109 'out' => '
110 mw.loader.addSource( {
111 "local": "/w/load.php"
112 } );
113 mw.loader.register( [
114 [
115 "test.version",
116 "016es8l"
117 ]
118 ] );',
119 ] ],
120 [ [
121 'msg' => 'Group signature',
122 'modules' => [
123 'test.blank' => new ResourceLoaderTestModule(),
124 'test.group.foo' => new ResourceLoaderTestModule( [ 'group' => 'x-foo' ] ),
125 'test.group.bar' => new ResourceLoaderTestModule( [ 'group' => 'x-bar' ] ),
126 ],
127 'out' => '
128 mw.loader.addSource( {
129 "local": "/w/load.php"
130 } );
131 mw.loader.register( [
132 [
133 "test.blank",
134 "{blankVer}"
135 ],
136 [
137 "test.group.foo",
138 "{blankVer}",
139 [],
140 "x-foo"
141 ],
142 [
143 "test.group.bar",
144 "{blankVer}",
145 [],
146 "x-bar"
147 ]
148 ] );'
149 ] ],
150 [ [
151 'msg' => 'Different target (non-test should not be registered)',
152 'modules' => [
153 'test.blank' => new ResourceLoaderTestModule(),
154 'test.target.foo' => new ResourceLoaderTestModule( [ 'targets' => [ 'x-foo' ] ] ),
155 ],
156 'out' => '
157 mw.loader.addSource( {
158 "local": "/w/load.php"
159 } );
160 mw.loader.register( [
161 [
162 "test.blank",
163 "{blankVer}"
164 ]
165 ] );'
166 ] ],
167 [ [
168 'msg' => 'Foreign source',
169 'sources' => [
170 'example' => [
171 'loadScript' => 'http://example.org/w/load.php',
172 'apiScript' => 'http://example.org/w/api.php',
173 ],
174 ],
175 'modules' => [
176 'test.blank' => new ResourceLoaderTestModule( [ 'source' => 'example' ] ),
177 ],
178 'out' => '
179 mw.loader.addSource( {
180 "local": "/w/load.php",
181 "example": "http://example.org/w/load.php"
182 } );
183 mw.loader.register( [
184 [
185 "test.blank",
186 "{blankVer}",
187 [],
188 null,
189 "example"
190 ]
191 ] );'
192 ] ],
193 [ [
194 'msg' => 'Conditional dependency function',
195 'modules' => [
196 'test.x.core' => new ResourceLoaderTestModule(),
197 'test.x.polyfill' => new ResourceLoaderTestModule( [
198 'skipFunction' => 'return true;'
199 ] ),
200 'test.y.polyfill' => new ResourceLoaderTestModule( [
201 'skipFunction' =>
202 'return !!(' .
203 ' window.JSON &&' .
204 ' JSON.parse &&' .
205 ' JSON.stringify' .
206 ');'
207 ] ),
208 'test.z.foo' => new ResourceLoaderTestModule( [
209 'dependencies' => [
210 'test.x.core',
211 'test.x.polyfill',
212 'test.y.polyfill',
213 ],
214 ] ),
215 ],
216 'out' => '
217 mw.loader.addSource( {
218 "local": "/w/load.php"
219 } );
220 mw.loader.register( [
221 [
222 "test.x.core",
223 "{blankVer}"
224 ],
225 [
226 "test.x.polyfill",
227 "{blankVer}",
228 [],
229 null,
230 null,
231 "return true;"
232 ],
233 [
234 "test.y.polyfill",
235 "{blankVer}",
236 [],
237 null,
238 null,
239 "return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
240 ],
241 [
242 "test.z.foo",
243 "{blankVer}",
244 [
245 0,
246 1,
247 2
248 ]
249 ]
250 ] );',
251 ] ],
252 [ [
253 // This may seem like an edge case, but a plain MediaWiki core install
254 // with a few extensions installed is likely far more complex than this
255 // even, not to mention an install like Wikipedia.
256 // TODO: Make this even more realistic.
257 'msg' => 'Advanced (everything combined)',
258 'sources' => [
259 'example' => [
260 'loadScript' => 'http://example.org/w/load.php',
261 'apiScript' => 'http://example.org/w/api.php',
262 ],
263 ],
264 'modules' => [
265 'test.blank' => new ResourceLoaderTestModule(),
266 'test.x.core' => new ResourceLoaderTestModule(),
267 'test.x.util' => new ResourceLoaderTestModule( [
268 'dependencies' => [
269 'test.x.core',
270 ],
271 ] ),
272 'test.x.foo' => new ResourceLoaderTestModule( [
273 'dependencies' => [
274 'test.x.core',
275 ],
276 ] ),
277 'test.x.bar' => new ResourceLoaderTestModule( [
278 'dependencies' => [
279 'test.x.core',
280 'test.x.util',
281 ],
282 ] ),
283 'test.x.quux' => new ResourceLoaderTestModule( [
284 'dependencies' => [
285 'test.x.foo',
286 'test.x.bar',
287 'test.x.util',
288 'test.x.unknown',
289 ],
290 ] ),
291 'test.group.foo.1' => new ResourceLoaderTestModule( [
292 'group' => 'x-foo',
293 ] ),
294 'test.group.foo.2' => new ResourceLoaderTestModule( [
295 'group' => 'x-foo',
296 ] ),
297 'test.group.bar.1' => new ResourceLoaderTestModule( [
298 'group' => 'x-bar',
299 ] ),
300 'test.group.bar.2' => new ResourceLoaderTestModule( [
301 'group' => 'x-bar',
302 'source' => 'example',
303 ] ),
304 'test.target.foo' => new ResourceLoaderTestModule( [
305 'targets' => [ 'x-foo' ],
306 ] ),
307 'test.target.bar' => new ResourceLoaderTestModule( [
308 'source' => 'example',
309 'targets' => [ 'x-foo' ],
310 ] ),
311 ],
312 'out' => '
313 mw.loader.addSource( {
314 "local": "/w/load.php",
315 "example": "http://example.org/w/load.php"
316 } );
317 mw.loader.register( [
318 [
319 "test.blank",
320 "{blankVer}"
321 ],
322 [
323 "test.x.core",
324 "{blankVer}"
325 ],
326 [
327 "test.x.util",
328 "{blankVer}",
329 [
330 1
331 ]
332 ],
333 [
334 "test.x.foo",
335 "{blankVer}",
336 [
337 1
338 ]
339 ],
340 [
341 "test.x.bar",
342 "{blankVer}",
343 [
344 2
345 ]
346 ],
347 [
348 "test.x.quux",
349 "{blankVer}",
350 [
351 3,
352 4,
353 "test.x.unknown"
354 ]
355 ],
356 [
357 "test.group.foo.1",
358 "{blankVer}",
359 [],
360 "x-foo"
361 ],
362 [
363 "test.group.foo.2",
364 "{blankVer}",
365 [],
366 "x-foo"
367 ],
368 [
369 "test.group.bar.1",
370 "{blankVer}",
371 [],
372 "x-bar"
373 ],
374 [
375 "test.group.bar.2",
376 "{blankVer}",
377 [],
378 "x-bar",
379 "example"
380 ]
381 ] );'
382 ] ],
383 ];
384 }
385
386 /**
387 * @dataProvider provideGetModuleRegistrations
388 * @covers ResourceLoaderStartUpModule::getModuleRegistrations
389 * @covers ResourceLoaderStartUpModule::compileUnresolvedDependencies
390 * @covers ResourceLoader::makeLoaderRegisterScript
391 */
392 public function testGetModuleRegistrations( $case ) {
393 if ( isset( $case['sources'] ) ) {
394 $this->setMwGlobals( 'wgResourceLoaderSources', $case['sources'] );
395 }
396
397 $context = $this->getResourceLoaderContext();
398 $rl = $context->getResourceLoader();
399 $rl->register( $case['modules'] );
400 $module = new ResourceLoaderStartUpModule();
401 $out = ltrim( $case['out'], "\n" );
402
403 // Disable log from getModuleRegistrations via MWExceptionHandler
404 // for case where getVersionHash() is expected to throw.
405 $this->setLogger( 'exception', new Psr\Log\NullLogger() );
406
407 $this->assertEquals(
408 self::expandPlaceholders( $out ),
409 $module->getModuleRegistrations( $context ),
410 $case['msg']
411 );
412 }
413
414 public static function provideRegistrations() {
415 return [
416 [ [
417 'test.blank' => new ResourceLoaderTestModule(),
418 'test.min' => new ResourceLoaderTestModule( [
419 'skipFunction' =>
420 'return !!(' .
421 ' window.JSON &&' .
422 ' JSON.parse &&' .
423 ' JSON.stringify' .
424 ');',
425 'dependencies' => [
426 'test.blank',
427 ],
428 ] ),
429 ] ]
430 ];
431 }
432 /**
433 * @covers ResourceLoaderStartUpModule::getModuleRegistrations
434 * @dataProvider provideRegistrations
435 */
436 public function testRegistrationsMinified( $modules ) {
437 $this->setMwGlobals( 'wgResourceLoaderDebug', false );
438
439 $context = $this->getResourceLoaderContext();
440 $rl = $context->getResourceLoader();
441 $rl->register( $modules );
442 $module = new ResourceLoaderStartUpModule();
443 $out = 'mw.loader.addSource({"local":"/w/load.php"});' . "\n"
444 . 'mw.loader.register(['
445 . '["test.blank","{blankVer}"],'
446 . '["test.min","{blankVer}",[0],null,null,'
447 . '"return!!(window.JSON\u0026\u0026JSON.parse\u0026\u0026JSON.stringify);"'
448 . ']]);';
449
450 $this->assertEquals(
451 self::expandPlaceholders( $out ),
452 $module->getModuleRegistrations( $context ),
453 'Minified output'
454 );
455 }
456
457 /**
458 * @covers ResourceLoaderStartUpModule::getModuleRegistrations
459 * @dataProvider provideRegistrations
460 */
461 public function testRegistrationsUnminified( $modules ) {
462 $context = $this->getResourceLoaderContext();
463 $rl = $context->getResourceLoader();
464 $rl->register( $modules );
465 $module = new ResourceLoaderStartUpModule();
466 $out =
467 'mw.loader.addSource( {
468 "local": "/w/load.php"
469 } );
470 mw.loader.register( [
471 [
472 "test.blank",
473 "{blankVer}"
474 ],
475 [
476 "test.min",
477 "{blankVer}",
478 [
479 0
480 ],
481 null,
482 null,
483 "return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
484 ]
485 ] );';
486
487 $this->assertEquals(
488 self::expandPlaceholders( $out ),
489 $module->getModuleRegistrations( $context ),
490 'Unminified output'
491 );
492 }
493
494 }