Merge "Language: s/error_log/wfWarn/"
[lhc/web/wiklou.git] / tests / phpunit / includes / GlobalFunctions / GlobalTest.php
1 <?php
2
3 /**
4 * @group GlobalFunctions
5 */
6 class GlobalTest extends MediaWikiTestCase {
7 protected function setUp() {
8 parent::setUp();
9
10 $readOnlyFile = tempnam( wfTempDir(), "mwtest_readonly" );
11 unlink( $readOnlyFile );
12
13 $this->setMwGlobals( array(
14 'wgReadOnlyFile' => $readOnlyFile,
15 'wgUrlProtocols' => array(
16 'http://',
17 'https://',
18 'mailto:',
19 '//',
20 'file://', # Non-default
21 ),
22 ) );
23 }
24
25 protected function tearDown() {
26 global $wgReadOnlyFile;
27
28 if ( file_exists( $wgReadOnlyFile ) ) {
29 unlink( $wgReadOnlyFile );
30 }
31
32 parent::tearDown();
33 }
34
35 /**
36 * @dataProvider provideForWfArrayDiff2
37 * @covers ::wfArrayDiff2
38 */
39 public function testWfArrayDiff2( $a, $b, $expected ) {
40 $this->assertEquals(
41 wfArrayDiff2( $a, $b ), $expected
42 );
43 }
44
45 // @todo Provide more tests
46 public static function provideForWfArrayDiff2() {
47 // $a $b $expected
48 return array(
49 array(
50 array( 'a', 'b' ),
51 array( 'a', 'b' ),
52 array(),
53 ),
54 array(
55 array( array( 'a' ), array( 'a', 'b', 'c' ) ),
56 array( array( 'a' ), array( 'a', 'b' ) ),
57 array( 1 => array( 'a', 'b', 'c' ) ),
58 ),
59 );
60 }
61
62 /*
63 * Test cases for random functions could hypothetically fail,
64 * even though they shouldn't.
65 */
66
67 /**
68 * @covers ::wfRandom
69 */
70 public function testRandom() {
71 $this->assertFalse(
72 wfRandom() == wfRandom()
73 );
74 }
75
76 /**
77 * @covers ::wfRandomString
78 */
79 public function testRandomString() {
80 $this->assertFalse(
81 wfRandomString() == wfRandomString()
82 );
83 $this->assertEquals(
84 strlen( wfRandomString( 10 ) ), 10
85 );
86 $this->assertTrue(
87 preg_match( '/^[0-9a-f]+$/i', wfRandomString() ) === 1
88 );
89 }
90
91 /**
92 * @covers ::wfUrlencode
93 */
94 public function testUrlencode() {
95 $this->assertEquals(
96 "%E7%89%B9%E5%88%A5:Contributions/Foobar",
97 wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) );
98 }
99
100 /**
101 * @covers ::wfExpandIRI
102 */
103 public function testExpandIRI() {
104 $this->assertEquals(
105 "https://te.wikibooks.org/wiki/ఉబుంటు_వాడుకరి_మార్గదర్శని",
106 wfExpandIRI( "https://te.wikibooks.org/wiki/"
107 . "%E0%B0%89%E0%B0%AC%E0%B1%81%E0%B0%82%E0%B0%9F%E0%B1%81_"
108 . "%E0%B0%B5%E0%B0%BE%E0%B0%A1%E0%B1%81%E0%B0%95%E0%B0%B0%E0%B0%BF_"
109 . "%E0%B0%AE%E0%B0%BE%E0%B0%B0%E0%B1%8D%E0%B0%97%E0%B0%A6%E0%B0%B0"
110 . "%E0%B1%8D%E0%B0%B6%E0%B0%A8%E0%B0%BF" ) );
111 }
112
113 /**
114 * @covers ::wfReadOnly
115 */
116 public function testReadOnlyEmpty() {
117 global $wgReadOnly;
118 $wgReadOnly = null;
119
120 $this->assertFalse( wfReadOnly() );
121 $this->assertFalse( wfReadOnly() );
122 }
123
124 /**
125 * @covers ::wfReadOnly
126 */
127 public function testReadOnlySet() {
128 global $wgReadOnly, $wgReadOnlyFile;
129
130 $f = fopen( $wgReadOnlyFile, "wt" );
131 fwrite( $f, 'Message' );
132 fclose( $f );
133 $wgReadOnly = null; # Check on $wgReadOnlyFile
134
135 $this->assertTrue( wfReadOnly() );
136 $this->assertTrue( wfReadOnly() ); # Check cached
137
138 unlink( $wgReadOnlyFile );
139 $wgReadOnly = null; # Clean cache
140
141 $this->assertFalse( wfReadOnly() );
142 $this->assertFalse( wfReadOnly() );
143 }
144
145 public static function provideArrayToCGI() {
146 return array(
147 array( array(), '' ), // empty
148 array( array( 'foo' => 'bar' ), 'foo=bar' ), // string test
149 array( array( 'foo' => '' ), 'foo=' ), // empty string test
150 array( array( 'foo' => 1 ), 'foo=1' ), // number test
151 array( array( 'foo' => true ), 'foo=1' ), // true test
152 array( array( 'foo' => false ), '' ), // false test
153 array( array( 'foo' => null ), '' ), // null test
154 array( array( 'foo' => 'A&B=5+6@!"\'' ), 'foo=A%26B%3D5%2B6%40%21%22%27' ), // urlencoding test
155 array(
156 array( 'foo' => 'bar', 'baz' => 'is', 'asdf' => 'qwerty' ),
157 'foo=bar&baz=is&asdf=qwerty'
158 ), // multi-item test
159 array( array( 'foo' => array( 'bar' => 'baz' ) ), 'foo%5Bbar%5D=baz' ),
160 array(
161 array( 'foo' => array( 'bar' => 'baz', 'qwerty' => 'asdf' ) ),
162 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf'
163 ),
164 array( array( 'foo' => array( 'bar', 'baz' ) ), 'foo%5B0%5D=bar&foo%5B1%5D=baz' ),
165 array(
166 array( 'foo' => array( 'bar' => array( 'bar' => 'baz' ) ) ),
167 'foo%5Bbar%5D%5Bbar%5D=baz'
168 ),
169 );
170 }
171
172 /**
173 * @dataProvider provideArrayToCGI
174 * @covers ::wfArrayToCgi
175 */
176 public function testArrayToCGI( $array, $result ) {
177 $this->assertEquals( $result, wfArrayToCgi( $array ) );
178 }
179
180 /**
181 * @covers ::wfArrayToCgi
182 */
183 public function testArrayToCGI2() {
184 $this->assertEquals(
185 "baz=bar&foo=bar",
186 wfArrayToCgi(
187 array( 'baz' => 'bar' ),
188 array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) );
189 }
190
191 public static function provideCgiToArray() {
192 return array(
193 array( '', array() ), // empty
194 array( 'foo=bar', array( 'foo' => 'bar' ) ), // string
195 array( 'foo=', array( 'foo' => '' ) ), // empty string
196 array( 'foo', array( 'foo' => '' ) ), // missing =
197 array( 'foo=bar&qwerty=asdf', array( 'foo' => 'bar', 'qwerty' => 'asdf' ) ), // multiple value
198 array( 'foo=A%26B%3D5%2B6%40%21%22%27', array( 'foo' => 'A&B=5+6@!"\'' ) ), // urldecoding test
199 array( 'foo%5Bbar%5D=baz', array( 'foo' => array( 'bar' => 'baz' ) ) ),
200 array(
201 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf',
202 array( 'foo' => array( 'bar' => 'baz', 'qwerty' => 'asdf' ) )
203 ),
204 array( 'foo%5B0%5D=bar&foo%5B1%5D=baz', array( 'foo' => array( 0 => 'bar', 1 => 'baz' ) ) ),
205 array(
206 'foo%5Bbar%5D%5Bbar%5D=baz',
207 array( 'foo' => array( 'bar' => array( 'bar' => 'baz' ) ) )
208 ),
209 );
210 }
211
212 /**
213 * @dataProvider provideCgiToArray
214 * @covers ::wfCgiToArray
215 */
216 public function testCgiToArray( $cgi, $result ) {
217 $this->assertEquals( $result, wfCgiToArray( $cgi ) );
218 }
219
220 public static function provideCgiRoundTrip() {
221 return array(
222 array( '' ),
223 array( 'foo=bar' ),
224 array( 'foo=' ),
225 array( 'foo=bar&baz=biz' ),
226 array( 'foo=A%26B%3D5%2B6%40%21%22%27' ),
227 array( 'foo%5Bbar%5D=baz' ),
228 array( 'foo%5B0%5D=bar&foo%5B1%5D=baz' ),
229 array( 'foo%5Bbar%5D%5Bbar%5D=baz' ),
230 );
231 }
232
233 /**
234 * @dataProvider provideCgiRoundTrip
235 * @covers ::wfArrayToCgi
236 */
237 public function testCgiRoundTrip( $cgi ) {
238 $this->assertEquals( $cgi, wfArrayToCgi( wfCgiToArray( $cgi ) ) );
239 }
240
241 /**
242 * @covers ::mimeTypeMatch
243 */
244 public function testMimeTypeMatch() {
245 $this->assertEquals(
246 'text/html',
247 mimeTypeMatch( 'text/html',
248 array( 'application/xhtml+xml' => 1.0,
249 'text/html' => 0.7,
250 'text/plain' => 0.3 ) ) );
251 $this->assertEquals(
252 'text/*',
253 mimeTypeMatch( 'text/html',
254 array( 'image/*' => 1.0,
255 'text/*' => 0.5 ) ) );
256 $this->assertEquals(
257 '*/*',
258 mimeTypeMatch( 'text/html',
259 array( '*/*' => 1.0 ) ) );
260 $this->assertNull(
261 mimeTypeMatch( 'text/html',
262 array( 'image/png' => 1.0,
263 'image/svg+xml' => 0.5 ) ) );
264 }
265
266 /**
267 * @covers ::wfNegotiateType
268 */
269 public function testNegotiateType() {
270 $this->assertEquals(
271 'text/html',
272 wfNegotiateType(
273 array( 'application/xhtml+xml' => 1.0,
274 'text/html' => 0.7,
275 'text/plain' => 0.5,
276 'text/*' => 0.2 ),
277 array( 'text/html' => 1.0 ) ) );
278 $this->assertEquals(
279 'application/xhtml+xml',
280 wfNegotiateType(
281 array( 'application/xhtml+xml' => 1.0,
282 'text/html' => 0.7,
283 'text/plain' => 0.5,
284 'text/*' => 0.2 ),
285 array( 'application/xhtml+xml' => 1.0,
286 'text/html' => 0.5 ) ) );
287 $this->assertEquals(
288 'text/html',
289 wfNegotiateType(
290 array( 'text/html' => 1.0,
291 'text/plain' => 0.5,
292 'text/*' => 0.5,
293 'application/xhtml+xml' => 0.2 ),
294 array( 'application/xhtml+xml' => 1.0,
295 'text/html' => 0.5 ) ) );
296 $this->assertEquals(
297 'text/html',
298 wfNegotiateType(
299 array( 'text/*' => 1.0,
300 'image/*' => 0.7,
301 '*/*' => 0.3 ),
302 array( 'application/xhtml+xml' => 1.0,
303 'text/html' => 0.5 ) ) );
304 $this->assertNull(
305 wfNegotiateType(
306 array( 'text/*' => 1.0 ),
307 array( 'application/xhtml+xml' => 1.0 ) ) );
308 }
309
310 /**
311 * @covers ::wfDebug
312 * @covers ::wfDebugMem
313 */
314 public function testDebugFunctionTest() {
315
316 global $wgDebugLogFile, $wgDebugTimestamps;
317
318 $old_log_file = $wgDebugLogFile;
319 $wgDebugLogFile = tempnam( wfTempDir(), 'mw-' );
320 # @todo FIXME: $wgDebugTimestamps should be tested
321 $old_wgDebugTimestamps = $wgDebugTimestamps;
322 $wgDebugTimestamps = false;
323
324 wfDebug( "This is a normal string" );
325 $this->assertEquals( "This is a normal string", file_get_contents( $wgDebugLogFile ) );
326 unlink( $wgDebugLogFile );
327
328 wfDebug( "This is nöt an ASCII string" );
329 $this->assertEquals( "This is nöt an ASCII string", file_get_contents( $wgDebugLogFile ) );
330 unlink( $wgDebugLogFile );
331
332 wfDebug( "\00305This has böth UTF and control chars\003" );
333 $this->assertEquals(
334 " 05This has böth UTF and control chars ",
335 file_get_contents( $wgDebugLogFile )
336 );
337 unlink( $wgDebugLogFile );
338
339 wfDebugMem();
340 $this->assertGreaterThan(
341 1000,
342 preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) )
343 );
344 unlink( $wgDebugLogFile );
345
346 wfDebugMem( true );
347 $this->assertGreaterThan(
348 1000000,
349 preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) )
350 );
351 unlink( $wgDebugLogFile );
352
353 $wgDebugLogFile = $old_log_file;
354 $wgDebugTimestamps = $old_wgDebugTimestamps;
355 }
356
357 /**
358 * @covers ::wfClientAcceptsGzip
359 */
360 public function testClientAcceptsGzipTest() {
361
362 $settings = array(
363 'gzip' => true,
364 'bzip' => false,
365 '*' => false,
366 'compress, gzip' => true,
367 'gzip;q=1.0' => true,
368 'foozip' => false,
369 'foo*zip' => false,
370 'gzip;q=abcde' => true, //is this REALLY valid?
371 'gzip;q=12345678.9' => true,
372 ' gzip' => true,
373 );
374
375 if ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
376 $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING'];
377 }
378
379 foreach ( $settings as $encoding => $expect ) {
380 $_SERVER['HTTP_ACCEPT_ENCODING'] = $encoding;
381
382 $this->assertEquals( $expect, wfClientAcceptsGzip( true ),
383 "'$encoding' => " . wfBoolToStr( $expect ) );
384 }
385
386 if ( isset( $old_server_setting ) ) {
387 $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting;
388 }
389 }
390
391 /**
392 * @covers ::swap
393 */
394 public function testSwapVarsTest() {
395 $this->hideDeprecated( 'swap' );
396
397 $var1 = 1;
398 $var2 = 2;
399
400 $this->assertEquals( $var1, 1, 'var1 is set originally' );
401 $this->assertEquals( $var2, 2, 'var1 is set originally' );
402
403 swap( $var1, $var2 );
404
405 $this->assertEquals( $var1, 2, 'var1 is swapped' );
406 $this->assertEquals( $var2, 1, 'var2 is swapped' );
407 }
408
409 /**
410 * @covers ::wfPercent
411 */
412 public function testWfPercentTest() {
413
414 $pcts = array(
415 array( 6 / 7, '0.86%', 2, false ),
416 array( 3 / 3, '1%' ),
417 array( 22 / 7, '3.14286%', 5 ),
418 array( 3 / 6, '0.5%' ),
419 array( 1 / 3, '0%', 0 ),
420 array( 10 / 3, '0%', -1 ),
421 array( 3 / 4 / 5, '0.1%', 1 ),
422 array( 6 / 7 * 8, '6.8571428571%', 10 ),
423 );
424
425 foreach ( $pcts as $pct ) {
426 if ( !isset( $pct[2] ) ) {
427 $pct[2] = 2;
428 }
429 if ( !isset( $pct[3] ) ) {
430 $pct[3] = true;
431 }
432
433 $this->assertEquals( wfPercent( $pct[0], $pct[2], $pct[3] ), $pct[1], $pct[1] );
434 }
435 }
436
437 /**
438 * test @see wfShorthandToInteger()
439 * @dataProvider provideShorthand
440 * @covers ::wfShorthandToInteger
441 */
442 public function testWfShorthandToInteger( $shorthand, $expected ) {
443 $this->assertEquals( $expected,
444 wfShorthandToInteger( $shorthand )
445 );
446 }
447
448 /** array( shorthand, expected integer ) */
449 public static function provideShorthand() {
450 return array(
451 # Null, empty ...
452 array( '', -1 ),
453 array( ' ', -1 ),
454 array( null, -1 ),
455
456 # Failures returns 0 :(
457 array( 'ABCDEFG', 0 ),
458 array( 'Ak', 0 ),
459
460 # Int, strings with spaces
461 array( 1, 1 ),
462 array( ' 1 ', 1 ),
463 array( 1023, 1023 ),
464 array( ' 1023 ', 1023 ),
465
466 # kilo, Mega, Giga
467 array( '1k', 1024 ),
468 array( '1K', 1024 ),
469 array( '1m', 1024 * 1024 ),
470 array( '1M', 1024 * 1024 ),
471 array( '1g', 1024 * 1024 * 1024 ),
472 array( '1G', 1024 * 1024 * 1024 ),
473
474 # Negatives
475 array( -1, -1 ),
476 array( -500, -500 ),
477 array( '-500', -500 ),
478 array( '-1k', -1024 ),
479
480 # Zeroes
481 array( '0', 0 ),
482 array( '0k', 0 ),
483 array( '0M', 0 ),
484 array( '0G', 0 ),
485 array( '-0', 0 ),
486 array( '-0k', 0 ),
487 array( '-0M', 0 ),
488 array( '-0G', 0 ),
489 );
490 }
491
492 /**
493 * @param string $old Text as it was in the database
494 * @param string $mine Text submitted while user was editing
495 * @param string $yours Text submitted by the user
496 * @param bool $expectedMergeResult Whether the merge should be a success
497 * @param string $expectedText Text after merge has been completed
498 *
499 * @dataProvider provideMerge()
500 * @group medium
501 * @covers ::wfMerge
502 */
503 public function testMerge( $old, $mine, $yours, $expectedMergeResult, $expectedText ) {
504 $this->checkHasDiff3();
505
506 $mergedText = null;
507 $isMerged = wfMerge( $old, $mine, $yours, $mergedText );
508
509 $msg = 'Merge should be a ';
510 $msg .= $expectedMergeResult ? 'success' : 'failure';
511 $this->assertEquals( $expectedMergeResult, $isMerged, $msg );
512
513 if ( $isMerged ) {
514 // Verify the merged text
515 $this->assertEquals( $expectedText, $mergedText,
516 'is merged text as expected?' );
517 }
518 }
519
520 public static function provideMerge() {
521 $EXPECT_MERGE_SUCCESS = true;
522 $EXPECT_MERGE_FAILURE = false;
523
524 return array(
525 // #0: clean merge
526 array(
527 // old:
528 "one one one\n" . // trimmed
529 "\n" .
530 "two two two",
531
532 // mine:
533 "one one one ONE ONE\n" .
534 "\n" .
535 "two two two\n", // with tailing whitespace
536
537 // yours:
538 "one one one\n" .
539 "\n" .
540 "two two TWO TWO", // trimmed
541
542 // ok:
543 $EXPECT_MERGE_SUCCESS,
544
545 // result:
546 "one one one ONE ONE\n" .
547 "\n" .
548 "two two TWO TWO\n", // note: will always end in a newline
549 ),
550
551 // #1: conflict, fail
552 array(
553 // old:
554 "one one one", // trimmed
555
556 // mine:
557 "one one one ONE ONE\n" .
558 "\n" .
559 "bla bla\n" .
560 "\n", // with tailing whitespace
561
562 // yours:
563 "one one one\n" .
564 "\n" .
565 "two two", // trimmed
566
567 $EXPECT_MERGE_FAILURE,
568
569 // result:
570 null,
571 ),
572 );
573 }
574
575 /**
576 * @dataProvider provideMakeUrlIndexes()
577 * @covers ::wfMakeUrlIndexes
578 */
579 public function testMakeUrlIndexes( $url, $expected ) {
580 $index = wfMakeUrlIndexes( $url );
581 $this->assertEquals( $expected, $index, "wfMakeUrlIndexes(\"$url\")" );
582 }
583
584 public static function provideMakeUrlIndexes() {
585 return array(
586 array(
587 // just a regular :)
588 'https://bugzilla.wikimedia.org/show_bug.cgi?id=28627',
589 array( 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627' )
590 ),
591 array(
592 // mailtos are handled special
593 // is this really right though? that final . probably belongs earlier?
594 'mailto:wiki@wikimedia.org',
595 array( 'mailto:org.wikimedia@wiki.' )
596 ),
597
598 // file URL cases per bug 28627...
599 array(
600 // three slashes: local filesystem path Unix-style
601 'file:///whatever/you/like.txt',
602 array( 'file://./whatever/you/like.txt' )
603 ),
604 array(
605 // three slashes: local filesystem path Windows-style
606 'file:///c:/whatever/you/like.txt',
607 array( 'file://./c:/whatever/you/like.txt' )
608 ),
609 array(
610 // two slashes: UNC filesystem path Windows-style
611 'file://intranet/whatever/you/like.txt',
612 array( 'file://intranet./whatever/you/like.txt' )
613 ),
614 // Multiple-slash cases that can sorta work on Mozilla
615 // if you hack it just right are kinda pathological,
616 // and unreliable cross-platform or on IE which means they're
617 // unlikely to appear on intranets.
618 //
619 // Those will survive the algorithm but with results that
620 // are less consistent.
621
622 // protocol-relative URL cases per bug 29854...
623 array(
624 '//bugzilla.wikimedia.org/show_bug.cgi?id=28627',
625 array(
626 'http://org.wikimedia.bugzilla./show_bug.cgi?id=28627',
627 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627'
628 )
629 ),
630 );
631 }
632
633 /**
634 * @dataProvider provideWfMatchesDomainList
635 * @covers ::wfMatchesDomainList
636 */
637 public function testWfMatchesDomainList( $url, $domains, $expected, $description ) {
638 $actual = wfMatchesDomainList( $url, $domains );
639 $this->assertEquals( $expected, $actual, $description );
640 }
641
642 public static function provideWfMatchesDomainList() {
643 $a = array();
644 $protocols = array( 'HTTP' => 'http:', 'HTTPS' => 'https:', 'protocol-relative' => '' );
645 foreach ( $protocols as $pDesc => $p ) {
646 $a = array_merge( $a, array(
647 array(
648 "$p//www.example.com",
649 array(),
650 false,
651 "No matches for empty domains array, $pDesc URL"
652 ),
653 array(
654 "$p//www.example.com",
655 array( 'www.example.com' ),
656 true,
657 "Exact match in domains array, $pDesc URL"
658 ),
659 array(
660 "$p//www.example.com",
661 array( 'example.com' ),
662 true,
663 "Match without subdomain in domains array, $pDesc URL"
664 ),
665 array(
666 "$p//www.example2.com",
667 array( 'www.example.com', 'www.example2.com', 'www.example3.com' ),
668 true,
669 "Exact match with other domains in array, $pDesc URL"
670 ),
671 array(
672 "$p//www.example2.com",
673 array( 'example.com', 'example2.com', 'example3,com' ),
674 true,
675 "Match without subdomain with other domains in array, $pDesc URL"
676 ),
677 array(
678 "$p//www.example4.com",
679 array( 'example.com', 'example2.com', 'example3,com' ),
680 false,
681 "Domain not in array, $pDesc URL"
682 ),
683 array(
684 "$p//nds-nl.wikipedia.org",
685 array( 'nl.wikipedia.org' ),
686 false,
687 "Non-matching substring of domain, $pDesc URL"
688 ),
689 ) );
690 }
691
692 return $a;
693 }
694
695 /**
696 * @covers ::wfMkdirParents
697 */
698 public function testWfMkdirParents() {
699 // Should not return true if file exists instead of directory
700 $fname = $this->getNewTempFile();
701 wfSuppressWarnings();
702 $ok = wfMkdirParents( $fname );
703 wfRestoreWarnings();
704 $this->assertFalse( $ok );
705 }
706
707 /**
708 * @dataProvider provideWfShellMaintenanceCmdList
709 * @covers ::wfShellMaintenanceCmd
710 */
711 public function testWfShellMaintenanceCmd( $script, $parameters, $options,
712 $expected, $description
713 ) {
714 if ( wfIsWindows() ) {
715 // Approximation that's good enough for our purposes just now
716 $expected = str_replace( "'", '"', $expected );
717 }
718 $actual = wfShellMaintenanceCmd( $script, $parameters, $options );
719 $this->assertEquals( $expected, $actual, $description );
720 }
721
722 public static function provideWfShellMaintenanceCmdList() {
723 global $wgPhpCli;
724
725 return array(
726 array( 'eval.php', array( '--help', '--test' ), array(),
727 "'$wgPhpCli' 'eval.php' '--help' '--test'",
728 "Called eval.php --help --test" ),
729 array( 'eval.php', array( '--help', '--test space' ), array( 'php' => 'php5' ),
730 "'php5' 'eval.php' '--help' '--test space'",
731 "Called eval.php --help --test with php option" ),
732 array( 'eval.php', array( '--help', '--test', 'X' ), array( 'wrapper' => 'MWScript.php' ),
733 "'$wgPhpCli' 'MWScript.php' 'eval.php' '--help' '--test' 'X'",
734 "Called eval.php --help --test with wrapper option" ),
735 array(
736 'eval.php',
737 array( '--help', '--test', 'y' ),
738 array( 'php' => 'php5', 'wrapper' => 'MWScript.php' ),
739 "'php5' 'MWScript.php' 'eval.php' '--help' '--test' 'y'",
740 "Called eval.php --help --test with wrapper and php option"
741 ),
742 );
743 }
744 /* @todo many more! */
745 }