]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - tests/phpunit/includes/resourceloader/ResourceLoaderFileModuleTest.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / tests / phpunit / includes / resourceloader / ResourceLoaderFileModuleTest.php
1 <?php
2
3 /**
4  * @group Database
5  * @group ResourceLoader
6  */
7 class ResourceLoaderFileModuleTest extends ResourceLoaderTestCase {
8
9         protected function setUp() {
10                 parent::setUp();
11
12                 // The return value of the closure shouldn't matter since this test should
13                 // never call it
14                 SkinFactory::getDefaultInstance()->register(
15                         'fakeskin',
16                         'FakeSkin',
17                         function () {
18                         }
19                 );
20         }
21
22         private static function getModules() {
23                 $base = [
24                         'localBasePath' => realpath( __DIR__ ),
25                 ];
26
27                 return [
28                         'noTemplateModule' => [],
29
30                         'deprecatedModule' => $base + [
31                                 'deprecated' => true,
32                         ],
33                         'deprecatedTomorrow' => $base + [
34                                 'deprecated' => 'Will be removed tomorrow.'
35                         ],
36
37                         'htmlTemplateModule' => $base + [
38                                 'templates' => [
39                                         'templates/template.html',
40                                         'templates/template2.html',
41                                 ]
42                         ],
43
44                         'htmlTemplateUnknown' => $base + [
45                                 'templates' => [
46                                         'templates/notfound.html',
47                                 ]
48                         ],
49
50                         'aliasedHtmlTemplateModule' => $base + [
51                                 'templates' => [
52                                         'foo.html' => 'templates/template.html',
53                                         'bar.html' => 'templates/template2.html',
54                                 ]
55                         ],
56
57                         'templateModuleHandlebars' => $base + [
58                                 'templates' => [
59                                         'templates/template_awesome.handlebars',
60                                 ],
61                         ],
62
63                         'aliasFooFromBar' => $base + [
64                                 'templates' => [
65                                         'foo.foo' => 'templates/template.bar',
66                                 ],
67                         ],
68                 ];
69         }
70
71         public static function providerTemplateDependencies() {
72                 $modules = self::getModules();
73
74                 return [
75                         [
76                                 $modules['noTemplateModule'],
77                                 [],
78                         ],
79                         [
80                                 $modules['htmlTemplateModule'],
81                                 [
82                                         'mediawiki.template',
83                                 ],
84                         ],
85                         [
86                                 $modules['templateModuleHandlebars'],
87                                 [
88                                         'mediawiki.template',
89                                         'mediawiki.template.handlebars',
90                                 ],
91                         ],
92                         [
93                                 $modules['aliasFooFromBar'],
94                                 [
95                                         'mediawiki.template',
96                                         'mediawiki.template.foo',
97                                 ],
98                         ],
99                 ];
100         }
101
102         /**
103          * @dataProvider providerTemplateDependencies
104          * @covers ResourceLoaderFileModule::__construct
105          * @covers ResourceLoaderFileModule::getDependencies
106          */
107         public function testTemplateDependencies( $module, $expected ) {
108                 $rl = new ResourceLoaderFileModule( $module );
109                 $rl->setName( 'testing' );
110                 $this->assertEquals( $rl->getDependencies(), $expected );
111         }
112
113         public static function providerDeprecatedModules() {
114                 return [
115                         [
116                                 'deprecatedModule',
117                                 'mw.log.warn("This page is using the deprecated ResourceLoader module \"deprecatedModule\".");',
118                         ],
119                         [
120                                 'deprecatedTomorrow',
121                                 'mw.log.warn(' .
122                                         '"This page is using the deprecated ResourceLoader module \"deprecatedTomorrow\".\\n' .
123                                         "Will be removed tomorrow." .
124                                         '");'
125                         ]
126                 ];
127         }
128
129         /**
130          * @dataProvider providerDeprecatedModules
131          * @covers ResourceLoaderFileModule::getScript
132          */
133         public function testDeprecatedModules( $name, $expected ) {
134                 $modules = self::getModules();
135                 $module = new ResourceLoaderFileModule( $modules[$name] );
136                 $module->setName( $name );
137                 $ctx = $this->getResourceLoaderContext();
138                 $this->assertEquals( $module->getScript( $ctx ), $expected );
139         }
140
141         /**
142          * @covers ResourceLoaderFileModule::getScript
143          */
144         public function testGetScript() {
145                 $module = new ResourceLoaderFileModule( [
146                         'localBasePath' => __DIR__ . '/../../data/resourceloader',
147                         'scripts' => [ 'script-nosemi.js', 'script-comment.js' ],
148                 ] );
149                 $module->setName( 'testing' );
150                 $ctx = $this->getResourceLoaderContext();
151                 $this->assertEquals(
152                         "/* eslint-disable */\nmw.foo()\n" .
153                         "\n" .
154                         "/* eslint-disable */\nmw.foo()\n// mw.bar();\n" .
155                         "\n",
156                         $module->getScript( $ctx ),
157                         'scripts are concatenated with a new-line'
158                 );
159         }
160
161         /**
162          * @covers ResourceLoaderFileModule::getAllStyleFiles
163          * @covers ResourceLoaderFileModule::getAllSkinStyleFiles
164          * @covers ResourceLoaderFileModule::getSkinStyleFiles
165          */
166         public function testGetAllSkinStyleFiles() {
167                 $baseParams = [
168                         'scripts' => [
169                                 'foo.js',
170                                 'bar.js',
171                         ],
172                         'styles' => [
173                                 'foo.css',
174                                 'bar.css' => [ 'media' => 'print' ],
175                                 'screen.less' => [ 'media' => 'screen' ],
176                                 'screen-query.css' => [ 'media' => 'screen and (min-width: 400px)' ],
177                         ],
178                         'skinStyles' => [
179                                 'default' => 'quux-fallback.less',
180                                 'fakeskin' => [
181                                         'baz-vector.css',
182                                         'quux-vector.less',
183                                 ],
184                         ],
185                         'messages' => [
186                                 'hello',
187                                 'world',
188                         ],
189                 ];
190
191                 $module = new ResourceLoaderFileModule( $baseParams );
192                 $module->setName( 'testing' );
193
194                 $this->assertEquals(
195                         [
196                                 'foo.css',
197                                 'baz-vector.css',
198                                 'quux-vector.less',
199                                 'quux-fallback.less',
200                                 'bar.css',
201                                 'screen.less',
202                                 'screen-query.css',
203                         ],
204                         array_map( 'basename', $module->getAllStyleFiles() )
205                 );
206         }
207
208         /**
209          * Strip @noflip annotations from CSS code.
210          * @param string $css
211          * @return string
212          */
213         private static function stripNoflip( $css ) {
214                 return str_replace( '/*@noflip*/ ', '', $css );
215         }
216
217         /**
218          * What happens when you mix @embed and @noflip?
219          * This really is an integration test, but oh well.
220          *
221          * @covers ResourceLoaderFileModule::getStyles
222          * @covers ResourceLoaderFileModule::getStyleFiles
223          */
224         public function testMixedCssAnnotations() {
225                 $basePath = __DIR__ . '/../../data/css';
226                 $testModule = new ResourceLoaderFileModule( [
227                         'localBasePath' => $basePath,
228                         'styles' => [ 'test.css' ],
229                 ] );
230                 $testModule->setName( 'testing' );
231                 $expectedModule = new ResourceLoaderFileModule( [
232                         'localBasePath' => $basePath,
233                         'styles' => [ 'expected.css' ],
234                 ] );
235                 $expectedModule->setName( 'testing' );
236
237                 $contextLtr = $this->getResourceLoaderContext( [
238                         'lang' => 'en',
239                         'dir' => 'ltr',
240                 ] );
241                 $contextRtl = $this->getResourceLoaderContext( [
242                         'lang' => 'he',
243                         'dir' => 'rtl',
244                 ] );
245
246                 // Since we want to compare the effect of @noflip+@embed against the effect of just @embed, and
247                 // the @noflip annotations are always preserved, we need to strip them first.
248                 $this->assertEquals(
249                         $expectedModule->getStyles( $contextLtr ),
250                         self::stripNoflip( $testModule->getStyles( $contextLtr ) ),
251                         "/*@noflip*/ with /*@embed*/ gives correct results in LTR mode"
252                 );
253                 $this->assertEquals(
254                         $expectedModule->getStyles( $contextLtr ),
255                         self::stripNoflip( $testModule->getStyles( $contextRtl ) ),
256                         "/*@noflip*/ with /*@embed*/ gives correct results in RTL mode"
257                 );
258         }
259
260         public static function providerGetTemplates() {
261                 $modules = self::getModules();
262
263                 return [
264                         [
265                                 $modules['noTemplateModule'],
266                                 [],
267                         ],
268                         [
269                                 $modules['templateModuleHandlebars'],
270                                 [
271                                         'templates/template_awesome.handlebars' => "wow\n",
272                                 ],
273                         ],
274                         [
275                                 $modules['htmlTemplateModule'],
276                                 [
277                                         'templates/template.html' => "<strong>hello</strong>\n",
278                                         'templates/template2.html' => "<div>goodbye</div>\n",
279                                 ],
280                         ],
281                         [
282                                 $modules['aliasedHtmlTemplateModule'],
283                                 [
284                                         'foo.html' => "<strong>hello</strong>\n",
285                                         'bar.html' => "<div>goodbye</div>\n",
286                                 ],
287                         ],
288                         [
289                                 $modules['htmlTemplateUnknown'],
290                                 false,
291                         ],
292                 ];
293         }
294
295         /**
296          * @dataProvider providerGetTemplates
297          * @covers ResourceLoaderFileModule::getTemplates
298          */
299         public function testGetTemplates( $module, $expected ) {
300                 $rl = new ResourceLoaderFileModule( $module );
301                 $rl->setName( 'testing' );
302
303                 if ( $expected === false ) {
304                         $this->setExpectedException( MWException::class );
305                         $rl->getTemplates();
306                 } else {
307                         $this->assertEquals( $rl->getTemplates(), $expected );
308                 }
309         }
310
311         /**
312          * @covers ResourceLoaderFileModule::stripBom
313          */
314         public function testBomConcatenation() {
315                 $basePath = __DIR__ . '/../../data/css';
316                 $testModule = new ResourceLoaderFileModule( [
317                         'localBasePath' => $basePath,
318                         'styles' => [ 'bom.css' ],
319                         ] );
320                 $testModule->setName( 'testing' );
321                 $this->assertEquals(
322                         substr( file_get_contents( "$basePath/bom.css" ), 0, 10 ),
323                         "\xef\xbb\xbf.efbbbf",
324                         'File has leading BOM'
325                 );
326
327                 $context = $this->getResourceLoaderContext();
328                 $this->assertEquals(
329                         $testModule->getStyles( $context ),
330                         [ 'all' => ".efbbbf_bom_char_at_start_of_file {}\n" ],
331                         'Leading BOM removed when concatenating files'
332                 );
333         }
334
335         /**
336          * @covers ResourceLoaderFileModule::getDefinitionSummary
337          */
338         public function testGetVersionHash() {
339                 $context = $this->getResourceLoaderContext();
340
341                 // Less variables
342                 $module = new ResourceLoaderFileTestModule();
343                 $version = $module->getVersionHash( $context );
344                 $module = new ResourceLoaderFileTestModule( [], [
345                         'lessVars' => [ 'key' => 'value' ],
346                 ] );
347                 $this->assertNotEquals(
348                         $version,
349                         $module->getVersionHash( $context ),
350                         'Using less variables is significant'
351                 );
352         }
353 }