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