Merge "Title: Title::getSubpage should not lose the interwiki prefix"
[lhc/web/wiklou.git] / tests / phpunit / includes / resourceloader / ResourceLoaderModuleTest.php
1 <?php
2
3 class ResourceLoaderModuleTest extends ResourceLoaderTestCase {
4
5 /**
6 * @covers ResourceLoaderModule::getVersionHash
7 */
8 public function testGetVersionHash() {
9 $context = $this->getResourceLoaderContext();
10
11 $baseParams = [
12 'scripts' => [ 'foo.js', 'bar.js' ],
13 'dependencies' => [ 'jquery', 'mediawiki' ],
14 'messages' => [ 'hello', 'world' ],
15 ];
16
17 $module = new ResourceLoaderFileModule( $baseParams );
18 $version = json_encode( $module->getVersionHash( $context ) );
19
20 // Exactly the same
21 $module = new ResourceLoaderFileModule( $baseParams );
22 $this->assertEquals(
23 $version,
24 json_encode( $module->getVersionHash( $context ) ),
25 'Instance is insignificant'
26 );
27
28 // Re-order dependencies
29 $module = new ResourceLoaderFileModule( [
30 'dependencies' => [ 'mediawiki', 'jquery' ],
31 ] + $baseParams );
32 $this->assertEquals(
33 $version,
34 json_encode( $module->getVersionHash( $context ) ),
35 'Order of dependencies is insignificant'
36 );
37
38 // Re-order messages
39 $module = new ResourceLoaderFileModule( [
40 'messages' => [ 'world', 'hello' ],
41 ] + $baseParams );
42 $this->assertEquals(
43 $version,
44 json_encode( $module->getVersionHash( $context ) ),
45 'Order of messages is insignificant'
46 );
47
48 // Re-order scripts
49 $module = new ResourceLoaderFileModule( [
50 'scripts' => [ 'bar.js', 'foo.js' ],
51 ] + $baseParams );
52 $this->assertNotEquals(
53 $version,
54 json_encode( $module->getVersionHash( $context ) ),
55 'Order of scripts is significant'
56 );
57
58 // Subclass
59 $module = new ResourceLoaderFileModuleTestingSubclass( $baseParams );
60 $this->assertNotEquals(
61 $version,
62 json_encode( $module->getVersionHash( $context ) ),
63 'Class is significant'
64 );
65 }
66
67 /**
68 * @covers ResourceLoaderModule::getVersionHash
69 */
70 public function testGetVersionHash_parentDefinition() {
71 $context = $this->getResourceLoaderContext();
72 $module = $this->getMockBuilder( ResourceLoaderModule::class )
73 ->setMethods( [ 'getDefinitionSummary' ] )->getMock();
74 $module->method( 'getDefinitionSummary' )->willReturn( [ 'a' => 'summary' ] );
75
76 $this->setExpectedException( LogicException::class, 'must call parent' );
77 $module->getVersionHash( $context );
78 }
79
80 /**
81 * @covers ResourceLoaderModule::validateScriptFile
82 */
83 public function testValidateScriptFile() {
84 $this->setMwGlobals( 'wgResourceLoaderValidateJS', true );
85
86 $context = $this->getResourceLoaderContext();
87
88 $module = new ResourceLoaderTestModule( [
89 'mayValidateScript' => true,
90 'script' => "var a = 'this is';\n {\ninvalid"
91 ] );
92 $this->assertEquals(
93 'mw.log.error(' .
94 '"JavaScript parse error: Parse error: Unexpected token; ' .
95 'token } expected in file \'input\' on line 3"' .
96 ');',
97 $module->getScript( $context ),
98 'Replace invalid syntax with error logging'
99 );
100
101 $module = new ResourceLoaderTestModule( [
102 'script' => "\n'valid';"
103 ] );
104 $this->assertEquals(
105 "\n'valid';",
106 $module->getScript( $context ),
107 'Leave valid scripts as-is'
108 );
109 }
110
111 public static function provideBuildContentScripts() {
112 return [
113 [
114 "mw.foo()",
115 "mw.foo()\n",
116 ],
117 [
118 "mw.foo();",
119 "mw.foo();\n",
120 ],
121 [
122 "mw.foo();\n",
123 "mw.foo();\n",
124 ],
125 [
126 "mw.foo()\n",
127 "mw.foo()\n",
128 ],
129 [
130 "mw.foo()\n// mw.bar();",
131 "mw.foo()\n// mw.bar();\n",
132 ],
133 [
134 "mw.foo()\n// mw.bar()",
135 "mw.foo()\n// mw.bar()\n",
136 ],
137 [
138 "mw.foo()// mw.bar();",
139 "mw.foo()// mw.bar();\n",
140 ],
141 ];
142 }
143
144 /**
145 * @dataProvider provideBuildContentScripts
146 * @covers ResourceLoaderModule::buildContent
147 */
148 public function testBuildContentScripts( $raw, $build, $message = null ) {
149 $context = $this->getResourceLoaderContext();
150 $module = new ResourceLoaderTestModule( [
151 'script' => $raw
152 ] );
153 $this->assertEquals( $raw, $module->getScript( $context ), 'Raw script' );
154 $this->assertEquals(
155 $build,
156 $module->getModuleContent( $context )[ 'scripts' ],
157 $message
158 );
159 }
160
161 /**
162 * @covers ResourceLoaderModule::getRelativePaths
163 * @covers ResourceLoaderModule::expandRelativePaths
164 */
165 public function testPlaceholderize() {
166 $getRelativePaths = new ReflectionMethod( ResourceLoaderModule::class, 'getRelativePaths' );
167 $getRelativePaths->setAccessible( true );
168 $expandRelativePaths = new ReflectionMethod( ResourceLoaderModule::class, 'expandRelativePaths' );
169 $expandRelativePaths->setAccessible( true );
170
171 $this->setMwGlobals( [
172 'IP' => '/srv/example/mediawiki/core',
173 ] );
174 $raw = [
175 '/srv/example/mediawiki/core/resources/foo.js',
176 '/srv/example/mediawiki/core/extensions/Example/modules/bar.js',
177 '/srv/example/mediawiki/skins/Example/baz.css',
178 '/srv/example/mediawiki/skins/Example/images/quux.png',
179 ];
180 $canonical = [
181 'resources/foo.js',
182 'extensions/Example/modules/bar.js',
183 '../skins/Example/baz.css',
184 '../skins/Example/images/quux.png',
185 ];
186 $this->assertEquals(
187 $canonical,
188 $getRelativePaths->invoke( null, $raw ),
189 'Insert placeholders'
190 );
191 $this->assertEquals(
192 $raw,
193 $expandRelativePaths->invoke( null, $canonical ),
194 'Substitute placeholders'
195 );
196 }
197
198 /**
199 * @covers ResourceLoaderModule::getHeaders
200 * @covers ResourceLoaderModule::getPreloadLinks
201 */
202 public function testGetHeaders() {
203 $context = $this->getResourceLoaderContext();
204
205 $module = new ResourceLoaderTestModule();
206 $this->assertSame( [], $module->getHeaders( $context ), 'Default' );
207
208 $module = $this->getMockBuilder( ResourceLoaderTestModule::class )
209 ->setMethods( [ 'getPreloadLinks' ] )->getMock();
210 $module->method( 'getPreloadLinks' )->willReturn( [
211 'https://example.org/script.js' => [ 'as' => 'script' ],
212 ] );
213 $this->assertSame(
214 [
215 'Link: <https://example.org/script.js>;rel=preload;as=script'
216 ],
217 $module->getHeaders( $context ),
218 'Preload one resource'
219 );
220
221 $module = $this->getMockBuilder( ResourceLoaderTestModule::class )
222 ->setMethods( [ 'getPreloadLinks' ] )->getMock();
223 $module->method( 'getPreloadLinks' )->willReturn( [
224 'https://example.org/script.js' => [ 'as' => 'script' ],
225 '/example.png' => [ 'as' => 'image' ],
226 ] );
227 $this->assertSame(
228 [
229 'Link: <https://example.org/script.js>;rel=preload;as=script,' .
230 '</example.png>;rel=preload;as=image'
231 ],
232 $module->getHeaders( $context ),
233 'Preload two resources'
234 );
235 }
236 }