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