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