Remove "@author Aaron Schulz" annotations
[lhc/web/wiklou.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 $rl = new ResourceLoaderFileModule( $modules[$name] );
136 $rl->setName( $name );
137 $ctx = $this->getResourceLoaderContext();
138 $this->assertEquals( $rl->getScript( $ctx ), $expected );
139 }
140
141 /**
142 * @covers ResourceLoaderFileModule::getAllStyleFiles
143 * @covers ResourceLoaderFileModule::getAllSkinStyleFiles
144 * @covers ResourceLoaderFileModule::getSkinStyleFiles
145 */
146 public function testGetAllSkinStyleFiles() {
147 $baseParams = [
148 'scripts' => [
149 'foo.js',
150 'bar.js',
151 ],
152 'styles' => [
153 'foo.css',
154 'bar.css' => [ 'media' => 'print' ],
155 'screen.less' => [ 'media' => 'screen' ],
156 'screen-query.css' => [ 'media' => 'screen and (min-width: 400px)' ],
157 ],
158 'skinStyles' => [
159 'default' => 'quux-fallback.less',
160 'fakeskin' => [
161 'baz-vector.css',
162 'quux-vector.less',
163 ],
164 ],
165 'messages' => [
166 'hello',
167 'world',
168 ],
169 ];
170
171 $module = new ResourceLoaderFileModule( $baseParams );
172 $module->setName( 'testing' );
173
174 $this->assertEquals(
175 [
176 'foo.css',
177 'baz-vector.css',
178 'quux-vector.less',
179 'quux-fallback.less',
180 'bar.css',
181 'screen.less',
182 'screen-query.css',
183 ],
184 array_map( 'basename', $module->getAllStyleFiles() )
185 );
186 }
187
188 /**
189 * Strip @noflip annotations from CSS code.
190 * @param string $css
191 * @return string
192 */
193 private static function stripNoflip( $css ) {
194 return str_replace( '/*@noflip*/ ', '', $css );
195 }
196
197 /**
198 * What happens when you mix @embed and @noflip?
199 * This really is an integration test, but oh well.
200 *
201 * @covers ResourceLoaderFileModule::getStyles
202 * @covers ResourceLoaderFileModule::getStyleFiles
203 */
204 public function testMixedCssAnnotations() {
205 $basePath = __DIR__ . '/../../data/css';
206 $testModule = new ResourceLoaderFileModule( [
207 'localBasePath' => $basePath,
208 'styles' => [ 'test.css' ],
209 ] );
210 $testModule->setName( 'testing' );
211 $expectedModule = new ResourceLoaderFileModule( [
212 'localBasePath' => $basePath,
213 'styles' => [ 'expected.css' ],
214 ] );
215 $expectedModule->setName( 'testing' );
216
217 $contextLtr = $this->getResourceLoaderContext( [
218 'lang' => 'en',
219 'dir' => 'ltr',
220 ] );
221 $contextRtl = $this->getResourceLoaderContext( [
222 'lang' => 'he',
223 'dir' => 'rtl',
224 ] );
225
226 // Since we want to compare the effect of @noflip+@embed against the effect of just @embed, and
227 // the @noflip annotations are always preserved, we need to strip them first.
228 $this->assertEquals(
229 $expectedModule->getStyles( $contextLtr ),
230 self::stripNoflip( $testModule->getStyles( $contextLtr ) ),
231 "/*@noflip*/ with /*@embed*/ gives correct results in LTR mode"
232 );
233 $this->assertEquals(
234 $expectedModule->getStyles( $contextLtr ),
235 self::stripNoflip( $testModule->getStyles( $contextRtl ) ),
236 "/*@noflip*/ with /*@embed*/ gives correct results in RTL mode"
237 );
238 }
239
240 public static function providerGetTemplates() {
241 $modules = self::getModules();
242
243 return [
244 [
245 $modules['noTemplateModule'],
246 [],
247 ],
248 [
249 $modules['templateModuleHandlebars'],
250 [
251 'templates/template_awesome.handlebars' => "wow\n",
252 ],
253 ],
254 [
255 $modules['htmlTemplateModule'],
256 [
257 'templates/template.html' => "<strong>hello</strong>\n",
258 'templates/template2.html' => "<div>goodbye</div>\n",
259 ],
260 ],
261 [
262 $modules['aliasedHtmlTemplateModule'],
263 [
264 'foo.html' => "<strong>hello</strong>\n",
265 'bar.html' => "<div>goodbye</div>\n",
266 ],
267 ],
268 [
269 $modules['htmlTemplateUnknown'],
270 false,
271 ],
272 ];
273 }
274
275 /**
276 * @dataProvider providerGetTemplates
277 * @covers ResourceLoaderFileModule::getTemplates
278 */
279 public function testGetTemplates( $module, $expected ) {
280 $rl = new ResourceLoaderFileModule( $module );
281 $rl->setName( 'testing' );
282
283 if ( $expected === false ) {
284 $this->setExpectedException( MWException::class );
285 $rl->getTemplates();
286 } else {
287 $this->assertEquals( $rl->getTemplates(), $expected );
288 }
289 }
290
291 /**
292 * @covers ResourceLoaderFileModule::stripBom
293 */
294 public function testBomConcatenation() {
295 $basePath = __DIR__ . '/../../data/css';
296 $testModule = new ResourceLoaderFileModule( [
297 'localBasePath' => $basePath,
298 'styles' => [ 'bom.css' ],
299 ] );
300 $testModule->setName( 'testing' );
301 $this->assertEquals(
302 substr( file_get_contents( "$basePath/bom.css" ), 0, 10 ),
303 "\xef\xbb\xbf.efbbbf",
304 'File has leading BOM'
305 );
306
307 $context = $this->getResourceLoaderContext();
308 $this->assertEquals(
309 $testModule->getStyles( $context ),
310 [ 'all' => ".efbbbf_bom_char_at_start_of_file {}\n" ],
311 'Leading BOM removed when concatenating files'
312 );
313 }
314 }