Merge "Reset services before every test"
[lhc/web/wiklou.git] / tests / phpunit / includes / registration / ExtensionRegistryTest.php
1 <?php
2
3 /**
4 * @covers ExtensionRegistry
5 */
6 class ExtensionRegistryTest extends MediaWikiTestCase {
7
8 private $dataDir;
9
10 public function setUp() {
11 parent::setUp();
12 $this->dataDir = __DIR__ . '/../../data/registration';
13 }
14
15 public function testQueue_invalid() {
16 $registry = new ExtensionRegistry();
17 $path = __DIR__ . '/doesnotexist.json';
18 $this->setExpectedException(
19 Exception::class,
20 "$path does not exist!"
21 );
22 $registry->queue( $path );
23 }
24
25 public function testQueue() {
26 $registry = new ExtensionRegistry();
27 $path = "{$this->dataDir}/good.json";
28 $registry->queue( $path );
29 $this->assertArrayHasKey(
30 $path,
31 $registry->getQueue()
32 );
33 $registry->clearQueue();
34 $this->assertEmpty( $registry->getQueue() );
35 }
36
37 public function testLoadFromQueue_empty() {
38 $registry = new ExtensionRegistry();
39 $registry->loadFromQueue();
40 $this->assertEmpty( $registry->getAllThings() );
41 }
42
43 public function testLoadFromQueue_late() {
44 $registry = new ExtensionRegistry();
45 $registry->finish();
46 $registry->queue( "{$this->dataDir}/good.json" );
47 $this->setExpectedException(
48 MWException::class,
49 "The following paths tried to load late: {$this->dataDir}/good.json"
50 );
51 $registry->loadFromQueue();
52 }
53
54 public function testLoadFromQueue() {
55 $registry = new ExtensionRegistry();
56 $registry->queue( "{$this->dataDir}/good.json" );
57 $registry->loadFromQueue();
58 $this->assertArrayHasKey( 'FooBar', $registry->getAllThings() );
59 $this->assertTrue( $registry->isLoaded( 'FooBar' ) );
60 $this->assertTrue( $registry->isLoaded( 'FooBar', '*' ) );
61 $this->assertSame( [ 'test' ], $registry->getAttribute( 'FooBarAttr' ) );
62 $this->assertSame( [], $registry->getAttribute( 'NotLoadedAttr' ) );
63 }
64
65 public function testLoadFromQueueWithConstraintWithVersion() {
66 $registry = new ExtensionRegistry();
67 $registry->queue( "{$this->dataDir}/good_with_version.json" );
68 $registry->loadFromQueue();
69 $this->assertTrue( $registry->isLoaded( 'FooBar', '>= 1.2.0' ) );
70 $this->assertFalse( $registry->isLoaded( 'FooBar', '^1.3.0' ) );
71 }
72
73 /**
74 * @expectedException LogicException
75 */
76 public function testLoadFromQueueWithConstraintWithoutVersion() {
77 $registry = new ExtensionRegistry();
78 $registry->queue( "{$this->dataDir}/good.json" );
79 $registry->loadFromQueue();
80 $registry->isLoaded( 'FooBar', '>= 1.2.0' );
81 }
82
83 /**
84 * @expectedException PHPUnit_Framework_Error
85 */
86 public function testReadFromQueue_nonexistent() {
87 $registry = new ExtensionRegistry();
88 $registry->readFromQueue( [
89 __DIR__ . '/doesnotexist.json' => 1
90 ] );
91 }
92
93 public function testReadFromQueueInitializeAutoloaderWithPsr4Namespaces() {
94 $registry = new ExtensionRegistry();
95 $registry->readFromQueue( [
96 "{$this->dataDir}/autoload_namespaces.json" => 1
97 ] );
98 $this->assertTrue(
99 class_exists( 'Test\\MediaWiki\\AutoLoader\\TestFooBar' ),
100 "Registry initializes Autoloader from AutoloadNamespaces"
101 );
102 }
103
104 /**
105 * @dataProvider provideExportExtractedDataGlobals
106 */
107 public function testExportExtractedDataGlobals( $desc, $before, $globals, $expected ) {
108 // Set globals for test
109 if ( $before ) {
110 foreach ( $before as $key => $value ) {
111 // mw prefixed globals does not exist normally
112 if ( substr( $key, 0, 2 ) == 'mw' ) {
113 $GLOBALS[$key] = $value;
114 } else {
115 $this->setMwGlobals( $key, $value );
116 }
117 }
118 }
119
120 $info = [
121 'globals' => $globals,
122 'callbacks' => [],
123 'defines' => [],
124 'credits' => [],
125 'attributes' => [],
126 'autoloaderPaths' => []
127 ];
128 $registry = new ExtensionRegistry();
129 $class = new ReflectionClass( ExtensionRegistry::class );
130 $method = $class->getMethod( 'exportExtractedData' );
131 $method->setAccessible( true );
132 $method->invokeArgs( $registry, [ $info ] );
133 foreach ( $expected as $name => $value ) {
134 $this->assertArrayHasKey( $name, $GLOBALS, $desc );
135 $this->assertEquals( $value, $GLOBALS[$name], $desc );
136 }
137
138 // Remove mw prefixed globals
139 if ( $before ) {
140 foreach ( $before as $key => $value ) {
141 if ( substr( $key, 0, 2 ) == 'mw' ) {
142 unset( $GLOBALS[$key] );
143 }
144 }
145 }
146 }
147
148 public static function provideExportExtractedDataGlobals() {
149 // "mwtest" prefix used instead of "$wg" to avoid potential conflicts
150 return [
151 [
152 'Simple non-array values',
153 [
154 'mwtestFooBarConfig' => true,
155 'mwtestFooBarConfig2' => 'string',
156 ],
157 [
158 'mwtestFooBarDefault' => 1234,
159 'mwtestFooBarConfig' => false,
160 ],
161 [
162 'mwtestFooBarConfig' => true,
163 'mwtestFooBarConfig2' => 'string',
164 'mwtestFooBarDefault' => 1234,
165 ],
166 ],
167 [
168 'No global already set, simple array',
169 null,
170 [
171 'mwtestDefaultOptions' => [
172 'foobar' => true,
173 ]
174 ],
175 [
176 'mwtestDefaultOptions' => [
177 'foobar' => true,
178 ]
179 ],
180 ],
181 [
182 'Global already set, simple array',
183 [
184 'mwtestDefaultOptions' => [
185 'foobar' => true,
186 'foo' => 'string'
187 ],
188 ],
189 [
190 'mwtestDefaultOptions' => [
191 'barbaz' => 12345,
192 'foobar' => false,
193 ],
194 ],
195 [
196 'mwtestDefaultOptions' => [
197 'barbaz' => 12345,
198 'foo' => 'string',
199 'foobar' => true,
200 ],
201 ]
202 ],
203 [
204 'Global already set, 1d array that appends',
205 [
206 'mwAvailableRights' => [
207 'foobar',
208 'foo'
209 ],
210 ],
211 [
212 'mwAvailableRights' => [
213 'barbaz',
214 ],
215 ],
216 [
217 'mwAvailableRights' => [
218 'barbaz',
219 'foobar',
220 'foo',
221 ],
222 ]
223 ],
224 [
225 'Global already set, array with integer keys',
226 [
227 'mwNamespacesFoo' => [
228 100 => true,
229 102 => false
230 ],
231 ],
232 [
233 'mwNamespacesFoo' => [
234 100 => false,
235 500 => true,
236 ExtensionRegistry::MERGE_STRATEGY => 'array_plus',
237 ],
238 ],
239 [
240 'mwNamespacesFoo' => [
241 100 => true,
242 102 => false,
243 500 => true,
244 ],
245 ]
246 ],
247 [
248 'No global already set, $wgHooks',
249 [
250 'wgHooks' => [],
251 ],
252 [
253 'wgHooks' => [
254 'FooBarEvent' => [
255 'FooBarClass::onFooBarEvent'
256 ],
257 ExtensionRegistry::MERGE_STRATEGY => 'array_merge_recursive'
258 ],
259 ],
260 [
261 'wgHooks' => [
262 'FooBarEvent' => [
263 'FooBarClass::onFooBarEvent'
264 ],
265 ],
266 ],
267 ],
268 [
269 'Global already set, $wgHooks',
270 [
271 'wgHooks' => [
272 'FooBarEvent' => [
273 'FooBarClass::onFooBarEvent'
274 ],
275 'BazBarEvent' => [
276 'FooBarClass::onBazBarEvent',
277 ],
278 ],
279 ],
280 [
281 'wgHooks' => [
282 'FooBarEvent' => [
283 'BazBarClass::onFooBarEvent',
284 ],
285 ExtensionRegistry::MERGE_STRATEGY => 'array_merge_recursive',
286 ],
287 ],
288 [
289 'wgHooks' => [
290 'FooBarEvent' => [
291 'FooBarClass::onFooBarEvent',
292 'BazBarClass::onFooBarEvent',
293 ],
294 'BazBarEvent' => [
295 'FooBarClass::onBazBarEvent',
296 ],
297 ],
298 ],
299 ],
300 [
301 'Global already set, $wgGroupPermissions',
302 [
303 'wgGroupPermissions' => [
304 'sysop' => [
305 'something' => true,
306 ],
307 'user' => [
308 'somethingtwo' => true,
309 ]
310 ],
311 ],
312 [
313 'wgGroupPermissions' => [
314 'customgroup' => [
315 'right' => true,
316 ],
317 'user' => [
318 'right' => true,
319 'somethingtwo' => false,
320 'nonduplicated' => true,
321 ],
322 ExtensionRegistry::MERGE_STRATEGY => 'array_plus_2d',
323 ],
324 ],
325 [
326 'wgGroupPermissions' => [
327 'customgroup' => [
328 'right' => true,
329 ],
330 'sysop' => [
331 'something' => true,
332 ],
333 'user' => [
334 'somethingtwo' => true,
335 'right' => true,
336 'nonduplicated' => true,
337 ]
338 ],
339 ],
340 ],
341 [
342 'False local setting should not be overridden (T100767)',
343 [
344 'mwtestT100767' => false,
345 ],
346 [
347 'mwtestT100767' => true,
348 ],
349 [
350 'mwtestT100767' => false,
351 ],
352 ],
353 [
354 'test array_replace_recursive',
355 [
356 'mwtestJsonConfigs' => [
357 'JsonZeroConfig' => [
358 'namespace' => 480,
359 'nsName' => 'Zero',
360 'isLocal' => true,
361 ],
362 ],
363 ],
364 [
365 'mwtestJsonConfigs' => [
366 'JsonZeroConfig' => [
367 'isLocal' => false,
368 'remote' => [
369 'username' => 'foo',
370 ],
371 ],
372 ExtensionRegistry::MERGE_STRATEGY => 'array_replace_recursive',
373 ],
374 ],
375 [
376 'mwtestJsonConfigs' => [
377 'JsonZeroConfig' => [
378 'namespace' => 480,
379 'nsName' => 'Zero',
380 'isLocal' => false,
381 'remote' => [
382 'username' => 'foo',
383 ],
384 ],
385 ],
386 ],
387 ],
388 [
389 'global is null before',
390 [
391 'NullGlobal' => null,
392 ],
393 [
394 'NullGlobal' => 'not-null'
395 ],
396 [
397 'NullGlobal' => null
398 ],
399 ],
400 ];
401 }
402 }