gallery: Fix phan annotation for ImageGalleryBase::getImages
[mediawiki.git] / tests / phpunit / includes / GlobalFunctions / GlobalTest.php
blob8de75bc01c303854317e837edc5fc8d2c7475e68
1 <?php
3 use MediaWiki\Logger\LegacyLogger;
4 use MediaWiki\MainConfigNames;
6 /**
7 * @group Database
8 * @group GlobalFunctions
9 */
10 class GlobalTest extends MediaWikiIntegrationTestCase {
11 protected function setUp(): void {
12 parent::setUp();
14 $this->overrideConfigValues( [
15 MainConfigNames::UrlProtocols => [
16 'http://',
17 'https://',
18 'mailto:',
19 '//',
20 'file://', # Non-default
22 ] );
25 /**
26 * @dataProvider provideForWfArrayDiff2
27 * @covers ::wfArrayDiff2
29 public function testWfArrayDiff2( $a, $b, $expected ) {
30 $this->expectDeprecationAndContinue( '/wfArrayDiff2/' );
31 $this->assertEquals(
32 $expected, wfArrayDiff2( $a, $b )
36 // @todo Provide more tests
37 public static function provideForWfArrayDiff2() {
38 // $a $b $expected
39 return [
41 [ 'a', 'b' ],
42 [ 'a', 'b' ],
43 [],
46 [ [ 'a' ], [ 'a', 'b', 'c' ] ],
47 [ [ 'a' ], [ 'a', 'b' ] ],
48 [ 1 => [ 'a', 'b', 'c' ] ],
54 * Test cases for random functions could hypothetically fail,
55 * even though they shouldn't.
58 /**
59 * @covers ::wfRandom
61 public function testRandom() {
62 $this->assertFalse(
63 wfRandom() == wfRandom()
67 /**
68 * @covers ::wfRandomString
70 public function testRandomString() {
71 $this->assertFalse(
72 wfRandomString() == wfRandomString()
74 $this->assertSame( 10, strlen( wfRandomString( 10 ) ), 'length' );
75 $this->assertSame( 1, preg_match( '/^[0-9a-f]+$/i', wfRandomString() ), 'pattern' );
78 /**
79 * @covers ::wfUrlencode
81 public function testUrlencode() {
82 $this->assertEquals(
83 "%E7%89%B9%E5%88%A5:Contributions/Foobar",
84 wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) );
87 public static function provideArrayToCGI() {
88 return [
89 [ [], '' ], // empty
90 [ [ 'foo' => 'bar' ], 'foo=bar' ], // string test
91 [ [ 'foo' => '' ], 'foo=' ], // empty string test
92 [ [ 'foo' => 1 ], 'foo=1' ], // number test
93 [ [ 'foo' => true ], 'foo=1' ], // true test
94 [ [ 'foo' => false ], '' ], // false test
95 [ [ 'foo' => null ], '' ], // null test
96 [ [ 'foo' => 'A&B=5+6@!"\'' ], 'foo=A%26B%3D5%2B6%40%21%22%27' ], // urlencoding test
98 [ 'foo' => 'bar', 'baz' => 'is', 'asdf' => 'qwerty' ],
99 'foo=bar&baz=is&asdf=qwerty'
100 ], // multi-item test
101 [ [ 'foo' => [ 'bar' => 'baz' ] ], 'foo%5Bbar%5D=baz' ],
103 [ 'foo' => [ 'bar' => 'baz', 'qwerty' => 'asdf' ] ],
104 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf'
106 [ [ 'foo' => [ 'bar', 'baz' ] ], 'foo%5B0%5D=bar&foo%5B1%5D=baz' ],
108 [ 'foo' => [ 'bar' => [ 'bar' => 'baz' ] ] ],
109 'foo%5Bbar%5D%5Bbar%5D=baz'
115 * @dataProvider provideArrayToCGI
116 * @covers ::wfArrayToCgi
118 public function testArrayToCGI( $array, $result ) {
119 $this->assertEquals( $result, wfArrayToCgi( $array ) );
123 * @covers ::wfArrayToCgi
125 public function testArrayToCGI2() {
126 $this->assertEquals(
127 "baz=bar&foo=bar",
128 wfArrayToCgi(
129 [ 'baz' => 'bar' ],
130 [ 'foo' => 'bar', 'baz' => 'overridden value' ] ) );
133 public static function provideCgiToArray() {
134 return [
135 [ '', [] ], // empty
136 [ 'foo=bar', [ 'foo' => 'bar' ] ], // string
137 [ 'foo=', [ 'foo' => '' ] ], // empty string
138 [ 'foo', [ 'foo' => '' ] ], // missing =
139 [ 'foo=bar&qwerty=asdf', [ 'foo' => 'bar', 'qwerty' => 'asdf' ] ], // multiple value
140 [ 'foo=A%26B%3D5%2B6%40%21%22%27', [ 'foo' => 'A&B=5+6@!"\'' ] ], // urldecoding test
141 [ 'foo[bar]=baz', [ 'foo' => [ 'bar' => 'baz' ] ] ],
142 [ 'foo%5Bbar%5D=baz', [ 'foo' => [ 'bar' => 'baz' ] ] ], // urldecoding test 2
144 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf',
145 [ 'foo' => [ 'bar' => 'baz', 'qwerty' => 'asdf' ] ]
147 [ 'foo%5B0%5D=bar&foo%5B1%5D=baz', [ 'foo' => [ 0 => 'bar', 1 => 'baz' ] ] ],
149 'foo%5Bbar%5D%5Bbar%5D=baz',
150 [ 'foo' => [ 'bar' => [ 'bar' => 'baz' ] ] ]
152 [ 'foo[]=x&foo[]=y', [ 'foo' => [ '' => 'y' ] ] ], // implicit keys are NOT handled like in PHP (bug?)
153 [ 'foo=x&foo[]=y', [ 'foo' => [ '' => 'y' ] ] ], // mixed value/array doesn't cause errors
158 * @dataProvider provideCgiToArray
159 * @covers ::wfCgiToArray
161 public function testCgiToArray( $cgi, $result ) {
162 $this->assertEquals( $result, wfCgiToArray( $cgi ) );
165 public static function provideCgiRoundTrip() {
166 return [
167 [ '' ],
168 [ 'foo=bar' ],
169 [ 'foo=' ],
170 [ 'foo=bar&baz=biz' ],
171 [ 'foo=A%26B%3D5%2B6%40%21%22%27' ],
172 [ 'foo%5Bbar%5D=baz' ],
173 [ 'foo%5B0%5D=bar&foo%5B1%5D=baz' ],
174 [ 'foo%5Bbar%5D%5Bbar%5D=baz' ],
179 * @dataProvider provideCgiRoundTrip
180 * @covers ::wfArrayToCgi
182 public function testCgiRoundTrip( $cgi ) {
183 $this->assertEquals( $cgi, wfArrayToCgi( wfCgiToArray( $cgi ) ) );
187 * @covers ::wfDebug
189 public function testDebugFunctionTest() {
190 $debugLogFile = $this->getNewTempFile();
192 $this->overrideConfigValue( MainConfigNames::DebugLogFile, $debugLogFile );
193 $this->setLogger( 'wfDebug', new LegacyLogger( 'wfDebug' ) );
195 unlink( $debugLogFile );
196 wfDebug( "This is a normal string" );
197 $this->assertEquals( "This is a normal string\n", file_get_contents( $debugLogFile ) );
199 unlink( $debugLogFile );
200 wfDebug( "This is nöt an ASCII string" );
201 $this->assertEquals( "This is nöt an ASCII string\n", file_get_contents( $debugLogFile ) );
203 unlink( $debugLogFile );
204 wfDebug( "\00305This has böth UTF and control chars\003" );
205 $this->assertEquals(
206 " 05This has böth UTF and control chars \n",
207 file_get_contents( $debugLogFile )
210 unlink( $debugLogFile );
214 * @covers ::wfClientAcceptsGzip
216 public function testClientAcceptsGzipTest() {
217 $settings = [
218 'gzip' => true,
219 'bzip' => false,
220 '*' => false,
221 'compress, gzip' => true,
222 'gzip;q=1.0' => true,
223 'foozip' => false,
224 'foo*zip' => false,
225 'gzip;q=abcde' => true, // is this REALLY valid?
226 'gzip;q=12345678.9' => true,
227 ' gzip' => true,
230 if ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
231 $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING'];
234 foreach ( $settings as $encoding => $expect ) {
235 $_SERVER['HTTP_ACCEPT_ENCODING'] = $encoding;
237 $this->assertEquals( $expect, wfClientAcceptsGzip( true ),
238 "'$encoding' => " . wfBoolToStr( $expect ) );
241 if ( isset( $old_server_setting ) ) {
242 $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting;
247 * @covers ::wfPercent
248 * @dataProvider provideWfPercentTest
250 public function testWfPercentTest( float $input,
251 string $expected,
252 int $accuracy = 2,
253 bool $round = true
255 $this->assertSame( $expected, wfPercent( $input, $accuracy, $round ) );
258 public static function provideWfPercentTest() {
259 return [
260 [ 6 / 7, '0.86%', 2, false ],
261 [ 3 / 3, '1%' ],
262 [ 22 / 7, '3.14286%', 5 ],
263 [ 3 / 6, '0.5%' ],
264 [ 1 / 3, '0%', 0 ],
265 [ 10 / 3, '0%', -1 ],
266 [ 123.456, '120%', -1 ],
267 [ 3 / 4 / 5, '0.1%', 1 ],
268 [ 6 / 7 * 8, '6.8571428571%', 10 ],
273 * test @see wfShorthandToInteger()
274 * @dataProvider provideShorthand
275 * @covers ::wfShorthandToInteger
277 public function testWfShorthandToInteger( $shorthand, $expected ) {
278 $this->assertEquals( $expected,
279 wfShorthandToInteger( $shorthand )
283 public static function provideShorthand() {
284 // Syntax: [ shorthand, expected integer ]
285 return [
286 # Null, empty ...
287 [ '', -1 ],
288 [ ' ', -1 ],
289 [ null, -1 ],
291 # Failures returns 0 :(
292 [ 'ABCDEFG', 0 ],
293 [ 'Ak', 0 ],
295 # Int, strings with spaces
296 [ 1, 1 ],
297 [ ' 1 ', 1 ],
298 [ 1023, 1023 ],
299 [ ' 1023 ', 1023 ],
301 # kilo, Mega, Giga
302 [ '1k', 1024 ],
303 [ '1K', 1024 ],
304 [ '1m', 1024 * 1024 ],
305 [ '1M', 1024 * 1024 ],
306 [ '1g', 1024 * 1024 * 1024 ],
307 [ '1G', 1024 * 1024 * 1024 ],
309 # Negatives
310 [ -1, -1 ],
311 [ -500, -500 ],
312 [ '-500', -500 ],
313 [ '-1k', -1024 ],
315 # Zeroes
316 [ '0', 0 ],
317 [ '0k', 0 ],
318 [ '0M', 0 ],
319 [ '0G', 0 ],
320 [ '-0', 0 ],
321 [ '-0k', 0 ],
322 [ '-0M', 0 ],
323 [ '-0G', 0 ],
328 * @covers ::wfMerge
330 public function testMerge_worksWithLessParameters() {
331 $this->markTestSkippedIfNoDiff3();
333 $mergedText = null;
334 $successfulMerge = wfMerge( "old1\n\nold2", "old1\n\nnew2", "new1\n\nold2", $mergedText );
336 $mergedText = null;
337 $conflictingMerge = wfMerge( 'old', 'old and mine', 'old and yours', $mergedText );
339 $this->assertTrue( $successfulMerge );
340 $this->assertFalse( $conflictingMerge );
344 * @param string $old Text as it was in the database
345 * @param string $mine Text submitted while user was editing
346 * @param string $yours Text submitted by the user
347 * @param bool $expectedMergeResult Whether the merge should be a success
348 * @param string $expectedText Text after merge has been completed
349 * @param string $expectedMergeAttemptResult Diff3 output if conflicts occur
351 * @dataProvider provideMerge()
352 * @group medium
353 * @covers ::wfMerge
355 public function testMerge(
356 $old, $mine, $yours, $expectedMergeResult, $expectedText, $expectedMergeAttemptResult
358 $this->markTestSkippedIfNoDiff3();
360 $mergedText = null;
361 $mergeAttemptResult = null;
362 $isMerged = wfMerge( $old, $mine, $yours, $mergedText, $mergeAttemptResult );
364 $msg = 'Merge should be a ';
365 $msg .= $expectedMergeResult ? 'success' : 'failure';
366 $this->assertEquals( $expectedMergeResult, $isMerged, $msg );
367 $this->assertEquals( $expectedMergeAttemptResult, $mergeAttemptResult );
369 if ( $isMerged ) {
370 // Verify the merged text
371 $this->assertEquals( $expectedText, $mergedText,
372 'is merged text as expected?' );
376 public static function provideMerge() {
377 $EXPECT_MERGE_SUCCESS = true;
378 $EXPECT_MERGE_FAILURE = false;
380 return [
381 // #0: clean merge
383 // old:
384 "one one one\n" . // trimmed
385 "\n" .
386 "two two two",
388 // mine:
389 "one one one ONE ONE\n" .
390 "\n" .
391 "two two two\n", // with tailing whitespace
393 // yours:
394 "one one one\n" .
395 "\n" .
396 "two two TWO TWO", // trimmed
398 // ok:
399 $EXPECT_MERGE_SUCCESS,
401 // result:
402 "one one one ONE ONE\n" .
403 "\n" .
404 "two two TWO TWO\n", // note: will always end in a newline
406 // mergeAttemptResult:
410 // #1: conflict, fail
412 // old:
413 "one one one", // trimmed
415 // mine:
416 "one one one ONE ONE\n" .
417 "\n" .
418 "bla bla\n" .
419 "\n", // with tailing whitespace
421 // yours:
422 "one one one\n" .
423 "\n" .
424 "two two", // trimmed
426 $EXPECT_MERGE_FAILURE,
428 // result:
429 null,
431 // mergeAttemptResult:
432 "1,3c\n" .
433 "one one one\n" .
434 "\n" .
435 "two two\n" .
436 ".\n",
442 * Same tests as the UrlUtils method to ensure they don't fall out of sync
443 * @dataProvider UrlUtilsProviders::provideMatchesDomainList
444 * @covers ::wfMatchesDomainList
446 public function testWfMatchesDomainList( $url, $domains, $expected ) {
447 $actual = wfMatchesDomainList( $url, $domains );
448 $this->assertEquals( $expected, $actual );
452 * @covers ::wfMkdirParents
454 public function testWfMkdirParents() {
455 // Should not return true if file exists instead of directory
456 $fname = $this->getNewTempFile();
457 $this->assertFalse( @wfMkdirParents( $fname ) );
461 * @dataProvider provideWfShellWikiCmdList
462 * @covers ::wfShellWikiCmd
464 public function testWfShellWikiCmd( $script, $parameters, $options,
465 $expected, $description
467 if ( wfIsWindows() ) {
468 // Approximation that's good enough for our purposes just now
469 $expected = str_replace( "'", '"', $expected );
471 $actual = wfShellWikiCmd( $script, $parameters, $options );
472 $this->assertEquals( $expected, $actual, $description );
475 public static function provideWfShellWikiCmdList() {
476 global $wgPhpCli;
478 return [
479 [ 'eval.php', [ '--help', '--test' ], [],
480 "'$wgPhpCli' 'eval.php' '--help' '--test'",
481 "Called eval.php --help --test" ],
482 [ 'eval.php', [ '--help', '--test space' ], [ 'php' => 'php5' ],
483 "'php5' 'eval.php' '--help' '--test space'",
484 "Called eval.php --help --test with php option" ],
485 [ 'eval.php', [ '--help', '--test', 'X' ], [ 'wrapper' => 'MWScript.php' ],
486 "'$wgPhpCli' 'MWScript.php' 'eval.php' '--help' '--test' 'X'",
487 "Called eval.php --help --test with wrapper option" ],
489 'eval.php',
490 [ '--help', '--test', 'y' ],
491 [ 'php' => 'php5', 'wrapper' => 'MWScript.php' ],
492 "'php5' 'MWScript.php' 'eval.php' '--help' '--test' 'y'",
493 "Called eval.php --help --test with wrapper and php option"
498 /* @todo many more! */