3 use MediaWiki\Logger\LegacyLogger
;
4 use MediaWiki\MainConfigNames
;
8 * @group GlobalFunctions
10 class GlobalTest
extends MediaWikiIntegrationTestCase
{
11 protected function setUp(): void
{
14 $this->overrideConfigValues( [
15 MainConfigNames
::UrlProtocols
=> [
20 'file://', # Non-default
26 * @dataProvider provideForWfArrayDiff2
27 * @covers ::wfArrayDiff2
29 public function testWfArrayDiff2( $a, $b, $expected ) {
30 $this->expectDeprecationAndContinue( '/wfArrayDiff2/' );
32 $expected, wfArrayDiff2( $a, $b )
36 // @todo Provide more tests
37 public static function provideForWfArrayDiff2() {
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.
61 public function testRandom() {
63 wfRandom() == wfRandom()
68 * @covers ::wfRandomString
70 public function testRandomString() {
72 wfRandomString() == wfRandomString()
74 $this->assertSame( 10, strlen( wfRandomString( 10 ) ), 'length' );
75 $this->assertSame( 1, preg_match( '/^[0-9a-f]+$/i', wfRandomString() ), 'pattern' );
79 * @covers ::wfUrlencode
81 public function testUrlencode() {
83 "%E7%89%B9%E5%88%A5:Contributions/Foobar",
84 wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) );
87 public static function provideArrayToCGI() {
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() {
130 [ 'foo' => 'bar', 'baz' => 'overridden value' ] ) );
133 public static function provideCgiToArray() {
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() {
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 ) ) );
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" );
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() {
221 'compress, gzip' => true,
222 'gzip;q=1.0' => true,
225 'gzip;q=abcde' => true, // is this REALLY valid?
226 'gzip;q=12345678.9' => 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,
255 $this->assertSame( $expected, wfPercent( $input, $accuracy, $round ) );
258 public static function provideWfPercentTest() {
260 [ 6 / 7, '0.86%', 2, false ],
262 [ 22 / 7, '3.14286%', 5 ],
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 ]
291 # Failures returns 0 :(
295 # Int, strings with spaces
304 [ '1m', 1024 * 1024 ],
305 [ '1M', 1024 * 1024 ],
306 [ '1g', 1024 * 1024 * 1024 ],
307 [ '1G', 1024 * 1024 * 1024 ],
330 public function testMerge_worksWithLessParameters() {
331 $this->markTestSkippedIfNoDiff3();
334 $successfulMerge = wfMerge( "old1\n\nold2", "old1\n\nnew2", "new1\n\nold2", $mergedText );
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()
355 public function testMerge(
356 $old, $mine, $yours, $expectedMergeResult, $expectedText, $expectedMergeAttemptResult
358 $this->markTestSkippedIfNoDiff3();
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 );
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;
384 "one one one\n" . // trimmed
389 "one one one ONE ONE\n" .
391 "two two two\n", // with tailing whitespace
396 "two two TWO TWO", // trimmed
399 $EXPECT_MERGE_SUCCESS,
402 "one one one ONE ONE\n" .
404 "two two TWO TWO\n", // note: will always end in a newline
406 // mergeAttemptResult:
410 // #1: conflict, fail
413 "one one one", // trimmed
416 "one one one ONE ONE\n" .
419 "\n", // with tailing whitespace
424 "two two", // trimmed
426 $EXPECT_MERGE_FAILURE,
431 // mergeAttemptResult:
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() {
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" ],
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! */