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