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