Partial revert of r91106: followup to r91127.
[lhc/web/wiklou.git] / tests / phpunit / includes / GlobalFunctions / GlobalTest.php
1 <?php
2
3 class GlobalTest extends MediaWikiTestCase {
4 function setUp() {
5 global $wgReadOnlyFile, $wgContLang, $wgLang, $wgUrlProtocols, $wgLanguageCode;
6 parent::setUp();
7 $this->originals['wgReadOnlyFile'] = $wgReadOnlyFile;
8 $this->originals['wgUrlProtocols'] = $wgUrlProtocols;
9 $wgReadOnlyFile = tempnam( wfTempDir(), "mwtest_readonly" );
10 $wgUrlProtocols[] = 'file://';
11 unlink( $wgReadOnlyFile );
12 }
13
14 function tearDown() {
15 global $wgReadOnlyFile, $wgUrlProtocols;
16 if ( file_exists( $wgReadOnlyFile ) ) {
17 unlink( $wgReadOnlyFile );
18 }
19 $wgReadOnlyFile = $this->originals['wgReadOnlyFile'];
20 $wgUrlProtocols = $this->originals['wgUrlProtocols'];
21 }
22
23 /** @dataProvider provideForWfArrayDiff2 */
24 public function testWfArrayDiff2( $a, $b, $expected ) {
25 $this->assertEquals(
26 wfArrayDiff2( $a, $b), $expected
27 );
28 }
29
30 // @todo Provide more tests
31 public function provideForWfArrayDiff2() {
32 // $a $b $expected
33 return array(
34 array(
35 array( 'a', 'b'),
36 array( 'a', 'b'),
37 array(),
38 ),
39 array(
40 array( array( 'a'), array( 'a', 'b', 'c' )),
41 array( array( 'a'), array( 'a', 'b' )),
42 array( 1 => array( 'a', 'b', 'c' ) ),
43 ),
44 );
45 }
46
47 function testRandom() {
48 # This could hypothetically fail, but it shouldn't ;)
49 $this->assertFalse(
50 wfRandom() == wfRandom() );
51 }
52
53 function testUrlencode() {
54 $this->assertEquals(
55 "%E7%89%B9%E5%88%A5:Contributions/Foobar",
56 wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) );
57 }
58
59 function testReadOnlyEmpty() {
60 global $wgReadOnly;
61 $wgReadOnly = null;
62
63 $this->assertFalse( wfReadOnly() );
64 $this->assertFalse( wfReadOnly() );
65 }
66
67 function testReadOnlySet() {
68 global $wgReadOnly, $wgReadOnlyFile;
69
70 $f = fopen( $wgReadOnlyFile, "wt" );
71 fwrite( $f, 'Message' );
72 fclose( $f );
73 $wgReadOnly = null; # Check on $wgReadOnlyFile
74
75 $this->assertTrue( wfReadOnly() );
76 $this->assertTrue( wfReadOnly() ); # Check cached
77
78 unlink( $wgReadOnlyFile );
79 $wgReadOnly = null; # Clean cache
80
81 $this->assertFalse( wfReadOnly() );
82 $this->assertFalse( wfReadOnly() );
83 }
84
85 function testQuotedPrintable() {
86 $this->assertEquals(
87 "=?UTF-8?Q?=C4=88u=20legebla=3F?=",
88 UserMailer::quotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) );
89 }
90
91 function testTime() {
92 $start = wfTime();
93 $this->assertInternalType( 'float', $start );
94 $end = wfTime();
95 $this->assertTrue( $end > $start, "Time is running backwards!" );
96 }
97
98 function testArrayToCGI() {
99 $this->assertEquals(
100 "baz=AT%26T&foo=bar",
101 wfArrayToCGI(
102 array( 'baz' => 'AT&T', 'ignore' => '' ),
103 array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) );
104 $this->assertEquals(
105 "path%5B0%5D=wiki&path%5B1%5D=test&cfg%5Bservers%5D%5Bhttp%5D=localhost",
106 wfArrayToCGI( array(
107 'path' => array( 'wiki', 'test' ),
108 'cfg' => array( 'servers' => array( 'http' => 'localhost' ) ) ) ) );
109 }
110
111 function testCgiToArray() {
112 $this->assertEquals(
113 array( 'path' => array( 'wiki', 'test' ),
114 'cfg' => array( 'servers' => array( 'http' => 'localhost' ) ) ),
115 wfCgiToArray( 'path%5B0%5D=wiki&path%5B1%5D=test&cfg%5Bservers%5D%5Bhttp%5D=localhost' ) );
116 }
117
118 function testMimeTypeMatch() {
119 $this->assertEquals(
120 'text/html',
121 mimeTypeMatch( 'text/html',
122 array( 'application/xhtml+xml' => 1.0,
123 'text/html' => 0.7,
124 'text/plain' => 0.3 ) ) );
125 $this->assertEquals(
126 'text/*',
127 mimeTypeMatch( 'text/html',
128 array( 'image/*' => 1.0,
129 'text/*' => 0.5 ) ) );
130 $this->assertEquals(
131 '*/*',
132 mimeTypeMatch( 'text/html',
133 array( '*/*' => 1.0 ) ) );
134 $this->assertNull(
135 mimeTypeMatch( 'text/html',
136 array( 'image/png' => 1.0,
137 'image/svg+xml' => 0.5 ) ) );
138 }
139
140 function testNegotiateType() {
141 $this->assertEquals(
142 'text/html',
143 wfNegotiateType(
144 array( 'application/xhtml+xml' => 1.0,
145 'text/html' => 0.7,
146 'text/plain' => 0.5,
147 'text/*' => 0.2 ),
148 array( 'text/html' => 1.0 ) ) );
149 $this->assertEquals(
150 'application/xhtml+xml',
151 wfNegotiateType(
152 array( 'application/xhtml+xml' => 1.0,
153 'text/html' => 0.7,
154 'text/plain' => 0.5,
155 'text/*' => 0.2 ),
156 array( 'application/xhtml+xml' => 1.0,
157 'text/html' => 0.5 ) ) );
158 $this->assertEquals(
159 'text/html',
160 wfNegotiateType(
161 array( 'text/html' => 1.0,
162 'text/plain' => 0.5,
163 'text/*' => 0.5,
164 'application/xhtml+xml' => 0.2 ),
165 array( 'application/xhtml+xml' => 1.0,
166 'text/html' => 0.5 ) ) );
167 $this->assertEquals(
168 'text/html',
169 wfNegotiateType(
170 array( 'text/*' => 1.0,
171 'image/*' => 0.7,
172 '*/*' => 0.3 ),
173 array( 'application/xhtml+xml' => 1.0,
174 'text/html' => 0.5 ) ) );
175 $this->assertNull(
176 wfNegotiateType(
177 array( 'text/*' => 1.0 ),
178 array( 'application/xhtml+xml' => 1.0 ) ) );
179 }
180
181 function testTimestamp() {
182 $t = gmmktime( 12, 34, 56, 1, 15, 2001 );
183 $this->assertEquals(
184 '20010115123456',
185 wfTimestamp( TS_MW, $t ),
186 'TS_UNIX to TS_MW' );
187 $this->assertEquals(
188 '19690115123456',
189 wfTimestamp( TS_MW, -30281104 ),
190 'Negative TS_UNIX to TS_MW' );
191 $this->assertEquals(
192 979562096,
193 wfTimestamp( TS_UNIX, $t ),
194 'TS_UNIX to TS_UNIX' );
195 $this->assertEquals(
196 '2001-01-15 12:34:56',
197 wfTimestamp( TS_DB, $t ),
198 'TS_UNIX to TS_DB' );
199 $this->assertEquals(
200 '20010115T123456Z',
201 wfTimestamp( TS_ISO_8601_BASIC, $t ),
202 'TS_ISO_8601_BASIC to TS_DB' );
203
204 $this->assertEquals(
205 '20010115123456',
206 wfTimestamp( TS_MW, '20010115123456' ),
207 'TS_MW to TS_MW' );
208 $this->assertEquals(
209 979562096,
210 wfTimestamp( TS_UNIX, '20010115123456' ),
211 'TS_MW to TS_UNIX' );
212 $this->assertEquals(
213 '2001-01-15 12:34:56',
214 wfTimestamp( TS_DB, '20010115123456' ),
215 'TS_MW to TS_DB' );
216 $this->assertEquals(
217 '20010115T123456Z',
218 wfTimestamp( TS_ISO_8601_BASIC, '20010115123456' ),
219 'TS_MW to TS_ISO_8601_BASIC' );
220
221 $this->assertEquals(
222 '20010115123456',
223 wfTimestamp( TS_MW, '2001-01-15 12:34:56' ),
224 'TS_DB to TS_MW' );
225 $this->assertEquals(
226 979562096,
227 wfTimestamp( TS_UNIX, '2001-01-15 12:34:56' ),
228 'TS_DB to TS_UNIX' );
229 $this->assertEquals(
230 '2001-01-15 12:34:56',
231 wfTimestamp( TS_DB, '2001-01-15 12:34:56' ),
232 'TS_DB to TS_DB' );
233 $this->assertEquals(
234 '20010115T123456Z',
235 wfTimestamp( TS_ISO_8601_BASIC, '2001-01-15 12:34:56' ),
236 'TS_DB to TS_ISO_8601_BASIC' );
237
238 # rfc2822 section 3.3
239
240 $this->assertEquals(
241 'Mon, 15 Jan 2001 12:34:56 GMT',
242 wfTimestamp( TS_RFC2822, '20010115123456' ),
243 'TS_MW to TS_RFC2822' );
244
245 $this->assertEquals(
246 '20010115123456',
247 wfTimestamp( TS_MW, 'Mon, 15 Jan 2001 12:34:56 GMT' ),
248 'TS_RFC2822 to TS_MW' );
249
250 $this->assertEquals(
251 '20010115123456',
252 wfTimestamp( TS_MW, ' Mon, 15 Jan 2001 12:34:56 GMT' ),
253 'TS_RFC2822 with leading space to TS_MW' );
254
255 $this->assertEquals(
256 '20010115123456',
257 wfTimestamp( TS_MW, '15 Jan 2001 12:34:56 GMT' ),
258 'TS_RFC2822 without optional day-of-week to TS_MW' );
259
260 # FWS = ([*WSP CRLF] 1*WSP) / obs-FWS ; Folding white space
261 # obs-FWS = 1*WSP *(CRLF 1*WSP) ; Section 4.2
262 $this->assertEquals(
263 '20010115123456',
264 wfTimestamp( TS_MW, 'Mon, 15 Jan 2001 12:34:56 GMT' ),
265 'TS_RFC2822 to TS_MW' );
266
267 # WSP = SP / HTAB ; rfc2234
268 $this->assertEquals(
269 '20010115123456',
270 wfTimestamp( TS_MW, "Mon, 15 Jan\x092001 12:34:56 GMT" ),
271 'TS_RFC2822 with HTAB to TS_MW' );
272
273 $this->assertEquals(
274 '20010115123456',
275 wfTimestamp( TS_MW, "Mon, 15 Jan\x09 \x09 2001 12:34:56 GMT" ),
276 'TS_RFC2822 with HTAB and SP to TS_MW' );
277
278 $this->assertEquals(
279 '19941106084937',
280 wfTimestamp( TS_MW, "Sun, 6 Nov 94 08:49:37 GMT" ),
281 'TS_RFC2822 with obsolete year to TS_MW' );
282 }
283
284 /**
285 * This test checks wfTimestamp() with values outside.
286 * It needs PHP 64 bits or PHP > 5.1.
287 * See r74778 and bug 25451
288 */
289 function testOldTimestamps() {
290 $this->assertEquals( 'Fri, 13 Dec 1901 20:45:54 GMT',
291 wfTimestamp( TS_RFC2822, '19011213204554' ),
292 'Earliest time according to php documentation' );
293
294 $this->assertEquals( 'Tue, 19 Jan 2038 03:14:07 GMT',
295 wfTimestamp( TS_RFC2822, '20380119031407' ),
296 'Latest 32 bit time' );
297
298 $this->assertEquals( '-2147483648',
299 wfTimestamp( TS_UNIX, '19011213204552' ),
300 'Earliest 32 bit unix time' );
301
302 $this->assertEquals( '2147483647',
303 wfTimestamp( TS_UNIX, '20380119031407' ),
304 'Latest 32 bit unix time' );
305
306 $this->assertEquals( 'Fri, 13 Dec 1901 20:45:52 GMT',
307 wfTimestamp( TS_RFC2822, '19011213204552' ),
308 'Earliest 32 bit time' );
309
310 $this->assertEquals( 'Fri, 13 Dec 1901 20:45:51 GMT',
311 wfTimestamp( TS_RFC2822, '19011213204551' ),
312 'Earliest 32 bit time - 1' );
313
314 $this->assertEquals( 'Tue, 19 Jan 2038 03:14:08 GMT',
315 wfTimestamp( TS_RFC2822, '20380119031408' ),
316 'Latest 32 bit time + 1' );
317
318 $this->assertEquals( '19011212000000',
319 wfTimestamp(TS_MW, '19011212000000'),
320 'Convert to itself r74778#c10645' );
321
322 $this->assertEquals( '-2147483649',
323 wfTimestamp( TS_UNIX, '19011213204551' ),
324 'Earliest 32 bit unix time - 1' );
325
326 $this->assertEquals( '2147483648',
327 wfTimestamp( TS_UNIX, '20380119031408' ),
328 'Latest 32 bit unix time + 1' );
329
330 $this->assertEquals( '19011213204551',
331 wfTimestamp( TS_MW, '-2147483649' ),
332 '1901 negative unix time to MediaWiki' );
333
334 $this->assertEquals( '18010115123456',
335 wfTimestamp( TS_MW, '-5331871504' ),
336 '1801 negative unix time to MediaWiki' );
337
338 $this->assertEquals( 'Tue, 09 Aug 0117 12:34:56 GMT',
339 wfTimestamp( TS_RFC2822, '0117-08-09 12:34:56'),
340 'Death of Roman Emperor [[Trajan]]');
341
342 /* @todo FIXME: 00 to 101 years are taken as being in [1970-2069] */
343
344 $this->assertEquals( 'Sun, 01 Jan 0101 00:00:00 GMT',
345 wfTimestamp( TS_RFC2822, '-58979923200'),
346 '1/1/101');
347
348 $this->assertEquals( 'Mon, 01 Jan 0001 00:00:00 GMT',
349 wfTimestamp( TS_RFC2822, '-62135596800'),
350 'Year 1');
351
352 /* It is not clear if we should generate a year 0 or not
353 * We are completely off RFC2822 requirement of year being
354 * 1900 or later.
355 */
356 $this->assertEquals( 'Wed, 18 Oct 0000 00:00:00 GMT',
357 wfTimestamp( TS_RFC2822, '-62142076800'),
358 'ISO 8601:2004 [[year 0]], also called [[1 BC]]');
359 }
360
361 function testHttpDate() {
362 # The Resource Loader uses wfTimestamp() to convert timestamps
363 # from If-Modified-Since header.
364 # Thus it must be able to parse all rfc2616 date formats
365 # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
366
367 $this->assertEquals(
368 '19941106084937',
369 wfTimestamp( TS_MW, 'Sun, 06 Nov 1994 08:49:37 GMT' ),
370 'RFC 822 date' );
371
372 $this->assertEquals(
373 '19941106084937',
374 wfTimestamp( TS_MW, 'Sunday, 06-Nov-94 08:49:37 GMT' ),
375 'RFC 850 date' );
376
377 $this->assertEquals(
378 '19941106084937',
379 wfTimestamp( TS_MW, 'Sun Nov 6 08:49:37 1994' ),
380 "ANSI C's asctime() format" );
381
382 // See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html and r77171
383 $this->assertEquals(
384 '20101122141242',
385 wfTimestamp( TS_MW, 'Mon, 22 Nov 2010 14:12:42 GMT; length=52626' ),
386 "Netscape extension to HTTP/1.0" );
387
388 }
389
390 function testTimestampParameter() {
391 // There are a number of assumptions in our codebase where wfTimestamp() should give
392 // the current date but it is not given a 0 there. See r71751 CR
393
394 $now = wfTimestamp( TS_UNIX );
395 // We check that wfTimestamp doesn't return false (error) and use a LessThan assert
396 // for the cases where the test is run in a second boundary.
397
398 $zero = wfTimestamp( TS_UNIX, 0 );
399 $this->assertNotEquals( false, $zero );
400 $this->assertLessThan( 5, $zero - $now );
401
402 $empty = wfTimestamp( TS_UNIX, '' );
403 $this->assertNotEquals( false, $empty );
404 $this->assertLessThan( 5, $empty - $now );
405
406 $null = wfTimestamp( TS_UNIX, null );
407 $this->assertNotEquals( false, $null );
408 $this->assertLessThan( 5, $null - $now );
409 }
410
411 function testBasename() {
412 $sets = array(
413 '' => '',
414 '/' => '',
415 '\\' => '',
416 '//' => '',
417 '\\\\' => '',
418 'a' => 'a',
419 'aaaa' => 'aaaa',
420 '/a' => 'a',
421 '\\a' => 'a',
422 '/aaaa' => 'aaaa',
423 '\\aaaa' => 'aaaa',
424 '/aaaa/' => 'aaaa',
425 '\\aaaa\\' => 'aaaa',
426 '\\aaaa\\' => 'aaaa',
427 '/mnt/upload3/wikipedia/en/thumb/8/8b/Zork_Grand_Inquisitor_box_cover.jpg/93px-Zork_Grand_Inquisitor_box_cover.jpg' => '93px-Zork_Grand_Inquisitor_box_cover.jpg',
428 'C:\\Progra~1\\Wikime~1\\Wikipe~1\\VIEWER.EXE' => 'VIEWER.EXE',
429 'Östergötland_coat_of_arms.png' => 'Östergötland_coat_of_arms.png',
430 );
431 foreach ( $sets as $from => $to ) {
432 $this->assertEquals( $to, wfBaseName( $from ),
433 "wfBaseName('$from') => '$to'" );
434 }
435 }
436
437
438 function testFallbackMbstringFunctions() {
439
440 if( !extension_loaded( 'mbstring' ) ) {
441 $this->markTestSkipped( "The mb_string functions must be installed to test the fallback functions" );
442 }
443
444 $sampleUTF = "Östergötland_coat_of_arms.png";
445
446
447 //mb_substr
448 $substr_params = array(
449 array( 0, 0 ),
450 array( 5, -4 ),
451 array( 33 ),
452 array( 100, -5 ),
453 array( -8, 10 ),
454 array( 1, 1 ),
455 array( 2, -1 )
456 );
457
458 foreach( $substr_params as $param_set ) {
459 $old_param_set = $param_set;
460 array_unshift( $param_set, $sampleUTF );
461
462 $this->assertEquals(
463 MWFunction::callArray( 'mb_substr', $param_set ),
464 MWFunction::callArray( 'Fallback::mb_substr', $param_set ),
465 'Fallback mb_substr with params ' . implode( ', ', $old_param_set )
466 );
467 }
468
469
470 //mb_strlen
471 $this->assertEquals(
472 mb_strlen( $sampleUTF ),
473 Fallback::mb_strlen( $sampleUTF ),
474 'Fallback mb_strlen'
475 );
476
477
478 //mb_str(r?)pos
479 $strpos_params = array(
480 //array( 'ter' ),
481 //array( 'Ö' ),
482 //array( 'Ö', 3 ),
483 //array( 'oat_', 100 ),
484 //array( 'c', -10 ),
485 //Broken for now
486 );
487
488 foreach( $strpos_params as $param_set ) {
489 $old_param_set = $param_set;
490 array_unshift( $param_set, $sampleUTF );
491
492 $this->assertEquals(
493 MWFunction::callArray( 'mb_strpos', $param_set ),
494 MWFunction::callArray( 'Fallback::mb_strpos', $param_set ),
495 'Fallback mb_strpos with params ' . implode( ', ', $old_param_set )
496 );
497
498 $this->assertEquals(
499 MWFunction::callArray( 'mb_strrpos', $param_set ),
500 MWFunction::callArray( 'Fallback::mb_strrpos', $param_set ),
501 'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set )
502 );
503 }
504
505 }
506
507
508 function testDebugFunctionTest() {
509
510 global $wgDebugLogFile, $wgOut, $wgShowDebug, $wgDebugTimestamps;
511
512 $old_log_file = $wgDebugLogFile;
513 $wgDebugLogFile = tempnam( wfTempDir(), 'mw-' );
514 # @todo FIXME: This setting should be tested
515 $wgDebugTimestamps = false;
516
517
518
519 wfDebug( "This is a normal string" );
520 $this->assertEquals( "This is a normal string", file_get_contents( $wgDebugLogFile ) );
521 unlink( $wgDebugLogFile );
522
523
524 wfDebug( "This is nöt an ASCII string" );
525 $this->assertEquals( "This is nöt an ASCII string", file_get_contents( $wgDebugLogFile ) );
526 unlink( $wgDebugLogFile );
527
528
529 wfDebug( "\00305This has böth UTF and control chars\003" );
530 $this->assertEquals( " 05This has böth UTF and control chars ", file_get_contents( $wgDebugLogFile ) );
531 unlink( $wgDebugLogFile );
532
533
534
535 $old_wgOut = $wgOut;
536 $old_wgShowDebug = $wgShowDebug;
537
538 $wgOut = new MockOutputPage;
539
540 $wgShowDebug = true;
541
542 $message = "\00305This has böth UTF and control chars\003";
543
544 wfDebug( $message );
545
546 if( $wgOut->message == "JAJA is a stupid error message. Anyway, here's your message: $message" ) {
547 $this->assertTrue( true, 'MockOutputPage called, set the proper message.' );
548 }
549 else {
550 $this->assertTrue( false, 'MockOutputPage was not called.' );
551 }
552
553 $wgOut = $old_wgOut;
554 $wgShowDebug = $old_wgShowDebug;
555 unlink( $wgDebugLogFile );
556
557
558
559 wfDebugMem();
560 $this->assertGreaterThan( 5000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) );
561 unlink( $wgDebugLogFile );
562
563 wfDebugMem(true);
564 $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) );
565 unlink( $wgDebugLogFile );
566
567
568
569 $wgDebugLogFile = $old_log_file;
570
571 }
572
573 function testClientAcceptsGzipTest() {
574
575 $settings = array(
576 'gzip' => true,
577 'bzip' => false,
578 '*' => false,
579 'compress, gzip' => true,
580 'gzip;q=1.0' => true,
581 'foozip' => false,
582 'foo*zip' => false,
583 'gzip;q=abcde' => true, //is this REALLY valid?
584 'gzip;q=12345678.9' => true,
585 ' gzip' => true,
586 );
587
588 if( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING'];
589
590 foreach ( $settings as $encoding => $expect ) {
591 $_SERVER['HTTP_ACCEPT_ENCODING'] = $encoding;
592
593 $this->assertEquals( $expect, wfClientAcceptsGzip( true ),
594 "'$encoding' => " . wfBoolToStr( $expect ) );
595 }
596
597 if( isset( $old_server_setting ) ) $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting;
598
599 }
600
601
602
603 function testSwapVarsTest() {
604
605
606 $var1 = 1;
607 $var2 = 2;
608
609 $this->assertEquals( $var1, 1, 'var1 is set originally' );
610 $this->assertEquals( $var2, 2, 'var1 is set originally' );
611
612 swap( $var1, $var2 );
613
614 $this->assertEquals( $var1, 2, 'var1 is swapped' );
615 $this->assertEquals( $var2, 1, 'var2 is swapped' );
616
617 }
618
619
620 function testWfPercentTest() {
621
622 $pcts = array(
623 array( 6/7, '0.86%', 2, false ),
624 array( 3/3, '1%' ),
625 array( 22/7, '3.14286%', 5 ),
626 array( 3/6, '0.5%' ),
627 array( 1/3, '0%', 0 ),
628 array( 10/3, '0%', -1 ),
629 array( 3/4/5, '0.1%', 1 ),
630 array( 6/7*8, '6.8571428571%', 10 ),
631 );
632
633 foreach( $pcts as $pct ) {
634 if( !isset( $pct[2] ) ) $pct[2] = 2;
635 if( !isset( $pct[3] ) ) $pct[3] = true;
636
637 $this->assertEquals( wfPercent( $pct[0], $pct[2], $pct[3] ), $pct[1], $pct[1] );
638 }
639
640 }
641
642
643 function testInStringTest() {
644
645 $this->assertTrue( in_string( 'foo', 'foobar' ), 'foo is in foobar' );
646 $this->assertFalse( in_string( 'Bar', 'foobar' ), 'Case-sensitive by default' );
647 $this->assertTrue( in_string( 'Foo', 'foobar', true ), 'Case-insensitive when asked' );
648
649 }
650
651 /**
652 * test @see wfShorthandToInteger()
653 * @dataProvider provideShorthand
654 */
655 public function testWfShorthandToInteger( $shorthand, $expected ) {
656 $this->assertEquals( $expected,
657 wfShorthandToInteger( $shorthand )
658 );
659 }
660
661 /** array( shorthand, expected integer ) */
662 public function provideShorthand() {
663 return array(
664 # Null, empty ...
665 array( '', -1),
666 array( ' ', -1),
667 array( null, -1),
668
669 # Failures returns 0 :(
670 array( 'ABCDEFG', 0 ),
671 array( 'Ak', 0 ),
672
673 # Int, strings with spaces
674 array( 1, 1 ),
675 array( ' 1 ', 1 ),
676 array( 1023, 1023 ),
677 array( ' 1023 ', 1023 ),
678
679 # kilo, Mega, Giga
680 array( '1k', 1024 ),
681 array( '1K', 1024 ),
682 array( '1m', 1024 * 1024 ),
683 array( '1M', 1024 * 1024 ),
684 array( '1g', 1024 * 1024 * 1024 ),
685 array( '1G', 1024 * 1024 * 1024 ),
686
687 # Negatives
688 array( -1, -1 ),
689 array( -500, -500 ),
690 array( '-500', -500 ),
691 array( '-1k', -1024 ),
692
693 # Zeroes
694 array( '0', 0 ),
695 array( '0k', 0 ),
696 array( '0M', 0 ),
697 array( '0G', 0 ),
698 array( '-0', 0 ),
699 array( '-0k', 0 ),
700 array( '-0M', 0 ),
701 array( '-0G', 0 ),
702 );
703 }
704
705
706 /**
707 * test @see wfBCP47().
708 * Please note the BCP explicitly state that language codes are case
709 * insensitive, there are some exceptions to the rule :)
710 * This test is used to verify our formatting against all lower and
711 * all upper cases language code.
712 *
713 * @see http://tools.ietf.org/html/bcp47
714 * @dataProvider provideLanguageCodes()
715 */
716 function testBCP47( $code, $expected ) {
717 $code = strtolower( $code );
718 $this->assertEquals( $expected, wfBCP47($code),
719 "Applying BCP47 standard to lower case '$code'"
720 );
721
722 $code = strtoupper( $code );
723 $this->assertEquals( $expected, wfBCP47($code),
724 "Applying BCP47 standard to upper case '$code'"
725 );
726 }
727
728 /**
729 * Array format is ($code, $expected)
730 */
731 function provideLanguageCodes() {
732 return array(
733 // Extracted from BCP47 (list not exhaustive)
734 # 2.1.1
735 array( 'en-ca-x-ca' , 'en-CA-x-ca' ),
736 array( 'sgn-be-fr' , 'sgn-BE-FR' ),
737 array( 'az-latn-x-latn', 'az-Latn-x-latn' ),
738 # 2.2
739 array( 'sr-Latn-RS', 'sr-Latn-RS' ),
740 array( 'az-arab-ir', 'az-Arab-IR' ),
741
742 # 2.2.5
743 array( 'sl-nedis' , 'sl-nedis' ),
744 array( 'de-ch-1996', 'de-CH-1996' ),
745
746 # 2.2.6
747 array(
748 'en-latn-gb-boont-r-extended-sequence-x-private',
749 'en-Latn-GB-boont-r-extended-sequence-x-private'
750 ),
751
752 // Examples from BCP47 Appendix A
753 # Simple language subtag:
754 array( 'DE', 'de' ),
755 array( 'fR', 'fr' ),
756 array( 'ja', 'ja' ),
757
758 # Language subtag plus script subtag:
759 array( 'zh-hans', 'zh-Hans'),
760 array( 'sr-cyrl', 'sr-Cyrl'),
761 array( 'sr-latn', 'sr-Latn'),
762
763 # Extended language subtags and their primary language subtag
764 # counterparts:
765 array( 'zh-cmn-hans-cn', 'zh-cmn-Hans-CN' ),
766 array( 'cmn-hans-cn' , 'cmn-Hans-CN' ),
767 array( 'zh-yue-hk' , 'zh-yue-HK' ),
768 array( 'yue-hk' , 'yue-HK' ),
769
770 # Language-Script-Region:
771 array( 'zh-hans-cn', 'zh-Hans-CN' ),
772 array( 'sr-latn-RS', 'sr-Latn-RS' ),
773
774 # Language-Variant:
775 array( 'sl-rozaj' , 'sl-rozaj' ),
776 array( 'sl-rozaj-biske', 'sl-rozaj-biske' ),
777 array( 'sl-nedis' , 'sl-nedis' ),
778
779 # Language-Region-Variant:
780 array( 'de-ch-1901' , 'de-CH-1901' ),
781 array( 'sl-it-nedis' , 'sl-IT-nedis' ),
782
783 # Language-Script-Region-Variant:
784 array( 'hy-latn-it-arevela', 'hy-Latn-IT-arevela' ),
785
786 # Language-Region:
787 array( 'de-de' , 'de-DE' ),
788 array( 'en-us' , 'en-US' ),
789 array( 'es-419', 'es-419'),
790
791 # Private use subtags:
792 array( 'de-ch-x-phonebk' , 'de-CH-x-phonebk' ),
793 array( 'az-arab-x-aze-derbend', 'az-Arab-x-aze-derbend' ),
794 /**
795 * Previous test does not reflect the BCP which states:
796 * az-Arab-x-AZE-derbend
797 * AZE being private, it should be lower case, hence the test above
798 * should probably be:
799 #array( 'az-arab-x-aze-derbend', 'az-Arab-x-AZE-derbend' ),
800 */
801
802 # Private use registry values:
803 array( 'x-whatever', 'x-whatever' ),
804 array( 'qaa-qaaa-qm-x-southern', 'qaa-Qaaa-QM-x-southern' ),
805 array( 'de-qaaa' , 'de-Qaaa' ),
806 array( 'sr-latn-qm', 'sr-Latn-QM' ),
807 array( 'sr-qaaa-rs', 'sr-Qaaa-RS' ),
808
809 # Tags that use extensions
810 array( 'en-us-u-islamcal', 'en-US-u-islamcal' ),
811 array( 'zh-cn-a-myext-x-private', 'zh-CN-a-myext-x-private' ),
812 array( 'en-a-myext-b-another', 'en-a-myext-b-another' ),
813
814 # Invalid:
815 // de-419-DE
816 // a-DE
817 // ar-a-aaa-b-bbb-a-ccc
818
819 /*
820 // ISO 15924 :
821 array( 'sr-Cyrl', 'sr-Cyrl' ),
822 # @todo FIXME: Fix our function?
823 array( 'SR-lATN', 'sr-Latn' ),
824 array( 'fr-latn', 'fr-Latn' ),
825 // Use lowercase for single segment
826 // ISO 3166-1-alpha-2 code
827 array( 'US', 'us' ), # USA
828 array( 'uS', 'us' ), # USA
829 array( 'Fr', 'fr' ), # France
830 array( 'va', 'va' ), # Holy See (Vatican City State)
831 */);
832 }
833
834 /**
835 * @dataProvider provideMakeUrlIndex()
836 */
837 function testMakeUrlIndex( $url, $expected ) {
838 $index = wfMakeUrlIndex( $url );
839 $this->assertEquals( $expected, $index, "wfMakeUrlIndex(\"$url\")" );
840 }
841
842 function provideMakeUrlIndex() {
843 return array(
844 array(
845 // just a regular :)
846 'https://bugzilla.wikimedia.org/show_bug.cgi?id=28627',
847 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627'
848 ),
849 array(
850 // mailtos are handled special
851 // is this really right though? that final . probably belongs earlier?
852 'mailto:wiki@wikimedia.org',
853 'mailto:org.wikimedia@wiki.',
854 ),
855
856 // file URL cases per bug 28627...
857 array(
858 // three slashes: local filesystem path Unix-style
859 'file:///whatever/you/like.txt',
860 'file://./whatever/you/like.txt'
861 ),
862 array(
863 // three slashes: local filesystem path Windows-style
864 'file:///c:/whatever/you/like.txt',
865 'file://./c:/whatever/you/like.txt'
866 ),
867 array(
868 // two slashes: UNC filesystem path Windows-style
869 'file://intranet/whatever/you/like.txt',
870 'file://intranet./whatever/you/like.txt'
871 ),
872 // Multiple-slash cases that can sorta work on Mozilla
873 // if you hack it just right are kinda pathological,
874 // and unreliable cross-platform or on IE which means they're
875 // unlikely to appear on intranets.
876 //
877 // Those will survive the algorithm but with results that
878 // are less consistent.
879 );
880 }
881
882 /* TODO: many more! */
883 }
884
885
886 class MockOutputPage {
887
888 public $message;
889
890 function debug( $message ) {
891 $this->message = "JAJA is a stupid error message. Anyway, here's your message: $message";
892 }
893 }
894