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