diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2013-12-08 09:55:49 +0100 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2013-12-08 09:55:49 +0100 |
commit | 4ac9fa081a7c045f6a9f1cfc529d82423f485b2e (patch) | |
tree | af68743f2f4a47d13f2b0eb05f5c4aaf86d8ea37 /tests/phpunit | |
parent | af4da56f1ad4d3ef7b06557bae365da2ea27a897 (diff) |
Update to MediaWiki 1.22.0
Diffstat (limited to 'tests/phpunit')
256 files changed, 7809 insertions, 3050 deletions
diff --git a/tests/phpunit/MediaWikiLangTestCase.php b/tests/phpunit/MediaWikiLangTestCase.php index 0cf6e383..1131385f 100644 --- a/tests/phpunit/MediaWikiLangTestCase.php +++ b/tests/phpunit/MediaWikiLangTestCase.php @@ -15,6 +15,10 @@ abstract class MediaWikiLangTestCase extends MediaWikiTestCase { "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")" ); } + // HACK: Call getLanguage() so the real $wgContLang is cached as the user language + // rather than our fake one. This is to avoid breaking other, unrelated tests. + RequestContext::getMain()->getLanguage(); + $langCode = 'en'; # For mainpage to be 'Main Page' $langObj = Language::factory( $langCode ); diff --git a/tests/phpunit/MediaWikiPHPUnitCommand.php b/tests/phpunit/MediaWikiPHPUnitCommand.php index 12c2e003..042956a9 100644 --- a/tests/phpunit/MediaWikiPHPUnitCommand.php +++ b/tests/phpunit/MediaWikiPHPUnitCommand.php @@ -12,13 +12,29 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command { 'use-normal-tables' => false, 'reuse-db' => false, 'wiki=' => false, + 'debug-tests' => false, ); public function __construct() { foreach ( self::$additionalOptions as $option => $default ) { $this->longOptions[$option] = $option . 'Handler'; } + } + + protected function handleArguments( array $argv ) { + parent::handleArguments( $argv ); + + if ( !isset( $this->arguments['listeners'] ) ) { + $this->arguments['listeners'] = array(); + } + foreach ( $this->options[0] as $option ) { + switch ( $option[0] ) { + case '--debug-tests': + $this->arguments['listeners'][] = new MediaWikiPHPUnitTestListener( 'PHPUnitCommand' ); + break; + } + } } public static function main( $exit = true ) { @@ -86,7 +102,7 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command { ParserTest-specific options: --regex="<regex>" Only run parser tests that match the given regex - --file="<filename>" Prints the version and exits. + --file="<filename>" File describing parser tests --keep-uploads Re-use the same upload directory for each test, don't delete it @@ -95,7 +111,9 @@ Database options: --reuse-db Init DB only if tables are missing and keep after finish. +Debugging options: + --debug-tests Log testing activity to the PHPUnitCommand log channel. + EOT; } - } diff --git a/tests/phpunit/MediaWikiPHPUnitTestListener.php b/tests/phpunit/MediaWikiPHPUnitTestListener.php new file mode 100644 index 00000000..7237ef32 --- /dev/null +++ b/tests/phpunit/MediaWikiPHPUnitTestListener.php @@ -0,0 +1,114 @@ +<?php +class MediaWikiPHPUnitTestListener implements PHPUnit_Framework_TestListener { + + /** + * @var string + */ + protected $logChannel; + + public function __construct( $logChannel ) { + $this->logChannel = $logChannel; + } + + protected function getTestName( PHPUnit_Framework_Test $test ) { + $name = get_class( $test ); + + if ( $test instanceof PHPUnit_Framework_TestCase ) { + $name .= '::' . $test->getName( true ); + } + + return $name; + } + + protected function getErrorName( Exception $exception ) { + $name = get_class( $exception ); + $name = "[$name] " . $exception->getMessage(); + + return $name; + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError( PHPUnit_Framework_Test $test, Exception $e, $time ) { + wfDebugLog( $this->logChannel, 'ERROR in ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure( PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time ) { + wfDebugLog( $this->logChannel, 'FAILURE in ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time ) { + wfDebugLog( $this->logChannel, 'Incomplete test ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time ) { + wfDebugLog( $this->logChannel, 'Skipped test ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite( PHPUnit_Framework_TestSuite $suite ) { + wfDebugLog( $this->logChannel, 'START suite ' . $suite->getName() ); + } + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite( PHPUnit_Framework_TestSuite $suite ) { + wfDebugLog( $this->logChannel, 'END suite ' . $suite->getName() ); + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest( PHPUnit_Framework_Test $test ) { + wfDebugLog( $this->logChannel, 'Start test ' . $this->getTestName( $test ) ); + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest( PHPUnit_Framework_Test $test, $time ) { + wfDebugLog( $this->logChannel, 'End test ' . $this->getTestName( $test ) ); + } +} diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php index 7e6e0ab8..6ce78b56 100644 --- a/tests/phpunit/MediaWikiTestCase.php +++ b/tests/phpunit/MediaWikiTestCase.php @@ -64,7 +64,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { 'oracle' ); - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->backupGlobals = false; @@ -137,6 +137,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { protected function getNewTempFile() { $fname = tempnam( wfTempDir(), 'MW_PHPUnit_' . get_class( $this ) . '_' ); $this->tmpfiles[] = $fname; + return $fname; } @@ -158,6 +159,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { // where temporary directory creation is bundled and can be improved unlink( $fname ); $this->assertTrue( wfMkdirParents( $fname ) ); + return $fname; } @@ -171,7 +173,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->called['setUp'] = 1; /* - //@todo: global variables to restore for *every* test + // @todo global variables to restore for *every* test array( 'wgLang', 'wgContLang', @@ -348,7 +350,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * Stub. If a test needs to add additional data to the database, it should * implement this method and do so */ - function addDBData() {} + function addDBData() { + } private function addCoreDBData() { # disabled for performance @@ -377,7 +380,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { 'page_touched' => $this->db->timestamp(), 'page_latest' => 0, 'page_len' => 0 ), __METHOD__, array( 'IGNORE' ) ); - } User::resetIdByNameCache(); @@ -394,7 +396,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $user->saveSettings(); } - //Make 1 page with 1 revision $page = WikiPage::factory( Title::newFromText( 'UTPage' ) ); if ( !$page->getId() == 0 ) { @@ -438,7 +439,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * even if using different parameters. * * @param DatabaseBase $db The database connection - * @param String $prefix The prefix to use for the new table set (aka schema). + * @param String $prefix The prefix to use for the new table set (aka schema). * * @throws MWException if the database table prefix is already $prefix */ @@ -461,6 +462,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { if ( ( $db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) { CloneDatabase::changePrefix( $prefix ); + return; } else { $dbClone->cloneTableStructure(); @@ -523,6 +525,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { private static function unprefixTable( $tableName ) { global $wgDBprefix; + return substr( $tableName, strlen( $wgDBprefix ) ); } @@ -534,6 +537,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { global $wgDBprefix; $tables = $db->listTables( $wgDBprefix, __METHOD__ ); + + if ( $db->getType() === 'mysql' ) { + # bug 43571: cannot clone VIEWs under MySQL + $views = $db->listViews( $wgDBprefix, __METHOD__ ); + $tables = array_diff( $tables, $views ); + } $tables = array_map( array( __CLASS__, 'unprefixTable' ), $tables ); // Don't duplicate test tables from the previous fataled run @@ -547,6 +556,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { unset( $tables['searchindex_segments'] ); $tables = array_flip( $tables ); } + return $tables; } @@ -561,13 +571,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { if ( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) { return MediaWikiPHPUnitCommand::$additionalOptions[$offset]; } - } public function setCliArg( $offset, $value ) { MediaWikiPHPUnitCommand::$additionalOptions[$offset] = $value; - } /** @@ -775,7 +783,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { } /** - * Returns true iff the given namespace defaults to Wikitext + * Returns true if the given namespace defaults to Wikitext * according to $wgNamespaceContentModels * * @param int $ns The namespace ID to check @@ -839,12 +847,13 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { ) { $wikitextNS = $ns; + return $wikitextNS; } } // give up - // @todo: Inside a test, we could skip the test as incomplete. + // @todo Inside a test, we could skip the test as incomplete. // But frequently, this is used in fixture setup. throw new MWException( "No namespace defaults to wikitext!" ); } @@ -906,6 +915,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { if ( !$loaded ) { $this->markTestSkipped( "PHP extension '$extName' is not loaded, skipping." ); } + return $loaded; } @@ -914,6 +924,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * the provided code. * * @since 1.21 + * @deprecated since 1.22 Use setExpectedException * * @param callable $code * @param string $expected @@ -934,5 +945,4 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->assertInstanceOf( $expected, $pokemons, $message ); } - } diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php index 01caf8f4..d929b79d 100644 --- a/tests/phpunit/bootstrap.php +++ b/tests/phpunit/bootstrap.php @@ -11,22 +11,5 @@ if ( !defined( 'MW_PHPUNIT_TEST' ) ) { You are running these tests directly from phpunit. You may not have all globals correctly set. Running phpunit.php instead is recommended. EOF; - require_once ( __DIR__ . "/phpunit.php" ); + require_once __DIR__ . "/phpunit.php"; } - -// Output a notice when running with older versions of PHPUnit -if ( version_compare( PHPUnit_Runner_Version::id(), "3.6.7", "<" ) ) { - echo <<<EOF -******************************************************************************** - -These tests run best with version PHPUnit 3.6.7 or better. Earlier versions may -show failures because earlier versions of PHPUnit do not properly implement -dependencies. - -******************************************************************************** - -EOF; -} - -/** @todo Check if this is really needed */ -MessageCache::destroyInstance(); diff --git a/tests/phpunit/data/db/sqlite/tables-1.16.sql b/tests/phpunit/data/db/sqlite/tables-1.16.sql index 6e56add2..7e8f30ec 100644 --- a/tests/phpunit/data/db/sqlite/tables-1.16.sql +++ b/tests/phpunit/data/db/sqlite/tables-1.16.sql @@ -146,11 +146,6 @@ CREATE TABLE /*_*/externallinks ( CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); -CREATE TABLE /*_*/external_user ( - eu_local_id int unsigned NOT NULL PRIMARY KEY, - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); CREATE TABLE /*_*/langlinks ( ll_from int unsigned NOT NULL default 0, ll_lang varbinary(20) NOT NULL default '', diff --git a/tests/phpunit/data/db/sqlite/tables-1.17.sql b/tests/phpunit/data/db/sqlite/tables-1.17.sql index 69ae3764..e02e3e14 100644 --- a/tests/phpunit/data/db/sqlite/tables-1.17.sql +++ b/tests/phpunit/data/db/sqlite/tables-1.17.sql @@ -151,11 +151,6 @@ CREATE TABLE /*_*/externallinks ( CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); -CREATE TABLE /*_*/external_user ( - eu_local_id int unsigned NOT NULL PRIMARY KEY, - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); CREATE TABLE /*_*/langlinks ( ll_from int unsigned NOT NULL default 0, ll_lang varbinary(20) NOT NULL default '', diff --git a/tests/phpunit/data/db/sqlite/tables-1.18.sql b/tests/phpunit/data/db/sqlite/tables-1.18.sql index b106d2b7..8bfc28e2 100644 --- a/tests/phpunit/data/db/sqlite/tables-1.18.sql +++ b/tests/phpunit/data/db/sqlite/tables-1.18.sql @@ -157,11 +157,6 @@ CREATE TABLE /*_*/externallinks ( CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); -CREATE TABLE /*_*/external_user ( - eu_local_id int unsigned NOT NULL PRIMARY KEY, - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); CREATE TABLE /*_*/langlinks ( ll_from int unsigned NOT NULL default 0, ll_lang varbinary(20) NOT NULL default '', diff --git a/tests/phpunit/data/less/common/test.common.mixins.less b/tests/phpunit/data/less/common/test.common.mixins.less new file mode 100644 index 00000000..2fbe9b79 --- /dev/null +++ b/tests/phpunit/data/less/common/test.common.mixins.less @@ -0,0 +1,5 @@ +.test-mixin (@value) { + color: @value; + border: @foo solid @Foo; + line-height: test-sum(@bar, 10, 20); +} diff --git a/tests/phpunit/data/less/module/dependency.less b/tests/phpunit/data/less/module/dependency.less new file mode 100644 index 00000000..c7725a25 --- /dev/null +++ b/tests/phpunit/data/less/module/dependency.less @@ -0,0 +1,3 @@ +@import "test.common.mixins"; + +@unitTestColor: green; diff --git a/tests/phpunit/data/less/module/styles.css b/tests/phpunit/data/less/module/styles.css new file mode 100644 index 00000000..b78780a9 --- /dev/null +++ b/tests/phpunit/data/less/module/styles.css @@ -0,0 +1,6 @@ +/* @noflip */ +.unit-tests { + color: green; + border: 2px solid #eeeeee; + line-height: 35; +} diff --git a/tests/phpunit/data/less/module/styles.less b/tests/phpunit/data/less/module/styles.less new file mode 100644 index 00000000..ecac8392 --- /dev/null +++ b/tests/phpunit/data/less/module/styles.less @@ -0,0 +1,6 @@ +@import "dependency"; + +/* @noflip */ +.unit-tests { + .test-mixin(@unitTestColor); +} diff --git a/tests/phpunit/data/xmp/7.result.php b/tests/phpunit/data/xmp/7.result.php index 9aa867bc..115cdc92 100644 --- a/tests/phpunit/data/xmp/7.result.php +++ b/tests/phpunit/data/xmp/7.result.php @@ -1,26 +1,26 @@ <?php -$result = array ( +$result = array( 'xmp-exif' => - array ( + array( 'CameraOwnerName' => 'Me!', ), 'xmp-general' => - array ( + array( 'LicenseUrl' => 'http://creativecommons.com/cc-by-2.9', 'ImageDescription' => - array ( + array( 'x-default' => 'Test image for the cc: xmp: xmpRights: namespaces in xmp', '_type' => 'lang', ), 'ObjectName' => - array ( + array( 'x-default' => 'xmp core/xmp rights/cc ns test', '_type' => 'lang', ), 'DateTimeDigitized' => '2005:04:03', 'Software' => 'The one true editor: Vi (ok i used gimp)', 'Identifier' => - array ( + array( 0 => 'http://example.com/identifierurl', 1 => 'urn:sha1:342524abcdef', '_type' => 'ul', @@ -33,12 +33,12 @@ $result = array ( 'RightsCertificate' => 'http://example.com/rights-certificate/', 'Copyrighted' => 'True', 'CopyrightOwner' => - array ( + array( 0 => 'Bawolff is copyright owner', '_type' => 'ul', ), 'UsageTerms' => - array ( + array( 'x-default' => 'do whatever you want', 'en-gb' => 'Do whatever you want in british english', '_type' => 'lang', @@ -46,7 +46,7 @@ $result = array ( 'WebStatement' => 'http://example.com/web_statement', ), 'xmp-deprecated' => - array ( + array( 'Identifier' => 'http://example.com/identifierurl/wrong', ), ); diff --git a/tests/phpunit/includes/ArticleTablesTest.php b/tests/phpunit/includes/ArticleTablesTest.php index 967ffa17..0f159ae4 100644 --- a/tests/phpunit/includes/ArticleTablesTest.php +++ b/tests/phpunit/includes/ArticleTablesTest.php @@ -5,7 +5,7 @@ */ class ArticleTablesTest extends MediaWikiLangTestCase { - function testbug14404() { + public function testbug14404() { global $wgContLang, $wgLanguageCode, $wgLang; $title = Title::newFromText( 'Bug 14404' ); @@ -16,18 +16,17 @@ class ArticleTablesTest extends MediaWikiLangTestCase { $wgContLang = Language::factory( 'es' ); $wgLang = Language::factory( 'fr' ); - $status = $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', 0, false, $user ); + $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', 0, false, $user ); $templates1 = $title->getTemplateLinksFrom(); $wgLang = Language::factory( 'de' ); $page->mPreparedEdit = false; // In order to force the rerendering of the same wikitext // We need an edit, a purge is not enough to regenerate the tables - $status = $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', EDIT_UPDATE, false, $user ); + $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', EDIT_UPDATE, false, $user ); $templates2 = $title->getTemplateLinksFrom(); $this->assertEquals( $templates1, $templates2 ); $this->assertEquals( $templates1[0]->getFullText(), 'Historial' ); } - } diff --git a/tests/phpunit/includes/ArticleTest.php b/tests/phpunit/includes/ArticleTest.php index 867c4f00..b4d6dca6 100644 --- a/tests/phpunit/includes/ArticleTest.php +++ b/tests/phpunit/includes/ArticleTest.php @@ -25,14 +25,14 @@ class ArticleTest extends MediaWikiTestCase { $this->article = null; } - function testImplementsGetMagic() { + public function testImplementsGetMagic() { $this->assertEquals( false, $this->article->mLatest, "Article __get magic" ); } /** * @depends testImplementsGetMagic */ - function testImplementsSetMagic() { + public function testImplementsSetMagic() { $this->article->mLatest = 2; $this->assertEquals( 2, $this->article->mLatest, "Article __set magic" ); } @@ -40,13 +40,13 @@ class ArticleTest extends MediaWikiTestCase { /** * @depends testImplementsSetMagic */ - function testImplementsCallMagic() { + public function testImplementsCallMagic() { $this->article->mLatest = 33; $this->article->mDataLoaded = true; $this->assertEquals( 33, $this->article->getLatest(), "Article __call magic" ); } - function testGetOrSetOnNewProperty() { + public function testGetOrSetOnNewProperty() { $this->article->ext_someNewProperty = 12; $this->assertEquals( 12, $this->article->ext_someNewProperty, "Article get/set magic on new field" ); @@ -59,7 +59,7 @@ class ArticleTest extends MediaWikiTestCase { /** * Checks for the existence of the backwards compatibility static functions (forwarders to WikiPage class) */ - function testStaticFunctions() { + public function testStaticFunctions() { $this->hideDeprecated( 'Article::getAutosummary' ); $this->hideDeprecated( 'WikiPage::getAutosummary' ); $this->hideDeprecated( 'CategoryPage::getAutosummary' ); // Inherited from Article @@ -76,7 +76,7 @@ class ArticleTest extends MediaWikiTestCase { "Article static functions" ); } - function testWikiPageFactory() { + public function testWikiPageFactory() { $title = Title::makeTitle( NS_FILE, 'Someimage.png' ); $page = WikiPage::factory( $title ); $this->assertEquals( 'WikiFilePage', get_class( $page ) ); diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php index 19c9b687..21de0985 100644 --- a/tests/phpunit/includes/BlockTest.php +++ b/tests/phpunit/includes/BlockTest.php @@ -51,36 +51,36 @@ class BlockTest extends MediaWikiLangTestCase { } else { throw new MWException( "Failed to insert block for BlockTest; old leftover block remaining?" ); } + + $this->addXffBlocks(); } /** * debug function : dump the ipblocks table */ function dumpBlocks() { - $v = $this->db->query( 'SELECT * FROM unittest_ipblocks' ); + $v = $this->db->select( 'ipblocks', '*' ); print "Got " . $v->numRows() . " rows. Full dump follow:\n"; foreach ( $v as $row ) { print_r( $row ); } } - function testInitializerFunctionsReturnCorrectBlock() { + public function testInitializerFunctionsReturnCorrectBlock() { // $this->dumpBlocks(); $this->assertTrue( $this->block->equals( Block::newFromTarget( 'UTBlockee' ) ), "newFromTarget() returns the same block as the one that was made" ); $this->assertTrue( $this->block->equals( Block::newFromID( $this->blockId ) ), "newFromID() returns the same block as the one that was made" ); - } /** * per bug 26425 */ - function testBug26425BlockTimestampDefaultsToTime() { + public function testBug26425BlockTimestampDefaultsToTime() { // delta to stop one-off errors when things happen to go over a second mark. $delta = abs( $this->madeAt - $this->block->mTimestamp ); $this->assertLessThan( 2, $delta, "If no timestamp is specified, the block is recorded as time()" ); - } /** @@ -91,7 +91,7 @@ class BlockTest extends MediaWikiLangTestCase { * * @dataProvider provideBug29116Data */ - function testBug29116LoadWithEmptyIp( $vagueTarget ) { + public function testBug29116LoadWithEmptyIp( $vagueTarget ) { $this->hideDeprecated( 'Block::load' ); $uid = User::idFromName( 'UTBlockee' ); @@ -111,7 +111,7 @@ class BlockTest extends MediaWikiLangTestCase { * * @dataProvider provideBug29116Data */ - function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) { + public function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) { $block = Block::newFromTarget( 'UTBlockee', $vagueTarget ); $this->assertTrue( $this->block->equals( $block ), "newFromTarget() returns the same block as the one that was made when given empty vagueTarget param " . var_export( $vagueTarget, true ) ); } @@ -124,14 +124,13 @@ class BlockTest extends MediaWikiLangTestCase { ); } - function testBlockedUserCanNotCreateAccount() { + public function testBlockedUserCanNotCreateAccount() { $username = 'BlockedUserToCreateAccountWith'; $u = User::newFromName( $username ); $u->setPassword( 'NotRandomPass' ); $u->addToDatabase(); unset( $u ); - // Sanity check $this->assertNull( Block::newFromTarget( $username ), @@ -185,7 +184,7 @@ class BlockTest extends MediaWikiLangTestCase { ); } - function testCrappyCrossWikiBlocks() { + public function testCrappyCrossWikiBlocks() { // Delete the last round's block if it's still there $oldBlock = Block::newFromTarget( 'UserOnForeignWiki' ); if ( $oldBlock ) { @@ -228,4 +227,128 @@ class BlockTest extends MediaWikiLangTestCase { $this->assertEquals( 'MetaWikiUser', $block->getByName(), 'Correct blocker name' ); $this->assertEquals( 0, $block->getBy(), 'Correct blocker id' ); } + + protected function addXffBlocks() { + static $inited = false; + + if ( $inited ) { + return; + } + + $inited = true; + + $blockList = array( + array( 'target' => '70.2.0.0/16', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range Hardblock', + 'ACDisable' => false, + 'isHardblock' => true, + 'isAutoBlocking' => false, + ), + array( 'target' => '2001:4860:4001::/48', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range6 Hardblock', + 'ACDisable' => false, + 'isHardblock' => true, + 'isAutoBlocking' => false, + ), + array( 'target' => '60.2.0.0/16', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range Softblock with AC Disabled', + 'ACDisable' => true, + 'isHardblock' => false, + 'isAutoBlocking' => false, + ), + array( 'target' => '50.2.0.0/16', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range Softblock', + 'ACDisable' => false, + 'isHardblock' => false, + 'isAutoBlocking' => false, + ), + array( 'target' => '50.1.1.1', + 'type' => Block::TYPE_IP, + 'desc' => 'Exact Softblock', + 'ACDisable' => false, + 'isHardblock' => false, + 'isAutoBlocking' => false, + ), + ); + + foreach ( $blockList as $insBlock ) { + $target = $insBlock['target']; + + if ( $insBlock['type'] === Block::TYPE_IP ) { + $target = User::newFromName( IP::sanitizeIP( $target ), false )->getName(); + } elseif ( $insBlock['type'] === Block::TYPE_RANGE ) { + $target = IP::sanitizeRange( $target ); + } + + $block = new Block(); + $block->setTarget( $target ); + $block->setBlocker( 'testblocker@global' ); + $block->mReason = $insBlock['desc']; + $block->mExpiry = 'infinity'; + $block->prevents( 'createaccount', $insBlock['ACDisable'] ); + $block->isHardblock( $insBlock['isHardblock'] ); + $block->isAutoblocking( $insBlock['isAutoBlocking'] ); + $block->insert(); + } + } + + public static function providerXff() { + return array( + array( 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Hardblock' + ), + array( 'xff' => '1.2.3.4, 50.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Softblock with AC Disabled' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 50.1.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Exact Softblock' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 50.1.1.1, 2.3.4.5', + 'count' => 3, + 'result' => 'Exact Softblock' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Hardblock' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Hardblock' + ), + array( 'xff' => '50.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Softblock with AC Disabled' + ), + array( 'xff' => '1.2.3.4, 50.1.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Exact Softblock' + ), + array( 'xff' => '1.2.3.4, <$A_BUNCH-OF{INVALID}TEXT\>, 60.2.1.1, 2.3.4.5', + 'count' => 1, + 'result' => 'Range Softblock with AC Disabled' + ), + array( 'xff' => '1.2.3.4, 50.2.1.1, 2001:4860:4001:802::1003, 2.3.4.5', + 'count' => 2, + 'result' => 'Range6 Hardblock' + ), + ); + } + + /** + * @dataProvider providerXff + */ + public function testBlocksOnXff( $xff, $exCount, $exResult ) { + $list = array_map( 'trim', explode( ',', $xff ) ); + $xffblocks = Block::getBlocksForIPList( $list, true ); + $this->assertEquals( $exCount, count( $xffblocks ), 'Number of blocks for ' . $xff ); + $block = Block::chooseBlock( $xffblocks, $list ); + $this->assertEquals( $exResult, $block->mReason, 'Correct block type for XFF header ' . $xff ); + } } diff --git a/tests/phpunit/includes/CdbTest.php b/tests/phpunit/includes/CdbTest.php index add585d7..e3d9da7c 100644 --- a/tests/phpunit/includes/CdbTest.php +++ b/tests/phpunit/includes/CdbTest.php @@ -66,7 +66,6 @@ class CdbTest extends MediaWikiTestCase { $this->cdbAssert( "PHP error", $key, $v1, $value ); $this->cdbAssert( "DBA error", $key, $v2, $value ); } - } private function randomString() { @@ -75,6 +74,7 @@ class CdbTest extends MediaWikiTestCase { for ( $j = 0; $j < $len; $j++ ) { $s .= chr( mt_rand( 0, 255 ) ); } + return $s; } diff --git a/tests/phpunit/includes/CollationTest.php b/tests/phpunit/includes/CollationTest.php index c746208b..43bb3941 100644 --- a/tests/phpunit/includes/CollationTest.php +++ b/tests/phpunit/includes/CollationTest.php @@ -20,7 +20,7 @@ class CollationTest extends MediaWikiLangTestCase { * * @dataProvider prefixDataProvider */ - function testIsPrefix( $lang, $base, $extended ) { + public function testIsPrefix( $lang, $base, $extended ) { $cp = Collator::create( $lang ); $cp->setStrength( Collator::PRIMARY ); $baseBin = $cp->getSortKey( $base ); @@ -47,12 +47,13 @@ class CollationTest extends MediaWikiLangTestCase { array( 'en', 'A', 'Aꦲ' ), ); } + /** * Opposite of testIsPrefix * * @dataProvider notPrefixDataProvider */ - function testNotIsPrefix( $lang, $base, $extended ) { + public function testNotIsPrefix( $lang, $base, $extended ) { $cp = Collator::create( $lang ); $cp->setStrength( Collator::PRIMARY ); $baseBin = $cp->getSortKey( $base ); @@ -80,10 +81,11 @@ class CollationTest extends MediaWikiLangTestCase { * * @dataProvider firstLetterProvider */ - function testGetFirstLetter( $collation, $string, $firstLetter ) { + public function testGetFirstLetter( $collation, $string, $firstLetter ) { $col = Collation::factory( $collation ); $this->assertEquals( $firstLetter, $col->getFirstLetter( $string ) ); } + function firstLetterProvider() { return array( array( 'uppercase', 'Abc', 'A' ), diff --git a/tests/phpunit/includes/DiffHistoryBlobTest.php b/tests/phpunit/includes/DiffHistoryBlobTest.php index dcd9dddf..a4d5b91a 100644 --- a/tests/phpunit/includes/DiffHistoryBlobTest.php +++ b/tests/phpunit/includes/DiffHistoryBlobTest.php @@ -4,14 +4,17 @@ class DiffHistoryBlobTest extends MediaWikiTestCase { protected function setUp() { if ( !extension_loaded( 'xdiff' ) ) { $this->markTestSkipped( 'The xdiff extension is not available' ); + return; } if ( !function_exists( 'xdiff_string_rabdiff' ) ) { $this->markTestSkipped( 'The version of xdiff extension is lower than 1.5.0' ); + return; } - if ( !extension_loaded( 'hash' ) && !extension_loaded( 'mhash' ) ) { - $this->markTestSkipped( 'Neither the hash nor mhash extension is available' ); + if ( !extension_loaded( 'hash' ) ) { + $this->markTestSkipped( 'The hash extension is not available' ); + return; } parent::setUp(); @@ -21,7 +24,7 @@ class DiffHistoryBlobTest extends MediaWikiTestCase { * Test for DiffHistoryBlob::xdiffAdler32() * @dataProvider provideXdiffAdler32 */ - function testXdiffAdler32( $input ) { + public function testXdiffAdler32( $input ) { $xdiffHash = substr( xdiff_string_rabdiff( $input, '' ), 0, 4 ); $dhb = new DiffHistoryBlob; $myHash = $dhb->xdiffAdler32( $input ); diff --git a/tests/phpunit/includes/EditPageTest.php b/tests/phpunit/includes/EditPageTest.php index 00eba30a..87272a4c 100644 --- a/tests/phpunit/includes/EditPageTest.php +++ b/tests/phpunit/includes/EditPageTest.php @@ -9,12 +9,12 @@ * @group medium * ^--- tell phpunit that these test cases may take longer than 2 seconds. */ -class EditPageTest extends MediaWikiTestCase { +class EditPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideExtractSectionTitle */ - function testExtractSectionTitle( $section, $title ) { + public function testExtractSectionTitle( $section, $title ) { $extracted = EditPage::extractSectionTitle( $section ); $this->assertEquals( $title, $extracted ); } @@ -173,15 +173,90 @@ class EditPageTest extends MediaWikiTestCase { } public function testCreatePage() { - $text = "Hello World!"; - $edit = array( - 'wpTextbox1' => $text, - 'wpSummary' => 'just testing', + $this->assertEdit( + 'EditPageTest_testCreatePage', + null, + null, + array( + 'wpTextbox1' => "Hello World!", + ), + EditPage::AS_SUCCESS_NEW_ARTICLE, + "Hello World!", + "expected article being created" + )->doDeleteArticleReal( 'EditPageTest_testCreatePage' ); + + $this->assertEdit( + 'EditPageTest_testCreatePage', + null, + null, + array( + 'wpTextbox1' => "", + ), + EditPage::AS_BLANK_ARTICLE, + null, + "expected article not being created if empty" + ); + + + $this->assertEdit( + 'MediaWiki:January', + null, + 'UTSysop', + array( + 'wpTextbox1' => "Not January", + ), + EditPage::AS_SUCCESS_NEW_ARTICLE, + "Not January", + "expected MediaWiki: page being created" + )->doDeleteArticleReal( 'EditPageTest_testCreatePage' ); + + $this->assertEdit( + 'MediaWiki:EditPageTest_testCreatePage', + null, + 'UTSysop', + array( + 'wpTextbox1' => "", + ), + EditPage::AS_BLANK_ARTICLE, + null, + "expected not-registered MediaWiki: page not being created if empty" ); - $this->assertEdit( 'EditPageTest_testCreatePafe', null, null, $edit, - EditPage::AS_SUCCESS_NEW_ARTICLE, $text, - "expected successfull creation with given text" ); + $this->assertEdit( + 'MediaWiki:January', + null, + 'UTSysop', + array( + 'wpTextbox1' => "", + ), + EditPage::AS_SUCCESS_NEW_ARTICLE, + "", + "expected registered MediaWiki: page being created even if empty" + )->doDeleteArticleReal( 'EditPageTest_testCreatePage' ); + + $this->assertEdit( + 'MediaWiki:Ipb-default-expiry', + null, + 'UTSysop', + array( + 'wpTextbox1' => "", + ), + EditPage::AS_BLANK_ARTICLE, + "", + "expected registered MediaWiki: page whose default content is empty not being created if empty" + ); + + $this->assertEdit( + 'MediaWiki:January', + null, + 'UTSysop', + array( + 'wpTextbox1' => "January", + ), + EditPage::AS_BLANK_ARTICLE, + null, + "expected MediaWiki: page not being created if text equals default message" + ); } public function testUpdatePage() { diff --git a/tests/phpunit/includes/ExternalStoreTest.php b/tests/phpunit/includes/ExternalStoreTest.php index 99544e7e..fcffcbc2 100644 --- a/tests/phpunit/includes/ExternalStoreTest.php +++ b/tests/phpunit/includes/ExternalStoreTest.php @@ -5,7 +5,7 @@ class ExternalStoreTest extends MediaWikiTestCase { - function testExternalFetchFromURL() { + public function testExternalFetchFromURL() { $this->setMwGlobals( 'wgExternalStores', false ); $this->assertFalse( diff --git a/tests/phpunit/includes/ExtraParserTest.php b/tests/phpunit/includes/ExtraParserTest.php index 067cfc4a..6c67beb1 100644 --- a/tests/phpunit/includes/ExtraParserTest.php +++ b/tests/phpunit/includes/ExtraParserTest.php @@ -27,7 +27,7 @@ class ExtraParserTest extends MediaWikiTestCase { } // Bug 8689 - Long numeric lines kill the parser - function testBug8689() { + public function testBug8689() { global $wgUser; $longLine = '1.' . str_repeat( '1234567890', 100000 ) . "\n"; @@ -38,13 +38,13 @@ class ExtraParserTest extends MediaWikiTestCase { } /* Test the parser entry points */ - function testParse() { + public function testParse() { $title = Title::newFromText( __FUNCTION__ ); $parserOutput = $this->parser->parse( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options ); $this->assertEquals( "<p>Test\nContent of <i>Template:Foo</i>\nContent of <i>Template:Bar</i>\n</p>", $parserOutput->getText() ); } - function testPreSaveTransform() { + public function testPreSaveTransform() { global $wgUser; $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->preSaveTransform( "Test\r\n{{subst:Foo}}\n{{Bar}}", $title, $wgUser, $this->options ); @@ -52,7 +52,7 @@ class ExtraParserTest extends MediaWikiTestCase { $this->assertEquals( "Test\nContent of ''Template:Foo''\n{{Bar}}", $outputText ); } - function testPreprocess() { + public function testPreprocess() { $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->preprocess( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options ); @@ -62,7 +62,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * cleanSig() makes all templates substs and removes tildes */ - function testCleanSig() { + public function testCleanSig() { $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); @@ -72,9 +72,8 @@ class ExtraParserTest extends MediaWikiTestCase { /** * cleanSig() should do nothing if disabled */ - function testCleanSigDisabled() { - global $wgCleanSignatures; - $wgCleanSignatures = false; + public function testCleanSigDisabled() { + $this->setMwGlobals( 'wgCleanSignatures', false ); $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); @@ -86,7 +85,7 @@ class ExtraParserTest extends MediaWikiTestCase { * cleanSigInSig() just removes tildes * @dataProvider provideStringsForCleanSigInSig */ - function testCleanSigInSig( $in, $out ) { + public function testCleanSigInSig( $in, $out ) { $this->assertEquals( Parser::cleanSigInSig( $in ), $out ); } @@ -98,7 +97,7 @@ class ExtraParserTest extends MediaWikiTestCase { ); } - function testGetSection() { + public function testGetSection() { $outputText2 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 2 ); $outputText1 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1 ); @@ -106,7 +105,7 @@ class ExtraParserTest extends MediaWikiTestCase { $this->assertEquals( "== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2", $outputText1 ); } - function testReplaceSection() { + public function testReplaceSection() { $outputText = $this->parser->replaceSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1, "New section 1" ); $this->assertEquals( "Section 0\nNew section 1\n\n== Heading 3 ==\nSection 3", $outputText ); @@ -115,7 +114,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * Templates and comments are not affected, but noinclude/onlyinclude is. */ - function testGetPreloadText() { + public function testGetPreloadText() { $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->getPreloadText( "{{Foo}}<noinclude> censored</noinclude> information <!-- is very secret -->", $title, $this->options ); @@ -135,7 +134,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * @group Database */ - function testTrackingCategory() { + public function testTrackingCategory() { $title = Title::newFromText( __FUNCTION__ ); $catName = wfMessage( 'broken-file-category' )->inContentLanguage()->text(); $cat = Title::makeTitleSafe( NS_CATEGORY, $catName ); @@ -148,7 +147,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * @group Database */ - function testTrackingCategorySpecial() { + public function testTrackingCategorySpecial() { // Special pages shouldn't have tracking cats. $title = SpecialPage::getTitleFor( 'Contributions' ); $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options ); diff --git a/tests/phpunit/includes/FallbackTest.php b/tests/phpunit/includes/FallbackTest.php new file mode 100644 index 00000000..f408f471 --- /dev/null +++ b/tests/phpunit/includes/FallbackTest.php @@ -0,0 +1,73 @@ +<?php + +/** + * @covers Fallback + */ +class FallbackTest extends MediaWikiTestCase { + + public function testFallbackMbstringFunctions() { + + if ( !extension_loaded( 'mbstring' ) ) { + $this->markTestSkipped( "The mb_string functions must be installed to test the fallback functions" ); + } + + $sampleUTF = "Östergötland_coat_of_arms.png"; + + //mb_substr + $substr_params = array( + array( 0, 0 ), + array( 5, -4 ), + array( 33 ), + array( 100, -5 ), + array( -8, 10 ), + array( 1, 1 ), + array( 2, -1 ) + ); + + foreach ( $substr_params as $param_set ) { + $old_param_set = $param_set; + array_unshift( $param_set, $sampleUTF ); + + $this->assertEquals( + call_user_func_array( 'mb_substr', $param_set ), + call_user_func_array( 'Fallback::mb_substr', $param_set ), + 'Fallback mb_substr with params ' . implode( ', ', $old_param_set ) + ); + } + + //mb_strlen + $this->assertEquals( + mb_strlen( $sampleUTF ), + Fallback::mb_strlen( $sampleUTF ), + 'Fallback mb_strlen' + ); + + //mb_str(r?)pos + $strpos_params = array( + //array( 'ter' ), + //array( 'Ö' ), + //array( 'Ö', 3 ), + //array( 'oat_', 100 ), + //array( 'c', -10 ), + //Broken for now + ); + + foreach ( $strpos_params as $param_set ) { + $old_param_set = $param_set; + array_unshift( $param_set, $sampleUTF ); + + $this->assertEquals( + call_user_func_array( 'mb_strpos', $param_set ), + call_user_func_array( 'Fallback::mb_strpos', $param_set ), + 'Fallback mb_strpos with params ' . implode( ', ', $old_param_set ) + ); + + $this->assertEquals( + call_user_func_array( 'mb_strrpos', $param_set ), + call_user_func_array( 'Fallback::mb_strrpos', $param_set ), + 'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set ) + ); + } + } + +}
\ No newline at end of file diff --git a/tests/phpunit/includes/FauxRequestTest.php b/tests/phpunit/includes/FauxRequestTest.php new file mode 100644 index 00000000..9f3aa11d --- /dev/null +++ b/tests/phpunit/includes/FauxRequestTest.php @@ -0,0 +1,15 @@ +<?php + +class FauxRequestTest extends MediaWikiTestCase { + + public function testGetSetHeader() { + $value = 'test/test'; + + $request = new FauxRequest(); + $request->setHeader( 'Content-Type', $value ); + + $this->assertEquals( $request->getHeader( 'Content-Type' ), $value ); + $this->assertEquals( $request->getHeader( 'CONTENT-TYPE' ), $value ); + $this->assertEquals( $request->getHeader( 'content-type' ), $value ); + } +} diff --git a/tests/phpunit/includes/FauxResponseTest.php b/tests/phpunit/includes/FauxResponseTest.php index 56691c9e..f9ba1b3b 100644 --- a/tests/phpunit/includes/FauxResponseTest.php +++ b/tests/phpunit/includes/FauxResponseTest.php @@ -30,13 +30,13 @@ class FauxResponseTest extends MediaWikiTestCase { $this->response = new FauxResponse; } - function testCookie() { + public function testCookie() { $this->assertEquals( null, $this->response->getcookie( 'key' ), 'Non-existing cookie' ); $this->response->setcookie( 'key', 'val' ); $this->assertEquals( 'val', $this->response->getcookie( 'key' ), 'Existing cookie' ); } - function testHeader() { + public function testHeader() { $this->assertEquals( null, $this->response->getheader( 'Location' ), 'Non-existing header' ); $this->response->header( 'Location: http://localhost/' ); @@ -47,9 +47,12 @@ class FauxResponseTest extends MediaWikiTestCase { $this->response->header( 'Location: http://127.0.0.2/', false ); $this->assertEquals( 'http://127.0.0.1/', $this->response->getheader( 'Location' ), 'Same header with override disabled' ); + + $this->response->header( 'Location: http://localhost/' ); + $this->assertEquals( 'http://localhost/', $this->response->getheader( 'LOCATION' ), 'Get header case insensitive' ); } - function testResponseCode() { + public function testResponseCode() { $this->response->header( 'HTTP/1.1 200' ); $this->assertEquals( 200, $this->response->getStatusCode(), 'Header with no message' ); diff --git a/tests/phpunit/includes/FormOptionsInitializationTest.php b/tests/phpunit/includes/FormOptionsInitializationTest.php index 4053683f..fb2304dc 100644 --- a/tests/phpunit/includes/FormOptionsInitializationTest.php +++ b/tests/phpunit/includes/FormOptionsInitializationTest.php @@ -81,5 +81,4 @@ class FormOptionsInitializationTest extends MediaWikiTestCase { $this->object->getOptions() ); } - } diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php index 24fc47cf..6154df1d 100644 --- a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php +++ b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php @@ -29,7 +29,10 @@ class GlobalTest extends MediaWikiTestCase { parent::tearDown(); } - /** @dataProvider provideForWfArrayDiff2 */ + /** + * @dataProvider provideForWfArrayDiff2 + * @covers ::wfArrayDiff2 + */ public function testWfArrayDiff2( $a, $b, $expected ) { $this->assertEquals( wfArrayDiff2( $a, $b ), $expected @@ -53,25 +56,37 @@ class GlobalTest extends MediaWikiTestCase { ); } - function testRandom() { + /** + * @covers ::wfRandom + */ + public function testRandom() { # This could hypothetically fail, but it shouldn't ;) $this->assertFalse( wfRandom() == wfRandom() ); } - function testUrlencode() { + /** + * @covers ::wfUrlencode + */ + public function testUrlencode() { $this->assertEquals( "%E7%89%B9%E5%88%A5:Contributions/Foobar", wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) ); } - function testExpandIRI() { + /** + * @covers ::wfExpandIRI + */ + public function testExpandIRI() { $this->assertEquals( "https://te.wikibooks.org/wiki/ఉబుంటు_వాడుకరి_మార్గదర్శని", wfExpandIRI( "https://te.wikibooks.org/wiki/%E0%B0%89%E0%B0%AC%E0%B1%81%E0%B0%82%E0%B0%9F%E0%B1%81_%E0%B0%B5%E0%B0%BE%E0%B0%A1%E0%B1%81%E0%B0%95%E0%B0%B0%E0%B0%BF_%E0%B0%AE%E0%B0%BE%E0%B0%B0%E0%B1%8D%E0%B0%97%E0%B0%A6%E0%B0%B0%E0%B1%8D%E0%B0%B6%E0%B0%A8%E0%B0%BF" ) ); } - function testReadOnlyEmpty() { + /** + * @covers ::wfReadOnly + */ + public function testReadOnlyEmpty() { global $wgReadOnly; $wgReadOnly = null; @@ -79,7 +94,10 @@ class GlobalTest extends MediaWikiTestCase { $this->assertFalse( wfReadOnly() ); } - function testReadOnlySet() { + /** + * @covers ::wfReadOnly + */ + public function testReadOnlySet() { global $wgReadOnly, $wgReadOnlyFile; $f = fopen( $wgReadOnlyFile, "wt" ); @@ -97,19 +115,6 @@ class GlobalTest extends MediaWikiTestCase { $this->assertFalse( wfReadOnly() ); } - function testQuotedPrintable() { - $this->assertEquals( - "=?UTF-8?Q?=C4=88u=20legebla=3F?=", - UserMailer::quotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) ); - } - - function testTime() { - $start = wfTime(); - $this->assertInternalType( 'float', $start ); - $end = wfTime(); - $this->assertTrue( $end > $start, "Time is running backwards!" ); - } - public static function provideArrayToCGI() { return array( array( array(), '' ), // empty @@ -130,13 +135,17 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideArrayToCGI + * @covers ::wfArrayToCgi */ - function testArrayToCGI( $array, $result ) { + public function testArrayToCGI( $array, $result ) { $this->assertEquals( $result, wfArrayToCgi( $array ) ); } - function testArrayToCGI2() { + /** + * @covers ::testWfArrayDiff2 + */ + public function testArrayToCGI2() { $this->assertEquals( "baz=bar&foo=bar", wfArrayToCgi( @@ -161,8 +170,9 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideCgiToArray + * @covers ::wfCgiToArray */ - function testCgiToArray( $cgi, $result ) { + public function testCgiToArray( $cgi, $result ) { $this->assertEquals( $result, wfCgiToArray( $cgi ) ); } @@ -181,12 +191,16 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideCgiRoundTrip + * @covers ::wfArrayToCgi */ - function testCgiRoundTrip( $cgi ) { + public function testCgiRoundTrip( $cgi ) { $this->assertEquals( $cgi, wfArrayToCgi( wfCgiToArray( $cgi ) ) ); } - function testMimeTypeMatch() { + /** + * @covers ::mimeTypeMatch + */ + public function testMimeTypeMatch() { $this->assertEquals( 'text/html', mimeTypeMatch( 'text/html', @@ -208,7 +222,10 @@ class GlobalTest extends MediaWikiTestCase { 'image/svg+xml' => 0.5 ) ) ); } - function testNegotiateType() { + /** + * @covers ::wfNegotiateType + */ + public function testNegotiateType() { $this->assertEquals( 'text/html', wfNegotiateType( @@ -249,77 +266,11 @@ class GlobalTest extends MediaWikiTestCase { array( 'application/xhtml+xml' => 1.0 ) ) ); } - function testFallbackMbstringFunctions() { - - if ( !extension_loaded( 'mbstring' ) ) { - $this->markTestSkipped( "The mb_string functions must be installed to test the fallback functions" ); - } - - $sampleUTF = "Östergötland_coat_of_arms.png"; - - - //mb_substr - $substr_params = array( - array( 0, 0 ), - array( 5, -4 ), - array( 33 ), - array( 100, -5 ), - array( -8, 10 ), - array( 1, 1 ), - array( 2, -1 ) - ); - - foreach ( $substr_params as $param_set ) { - $old_param_set = $param_set; - array_unshift( $param_set, $sampleUTF ); - - $this->assertEquals( - MWFunction::callArray( 'mb_substr', $param_set ), - MWFunction::callArray( 'Fallback::mb_substr', $param_set ), - 'Fallback mb_substr with params ' . implode( ', ', $old_param_set ) - ); - } - - - //mb_strlen - $this->assertEquals( - mb_strlen( $sampleUTF ), - Fallback::mb_strlen( $sampleUTF ), - 'Fallback mb_strlen' - ); - - - //mb_str(r?)pos - $strpos_params = array( - //array( 'ter' ), - //array( 'Ö' ), - //array( 'Ö', 3 ), - //array( 'oat_', 100 ), - //array( 'c', -10 ), - //Broken for now - ); - - foreach ( $strpos_params as $param_set ) { - $old_param_set = $param_set; - array_unshift( $param_set, $sampleUTF ); - - $this->assertEquals( - MWFunction::callArray( 'mb_strpos', $param_set ), - MWFunction::callArray( 'Fallback::mb_strpos', $param_set ), - 'Fallback mb_strpos with params ' . implode( ', ', $old_param_set ) - ); - - $this->assertEquals( - MWFunction::callArray( 'mb_strrpos', $param_set ), - MWFunction::callArray( 'Fallback::mb_strrpos', $param_set ), - 'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set ) - ); - } - - } - - - function testDebugFunctionTest() { + /** + * @covers ::wfDebug + * @covers ::wfDebugMem + */ + public function testDebugFunctionTest() { global $wgDebugLogFile, $wgDebugTimestamps; @@ -329,7 +280,6 @@ class GlobalTest extends MediaWikiTestCase { $old_wgDebugTimestamps = $wgDebugTimestamps; $wgDebugTimestamps = false; - wfDebug( "This is a normal string" ); $this->assertEquals( "This is a normal string", file_get_contents( $wgDebugLogFile ) ); unlink( $wgDebugLogFile ); @@ -338,7 +288,6 @@ class GlobalTest extends MediaWikiTestCase { $this->assertEquals( "This is nöt an ASCII string", file_get_contents( $wgDebugLogFile ) ); unlink( $wgDebugLogFile ); - wfDebug( "\00305This has böth UTF and control chars\003" ); $this->assertEquals( " 05This has böth UTF and control chars ", file_get_contents( $wgDebugLogFile ) ); unlink( $wgDebugLogFile ); @@ -351,12 +300,14 @@ class GlobalTest extends MediaWikiTestCase { $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) ); unlink( $wgDebugLogFile ); - $wgDebugLogFile = $old_log_file; $wgDebugTimestamps = $old_wgDebugTimestamps; } - function testClientAcceptsGzipTest() { + /** + * @covers ::wfClientAcceptsGzip + */ + public function testClientAcceptsGzipTest() { $settings = array( 'gzip' => true, @@ -387,7 +338,10 @@ class GlobalTest extends MediaWikiTestCase { } } - function testSwapVarsTest() { + /** + * @covers ::swap + */ + public function testSwapVarsTest() { $var1 = 1; $var2 = 2; @@ -398,10 +352,12 @@ class GlobalTest extends MediaWikiTestCase { $this->assertEquals( $var1, 2, 'var1 is swapped' ); $this->assertEquals( $var2, 1, 'var2 is swapped' ); - } - function testWfPercentTest() { + /** + * @covers ::wfPercent + */ + public function testWfPercentTest() { $pcts = array( array( 6 / 7, '0.86%', 2, false ), @@ -429,6 +385,7 @@ class GlobalTest extends MediaWikiTestCase { /** * test @see wfShorthandToInteger() * @dataProvider provideShorthand + * @covers ::wfShorthandToInteger */ public function testWfShorthandToInteger( $shorthand, $expected ) { $this->assertEquals( $expected, @@ -439,7 +396,7 @@ class GlobalTest extends MediaWikiTestCase { /** array( shorthand, expected integer ) */ public static function provideShorthand() { return array( - # Null, empty ... + # Null, empty ... array( '', -1 ), array( ' ', -1 ), array( null, -1 ), @@ -489,6 +446,7 @@ class GlobalTest extends MediaWikiTestCase { * * @dataProvider provideMerge() * @group medium + * @covers ::wfMerge */ public function testMerge( $old, $mine, $yours, $expectedMergeResult, $expectedText ) { $this->checkHasDiff3(); @@ -564,13 +522,14 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideMakeUrlIndexes() + * @covers ::wfMakeUrlIndexes */ - function testMakeUrlIndexes( $url, $expected ) { + public function testMakeUrlIndexes( $url, $expected ) { $index = wfMakeUrlIndexes( $url ); $this->assertEquals( $expected, $index, "wfMakeUrlIndexes(\"$url\")" ); } - function provideMakeUrlIndexes() { + public static function provideMakeUrlIndexes() { return array( array( // just a regular :) @@ -621,13 +580,14 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideWfMatchesDomainList + * @covers ::wfMatchesDomainList */ - function testWfMatchesDomainList( $url, $domains, $expected, $description ) { + public function testWfMatchesDomainList( $url, $domains, $expected, $description ) { $actual = wfMatchesDomainList( $url, $domains ); $this->assertEquals( $expected, $actual, $description ); } - function provideWfMatchesDomainList() { + public static function provideWfMatchesDomainList() { $a = array(); $protocols = array( 'HTTP' => 'http:', 'HTTPS' => 'https:', 'protocol-relative' => '' ); foreach ( $protocols as $pDesc => $p ) { @@ -638,18 +598,30 @@ class GlobalTest extends MediaWikiTestCase { array( "$p//www.example2.com", array( 'www.example.com', 'www.example2.com', 'www.example3.com' ), true, "Exact match with other domains in array, $pDesc URL" ), array( "$p//www.example2.com", array( 'example.com', 'example2.com', 'example3,com' ), true, "Match without subdomain with other domains in array, $pDesc URL" ), array( "$p//www.example4.com", array( 'example.com', 'example2.com', 'example3,com' ), false, "Domain not in array, $pDesc URL" ), - - // FIXME: This is a bug in wfMatchesDomainList(). If and when this is fixed, update this test case - array( "$p//nds-nl.wikipedia.org", array( 'nl.wikipedia.org' ), true, "Substrings of domains match while they shouldn't, $pDesc URL" ), + array( "$p//nds-nl.wikipedia.org", array( 'nl.wikipedia.org' ), false, "Non-matching substring of domain, $pDesc URL" ), ) ); } + return $a; } /** + * @covers ::wfMkdirParents + */ + public function testWfMkdirParents() { + // Should not return true if file exists instead of directory + $fname = $this->getNewTempFile(); + wfSuppressWarnings(); + $ok = wfMkdirParents( $fname ); + wfRestoreWarnings(); + $this->assertFalse( $ok ); + } + + /** * @dataProvider provideWfShellMaintenanceCmdList + * @covers ::wfShellMaintenanceCmd */ - function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) { + public function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) { if ( wfIsWindows() ) { // Approximation that's good enough for our purposes just now $expected = str_replace( "'", '"', $expected ); @@ -658,8 +630,9 @@ class GlobalTest extends MediaWikiTestCase { $this->assertEquals( $expected, $actual, $description ); } - function provideWfShellMaintenanceCmdList() { + public static function provideWfShellMaintenanceCmdList() { global $wgPhpCli; + return array( array( 'eval.php', array( '--help', '--test' ), array(), "'$wgPhpCli' 'eval.php' '--help' '--test'", @@ -675,5 +648,5 @@ class GlobalTest extends MediaWikiTestCase { "Called eval.php --help --test with wrapper and php option" ), ); } - /* TODO: many more! */ + /* @TODO many more! */ } diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php index 4879a38d..cf891e7b 100644 --- a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php +++ b/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php @@ -6,13 +6,15 @@ class GlobalWithDBTest extends MediaWikiTestCase { /** * @dataProvider provideWfIsBadImageList + * @covers ::wfIsBadImage */ - function testWfIsBadImage( $name, $title, $blacklist, $expected, $desc ) { + public function testWfIsBadImage( $name, $title, $blacklist, $expected, $desc ) { $this->assertEquals( $expected, wfIsBadImage( $name, $title, $blacklist ), $desc ); } - function provideWfIsBadImageList() { + public static function provideWfIsBadImageList() { $blacklist = '* [[File:Bad.jpg]] except [[Nasty page]]'; + return array( array( 'Bad.jpg', false, $blacklist, true, 'Called on a bad image' ), diff --git a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php index 4bd8c685..9bb74873 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php @@ -1,9 +1,11 @@ <?php /** - * Tests for wfAssembleUrl() + * @covers ::wfAssembleUrl */ class WfAssembleUrlTest extends MediaWikiTestCase { - /** @dataProvider provideURLParts */ + /** + * @dataProvider provideURLParts + */ public function testWfAssembleUrl( $parts, $output ) { $partsDump = print_r( $parts, true ); $this->assertEquals( @@ -87,7 +89,6 @@ class WfAssembleUrlTest extends MediaWikiTestCase { $url .= '#' . $fragment; } - $cases[] = array( $parts, $url, diff --git a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php b/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php index 8df038dd..a01c0d49 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php +++ b/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php @@ -1,6 +1,6 @@ <?php /** - * Tests for wfBCP47() + * @covers ::wfBCP47 */ class WfBCP47Test extends MediaWikiTestCase { /** @@ -13,7 +13,7 @@ class WfBCP47Test extends MediaWikiTestCase { * @see http://tools.ietf.org/html/bcp47 * @dataProvider provideLanguageCodes() */ - function testBCP47( $code, $expected ) { + public function testBCP47( $code, $expected ) { $code = strtolower( $code ); $this->assertEquals( $expected, wfBCP47( $code ), "Applying BCP47 standard to lower case '$code'" @@ -28,7 +28,7 @@ class WfBCP47Test extends MediaWikiTestCase { /** * Array format is ($code, $expected) */ - function provideLanguageCodes() { + public static function provideLanguageCodes() { return array( // Extracted from BCP47 (list not exhaustive) # 2.1.1 @@ -115,20 +115,6 @@ class WfBCP47Test extends MediaWikiTestCase { // de-419-DE // a-DE // ar-a-aaa-b-bbb-a-ccc - - /* - // ISO 15924 : - array( 'sr-Cyrl', 'sr-Cyrl' ), - # @todo FIXME: Fix our function? - array( 'SR-lATN', 'sr-Latn' ), - array( 'fr-latn', 'fr-Latn' ), - // Use lowercase for single segment - // ISO 3166-1-alpha-2 code - array( 'US', 'us' ), # USA - array( 'uS', 'us' ), # USA - array( 'Fr', 'fr' ), # France - array( 'va', 'va' ), # Holy See (Vatican City State) - */ ); } } diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php index 10b62b3c..7da804e6 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php @@ -1,6 +1,6 @@ <?php /** - * Tests for wfBaseConvert() + * @covers ::wfBaseConvert */ class WfBaseConvertTest extends MediaWikiTestCase { public static function provideSingleDigitConversions() { @@ -152,6 +152,7 @@ class WfBaseConvertTest extends MediaWikiTestCase { $x[] = array( $base, $str ); } + return $x; } diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php index 407be8d2..8c548040 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php @@ -1,17 +1,17 @@ <?php /** - * Tests for wfBaseName() + * @covers ::wfBaseName */ class WfBaseNameTest extends MediaWikiTestCase { /** * @dataProvider providePaths */ - function testBaseName( $fullpath, $basename ) { + public function testBaseName( $fullpath, $basename ) { $this->assertEquals( $basename, wfBaseName( $fullpath ), "wfBaseName('$fullpath') => '$basename'" ); } - function providePaths() { + public static function providePaths() { return array( array( '', '' ), array( '/', '' ), diff --git a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php index c1225e3e..41230a1e 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php @@ -1,16 +1,17 @@ <?php /** - * Tests for wfExpandUrl() + * @covers ::wfExpandUrl */ class WfExpandUrlTest extends MediaWikiTestCase { - /** @dataProvider provideExpandableUrls */ + /** + * @dataProvider provideExpandableUrls + */ public function testWfExpandUrl( $fullUrl, $shortUrl, $defaultProto, $server, $canServer, $httpsMode, $message ) { // Fake $wgServer and $wgCanonicalServer - global $wgServer, $wgCanonicalServer; - $oldServer = $wgServer; - $oldCanServer = $wgCanonicalServer; - $wgServer = $server; - $wgCanonicalServer = $canServer; + $this->setMwGlobals( array( + 'wgServer' => $server, + 'wgCanonicalServer' => $canServer, + ) ); // Fake $_SERVER['HTTPS'] if needed if ( $httpsMode ) { @@ -20,10 +21,6 @@ class WfExpandUrlTest extends MediaWikiTestCase { } $this->assertEquals( $fullUrl, wfExpandUrl( $shortUrl, $defaultProto ), $message ); - - // Restore $wgServer and $wgCanonicalServer - $wgServer = $oldServer; - $wgCanonicalServer = $oldCanServer; } /** @@ -108,6 +105,7 @@ class WfExpandUrlTest extends MediaWikiTestCase { } } } + return $retval; } } diff --git a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php index 58cf6b95..62296245 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php @@ -1,8 +1,11 @@ <?php +/** + * @covers ::wfGetCaller + */ class WfGetCallerTest extends MediaWikiTestCase { - function testZero() { + public function testZero() { $this->assertEquals( __METHOD__, wfGetCaller( 1 ) ); } @@ -10,7 +13,7 @@ class WfGetCallerTest extends MediaWikiTestCase { return wfGetCaller(); } - function testOne() { + public function testOne() { $this->assertEquals( 'WfGetCallerTest::testOne', self::callerOne() ); } @@ -18,18 +21,20 @@ class WfGetCallerTest extends MediaWikiTestCase { if ( $n > 0 ) { return self::intermediateFunction( $level, $n - 1 ); } + return wfGetCaller( $level ); } - function testTwo() { + public function testTwo() { $this->assertEquals( 'WfGetCallerTest::testTwo', self::intermediateFunction() ); } - function testN() { + public function testN() { $this->assertEquals( 'WfGetCallerTest::testN', self::intermediateFunction( 2, 0 ) ); $this->assertEquals( 'WfGetCallerTest::intermediateFunction', self::intermediateFunction( 1, 0 ) ); - for ( $i = 0; $i < 10; $i++ ) + for ( $i = 0; $i < 10; $i++ ) { $this->assertEquals( 'WfGetCallerTest::intermediateFunction', self::intermediateFunction( $i + 1, $i ) ); + } } } diff --git a/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php index 841a1b12..5032dc11 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php @@ -1,7 +1,5 @@ <?php /** - * Tests for wfParseUrl() - * * Copyright © 2013 Alexandre Emsenhuber * * This program is free software; you can redistribute it and/or modify @@ -22,6 +20,9 @@ * @file */ +/** + * @covers ::wfParseUrl + */ class WfParseUrlTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); @@ -31,7 +32,9 @@ class WfParseUrlTest extends MediaWikiTestCase { ) ); } - /** @dataProvider provideURLs */ + /** + * @dataProvider provideURLs + */ public function testWfParseUrl( $url, $parts ) { $partsDump = var_export( $parts, true ); $this->assertEquals( diff --git a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php b/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php index 67861eeb..238a2c9c 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php @@ -1,9 +1,11 @@ <?php /** - * Tests for wfRemoveDotSegments() + *@covers ::wfRemoveDotSegments */ class WfRemoveDotSegmentsTest extends MediaWikiTestCase { - /** @dataProvider providePaths */ + /** + * @dataProvider providePaths + */ public function testWfRemoveDotSegments( $inputPath, $outputPath ) { $this->assertEquals( $outputPath, diff --git a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php b/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php index 9d66d6b9..aadec87f 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php @@ -1,10 +1,13 @@ <?php +/** + * @covers ::wfShorthandToInteger + */ class WfShorthandToIntegerTest extends MediaWikiTestCase { /** * @dataProvider provideABunchOfShorthands */ - function testWfShorthandToInteger( $input, $output, $description ) { + public function testWfShorthandToInteger( $input, $output, $description ) { $this->assertEquals( wfShorthandToInteger( $input ), $output, @@ -12,7 +15,7 @@ class WfShorthandToIntegerTest extends MediaWikiTestCase { ); } - function provideABunchOfShorthands() { + public static function provideABunchOfShorthands() { return array( array( '', -1, 'Empty string' ), array( ' ', -1, 'String of spaces' ), @@ -24,5 +27,4 @@ class WfShorthandToIntegerTest extends MediaWikiTestCase { array( '1k', 1024, 'One kb lowercased' ), ); } - } diff --git a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php index cf1830f5..5998f186 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php @@ -1,17 +1,18 @@ <?php /* - * Tests for wfTimestamp() + * @covers ::wfTimestamp */ class WfTimestampTest extends MediaWikiTestCase { /** * @dataProvider provideNormalTimestamps */ - function testNormalTimestamps( $input, $format, $output, $desc ) { + public function testNormalTimestamps( $input, $format, $output, $desc ) { $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); } - function provideNormalTimestamps() { + public static function provideNormalTimestamps() { $t = gmmktime( 12, 34, 56, 1, 15, 2001 ); + return array( // TS_UNIX array( $t, TS_MW, '20010115123456', 'TS_UNIX to TS_MW' ), @@ -56,11 +57,11 @@ class WfTimestampTest extends MediaWikiTestCase { * See r74778 and bug 25451 * @dataProvider provideOldTimestamps */ - function testOldTimestamps( $input, $format, $output, $desc ) { + public function testOldTimestamps( $input, $format, $output, $desc ) { $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); } - function provideOldTimestamps() { + public static function provideOldTimestamps() { return array( array( '19011213204554', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:54 GMT', 'Earliest time according to php documentation' ), array( '20380119031407', TS_RFC2822, 'Tue, 19 Jan 2038 03:14:07 GMT', 'Latest 32 bit time' ), @@ -95,11 +96,11 @@ class WfTimestampTest extends MediaWikiTestCase { * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 * @dataProvider provideHttpDates */ - function testHttpDate( $input, $output, $desc ) { + public function testHttpDate( $input, $output, $desc ) { $this->assertEquals( $output, wfTimestamp( TS_MW, $input ), $desc ); } - function provideHttpDates() { + public static function provideHttpDates() { return array( array( 'Sun, 06 Nov 1994 08:49:37 GMT', '19941106084937', 'RFC 822 date' ), array( 'Sunday, 06-Nov-94 08:49:37 GMT', '19941106084937', 'RFC 850 date' ), @@ -113,9 +114,9 @@ class WfTimestampTest extends MediaWikiTestCase { * There are a number of assumptions in our codebase where wfTimestamp() * should give the current date but it is not given a 0 there. See r71751 CR */ - function testTimestampParameter() { + public function testTimestampParameter() { $now = wfTimestamp( TS_UNIX ); - // We check that wfTimestamp doesn't return false (error) and use a LessThan assert + // We check that wfTimestamp doesn't return false (error) and use a LessThan assert // for the cases where the test is run in a second boundary. $zero = wfTimestamp( TS_UNIX, 0 ); diff --git a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php index 77685d50..ce6c82c5 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php @@ -1,18 +1,21 @@ <?php /** - * Tests for wfUrlencode() - * * The function only need a string parameter and might react to IIS7.0 + * @covers ::wfUrlencode */ class WfUrlencodeTest extends MediaWikiTestCase { #### TESTS ############################################################## - /** @dataProvider provideURLS */ + /** + * @dataProvider provideURLS + */ public function testEncodingUrlWith( $input, $expected ) { $this->verifyEncodingFor( 'Apache', $input, $expected ); } - /** @dataProvider provideURLS */ + /** + * @dataProvider provideURLS + */ public function testEncodingUrlWithMicrosoftIis7( $input, $expected ) { $this->verifyEncodingFor( 'Microsoft-IIS/7', $input, $expected ); } diff --git a/tests/phpunit/includes/HTMLCheckMatrixTest.php b/tests/phpunit/includes/HTMLCheckMatrixTest.php new file mode 100644 index 00000000..5bbafd37 --- /dev/null +++ b/tests/phpunit/includes/HTMLCheckMatrixTest.php @@ -0,0 +1,102 @@ +<?php + +/** + * Unit tests for the HTMLCheckMatrix form field + */ +class HtmlCheckMatrixTest extends MediaWikiTestCase { + static private $defaultOptions = array( + 'rows' => array( 'r1', 'r2' ), + 'columns' => array( 'c1', 'c2' ), + 'fieldname' => 'test', + ); + + public function testPlainInstantiation() { + try { + $form = new HTMLCheckMatrix( array() ); + } catch ( MWException $e ) { + $this->assertInstanceOf( 'HTMLFormFieldRequiredOptionsException', $e ); + return; + } + + $this->fail( 'Expected MWException indicating missing parameters but none was thrown.' ); + } + + public function testInstantiationWithMinimumRequiredParameters() { + $form = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertTrue( true ); // form instantiation must throw exception on failure + } + + public function testValidateCallsUserDefinedValidationCallback() { + $called = false; + $field = new HTMLCheckMatrix( self::$defaultOptions + array( + 'validation-callback' => function() use ( &$called ) { + $called = true; + return false; + }, + ) ); + $this->assertEquals( false, $this->validate( $field, array() ) ); + $this->assertTrue( $called ); + } + + public function testValidateRequiresArrayInput() { + $field = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertEquals( false, $this->validate( $field, null ) ); + $this->assertEquals( false, $this->validate( $field, true ) ); + $this->assertEquals( false, $this->validate( $field, 'abc' ) ); + $this->assertEquals( false, $this->validate( $field, new stdClass ) ); + $this->assertEquals( true, $this->validate( $field, array() ) ); + } + + public function testValidateAllowsOnlyKnownTags() { + $field = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertInternalType( 'string', $this->validate( $field, array( 'foo' ) ) ); + } + + public function testValidateAcceptsPartialTagList() { + $field = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertTrue( $this->validate( $field, array() ) ); + $this->assertTrue( $this->validate( $field, array( 'c1-r1' ) ) ); + $this->assertTrue( $this->validate( $field, array( 'c1-r1', 'c1-r2', 'c2-r1', 'c2-r2' ) ) ); + } + + /** + * This form object actually has no visibility into what happens later on, but essentially + * if the data submitted by the user passes validate the following is run: + * foreach ( $field->filterDataForSubmit( $data ) as $k => $v ) { + * $user->setOption( $k, $v ); + * } + */ + public function testValuesForcedOnRemainOn() { + $field = new HTMLCheckMatrix( self::$defaultOptions + array( + 'force-options-on' => array( 'c2-r1' ), + ) ); + $expected = array( + 'c1-r1' => false, + 'c1-r2' => false, + 'c2-r1' => true, + 'c2-r2' => false, + ); + $this->assertEquals( $expected, $field->filterDataForSubmit( array() ) ); + } + + public function testValuesForcedOffRemainOff() { + $field = new HTMLCheckMatrix( self::$defaultOptions + array( + 'force-options-off' => array( 'c1-r2', 'c2-r2' ), + ) ); + $expected = array( + 'c1-r1' => true, + 'c1-r2' => false, + 'c2-r1' => true, + 'c2-r2' => false, + ); + // array_keys on the result simulates submitting all fields checked + $this->assertEquals( $expected, $field->filterDataForSubmit( array_keys( $expected ) ) ); + } + + protected function validate( HTMLFormField $field, $submitted ) { + return $field->validate( + $submitted, + array( self::$defaultOptions['fieldname'] => $submitted ) + ); + } +} diff --git a/tests/phpunit/includes/HashRingTest.php b/tests/phpunit/includes/HashRingTest.php new file mode 100644 index 00000000..65f13696 --- /dev/null +++ b/tests/phpunit/includes/HashRingTest.php @@ -0,0 +1,53 @@ +<?php + +/** + * @group HashRing + */ +class HashRingTest extends MediaWikiTestCase { + public function testHashRing() { + $ring = new HashRing( array( 's1' => 1, 's2' => 1, 's3' => 2, 's4' => 2, 's5' => 2, 's6' => 3 ) ); + + $locations = array(); + for ( $i = 0; $i < 20; $i++ ) { + $locations[ "hello$i"] = $ring->getLocation( "hello$i" ); + } + $expectedLocations = array( + "hello0" => "s5", + "hello1" => "s6", + "hello2" => "s2", + "hello3" => "s5", + "hello4" => "s6", + "hello5" => "s4", + "hello6" => "s5", + "hello7" => "s4", + "hello8" => "s5", + "hello9" => "s5", + "hello10" => "s3", + "hello11" => "s6", + "hello12" => "s1", + "hello13" => "s3", + "hello14" => "s3", + "hello15" => "s5", + "hello16" => "s4", + "hello17" => "s6", + "hello18" => "s6", + "hello19" => "s3" + ); + + $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' ); + + $locations = array(); + for ( $i = 0; $i < 5; $i++ ) { + $locations[ "hello$i"] = $ring->getLocations( "hello$i", 2 ); + } + + $expectedLocations = array( + "hello0" => array( "s5", "s6" ), + "hello1" => array( "s6", "s4" ), + "hello2" => array( "s2", "s1" ), + "hello3" => array( "s5", "s6" ), + "hello4" => array( "s6", "s4" ), + ); + $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' ); + } +} diff --git a/tests/phpunit/includes/HooksTest.php b/tests/phpunit/includes/HooksTest.php index 89e789b1..81dd4870 100644 --- a/tests/phpunit/includes/HooksTest.php +++ b/tests/phpunit/includes/HooksTest.php @@ -2,81 +2,62 @@ class HooksTest extends MediaWikiTestCase { - public function testOldStyleHooks() { - $foo = 'Foo'; - $bar = 'Bar'; - - $i = new NothingClass(); - + function setUp() { global $wgHooks; - - $wgHooks['MediaWikiHooksTest001'][] = array( $i, 'someNonStatic' ); - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'fOO', $foo, 'Standard method' ); - $foo = 'Foo'; - - $wgHooks['MediaWikiHooksTest001'][] = $i; - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'foo', $foo, 'onEventName style' ); - $foo = 'Foo'; - - $wgHooks['MediaWikiHooksTest001'][] = array( $i, 'someNonStaticWithData', 'baz' ); - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'baz', $foo, 'Data included' ); - $foo = 'Foo'; - - $wgHooks['MediaWikiHooksTest001'][] = array( $i, 'someStatic' ); - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'bah', $foo, 'Standard static method' ); - //$foo = 'Foo'; - + parent::setUp(); + Hooks::clear( 'MediaWikiHooksTest001' ); unset( $wgHooks['MediaWikiHooksTest001'] ); - } - public function testNewStyleHooks() { - $foo = 'Foo'; - $bar = 'Bar'; - + public static function provideHooks() { $i = new NothingClass(); - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someNonStatic' ) ); - - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'fOO', $foo, 'Standard method' ); - $foo = 'Foo'; - - Hooks::register( 'MediaWikiHooksTest001', $i ); - - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'foo', $foo, 'onEventName style' ); - $foo = 'Foo'; + return array( + array( 'Object and method', array( $i, 'someNonStatic' ), 'changed-nonstatic', 'changed-nonstatic' ), + array( 'Object and no method', array( $i ), 'changed-onevent', 'original' ), + array( 'Object and method with data', array( $i, 'someNonStaticWithData', 'data' ), 'data', 'original' ), + array( 'Object and static method', array( $i, 'someStatic' ), 'changed-static', 'original' ), + array( 'Class::method static call', array( 'NothingClass::someStatic' ), 'changed-static', 'original' ), + array( 'Global function', array( 'NothingFunction' ), 'changed-func', 'original' ), + array( 'Global function with data', array( 'NothingFunctionData', 'data' ), 'data', 'original' ), + array( 'Closure', array( function ( &$foo, $bar ) { + $foo = 'changed-closure'; + + return true; + } ), 'changed-closure', 'original' ), + array( 'Closure with data', array( function ( $data, &$foo, $bar ) { + $foo = $data; + + return true; + }, 'data' ), 'data', 'original' ) + ); + } - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someNonStaticWithData', 'baz' ) ); + /** + * @dataProvider provideHooks + */ + public function testOldStyleHooks( $msg, array $hook, $expectedFoo, $expectedBar ) { + global $wgHooks; + $foo = $bar = 'original'; - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); + $wgHooks['MediaWikiHooksTest001'][] = $hook; + wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - $this->assertEquals( 'baz', $foo, 'Data included' ); - $foo = 'Foo'; + $this->assertSame( $expectedFoo, $foo, $msg ); + $this->assertSame( $expectedBar, $bar, $msg ); + } - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someStatic' ) ); + /** + * @dataProvider provideHooks + */ + public function testNewStyleHooks( $msg, $hook, $expectedFoo, $expectedBar ) { + $foo = $bar = 'original'; + Hooks::register( 'MediaWikiHooksTest001', $hook ); Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - $this->assertEquals( 'bah', $foo, 'Standard static method' ); - $foo = 'Foo'; - - Hooks::clear( 'MediaWikiHooksTest001' ); + $this->assertSame( $expectedFoo, $foo, $msg ); + $this->assertSame( $expectedBar, $bar, $msg ); } public function testNewStyleHookInteraction() { @@ -85,10 +66,6 @@ class HooksTest extends MediaWikiTestCase { $a = new NothingClass(); $b = new NothingClass(); - // make sure to start with a clean slate - Hooks::clear( 'MediaWikiHooksTest001' ); - unset( $wgHooks['MediaWikiHooksTest001'] ); - $wgHooks['MediaWikiHooksTest001'][] = $a; $this->assertTrue( Hooks::isRegistered( 'MediaWikiHooksTest001' ), 'Hook registered via $wgHooks should be noticed by Hooks::isRegistered' ); @@ -101,37 +78,81 @@ class HooksTest extends MediaWikiTestCase { Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); $this->assertEquals( 1, $a->calls, 'Hooks::run() should run hooks registered via wgHooks as well as Hooks::register' ); $this->assertEquals( 1, $b->calls, 'Hooks::run() should run hooks registered via wgHooks as well as Hooks::register' ); + } - // clean up - Hooks::clear( 'MediaWikiHooksTest001' ); - unset( $wgHooks['MediaWikiHooksTest001'] ); + /** + * @expectedException MWException + */ + public function testUncallableFunction() { + Hooks::register( 'MediaWikiHooksTest001', 'ThisFunctionDoesntExist' ); + Hooks::run( 'MediaWikiHooksTest001', array() ); } + + public function testFalseReturn() { + Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) { + return false; + } ); + Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) { + $foo = 'test'; + + return true; + } ); + $foo = 'original'; + Hooks::run( 'MediaWikiHooksTest001', array( &$foo ) ); + $this->assertSame( 'original', $foo, 'Hooks continued processing after a false return.' ); + } + + /** + * @expectedException FatalError + */ + public function testFatalError() { + Hooks::register( 'MediaWikiHooksTest001', function () { + return 'test'; + } ); + Hooks::run( 'MediaWikiHooksTest001', array() ); + } +} + +function NothingFunction( &$foo, &$bar ) { + $foo = 'changed-func'; + + return true; +} + +function NothingFunctionData( $data, &$foo, &$bar ) { + $foo = $data; + + return true; } class NothingClass { public $calls = 0; public static function someStatic( &$foo, &$bar ) { - $foo = 'bah'; + $foo = 'changed-static'; + return true; } public function someNonStatic( &$foo, &$bar ) { $this->calls++; - $foo = 'fOO'; - $bar = 'bAR'; + $foo = 'changed-nonstatic'; + $bar = 'changed-nonstatic'; + return true; } public function onMediaWikiHooksTest001( &$foo, &$bar ) { $this->calls++; - $foo = 'foo'; + $foo = 'changed-onevent'; + return true; } - public function someNonStaticWithData( $foo, &$bar ) { + public function someNonStaticWithData( $data, &$foo, &$bar ) { $this->calls++; - $bar = $foo; + $foo = $data; + return true; } } diff --git a/tests/phpunit/includes/HtmlFormatterTest.php b/tests/phpunit/includes/HtmlFormatterTest.php new file mode 100644 index 00000000..a37df74f --- /dev/null +++ b/tests/phpunit/includes/HtmlFormatterTest.php @@ -0,0 +1,81 @@ +<?php + +/** + * @group HtmlFormatter + */ +class HtmlFormatterTest extends MediaWikiTestCase { + /** + * @dataProvider getHtmlData + */ + public function testTransform( $input, $expected, $callback = false ) { + $input = self::normalize( $input ); + $formatter = new HtmlFormatter( HtmlFormatter::wrapHTML( $input ) ); + if ( $callback ) { + $callback( $formatter ); + } + $formatter->filterContent(); + $html = $formatter->getText(); + $this->assertEquals( self::normalize( $expected ), self::normalize( $html ) ); + } + + private static function normalize( $s ) { + return str_replace( "\n", '', + str_replace( "\r", '', $s ) // "yay" to Windows! + ); + } + + public function getHtmlData() { + $removeImages = function( HtmlFormatter $f ) { + $f->setRemoveMedia(); + }; + $removeTags = function( HtmlFormatter $f ) { + $f->remove( array( 'table', '.foo', '#bar', 'div.baz' ) ); + }; + $flattenSomeStuff = function( HtmlFormatter $f ) { + $f->flatten( array( 's', 'div' ) ); + }; + $flattenEverything = function( HtmlFormatter $f ) { + $f->flattenAllTags(); + }; + return array( + // remove images if asked + array( + '<img src="/foo/bar.jpg" alt="Blah"/>', + '', + $removeImages, + ), + // basic tag removal + array( + '<table><tr><td>foo</td></tr></table><div class="foo">foo</div><div class="foo quux">foo</div><span id="bar">bar</span> +<strong class="foo" id="bar">foobar</strong><div class="notfoo">test</div><div class="baz"/> +<span class="baz">baz</span>', + + '<div class="notfoo">test</div> +<span class="baz">baz</span>', + $removeTags, + ), + // don't flatten tags that start like chosen ones + array( + '<div><s>foo</s> <span>bar</span></div>', + 'foo <span>bar</span>', + $flattenSomeStuff, + ), + // total flattening + array( + '<div style="foo">bar<sup>2</sup></div>', + 'bar2', + $flattenEverything, + ), + // UTF-8 preservation and security + array( + '<span title="" \' &"><Тест!></span> &<&&&&', + '<span title="" \' &"><Тест!></span> &<&&&&', + ), + // https://bugzilla.wikimedia.org/show_bug.cgi?id=53086 + array( + 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup> <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>', + 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup> <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>', + ), + ); + } +} diff --git a/tests/phpunit/includes/HtmlTest.php b/tests/phpunit/includes/HtmlTest.php index 590664e8..1c62d032 100644 --- a/tests/phpunit/includes/HtmlTest.php +++ b/tests/phpunit/includes/HtmlTest.php @@ -37,14 +37,11 @@ class HtmlTest extends MediaWikiTestCase { 'wgLanguageCode' => $langCode, 'wgContLang' => $langObj, 'wgLang' => $langObj, - 'wgHtml5' => true, 'wgWellFormedXml' => false, ) ); } public function testElementBasics() { - global $wgWellFormedXml; - $this->assertEquals( '<img>', Html::element( 'img', null, '' ), @@ -63,7 +60,7 @@ class HtmlTest extends MediaWikiTestCase { 'Close tag for empty element (array, string)' ); - $wgWellFormedXml = true; + $this->setMwGlobals( 'wgWellFormedXml', true ); $this->assertEquals( '<img />', @@ -72,6 +69,31 @@ class HtmlTest extends MediaWikiTestCase { ); } + public function dataXmlMimeType() { + return array( + // ( $mimetype, $isXmlMimeType ) + # HTML is not an XML MimeType + array( 'text/html', false ), + # XML is an XML MimeType + array( 'text/xml', true ), + array( 'application/xml', true ), + # XHTML is an XML MimeType + array( 'application/xhtml+xml', true ), + # Make sure other +xml MimeTypes are supported + # SVG is another random MimeType even though we don't use it + array( 'image/svg+xml', true ), + # Complete random other MimeTypes are not XML + array( 'text/plain', false ), + ); + } + + /** + * @dataProvider dataXmlMimeType + */ + public function testXmlMimeType( $mimetype, $isXmlMimeType ) { + $this->assertEquals( $isXmlMimeType, Html::isXmlMimeType( $mimetype ) ); + } + public function testExpandAttributesSkipsNullAndFalse() { ### EMPTY ######## @@ -90,8 +112,6 @@ class HtmlTest extends MediaWikiTestCase { } public function testExpandAttributesForBooleans() { - global $wgHtml5, $wgWellFormedXml; - $this->assertEquals( '', Html::expandAttributes( array( 'selected' => false ) ), @@ -114,21 +134,13 @@ class HtmlTest extends MediaWikiTestCase { 'Boolean attributes have no value when value is true (passed as numerical array)' ); - $wgWellFormedXml = true; + $this->setMwGlobals( 'wgWellFormedXml', true ); $this->assertEquals( ' selected=""', Html::expandAttributes( array( 'selected' => true ) ), 'Boolean attributes have empty string value when value is true (wgWellFormedXml)' ); - - $wgHtml5 = false; - - $this->assertEquals( - ' selected="selected"', - Html::expandAttributes( array( 'selected' => true ) ), - 'Boolean attributes have their key as value when value is true (wgWellFormedXml, wgHTML5 = false)' - ); } /** @@ -136,8 +148,6 @@ class HtmlTest extends MediaWikiTestCase { * Please note it output a string prefixed with a space! */ public function testExpandAttributesVariousExpansions() { - global $wgWellFormedXml; - ### NOT EMPTY #### $this->assertEquals( ' empty_string=""', @@ -160,7 +170,7 @@ class HtmlTest extends MediaWikiTestCase { 'Number 0 value needs no quotes' ); - $wgWellFormedXml = true; + $this->setMwGlobals( 'wgWellFormedXml', true ); $this->assertEquals( ' empty_string=""', @@ -240,7 +250,7 @@ class HtmlTest extends MediaWikiTestCase { * Test feature added by r96188, let pass attributes values as * a PHP array. Restricted to class,rel, accesskey. */ - function testExpandAttributesSpaceSeparatedAttributesWithBoolean() { + public function testExpandAttributesSpaceSeparatedAttributesWithBoolean() { $this->assertEquals( ' class="booltrue one"', Html::expandAttributes( array( 'class' => array( @@ -264,7 +274,7 @@ class HtmlTest extends MediaWikiTestCase { * * Feature added by r96188 */ - function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() { + public function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() { $this->assertEquals( ' class=""', Html::expandAttributes( array( 'class' => array( @@ -275,7 +285,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testNamespaceSelector() { + public function testNamespaceSelector() { $this->assertEquals( '<select id=namespace name=namespace>' . "\n" . '<option value=0>(Main)</option>' . "\n" . @@ -354,7 +364,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testCanFilterOutNamespaces() { + public function testCanFilterOutNamespaces() { $this->assertEquals( '<select id=namespace name=namespace>' . "\n" . '<option value=2>User</option>' . "\n" . @@ -376,7 +386,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testCanDisableANamespaces() { + public function testCanDisableANamespaces() { $this->assertEquals( '<select id=namespace name=namespace>' . "\n" . '<option disabled value=0>(Main)</option>' . "\n" . @@ -406,7 +416,7 @@ class HtmlTest extends MediaWikiTestCase { /** * @dataProvider provideHtml5InputTypes */ - function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { + public function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { $this->assertEquals( '<input type=' . $HTML5InputType . '>', Html::element( 'input', array( 'type' => $HTML5InputType ) ), @@ -418,7 +428,7 @@ class HtmlTest extends MediaWikiTestCase { * List of input element types values introduced by HTML5 * Full list at http://www.w3.org/TR/html-markup/input.html */ - function provideHtml5InputTypes() { + public static function provideHtml5InputTypes() { $types = array( 'datetime', 'datetime-local', @@ -438,6 +448,7 @@ class HtmlTest extends MediaWikiTestCase { foreach ( $types as $type ) { $cases[] = array( $type ); } + return $cases; } @@ -446,7 +457,7 @@ class HtmlTest extends MediaWikiTestCase { * @covers Html::dropDefaults * @dataProvider provideElementsWithAttributesHavingDefaultValues */ - function testDropDefaults( $expected, $element, $attribs, $message = '' ) { + public function testDropDefaults( $expected, $element, $attribs, $message = '' ) { $this->assertEquals( $expected, Html::element( $element, $attribs ), $message ); } @@ -602,6 +613,7 @@ class HtmlTest extends MediaWikiTestCase { isset( $case[3] ) ? $case[3] : '' ); } + return $ret; } @@ -616,5 +628,4 @@ class HtmlTest extends MediaWikiTestCase { 'Allow special case "step=any".' ); } - } diff --git a/tests/phpunit/includes/HttpTest.php b/tests/phpunit/includes/HttpTest.php index 7698776c..11d8ed60 100644 --- a/tests/phpunit/includes/HttpTest.php +++ b/tests/phpunit/includes/HttpTest.php @@ -5,8 +5,9 @@ class HttpTest extends MediaWikiTestCase { /** * @dataProvider cookieDomains + * @covers Cookie::validateCookieDomain */ - function testValidateCookieDomain( $expected, $domain, $origin = null ) { + public function testValidateCookieDomain( $expected, $domain, $origin = null ) { if ( $origin ) { $ok = Cookie::validateCookieDomain( $domain, $origin ); $msg = "$domain against origin $origin"; @@ -50,8 +51,9 @@ class HttpTest extends MediaWikiTestCase { * Test Http::isValidURI() * @bug 27854 : Http::isValidURI is too lax * @dataProvider provideURI + * @covers Http::isValidURI */ - function testIsValidUri( $expect, $URI, $message = '' ) { + public function testIsValidUri( $expect, $URI, $message = '' ) { $this->assertEquals( $expect, (bool)Http::isValidURI( $URI ), @@ -132,7 +134,7 @@ class HttpTest extends MediaWikiTestCase { * rewritten when bug 29232 is taken care of (high-level handling of * HTTP redirects). */ - function testRelativeRedirections() { + public function testRelativeRedirections() { $h = MWHttpRequestTester::factory( 'http://oldsite/file.ext' ); # Forge a Location header @@ -176,7 +178,7 @@ class HttpTest extends MediaWikiTestCase { */ class MWHttpRequestTester extends MWHttpRequest { - // function derived from the MWHttpRequest factory function but + // function derived from the MWHttpRequest factory function but // returns appropriate tester class here public static function factory( $url, $options = null ) { if ( !Http::$httpEngine ) { @@ -194,6 +196,7 @@ class MWHttpRequestTester extends MWHttpRequest { throw new MWException( __METHOD__ . ': allow_url_fopen needs to be enabled for pure PHP' . ' http requests to work. If possible, curl should be used instead. See http://php.net/curl.' ); } + return new PhpHttpRequestTester( $url, $options ); default: } diff --git a/tests/phpunit/includes/IPTest.php b/tests/phpunit/includes/IPTest.php index 7bc29385..c074eea6 100644 --- a/tests/phpunit/includes/IPTest.php +++ b/tests/phpunit/includes/IPTest.php @@ -1,7 +1,12 @@ <?php /** - * Tests for IP validity functions. Ported from /t/inc/IP.t by avar. + * Tests for IP validity functions. + * + * Ported from /t/inc/IP.t by avar. + * * @group IP + * @todo Test methods in this call should be split into a method and a + * dataprovider. */ class IPTest extends MediaWikiTestCase { @@ -259,14 +264,63 @@ class IPTest extends MediaWikiTestCase { } /** - * test wrapper around ip2long which might return -1 or false depending on PHP version * @covers IP::toUnsigned + * @dataProvider provideToUnsigned */ - public function testip2longWrapper() { - // @todo FIXME: Add more tests ? - $this->assertEquals( pow( 2, 32 ) - 1, IP::toUnsigned( '255.255.255.255' ) ); - $i = 'IN.VA.LI.D'; - $this->assertFalse( IP::toUnSigned( $i ) ); + public function testToUnsigned( $expected, $input ) { + $result = IP::toUnsigned( $input ); + $this->assertTrue( $result === false || is_string( $result ) || is_int( $result ) ); + $this->assertEquals( $expected, $result ); + } + + /** + * Provider for IP::testToUnsigned() + */ + public static function provideToUnsigned() { + return array( + array( 1, '0.0.0.1' ), + array( 16909060, '1.2.3.4' ), + array( 2130706433, '127.0.0.1' ), + array( '2147483648', '128.0.0.0' ), + array( '3735931646', '222.173.202.254' ), + array( pow( 2, 32 ) - 1, '255.255.255.255' ), + array( false, 'IN.VA.LI.D' ), + array( 1, '::1' ), + array( '42540766452641154071740215577757643572', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ), + array( '42540766452641154071740215577757643572', '2001:db8:85a3::8a2e:0370:7334' ), + array( false, 'IN:VA::LI:D' ), + array( false, ':::1' ) + ); + } + + /** + * @covers IP::toHex + * @dataProvider provideToHex + */ + public function testToHex( $expected, $input ) { + $result = IP::toHex( $input ); + $this->assertTrue( $result === false || is_string( $result ) ); + $this->assertEquals( $expected, $result ); + } + + /** + * Provider for IP::testToHex() + */ + public static function provideToHex() { + return array( + array( '00000001', '0.0.0.1' ), + array( '01020304', '1.2.3.4' ), + array( '7F000001', '127.0.0.1' ), + array( '80000000', '128.0.0.0' ), + array( 'DEADCAFE', '222.173.202.254' ), + array( 'FFFFFFFF', '255.255.255.255' ), + array( false, 'IN.VA.LI.D' ), + array( 'v6-00000000000000000000000000000001', '::1' ), + array( 'v6-20010DB885A3000000008A2E03707334', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ), + array( 'v6-20010DB885A3000000008A2E03707334', '2001:db8:85a3::8a2e:0370:7334' ), + array( false, 'IN:VA::LI:D' ), + array( false, ':::1' ) + ); } /** @@ -338,7 +392,7 @@ class IPTest extends MediaWikiTestCase { * representing the network mask and the bit mask. * @covers IP::parseCIDR */ - function testCIDRParsing() { + public function testCIDRParsing() { $this->assertFalseCIDR( '192.0.2.0', "missing mask" ); $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" ); @@ -435,7 +489,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::splitHostAndPort(). * @dataProvider provideSplitHostAndPort */ - function testSplitHostAndPort( $expected, $input, $description ) { + public function testSplitHostAndPort( $expected, $input, $description ) { $this->assertEquals( $expected, IP::splitHostAndPort( $input ), $description ); } @@ -462,7 +516,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::combineHostAndPort() * @dataProvider provideCombineHostAndPort */ - function testCombineHostAndPort( $expected, $input, $description ) { + public function testCombineHostAndPort( $expected, $input, $description ) { list( $host, $port, $defaultPort ) = $input; $this->assertEquals( $expected, @@ -486,7 +540,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::sanitizeRange() * @dataProvider provideIPCIDRs */ - function testSanitizeRange( $input, $expected, $description ) { + public function testSanitizeRange( $input, $expected, $description ) { $this->assertEquals( $expected, IP::sanitizeRange( $input ), $description ); } @@ -510,7 +564,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::prettifyIP() * @dataProvider provideIPsToPrettify */ - function testPrettifyIP( $ip, $prettified ) { + public function testPrettifyIP( $ip, $prettified ) { $this->assertEquals( $prettified, IP::prettifyIP( $ip ), "Prettify of $ip" ); } diff --git a/tests/phpunit/includes/JsonTest.php b/tests/phpunit/includes/JsonTest.php deleted file mode 100644 index 96a2ead5..00000000 --- a/tests/phpunit/includes/JsonTest.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -class JsonTest extends MediaWikiTestCase { - - function testPhpBug46944Test() { - $this->assertNotEquals( - '\ud840\udc00', - strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ), - 'Test encoding an broken json_encode character (U+20000)' - ); - - } - - function testDecodeVarTypes() { - $this->assertInternalType( - 'object', - FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ), - 'Default to object' - ); - - $this->assertInternalType( - 'array', - FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ), - 'Optional array' - ); - } -} diff --git a/tests/phpunit/includes/LanguageConverterTest.php b/tests/phpunit/includes/LanguageConverterTest.php index d4d93b07..7c2134b9 100644 --- a/tests/phpunit/includes/LanguageConverterTest.php +++ b/tests/phpunit/includes/LanguageConverterTest.php @@ -30,39 +30,39 @@ class LanguageConverterTest extends MediaWikiLangTestCase { parent::tearDown(); } - function testGetPreferredVariantDefaults() { + public function testGetPreferredVariantDefaults() { $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaders() { + public function testGetPreferredVariantHeaders() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'tg-latn' ); $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderWeight() { + public function testGetPreferredVariantHeaderWeight() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'tg;q=1' ); $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderWeight2() { + public function testGetPreferredVariantHeaderWeight2() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'tg-latn;q=1' ); $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderMulti() { + public function testGetPreferredVariantHeaderMulti() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'en, tg-latn;q=1' ); $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantUserOption() { + public function testGetPreferredVariantUserOption() { global $wgUser; $wgUser = new User; @@ -75,7 +75,21 @@ class LanguageConverterTest extends MediaWikiLangTestCase { $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderUserVsUrl() { + public function testGetPreferredVariantUserOptionForForeignLanguage() { + global $wgContLang, $wgUser; + + $wgContLang = Language::factory( 'en' ); + $wgUser = new User; + $wgUser->load(); // from 'defaults' + $wgUser->mId = 1; + $wgUser->mDataLoaded = true; + $wgUser->mOptionsLoaded = true; + $wgUser->setOption( 'variant-tg', 'tg-latn' ); + + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); + } + + public function testGetPreferredVariantHeaderUserVsUrl() { global $wgContLang, $wgRequest, $wgUser; $wgContLang = Language::factory( 'tg-latn' ); @@ -85,19 +99,19 @@ class LanguageConverterTest extends MediaWikiLangTestCase { $wgUser->mFrom = 'defaults'; $wgUser->mOptionsLoaded = true; // The user's data is ignored because the variant is set in the URL. - $wgUser->setOption( 'variant', 'tg-latn' ); + $wgUser->setOption( 'variant', 'tg-latn' ); $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantDefaultLanguageVariant() { + public function testGetPreferredVariantDefaultLanguageVariant() { global $wgDefaultLanguageVariant; $wgDefaultLanguageVariant = 'tg-latn'; $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantDefaultLanguageVsUrlVariant() { + public function testGetPreferredVariantDefaultLanguageVsUrlVariant() { global $wgDefaultLanguageVariant, $wgRequest, $wgContLang; $wgContLang = Language::factory( 'tg-latn' ); @@ -123,7 +137,6 @@ class TestConverter extends LanguageConverter { 'tg' => new ReplacementArray() ); } - } class LanguageToTest extends Language { diff --git a/tests/phpunit/includes/LicensesTest.php b/tests/phpunit/includes/LicensesTest.php index 212b3b3b..478a2ffc 100644 --- a/tests/phpunit/includes/LicensesTest.php +++ b/tests/phpunit/includes/LicensesTest.php @@ -2,7 +2,7 @@ class LicensesTest extends MediaWikiTestCase { - function testLicenses() { + public function testLicenses() { $str = " * Free licenses: ** GFDL|Debian disagrees diff --git a/tests/phpunit/includes/LinkerTest.php b/tests/phpunit/includes/LinkerTest.php index e353c46c..b605f08f 100644 --- a/tests/phpunit/includes/LinkerTest.php +++ b/tests/phpunit/includes/LinkerTest.php @@ -6,7 +6,7 @@ class LinkerTest extends MediaWikiLangTestCase { * @dataProvider provideCasesForUserLink * @covers Linker::userLink */ - function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) { + public function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) { $this->setMwGlobals( array( 'wgArticlePath' => '/wiki/$1', 'wgWellFormedXml' => true, @@ -17,7 +17,7 @@ class LinkerTest extends MediaWikiLangTestCase { ); } - function provideCasesForUserLink() { + public static function provideCasesForUserLink() { # Format: # - expected # - userid diff --git a/tests/phpunit/includes/LinksUpdateTest.php b/tests/phpunit/includes/LinksUpdateTest.php index a79b3a25..5ade250e 100644 --- a/tests/phpunit/includes/LinksUpdateTest.php +++ b/tests/phpunit/includes/LinksUpdateTest.php @@ -7,7 +7,7 @@ */ class LinksUpdateTest extends MediaWikiTestCase { - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed = array_merge( $this->tablesUsed, @@ -60,18 +60,30 @@ class LinksUpdateTest extends MediaWikiTestCase { $po->addLink( Title::newFromText( "linksupdatetest:Foo" ) ); // interwiki link should be ignored $po->addLink( Title::newFromText( "#Foo" ) ); // hash link should be ignored - $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( + $update = $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( array( NS_MAIN, 'Foo' ), ) ); + $this->assertArrayEquals( array( + Title::makeTitle( NS_MAIN, 'Foo' ), // newFromText doesn't yield the same internal state.... + ), $update->getAddedLinks() ); $po = new ParserOutput(); $po->setTitleText( $t->getPrefixedText() ); $po->addLink( Title::newFromText( "Bar" ) ); + $po->addLink( Title::newFromText( "Talk:Bar" ) ); - $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( + $update = $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( array( NS_MAIN, 'Bar' ), + array( NS_TALK, 'Bar' ), ) ); + $this->assertArrayEquals( array( + Title::makeTitle( NS_MAIN, 'Bar' ), + Title::makeTitle( NS_TALK, 'Bar' ), + ), $update->getAddedLinks() ); + $this->assertArrayEquals( array( + Title::makeTitle( NS_MAIN, 'Foo' ), + ), $update->getRemovedLinks() ); } public function testUpdate_externallinks() { @@ -122,7 +134,6 @@ class LinksUpdateTest extends MediaWikiTestCase { $po->addImage( "Foo.png" ); - $this->assertLinksUpdate( $t, $po, 'imagelinks', 'il_to', 'il_from = 111', array( array( 'Foo.png' ), ) ); @@ -133,7 +144,6 @@ class LinksUpdateTest extends MediaWikiTestCase { $po->addLanguageLink( Title::newFromText( "en:Foo" )->getFullText() ); - $this->assertLinksUpdate( $t, $po, 'langlinks', 'll_lang, ll_title', 'll_from = 111', array( array( 'En', 'Foo' ), ) ); @@ -149,7 +159,7 @@ class LinksUpdateTest extends MediaWikiTestCase { ) ); } - #@todo: test recursive, too! + // @todo test recursive, too! protected function assertLinksUpdate( Title $title, ParserOutput $parserOutput, $table, $fields, $condition, array $expectedRows ) { $update = new LinksUpdate( $title, $parserOutput ); @@ -160,5 +170,6 @@ class LinksUpdateTest extends MediaWikiTestCase { $update->commitTransaction(); $this->assertSelect( $table, $fields, $condition, $expectedRows ); + return $update; } } diff --git a/tests/phpunit/includes/LocalFileTest.php b/tests/phpunit/includes/LocalFileTest.php index d6f0d2ee..2501c783 100644 --- a/tests/phpunit/includes/LocalFileTest.php +++ b/tests/phpunit/includes/LocalFileTest.php @@ -35,72 +35,72 @@ class LocalFileTest extends MediaWikiTestCase { $this->file_lc = $this->repo_lc->newFile( 'test!' ); } - function testGetHashPath() { + public function testGetHashPath() { $this->assertEquals( '', $this->file_hl0->getHashPath() ); $this->assertEquals( 'a/a2/', $this->file_hl2->getHashPath() ); $this->assertEquals( 'c/c4/', $this->file_lc->getHashPath() ); } - function testGetRel() { + public function testGetRel() { $this->assertEquals( 'Test!', $this->file_hl0->getRel() ); $this->assertEquals( 'a/a2/Test!', $this->file_hl2->getRel() ); $this->assertEquals( 'c/c4/test!', $this->file_lc->getRel() ); } - function testGetUrlRel() { + public function testGetUrlRel() { $this->assertEquals( 'Test%21', $this->file_hl0->getUrlRel() ); $this->assertEquals( 'a/a2/Test%21', $this->file_hl2->getUrlRel() ); $this->assertEquals( 'c/c4/test%21', $this->file_lc->getUrlRel() ); } - function testGetArchivePath() { + public function testGetArchivePath() { $this->assertEquals( 'mwstore://local-backend/test-public/archive', $this->file_hl0->getArchivePath() ); $this->assertEquals( 'mwstore://local-backend/test-public/archive/a/a2', $this->file_hl2->getArchivePath() ); $this->assertEquals( 'mwstore://local-backend/test-public/archive/!', $this->file_hl0->getArchivePath( '!' ) ); $this->assertEquals( 'mwstore://local-backend/test-public/archive/a/a2/!', $this->file_hl2->getArchivePath( '!' ) ); } - function testGetThumbPath() { + public function testGetThumbPath() { $this->assertEquals( 'mwstore://local-backend/test-thumb/Test!', $this->file_hl0->getThumbPath() ); $this->assertEquals( 'mwstore://local-backend/test-thumb/a/a2/Test!', $this->file_hl2->getThumbPath() ); $this->assertEquals( 'mwstore://local-backend/test-thumb/Test!/x', $this->file_hl0->getThumbPath( 'x' ) ); $this->assertEquals( 'mwstore://local-backend/test-thumb/a/a2/Test!/x', $this->file_hl2->getThumbPath( 'x' ) ); } - function testGetArchiveUrl() { + public function testGetArchiveUrl() { $this->assertEquals( '/testurl/archive', $this->file_hl0->getArchiveUrl() ); $this->assertEquals( '/testurl/archive/a/a2', $this->file_hl2->getArchiveUrl() ); $this->assertEquals( '/testurl/archive/%21', $this->file_hl0->getArchiveUrl( '!' ) ); $this->assertEquals( '/testurl/archive/a/a2/%21', $this->file_hl2->getArchiveUrl( '!' ) ); } - function testGetThumbUrl() { + public function testGetThumbUrl() { $this->assertEquals( '/testurl/thumb/Test%21', $this->file_hl0->getThumbUrl() ); $this->assertEquals( '/testurl/thumb/a/a2/Test%21', $this->file_hl2->getThumbUrl() ); $this->assertEquals( '/testurl/thumb/Test%21/x', $this->file_hl0->getThumbUrl( 'x' ) ); $this->assertEquals( '/testurl/thumb/a/a2/Test%21/x', $this->file_hl2->getThumbUrl( 'x' ) ); } - function testGetArchiveVirtualUrl() { + public function testGetArchiveVirtualUrl() { $this->assertEquals( 'mwrepo://test/public/archive', $this->file_hl0->getArchiveVirtualUrl() ); $this->assertEquals( 'mwrepo://test/public/archive/a/a2', $this->file_hl2->getArchiveVirtualUrl() ); $this->assertEquals( 'mwrepo://test/public/archive/%21', $this->file_hl0->getArchiveVirtualUrl( '!' ) ); $this->assertEquals( 'mwrepo://test/public/archive/a/a2/%21', $this->file_hl2->getArchiveVirtualUrl( '!' ) ); } - function testGetThumbVirtualUrl() { + public function testGetThumbVirtualUrl() { $this->assertEquals( 'mwrepo://test/thumb/Test%21', $this->file_hl0->getThumbVirtualUrl() ); $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21', $this->file_hl2->getThumbVirtualUrl() ); $this->assertEquals( 'mwrepo://test/thumb/Test%21/%21', $this->file_hl0->getThumbVirtualUrl( '!' ) ); $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21/%21', $this->file_hl2->getThumbVirtualUrl( '!' ) ); } - function testGetUrl() { + public function testGetUrl() { $this->assertEquals( '/testurl/Test%21', $this->file_hl0->getUrl() ); $this->assertEquals( '/testurl/a/a2/Test%21', $this->file_hl2->getUrl() ); } - function testWfLocalFile() { + public function testWfLocalFile() { $file = wfLocalFile( "File:Some_file_that_probably_doesn't exist.png" ); $this->assertThat( $file, $this->isInstanceOf( 'LocalFile' ), 'wfLocalFile() returns LocalFile for valid Titles' ); } diff --git a/tests/phpunit/includes/MWExceptionHandlerTest.php b/tests/phpunit/includes/MWExceptionHandlerTest.php new file mode 100644 index 00000000..987dfa83 --- /dev/null +++ b/tests/phpunit/includes/MWExceptionHandlerTest.php @@ -0,0 +1,73 @@ +<?php +/** + * Tests for includes/Exception.php. + * + * @author Antoine Musso + * @copyright Copyright © 2013, Antoine Musso + * @copyright Copyright © 2013, Wikimedia Foundation Inc. + * @file + */ + +class MWExceptionHandlerTest extends MediaWikiTestCase { + + /** + * @covers MWExceptionHandler::getRedactedTrace + */ + function testGetRedactedTrace() { + try { + $array = array( 'a', 'b' ); + $object = new StdClass(); + self::helperThrowAnException( $array, $object ); + } catch (Exception $e) { + } + + # Make sure our strack trace contains an array and an object passed to + # some function in the stacktrace. Else, we can not assert the trace + # redaction achieved its job. + $trace = $e->getTrace(); + $hasObject = false; + $hasArray = false; + foreach ( $trace as $frame ) { + if ( ! isset( $frame['args'] ) ) { + continue; + } + foreach ( $frame['args'] as $arg ) { + $hasObject = $hasObject || is_object( $arg ); + $hasArray = $hasArray || is_array( $arg ); + } + + if( $hasObject && $hasArray ) { + break; + } + } + $this->assertTrue( $hasObject, + "The stacktrace must have a function having an object has parameter" ); + $this->assertTrue( $hasArray, + "The stacktrace must have a function having an array has parameter" ); + + # Now we redact the trace.. and make sure no function arguments are + # arrays or objects. + $redacted = MWExceptionHandler::getRedactedTrace( $e ); + + foreach ( $redacted as $frame ) { + if ( ! isset( $frame['args'] ) ) { + continue; + } + foreach ( $frame['args'] as $arg ) { + $this->assertNotInternalType( 'array', $arg); + $this->assertNotInternalType( 'object', $arg); + } + } + } + + /** + * Helper function for testExpandArgumentsInCall + * + * Pass it an object and an array :-) + * + * @throws Exception + */ + protected static function helperThrowAnException( $a, $b ) { + throw new Exception(); + } +} diff --git a/tests/phpunit/includes/MWFunctionTest.php b/tests/phpunit/includes/MWFunctionTest.php index 6c17bf48..d86f2c9b 100644 --- a/tests/phpunit/includes/MWFunctionTest.php +++ b/tests/phpunit/includes/MWFunctionTest.php @@ -1,27 +1,7 @@ <?php class MWFunctionTest extends MediaWikiTestCase { - function testCallUserFuncWorkarounds() { - $this->assertEquals( - call_user_func( array( 'MWFunctionTest', 'someMethod' ) ), - MWFunction::call( 'MWFunctionTest::someMethod' ) - ); - $this->assertEquals( - call_user_func( array( 'MWFunctionTest', 'someMethod' ), 'foo', 'bar', 'baz' ), - MWFunction::call( 'MWFunctionTest::someMethod', 'foo', 'bar', 'baz' ) - ); - - $this->assertEquals( - call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array() ), - MWFunction::callArray( 'MWFunctionTest::someMethod', array() ) - ); - $this->assertEquals( - call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array( 'foo', 'bar', 'baz' ) ), - MWFunction::callArray( 'MWFunctionTest::someMethod', array( 'foo', 'bar', 'baz' ) ) - ); - } - - function testNewObjFunction() { + public function testNewObjFunction() { $arg1 = 'Foo'; $arg2 = 'Bar'; $arg3 = array( 'Baz' ); @@ -34,32 +14,7 @@ class MWFunctionTest extends MediaWikiTestCase { MWFunction::newObj( 'MWBlankClass', $args )->args, $newObject->args ); - - $this->assertEquals( - MWFunction::newObj( 'MWBlankClass', $args, true )->args, - $newObject->args, - 'Works even with PHP version < 5.1.3' - ); - } - - /** - * @expectedException MWException - */ - function testCallingParentFails() { - MWFunction::call( 'parent::foo' ); } - - /** - * @expectedException MWException - */ - function testCallingSelfFails() { - MWFunction::call( 'self::foo' ); - } - - public static function someMethod() { - return func_get_args(); - } - } class MWBlankClass { diff --git a/tests/phpunit/includes/MWNamespaceTest.php b/tests/phpunit/includes/MWNamespaceTest.php index 45f8dafc..10e9db61 100644 --- a/tests/phpunit/includes/MWNamespaceTest.php +++ b/tests/phpunit/includes/MWNamespaceTest.php @@ -125,7 +125,6 @@ class MWNamespaceTest extends MediaWikiTestCase { public function testGetAssociated() { $this->assertEquals( NS_TALK, MWNamespace::getAssociated( NS_MAIN ) ); $this->assertEquals( NS_MAIN, MWNamespace::getAssociated( NS_TALK ) ); - } ### Exceptions with getAssociated() @@ -201,7 +200,6 @@ class MWNamespaceTest extends MediaWikiTestCase { NS_SPECIAL, NS_MEDIA, "NS_SPECIAL and NS_MEDIA are different subject namespaces" ); - } /** @@ -346,33 +344,32 @@ class MWNamespaceTest extends MediaWikiTestCase { $this->assertEquals( array( NS_MAIN ), - MWNamespace::getcontentNamespaces(), + MWNamespace::getContentNamespaces(), '$wgContentNamespaces is an array with only NS_MAIN by default' ); - # test !is_array( $wgcontentNamespaces ) $wgContentNamespaces = ''; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); $wgContentNamespaces = false; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); $wgContentNamespaces = null; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); $wgContentNamespaces = 5; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); # test $wgContentNamespaces === array() $wgContentNamespaces = array(); - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); # test !in_array( NS_MAIN, $wgContentNamespaces ) $wgContentNamespaces = array( NS_USER, NS_CATEGORY ); $this->assertEquals( array( NS_MAIN, NS_USER, NS_CATEGORY ), - MWNamespace::getcontentNamespaces(), + MWNamespace::getContentNamespaces(), 'NS_MAIN is forced in $wgContentNamespaces even if unwanted' ); @@ -380,13 +377,13 @@ class MWNamespaceTest extends MediaWikiTestCase { $wgContentNamespaces = array( NS_MAIN ); $this->assertEquals( array( NS_MAIN ), - MWNamespace::getcontentNamespaces() + MWNamespace::getContentNamespaces() ); $wgContentNamespaces = array( NS_MAIN, NS_USER, NS_CATEGORY ); $this->assertEquals( array( NS_MAIN, NS_USER, NS_CATEGORY ), - MWNamespace::getcontentNamespaces() + MWNamespace::getContentNamespaces() ); } diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php index c378bb8e..1e18f975 100644 --- a/tests/phpunit/includes/MessageTest.php +++ b/tests/phpunit/includes/MessageTest.php @@ -10,7 +10,7 @@ class MessageTest extends MediaWikiLangTestCase { ) ); } - function testExists() { + public function testExists() { $this->assertTrue( wfMessage( 'mainpage' )->exists() ); $this->assertTrue( wfMessage( 'mainpage' )->params( array() )->exists() ); $this->assertTrue( wfMessage( 'mainpage' )->rawParams( 'foo', 123 )->exists() ); @@ -19,7 +19,7 @@ class MessageTest extends MediaWikiLangTestCase { $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->rawParams( 'foo', 123 )->exists() ); } - function testKey() { + public function testKey() { $this->assertInstanceOf( 'Message', wfMessage( 'mainpage' ) ); $this->assertInstanceOf( 'Message', wfMessage( 'i-dont-exist-evar' ) ); $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() ); @@ -28,47 +28,103 @@ class MessageTest extends MediaWikiLangTestCase { $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->escaped() ); } - function testInLanguage() { + public function testInLanguage() { $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( 'en' )->text() ); $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( 'ru' )->text() ); $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'en' ) )->text() ); $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'ru' ) )->text() ); } - function testMessageParams() { + public function testMessageParams() { $this->assertEquals( 'Return to $1.', wfMessage( 'returnto' )->text() ); $this->assertEquals( 'Return to $1.', wfMessage( 'returnto', array() )->text() ); $this->assertEquals( 'You have foo (bar).', wfMessage( 'youhavenewmessages', 'foo', 'bar' )->text() ); $this->assertEquals( 'You have foo (bar).', wfMessage( 'youhavenewmessages', array( 'foo', 'bar' ) )->text() ); } - function testMessageParamSubstitution() { + public function testMessageParamSubstitution() { $this->assertEquals( '(Заглавная страница)', wfMessage( 'parentheses', 'Заглавная страница' )->plain() ); $this->assertEquals( '(Заглавная страница $1)', wfMessage( 'parentheses', 'Заглавная страница $1' )->plain() ); $this->assertEquals( '(Заглавная страница)', wfMessage( 'parentheses' )->rawParams( 'Заглавная страница' )->plain() ); $this->assertEquals( '(Заглавная страница $1)', wfMessage( 'parentheses' )->rawParams( 'Заглавная страница $1' )->plain() ); } - function testDeliciouslyManyParams() { + public function testDeliciouslyManyParams() { $msg = new RawMessage( '$1$2$3$4$5$6$7$8$9$10$11$12' ); // One less than above has placeholders $params = array( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k' ); $this->assertEquals( 'abcdefghijka2', $msg->params( $params )->plain(), 'Params > 9 are replaced correctly' ); } - function testInContentLanguage() { - global $wgLang, $wgForceUIMsgAsContentMsg; - $wgLang = Language::factory( 'fr' ); + /** + * FIXME: This should not need database, but Language#formatExpiry does (bug 55912) + * @group Database + */ + public function testMessageParamTypes() { + $lang = Language::factory( 'en' ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatNum( 123456.789 ), + $msg->inLanguage( $lang )->numParams( 123456.789 )->plain(), + 'numParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatDuration( 1234 ), + $msg->inLanguage( $lang )->durationParams( 1234 )->plain(), + 'durationParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatExpiry( wfTimestampNow() ), + $msg->inLanguage( $lang )->expiryParams( wfTimestampNow() )->plain(), + 'expiryParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatTimePeriod( 1234 ), + $msg->inLanguage( $lang )->timeperiodParams( 1234 )->plain(), + 'timeperiodParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatSize( 123456 ), + $msg->inLanguage( $lang )->sizeParams( 123456 )->plain(), + 'sizeParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatBitrate( 123456 ), + $msg->inLanguage( $lang )->bitrateParams( 123456 )->plain(), + 'bitrateParams is handled correctly' + ); + } + + public function testInContentLanguageDisabled() { + $this->setMwGlobals( 'wgLang', Language::factory( 'fr' ) ); $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg disabled' ); - $wgForceUIMsgAsContentMsg['testInContentLanguage'] = 'mainpage'; + } + + public function testInContentLanguageEnabled() { + $this->setMwGlobals( array( + 'wgLang' => Language::factory( 'fr' ), + 'wgForceUIMsgAsContentMsg' => array( 'mainpage' ), + ) ); + $this->assertEquals( 'Accueil', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg enabled' ); } /** * @expectedException MWException */ - function testInLanguageThrows() { + public function testInLanguageThrows() { wfMessage( 'foo' )->inLanguage( 123 ); } } diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php index 4084fb17..56bb0fce 100644 --- a/tests/phpunit/includes/OutputPageTest.php +++ b/tests/phpunit/includes/OutputPageTest.php @@ -19,7 +19,6 @@ class OutputPageTest extends MediaWikiTestCase { * * options['printableQuery'] - value of query string for printable, or omitted for none * options['handheldQuery'] - value of query string for handheld, or omitted for none - * options['handheldForIPhone'] - value of the $wgHandheldForIPhone global * options['media'] - passed into the method under the same name * options['expectedReturn'] - expected return value * options['message'] - PHPUnit message for assertion @@ -39,7 +38,6 @@ class OutputPageTest extends MediaWikiTestCase { $fauxRequest = new FauxRequest( $queryData, false ); $this->setMWGlobals( array( 'wgRequest' => $fauxRequest, - 'wgHandheldForIPhone' => $args['handheldForIPhone'] ) ); $actualReturn = OutputPage::transformCssMedia( $args['media'] ); @@ -47,50 +45,31 @@ class OutputPageTest extends MediaWikiTestCase { } /** - * Tests a case of transformCssMedia with both values of wgHandheldForIPhone. - * Used to verify that behavior is orthogonal to that option. - * - * If the value of wgHandheldForIPhone should matter, use assertTransformCssMediaCase. - * - * @param array $args key-value array of arguments as shown in assertTransformCssMediaCase. - * Will be mutated. - */ - protected function assertTransformCssMediaCaseWithBothHandheldForIPhone( $args ) { - $message = $args['message']; - foreach ( array( true, false ) as $handheldForIPhone ) { - $args['handheldForIPhone'] = $handheldForIPhone; - $stringHandheldForIPhone = var_export( $handheldForIPhone, true ); - $args['message'] = "$message. \$wgHandheldForIPhone was $stringHandheldForIPhone"; - $this->assertTransformCssMediaCase( $args ); - } - } - - /** * Tests print requests */ public function testPrintRequests() { - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => 'screen', 'expectedReturn' => null, 'message' => 'On printable request, screen returns null' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => self::SCREEN_MEDIA_QUERY, 'expectedReturn' => null, 'message' => 'On printable request, screen media query returns null' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => self::SCREEN_ONLY_MEDIA_QUERY, 'expectedReturn' => null, 'message' => 'On printable request, screen media query with only returns null' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => 'print', 'expectedReturn' => '', @@ -103,25 +82,30 @@ class OutputPageTest extends MediaWikiTestCase { */ public function testScreenRequests() { $this->assertTransformCssMediaCase( array( - 'handheldForIPhone' => false, 'media' => 'screen', 'expectedReturn' => 'screen', - 'message' => 'On screen request, with handheldForIPhone false, screen media type is preserved' + 'message' => 'On screen request, screen media type is preserved' + ) ); + + $this->assertTransformCssMediaCase( array( + 'media' => 'handheld', + 'expectedReturn' => 'handheld', + 'message' => 'On screen request, handheld media type is preserved' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'media' => self::SCREEN_MEDIA_QUERY, 'expectedReturn' => self::SCREEN_MEDIA_QUERY, 'message' => 'On screen request, screen media query is preserved.' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'media' => self::SCREEN_ONLY_MEDIA_QUERY, 'expectedReturn' => self::SCREEN_ONLY_MEDIA_QUERY, 'message' => 'On screen request, screen media query with only is preserved.' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'media' => 'print', 'expectedReturn' => 'print', 'message' => 'On screen request, print media type is preserved' @@ -129,44 +113,21 @@ class OutputPageTest extends MediaWikiTestCase { } /** - * Tests handheld and wgHandheldForIPhone behavior + * Tests handheld behavior */ public function testHandheld() { - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'handheldQuery' => '1', 'media' => 'handheld', 'expectedReturn' => '', 'message' => 'On request with handheld querystring and media is handheld, returns empty string' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'handheldQuery' => '1', 'media' => 'screen', 'expectedReturn' => null, 'message' => 'On request with handheld querystring and media is screen, returns null' ) ); - - // A bit counter-intuitively, $wgHandheldForIPhone should only matter if the query handheld is false or omitted - $this->assertTransformCssMediaCase( array( - 'handheldQuery' => '0', - 'media' => 'screen', - 'handheldForIPhone' => true, - 'expectedReturn' => 'screen and (min-device-width: 481px)', - 'message' => 'With $wgHandheldForIPhone true, screen media type is transformed' - ) ); - - $this->assertTransformCssMediaCase( array( - 'media' => 'handheld', - 'handheldForIPhone' => true, - 'expectedReturn' => 'handheld, only screen and (max-device-width: 480px)', - 'message' => 'With $wgHandheldForIPhone true, handheld media type is transformed' - ) ); - - $this->assertTransformCssMediaCase( array( - 'media' => 'handheld', - 'handheldForIPhone' => false, - 'expectedReturn' => 'handheld', - 'message' => 'With $wgHandheldForIPhone false, handheld media type is preserved' - ) ); } } diff --git a/tests/phpunit/includes/PathRouterTest.php b/tests/phpunit/includes/PathRouterTest.php index 22591873..adfb215a 100644 --- a/tests/phpunit/includes/PathRouterTest.php +++ b/tests/phpunit/includes/PathRouterTest.php @@ -1,10 +1,17 @@ <?php /** - * Tests for the PathRouter parsing + * Tests for the PathRouter parsing. + * + * @todo Add covers tags. */ class PathRouterTest extends MediaWikiTestCase { + /** + * @var PathRouter + */ + protected $basicRouter; + protected function setUp() { parent::setUp(); $router = new PathRouter; @@ -151,18 +158,20 @@ class PathRouterTest extends MediaWikiTestCase { $router->add( array( 'qwerty' => "/qwerty/$1" ), array( 'qwerty' => '$key' ) ); $router->add( "/$2/$1", array( 'restricted-to-y' => '$2' ), array( '$2' => 'y' ) ); - foreach ( array( - '/Foo' => array( 'title' => 'Foo' ), - '/Bar' => array( 'ping' => 'pong' ), - '/Baz' => array( 'marco' => 'polo' ), - '/asdf-foo' => array( 'title' => 'qwerty-foo' ), - '/qwerty-bar' => array( 'title' => 'asdf-bar' ), - '/a/Foo' => array( 'title' => 'Foo' ), - '/asdf/Foo' => array( 'title' => 'Foo' ), - '/qwerty/Foo' => array( 'title' => 'Foo', 'qwerty' => 'qwerty' ), - '/baz/Foo' => array( 'title' => 'Foo', 'unrestricted' => 'baz' ), - '/y/Foo' => array( 'title' => 'Foo', 'restricted-to-y' => 'y' ), - ) as $path => $result ) { + foreach ( + array( + '/Foo' => array( 'title' => 'Foo' ), + '/Bar' => array( 'ping' => 'pong' ), + '/Baz' => array( 'marco' => 'polo' ), + '/asdf-foo' => array( 'title' => 'qwerty-foo' ), + '/qwerty-bar' => array( 'title' => 'asdf-bar' ), + '/a/Foo' => array( 'title' => 'Foo' ), + '/asdf/Foo' => array( 'title' => 'Foo' ), + '/qwerty/Foo' => array( 'title' => 'Foo', 'qwerty' => 'qwerty' ), + '/baz/Foo' => array( 'title' => 'Foo', 'unrestricted' => 'baz' ), + '/y/Foo' => array( 'title' => 'Foo', 'restricted-to-y' => 'y' ), + ) as $path => $result + ) { $this->assertEquals( $router->parse( $path ), $result ); } } @@ -251,5 +260,4 @@ class PathRouterTest extends MediaWikiTestCase { $matches = $router->parse( "/wiki/Foo" ); $this->assertEquals( $matches, array( 'title' => 'bar%20$1' ) ); } - } diff --git a/tests/phpunit/includes/PreferencesTest.php b/tests/phpunit/includes/PreferencesTest.php index 7aa3c4a4..3dec2da0 100644 --- a/tests/phpunit/includes/PreferencesTest.php +++ b/tests/phpunit/includes/PreferencesTest.php @@ -4,11 +4,16 @@ * @group Database */ class PreferencesTest extends MediaWikiTestCase { - /** Array of User objects */ + /** + * @var User[] + */ private $prefUsers; + /** + * @var RequestContext + */ private $context; - function __construct() { + public function __construct() { parent::__construct(); $this->prefUsers['noemail'] = new User; @@ -30,14 +35,17 @@ class PreferencesTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); - $this->setMwGlobals( 'wgEnableEmail', true ); + $this->setMwGlobals( array( + 'wgEnableEmail' => true, + 'wgEmailAuthentication' => true, + ) ); } /** * Placeholder to verify bug 34302 * @covers Preferences::profilePreferences */ - function testEmailFieldsWhenUserHasNoEmail() { + public function testEmailFieldsWhenUserHasNoEmail() { $prefs = $this->prefsFor( 'noemail' ); $this->assertArrayHasKey( 'cssclass', $prefs['emailaddress'] @@ -49,7 +57,7 @@ class PreferencesTest extends MediaWikiTestCase { * Placeholder to verify bug 34302 * @covers Preferences::profilePreferences */ - function testEmailFieldsWhenUserEmailNotAuthenticated() { + public function testEmailFieldsWhenUserEmailNotAuthenticated() { $prefs = $this->prefsFor( 'notauth' ); $this->assertArrayHasKey( 'cssclass', $prefs['emailaddress'] @@ -61,7 +69,7 @@ class PreferencesTest extends MediaWikiTestCase { * Placeholder to verify bug 34302 * @covers Preferences::profilePreferences */ - function testEmailFieldsWhenUserEmailIsAuthenticated() { + public function testEmailFieldsWhenUserEmailIsAuthenticated() { $prefs = $this->prefsFor( 'auth' ); $this->assertArrayHasKey( 'cssclass', $prefs['emailaddress'] @@ -70,13 +78,14 @@ class PreferencesTest extends MediaWikiTestCase { } /** Helper */ - function prefsFor( $user_key ) { + protected function prefsFor( $user_key ) { $preferences = array(); Preferences::profilePreferences( $this->prefUsers[$user_key] , $this->context , $preferences ); + return $preferences; } } diff --git a/tests/phpunit/includes/Providers.php b/tests/phpunit/includes/Providers.php deleted file mode 100644 index 948b6354..00000000 --- a/tests/phpunit/includes/Providers.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Generic providers for the MediaWiki PHPUnit test suite - * - * @author Antoine Musso - * @copyright Copyright © 2011, Antoine Musso - * @file - */ - -/** */ -class MediaWikiProvide { - - /* provide an array of numbers from 1 up to @param $num */ - private static function createProviderUpTo( $num ) { - $ret = array(); - for ( $i = 1; $i <= $num; $i++ ) { - $ret[] = array( $i ); - } - return $ret; - } - - /* array of months numbers (as an integer) */ - public static function Months() { - return self::createProviderUpTo( 12 ); - } - - /* array of days numbers (as an integer) */ - public static function Days() { - return self::createProviderUpTo( 31 ); - } - - public static function DaysMonths() { - $ret = array(); - - $months = self::Months(); - $days = self::Days(); - foreach ( $months as $month ) { - foreach ( $days as $day ) { - $ret[] = array( $day[0], $month[0] ); - } - } - return $ret; - } -} diff --git a/tests/phpunit/includes/RecentChangeTest.php b/tests/phpunit/includes/RecentChangeTest.php index a1e62363..cfa3e777 100644 --- a/tests/phpunit/includes/RecentChangeTest.php +++ b/tests/phpunit/includes/RecentChangeTest.php @@ -9,7 +9,7 @@ class RecentChangeTest extends MediaWikiTestCase { protected $user_comment; protected $context; - function __construct() { + public function __construct() { parent::__construct(); $this->title = Title::newFromText( 'SomeTitle' ); @@ -56,7 +56,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeBlock() { + public function testIrcMsgForLogTypeBlock() { $sep = $this->context->msg( 'colon-separator' )->text(); # block/block @@ -78,7 +78,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeDelete() { + public function testIrcMsgForLogTypeDelete() { $sep = $this->context->msg( 'colon-separator' )->text(); # delete/delete @@ -101,7 +101,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeNewusers() { + public function testIrcMsgForLogTypeNewusers() { $this->assertIRCComment( 'New user account', 'newusers', 'newusers', @@ -127,7 +127,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeMove() { + public function testIrcMsgForLogTypeMove() { $move_params = array( '4::target' => $this->target->getPrefixedText(), '5::noredir' => 0, @@ -154,7 +154,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypePatrol() { + public function testIrcMsgForLogTypePatrol() { # patrol/patrol $this->assertIRCComment( $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(), @@ -170,7 +170,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeProtect() { + public function testIrcMsgForLogTypeProtect() { $protectParams = array( '[edit=sysop] (indefinite) [move=sysop] (indefinite)' ); @@ -204,7 +204,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeUpload() { + public function testIrcMsgForLogTypeUpload() { $sep = $this->context->msg( 'colon-separator' )->text(); # upload/upload @@ -225,24 +225,24 @@ class RecentChangeTest extends MediaWikiTestCase { } /** - * @todo: Emulate these edits somehow and extract + * @todo Emulate these edits somehow and extract * raw edit summary from RecentChange object * -- */ /* - function testIrcMsgForBlankingAES() { + public function testIrcMsgForBlankingAES() { // $this->context->msg( 'autosumm-blank', .. ); } - function testIrcMsgForReplaceAES() { + public function testIrcMsgForReplaceAES() { // $this->context->msg( 'autosumm-replace', .. ); } - function testIrcMsgForRollbackAES() { + public function testIrcMsgForRollbackAES() { // $this->context->msg( 'revertpage', .. ); } - function testIrcMsgForUndoAES() { + public function testIrcMsgForUndoAES() { // $this->context->msg( 'undo-summary', .. ); } */ @@ -251,10 +251,11 @@ class RecentChangeTest extends MediaWikiTestCase { * @param $expected String Expected IRC text without colors codes * @param $type String Log type (move, delete, suppress, patrol ...) * @param $action String A log type action + * @param $params * @param $comment String (optional) A comment for the log action * @param $msg String (optional) A message for PHPUnit :-) */ - function assertIRCComment( $expected, $type, $action, $params, $comment = null, $msg = '' ) { + protected function assertIRCComment( $expected, $type, $action, $params, $comment = null, $msg = '' ) { $logEntry = new ManualLogEntry( $type, $action ); $logEntry->setPerformer( $this->user ); @@ -267,8 +268,8 @@ class RecentChangeTest extends MediaWikiTestCase { $formatter = LogFormatter::newFromEntry( $logEntry ); $formatter->setContext( $this->context ); - // Apply the same transformation as done in RecentChange::getIRCLine for rc_comment - $ircRcComment = RecentChange::cleanupForIRC( $formatter->getIRCActionComment() ); + // Apply the same transformation as done in IRCColourfulRCFeedFormatter::getLine for rc_comment + $ircRcComment = IRCColourfulRCFeedFormatter::cleanupForIRC( $formatter->getIRCActionComment() ); $this->assertEquals( $expected, @@ -276,5 +277,4 @@ class RecentChangeTest extends MediaWikiTestCase { $msg ); } - } diff --git a/tests/phpunit/includes/RequestContextTest.php b/tests/phpunit/includes/RequestContextTest.php index f5871716..1776b5d5 100644 --- a/tests/phpunit/includes/RequestContextTest.php +++ b/tests/phpunit/includes/RequestContextTest.php @@ -7,6 +7,8 @@ class RequestContextTest extends MediaWikiTestCase { /** * Test the relationship between title and wikipage in RequestContext + * @covers RequestContext::getWikiPage + * @covers RequestContext::getTitle */ public function testWikiPageTitle() { $context = new RequestContext(); @@ -25,9 +27,11 @@ class RequestContextTest extends MediaWikiTestCase { $context->setTitle( $curTitle ); $this->assertTrue( $curTitle->equals( $context->getWikiPage()->getTitle() ), "When a title is updated the WikiPage should be purged and recreated on-demand with the new title." ); - } + /** + * @covers RequestContext::importScopedSession + */ public function testImportScopedSession() { $context = RequestContext::getMain(); @@ -58,7 +62,7 @@ class RequestContextTest extends MediaWikiTestCase { $this->assertEquals( $sinfo['userId'], $context->getUser()->getId(), "Correct context user ID." ); $this->assertEquals( 'UnitTestContextUser', $context->getUser()->getName(), "Correct context user name." ); - unset ( $sc ); // restore previous context + unset( $sc ); // restore previous context $info = $context->exportSession(); $this->assertEquals( $oInfo['ip'], $info['ip'], "Correct initial IP address." ); diff --git a/tests/phpunit/includes/ResourceLoaderTest.php b/tests/phpunit/includes/ResourceLoaderTest.php index 60618b10..ca8b2b6e 100644 --- a/tests/phpunit/includes/ResourceLoaderTest.php +++ b/tests/phpunit/includes/ResourceLoaderTest.php @@ -4,6 +4,32 @@ class ResourceLoaderTest extends MediaWikiTestCase { protected static $resourceLoaderRegisterModulesHook; + protected function setUp() { + parent::setUp(); + + // $wgResourceLoaderLESSFunctions, $wgResourceLoaderLESSImportPaths; $wgResourceLoaderLESSVars; + + $this->setMwGlobals( array( + 'wgResourceLoaderLESSFunctions' => array( + 'test-sum' => function ( $frame, $less ) { + $sum = 0; + foreach ( $frame[2] as $arg ) { + $sum += (int)$arg[1]; + } + return $sum; + }, + ), + 'wgResourceLoaderLESSImportPaths' => array( + dirname( __DIR__ ) . '/data/less/common', + ), + 'wgResourceLoaderLESSVars' => array( + 'foo' => '2px', + 'Foo' => '#eeeeee', + 'bar' => 5, + ), + ) ); + } + /* Hook Methods */ /** @@ -11,6 +37,7 @@ class ResourceLoaderTest extends MediaWikiTestCase { */ public static function resourceLoaderRegisterModules( &$resourceLoader ) { self::$resourceLoaderRegisterModulesHook = true; + return true; } @@ -21,6 +48,14 @@ class ResourceLoaderTest extends MediaWikiTestCase { ); } + public static function provideResourceLoaderContext() { + $resourceLoader = new ResourceLoader(); + $request = new FauxRequest(); + return array( + array( new ResourceLoaderContext( $resourceLoader, $request ) ), + ); + } + /* Test Methods */ /** @@ -31,6 +66,7 @@ class ResourceLoaderTest extends MediaWikiTestCase { self::$resourceLoaderRegisterModulesHook = false; $resourceLoader = new ResourceLoader(); $this->assertTrue( self::$resourceLoaderRegisterModulesHook ); + return $resourceLoader; } @@ -48,7 +84,22 @@ class ResourceLoaderTest extends MediaWikiTestCase { } /** + * @dataProvider provideResourceLoaderContext + * @covers ResourceLoaderFileModule::compileLessFile + */ + public function testLessFileCompilation( $context ) { + $basePath = __DIR__ . '/../data/less/module'; + $module = new ResourceLoaderFileModule( array( + 'localBasePath' => $basePath, + 'styles' => array( 'styles.less' ), + ) ); + $styles = $module->getStyles( $context ); + $this->assertStringEqualsFile( $basePath . '/styles.css', $styles['all'] ); + } + + /** * @dataProvider providePackedModules + * @covers ResourceLoader::makePackedModulesString */ public function testMakePackedModulesString( $desc, $modules, $packed ) { $this->assertEquals( $packed, ResourceLoader::makePackedModulesString( $modules ), $desc ); @@ -56,6 +107,7 @@ class ResourceLoaderTest extends MediaWikiTestCase { /** * @dataProvider providePackedModules + * @covers ResourceLoaderContext::expandModuleNames */ public function testexpandModuleNames( $desc, $modules, $packed ) { $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc ); @@ -77,14 +129,20 @@ class ResourceLoaderTest extends MediaWikiTestCase { 'Regression fixed in r88706 with dotless names', array( 'foo', 'bar', 'baz' ), 'foo,bar,baz', - ) + ), + array( + 'Prefixless modules after a prefixed module', + array( 'single.module', 'foobar', 'foobaz' ), + 'single.module|foobar,foobaz', + ), ); } } /* Stubs */ -class ResourceLoaderTestModule extends ResourceLoaderModule {} +class ResourceLoaderTestModule extends ResourceLoaderModule { +} /* Hooks */ global $wgHooks; diff --git a/tests/phpunit/includes/RevisionStorageTest.php b/tests/phpunit/includes/RevisionStorageTest.php index e8d8db0a..e17c7b0f 100644 --- a/tests/phpunit/includes/RevisionStorageTest.php +++ b/tests/phpunit/includes/RevisionStorageTest.php @@ -17,7 +17,7 @@ class RevisionStorageTest extends MediaWikiTestCase { */ var $the_page; - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed = array_merge( $this->tablesUsed, @@ -38,7 +38,7 @@ class RevisionStorageTest extends MediaWikiTestCase { 'iwlinks' ) ); } - public function setUp() { + protected function setUp() { global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; parent::setUp(); @@ -365,7 +365,7 @@ class RevisionStorageTest extends MediaWikiTestCase { $page = $this->createPage( 'RevisionStorageTest_testIsCurrent', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT ); $rev1 = $page->getRevision(); - # @todo: find out if this should be true + # @todo find out if this should be true # $this->assertTrue( $rev1->isCurrent() ); $rev1x = Revision::newFromId( $rev1->getId() ); @@ -374,7 +374,7 @@ class RevisionStorageTest extends MediaWikiTestCase { $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), 'second rev' ); $rev2 = $page->getRevision(); - # @todo: find out if this should be true + # @todo find out if this should be true # $this->assertTrue( $rev2->isCurrent() ); $rev1x = Revision::newFromId( $rev1->getId() ); @@ -456,15 +456,15 @@ class RevisionStorageTest extends MediaWikiTestCase { * @dataProvider provideUserWasLastToEdit */ public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) { - $userA = \User::newFromName( "RevisionStorageTest_userA" ); - $userB = \User::newFromName( "RevisionStorageTest_userB" ); + $userA = User::newFromName( "RevisionStorageTest_userA" ); + $userB = User::newFromName( "RevisionStorageTest_userB" ); if ( $userA->getId() === 0 ) { - $userA = \User::createNew( $userA->getName() ); + $userA = User::createNew( $userA->getName() ); } if ( $userB->getId() === 0 ) { - $userB = \User::createNew( $userB->getName() ); + $userB = User::createNew( $userB->getName() ); } $ns = $this->getDefaultWikitextNS(); diff --git a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php b/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php index 3948e345..4e83e355 100644 --- a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php +++ b/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php @@ -6,14 +6,9 @@ * ^--- important, causes temporary tables to be used instead of the real database */ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { - var $saveContentHandlerNoDB = null; - function setUp() { - global $wgContentHandlerUseDB; - - $this->saveContentHandlerNoDB = $wgContentHandlerUseDB; - - $wgContentHandlerUseDB = false; + protected function setUp() { + $this->setMwGlobals( 'wgContentHandlerUseDB', false ); $dbw = wfGetDB( DB_MASTER ); @@ -32,14 +27,6 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { parent::setUp(); } - function tearDown() { - global $wgContentHandlerUseDB; - - parent::tearDown(); - - $wgContentHandlerUseDB = $this->saveContentHandlerNoDB; - } - /** * @covers Revision::selectFields */ @@ -76,7 +63,7 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { */ public function testGetContentFormat() { try { - //@todo: change this to test failure on using a non-standard (but supported) format + // @todo change this to test failure on using a non-standard (but supported) format // for a content model supported in the given location. As of 1.21, there are // no alternative formats for any of the standard content models that could be // used for this though. @@ -91,5 +78,4 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { $this->assertTrue( true ); // ok } } - } diff --git a/tests/phpunit/includes/RevisionTest.php b/tests/phpunit/includes/RevisionTest.php index db0245b9..b5819ff6 100644 --- a/tests/phpunit/includes/RevisionTest.php +++ b/tests/phpunit/includes/RevisionTest.php @@ -54,7 +54,10 @@ class RevisionTest extends MediaWikiTestCase { parent::tearDown(); } - function testGetRevisionText() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionText() { $row = new stdClass; $row->old_flags = ''; $row->old_text = 'This is a bunch of revision text.'; @@ -63,7 +66,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextGzip() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextGzip() { $this->checkPHPExtension( 'zlib' ); $row = new stdClass; @@ -74,7 +80,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8Native() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8Native() { $row = new stdClass; $row->old_flags = 'utf-8'; $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; @@ -84,7 +93,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8Legacy() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8Legacy() { $row = new stdClass; $row->old_flags = ''; $row->old_text = "Wiki est l'\xe9cole superieur !"; @@ -94,7 +106,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8NativeGzip() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8NativeGzip() { $this->checkPHPExtension( 'zlib' ); $row = new stdClass; @@ -106,7 +121,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8LegacyGzip() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8LegacyGzip() { $this->checkPHPExtension( 'zlib' ); $row = new stdClass; @@ -118,7 +136,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testCompressRevisionTextUtf8() { + /** + * @covers Revision::compressRevisionText + */ + public function testCompressRevisionTextUtf8() { $row = new stdClass; $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; $row->old_flags = Revision::compressRevisionText( $row->old_text ); @@ -132,11 +153,12 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ), "getRevisionText" ); } - function testCompressRevisionTextUtf8Gzip() { + /** + * @covers Revision::compressRevisionText + */ + public function testCompressRevisionTextUtf8Gzip() { $this->checkPHPExtension( 'zlib' ); - - global $wgCompressRevisions; - $wgCompressRevisions = true; + $this->setMwGlobals( 'wgCompressRevisions', true ); $row = new stdClass; $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; @@ -157,6 +179,8 @@ class RevisionTest extends MediaWikiTestCase { * @param string $text * @param string $title * @param string $model + * @param null $format + * * @return Revision */ function newTestRevision( $text, $title = "Test", $model = CONTENT_MODEL_WIKITEXT, $format = null ) { @@ -196,8 +220,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContentModel + * @covers Revision::getContentModel */ - function testGetContentModel( $text, $title, $model, $format, $expectedModel ) { + public function testGetContentModel( $text, $title, $model, $format, $expectedModel ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $this->assertEquals( $expectedModel, $rev->getContentModel() ); @@ -216,8 +241,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContentFormat + * @covers Revision::getContentFormat */ - function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) { + public function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $this->assertEquals( $expectedFormat, $rev->getContentFormat() ); @@ -235,8 +261,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContentHandler + * @covers Revision::getContentHandler */ - function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) { + public function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $this->assertEquals( $expectedClass, get_class( $rev->getContentHandler() ) ); @@ -254,8 +281,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContent + * @covers Revision::getContent */ - function testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization ) { + public function testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $content = $rev->getContent( $audience ); @@ -274,8 +302,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetText + * @covers Revision::getText */ - function testGetText( $text, $title, $model, $format, $audience, $expectedText ) { + public function testGetText( $text, $title, $model, $format, $audience, $expectedText ) { $this->hideDeprecated( 'Revision::getText' ); $rev = $this->newTestRevision( $text, $title, $model, $format ); @@ -286,8 +315,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetText + * @covers Revision::getRawText */ - function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) { + public function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) { $this->hideDeprecated( 'Revision::getRawText' ); $rev = $this->newTestRevision( $text, $title, $model, $format ); @@ -330,6 +360,9 @@ class RevisionTest extends MediaWikiTestCase { $this->assertEquals( $expected_hash, $rev->getSha1() ); } + /** + * @covers Revision::__construct + */ public function testConstructWithText() { $this->hideDeprecated( "Revision::getText" ); @@ -344,6 +377,9 @@ class RevisionTest extends MediaWikiTestCase { $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); } + /** + * @covers Revision::__construct + */ public function testConstructWithContent() { $this->hideDeprecated( "Revision::getText" ); @@ -363,8 +399,9 @@ class RevisionTest extends MediaWikiTestCase { * Tests whether $rev->getContent() returns a clone when needed. * * @group Database + * @covers Revision::getContent */ - function testGetContentClone() { + public function testGetContentClone() { $content = new RevisionTestModifyableContent( "foo" ); $rev = new Revision( @@ -396,8 +433,9 @@ class RevisionTest extends MediaWikiTestCase { * Tests whether $rev->getContent() returns the same object repeatedly if appropriate. * * @group Database + * @covers Revision::getContent */ - function testGetContentUncloned() { + public function testGetContentUncloned() { $rev = $this->newTestRevision( "hello", "testGetContentUncloned_dummy", CONTENT_MODEL_WIKITEXT ); $content = $rev->getContent( Revision::RAW ); $content2 = $rev->getContent( Revision::RAW ); @@ -405,7 +443,6 @@ class RevisionTest extends MediaWikiTestCase { // for immutable content like wikitext, this should be the same object $this->assertSame( $content, $content2 ); } - } class RevisionTestModifyableContent extends TextContent { @@ -424,7 +461,6 @@ class RevisionTestModifyableContent extends TextContent { public function setText( $text ) { $this->mText = $text; } - } class RevisionTestModifyableContentHandler extends TextContentHandler { diff --git a/tests/phpunit/includes/SampleTest.php b/tests/phpunit/includes/SampleTest.php index 8a881915..8516a4ce 100644 --- a/tests/phpunit/includes/SampleTest.php +++ b/tests/phpunit/includes/SampleTest.php @@ -33,7 +33,7 @@ class TestSample extends MediaWikiLangTestCase { * "Agile Documentation" at * http://www.phpunit.de/manual/3.4/en/other-uses-for-tests.html */ - function testTitleObjectStringConversion() { + public function testTitleObjectStringConversion() { $title = Title::newFromText( "text" ); $this->assertInstanceOf( 'Title', $title, "Title creation" ); $this->assertEquals( "Text", $title, "Automatic string conversion" ); @@ -98,7 +98,7 @@ class TestSample extends MediaWikiLangTestCase { * @expectedException MWException object * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.expectedException */ - function testTitleObjectFromObject() { + public function testTitleObjectFromObject() { $title = Title::newFromText( Title::newFromText( "test" ) ); $this->assertEquals( "Test", $title->isLocal() ); } diff --git a/tests/phpunit/includes/SanitizerTest.php b/tests/phpunit/includes/SanitizerTest.php index c0ed4a59..81246d33 100644 --- a/tests/phpunit/includes/SanitizerTest.php +++ b/tests/phpunit/includes/SanitizerTest.php @@ -1,5 +1,9 @@ <?php +/** + * @todo Tests covering decodeCharReferences can be refactored into a single + * method and dataprovider. + */ class SanitizerTest extends MediaWikiTestCase { protected function setUp() { @@ -8,7 +12,10 @@ class SanitizerTest extends MediaWikiTestCase { AutoLoader::loadClass( 'Sanitizer' ); } - function testDecodeNamedEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeNamedEntities() { $this->assertEquals( "\xc3\xa9cole", Sanitizer::decodeCharReferences( 'école' ), @@ -16,7 +23,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testDecodeNumericEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeNumericEntities() { $this->assertEquals( "\xc4\x88io bonas dans l'\xc3\xa9cole!", Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), @@ -24,7 +34,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testDecodeMixedEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeMixedEntities() { $this->assertEquals( "\xc4\x88io bonas dans l'\xc3\xa9cole!", Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), @@ -32,7 +45,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testDecodeMixedComplexEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeMixedComplexEntities() { $this->assertEquals( "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas Ĉio dans l'école)", Sanitizer::decodeCharReferences( @@ -42,7 +58,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testInvalidAmpersand() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testInvalidAmpersand() { $this->assertEquals( 'a & b', Sanitizer::decodeCharReferences( 'a & b' ), @@ -50,7 +69,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testInvalidEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testInvalidEntities() { $this->assertEquals( '&foo;', Sanitizer::decodeCharReferences( '&foo;' ), @@ -58,7 +80,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testInvalidNumberedEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testInvalidNumberedEntities() { $this->assertEquals( UTF8_REPLACEMENT, Sanitizer::decodeCharReferences( "�" ), 'Invalid numbered entity' ); } @@ -69,10 +94,8 @@ class SanitizerTest extends MediaWikiTestCase { * @param String $tag Name of an HTML5 element (ie: 'video') * @param Boolean $escaped Wheter sanitizer let the tag in or escape it (ie: '<video>') */ - function testRemovehtmltagsOnHtml5Tags( $tag, $escaped ) { + public function testRemovehtmltagsOnHtml5Tags( $tag, $escaped ) { $this->setMwGlobals( array( - # Enable HTML5 mode - 'wgHtml5' => true, 'wgUseTidy' => false ) ); @@ -90,7 +113,7 @@ class SanitizerTest extends MediaWikiTestCase { /** * Provide HTML5 tags */ - function provideHtml5Tags() { + public static function provideHtml5Tags() { $ESCAPED = true; # We want tag to be escaped $VERBATIM = false; # We want to keep the tag return array( @@ -101,31 +124,57 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testSelfClosingTag() { - $this->setMwGlobals( array( - 'wgUseTidy' => false - ) ); - - $this->assertEquals( - '<div>Hello world</div>', - Sanitizer::removeHTMLtags( '<div>Hello world</div />' ), - 'Self-closing closing div' + function dataRemoveHTMLtags() { + return array( + // former testSelfClosingTag + array( + '<div>Hello world</div />', + '<div>Hello world</div>', + 'Self-closing closing div' + ), + // Make sure special nested HTML5 semantics are not broken + // http://www.whatwg.org/html/text-level-semantics.html#the-kbd-element + array( + '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>', + '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>', + 'Nested <kbd>.' + ), + // http://www.whatwg.org/html/text-level-semantics.html#the-sub-and-sup-elements + array( + '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>', + '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>', + 'Nested <var>.' + ), + // http://www.whatwg.org/html/text-level-semantics.html#the-dfn-element + array( + '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>', + '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>', + '<abbr> inside <dfn>', + ), ); } + /** + * @dataProvider dataRemoveHTMLtags + * @covers Sanitizer::removeHTMLtags + */ + public function testRemoveHTMLtags( $input, $output, $msg = null ) { + $GLOBALS['wgUseTidy'] = false; + $this->assertEquals( $output, Sanitizer::removeHTMLtags( $input ), $msg ); + } /** * @dataProvider provideTagAttributesToDecode * @covers Sanitizer::decodeTagAttributes */ - function testDecodeTagAttributes( $expected, $attributes, $message = '' ) { + public function testDecodeTagAttributes( $expected, $attributes, $message = '' ) { $this->assertEquals( $expected, Sanitizer::decodeTagAttributes( $attributes ), $message ); } - function provideTagAttributesToDecode() { + public static function provideTagAttributesToDecode() { return array( array( array( 'foo' => 'bar' ), 'foo=bar', 'Unquoted attribute' ), array( array( 'foo' => 'bar' ), ' foo = bar ', 'Spaced attribute' ), @@ -148,7 +197,6 @@ class SanitizerTest extends MediaWikiTestCase { array( array( 'foo.' => 'baz' ), 'foo.=baz', 'A . is allowed as last character' ), array( array( 'foo6' => 'baz' ), 'foo6=baz', 'Numbers are allowed' ), - # This bit is more relaxed than XML rules, but some extensions use # it, like ProofreadPage (see bug 27539) array( array( '1foo' => 'baz' ), '1foo=baz', 'Leading numbers are allowed' ), @@ -167,7 +215,7 @@ class SanitizerTest extends MediaWikiTestCase { * @dataProvider provideDeprecatedAttributes * @covers Sanitizer::fixTagAttributes */ - function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl, $message = '' ) { + public function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl, $message = '' ) { $this->assertEquals( " $inputAttr", Sanitizer::fixTagAttributes( $inputAttr, $inputEl ), $message @@ -195,7 +243,7 @@ class SanitizerTest extends MediaWikiTestCase { * @dataProvider provideCssCommentsFixtures * @covers Sanitizer::checkCss */ - function testCssCommentsChecking( $expected, $css, $message = '' ) { + public function testCssCommentsChecking( $expected, $css, $message = '' ) { $this->assertEquals( $expected, Sanitizer::checkCss( $css ), $message @@ -205,10 +253,14 @@ class SanitizerTest extends MediaWikiTestCase { public static function provideCssCommentsFixtures() { /** array( <expected>, <css>, [message] ) */ return array( - array( ' ', '/**/' ), + // Valid comments spanning entire input + array( '/**/', '/**/' ), + array( '/* comment */', '/* comment */' ), + // Weird stuff array( ' ', '/****/' ), - array( ' ', '/* comment */' ), - array( ' ', "\\2f\\2a foo \\2a\\2f", + array( ' ', '/* /* */' ), + array( 'display: block;', "display:/* foo */block;" ), + array( 'display: block;', "display:\\2f\\2a foo \\2a\\2f block;", 'Backslash-escaped comments must be stripped (bug 28450)' ), array( '', '/* unfinished comment structure', 'Remove anything after a comment-start token' ), @@ -229,7 +281,7 @@ class SanitizerTest extends MediaWikiTestCase { /** * Test for support or lack of support for specific attributes in the attribute whitelist. */ - function provideAttributeSupport() { + public static function provideAttributeSupport() { /** array( <attributes>, <expected>, <message> ) */ return array( array( 'div', ' role="presentation"', ' role="presentation"', 'Support for WAI-ARIA\'s role="presentation".' ), @@ -239,12 +291,12 @@ class SanitizerTest extends MediaWikiTestCase { /** * @dataProvider provideAttributeSupport + * @covers Sanitizer::fixTagAttributes */ - function testAttributeSupport( $tag, $attributes, $expected, $message ) { + public function testAttributeSupport( $tag, $attributes, $expected, $message ) { $this->assertEquals( $expected, Sanitizer::fixTagAttributes( $attributes, $tag ), $message ); } - } diff --git a/tests/phpunit/includes/SanitizerValidateEmailTest.php b/tests/phpunit/includes/SanitizerValidateEmailTest.php index fe0bc64e..f13e8382 100644 --- a/tests/phpunit/includes/SanitizerValidateEmailTest.php +++ b/tests/phpunit/includes/SanitizerValidateEmailTest.php @@ -1,5 +1,10 @@ <?php +/** + * @covers Sanitizer::validateEmail + * @TODO all test methods in this class should be refactored and... + * use a single test method and a single data provider... + */ class SanitizerValidateEmailTest extends MediaWikiTestCase { private function checkEmail( $addr, $expected = true, $msg = '' ) { @@ -22,54 +27,56 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase { $this->checkEmail( $addr, false, $msg ); } - function testEmailWellKnownUserAtHostDotTldAreValid() { + public function testEmailWellKnownUserAtHostDotTldAreValid() { $this->valid( 'user@example.com' ); $this->valid( 'user@example.museum' ); } - function testEmailWithUpperCaseCharactersAreValid() { + public function testEmailWithUpperCaseCharactersAreValid() { $this->valid( 'USER@example.com' ); $this->valid( 'user@EXAMPLE.COM' ); $this->valid( 'user@Example.com' ); $this->valid( 'USER@eXAMPLE.com' ); } - function testEmailWithAPlusInUserName() { + public function testEmailWithAPlusInUserName() { $this->valid( 'user+sub@example.com' ); $this->valid( 'user+@example.com' ); } - function testEmailDoesNotNeedATopLevelDomain() { + public function testEmailDoesNotNeedATopLevelDomain() { $this->valid( "user@localhost" ); $this->valid( "FooBar@localdomain" ); $this->valid( "nobody@mycompany" ); } - function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { + public function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { $this->invalid( " user@host.com" ); $this->invalid( "user@host.com " ); $this->invalid( "\tuser@host.com" ); $this->invalid( "user@host.com\t" ); } - function testEmailWithWhiteSpacesAreInvalids() { + public function testEmailWithWhiteSpacesAreInvalids() { $this->invalid( "User user@host" ); $this->invalid( "first last@mycompany" ); $this->invalid( "firstlast@my company" ); } - // bug 26948 : comma were matched by an incorrect regexp range - function testEmailWithCommasAreInvalids() { + /** + * bug 26948 : comma were matched by an incorrect regexp range + */ + public function testEmailWithCommasAreInvalids() { $this->invalid( "user,foo@example.org" ); $this->invalid( "userfoo@ex,ample.org" ); } - function testEmailWithHyphens() { + public function testEmailWithHyphens() { $this->valid( "user-foo@example.org" ); $this->valid( "userfoo@ex-ample.org" ); } - function testEmailDomainCanNotBeginWithDot() { + public function testEmailDomainCanNotBeginWithDot() { $this->invalid( "user@." ); $this->invalid( "user@.localdomain" ); $this->invalid( "user@localdomain." ); @@ -78,19 +85,19 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase { $this->invalid( ".@a............" ); } - function testEmailWithFunnyCharacters() { + public function testEmailWithFunnyCharacters() { $this->valid( "\$user!ex{this}@123.com" ); } - function testEmailTopLevelDomainCanBeNumerical() { + public function testEmailTopLevelDomainCanBeNumerical() { $this->valid( "user@example.1234" ); } - function testEmailWithoutAtSignIsInvalid() { + public function testEmailWithoutAtSignIsInvalid() { $this->invalid( 'useràexample.com' ); } - function testEmailWithOneCharacterDomainIsValid() { + public function testEmailWithOneCharacterDomainIsValid() { $this->valid( 'user@a' ); } } diff --git a/tests/phpunit/includes/SeleniumConfigurationTest.php b/tests/phpunit/includes/SeleniumConfigurationTest.php deleted file mode 100644 index 3422c90c..00000000 --- a/tests/phpunit/includes/SeleniumConfigurationTest.php +++ /dev/null @@ -1,222 +0,0 @@ -<?php - -class SeleniumConfigurationTest extends MediaWikiTestCase { - - /** - * The file where the test temporarity stores the selenium config. - * This should be cleaned up as part of teardown. - */ - private $tempFileName; - - /** - * String containing the a sample selenium settings - */ - private $testConfig0 = ' -[SeleniumSettings] -browsers[firefox] = "*firefox" -browsers[iexplorer] = "*iexploreproxy" -browsers[chrome] = "*chrome" -host = "localhost" -port = "foobarr" -wikiUrl = "http://localhost/deployment" -username = "xxxxxxx" -userPassword = "" -testBrowser = "chrome" -startserver = -stopserver = -jUnitLogFile = -runAgainstGrid = false - -[SeleniumTests] -testSuite[SimpleSeleniumTestSuite] = "tests/selenium/SimpleSeleniumTestSuite.php" -testSuite[TestSuiteName] = "testSuitePath" -'; - /** - * Array of expected browsers from $testConfig0 - */ - private $testBrowsers0 = array( 'firefox' => '*firefox', - 'iexplorer' => '*iexploreproxy', - 'chrome' => '*chrome' - ); - /** - * Array of expected selenium settings from $testConfig0 - */ - private $testSettings0 = array( - 'host' => 'localhost', - 'port' => 'foobarr', - 'wikiUrl' => 'http://localhost/deployment', - 'username' => 'xxxxxxx', - 'userPassword' => '', - 'testBrowser' => 'chrome', - 'startserver' => null, - 'stopserver' => null, - 'seleniumserverexecpath' => null, - 'jUnitLogFile' => null, - 'runAgainstGrid' => null - ); - /** - * Array of expected testSuites from $testConfig0 - */ - private $testSuites0 = array( - 'SimpleSeleniumTestSuite' => 'tests/selenium/SimpleSeleniumTestSuite.php', - 'TestSuiteName' => 'testSuitePath' - ); - - /** - * Another sample selenium settings file contents - */ - private $testConfig1 = - ' -[SeleniumSettings] -host = "localhost" -testBrowser = "firefox" -'; - /** - * Expected browsers from $testConfig1 - */ - private $testBrowsers1 = null; - /** - * Expected selenium settings from $testConfig1 - */ - private $testSettings1 = array( - 'host' => 'localhost', - 'port' => null, - 'wikiUrl' => null, - 'username' => null, - 'userPassword' => null, - 'testBrowser' => 'firefox', - 'startserver' => null, - 'stopserver' => null, - 'seleniumserverexecpath' => null, - 'jUnitLogFile' => null, - 'runAgainstGrid' => null - ); - /** - * Expected test suites from $testConfig1 - */ - private $testSuites1 = null; - - - protected function setUp() { - parent::setUp(); - if ( !defined( 'SELENIUMTEST' ) ) { - define( 'SELENIUMTEST', true ); - } - } - - /** - * Clean up the temporary file used to store the selenium settings. - */ - protected function tearDown() { - if ( strlen( $this->tempFileName ) > 0 ) { - unlink( $this->tempFileName ); - unset( $this->tempFileName ); - } - parent::tearDown(); - } - - /** - * @expectedException MWException - * @group SeleniumFramework - */ - public function testErrorOnIncorrectConfigFile() { - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites, - "Some_fake_settings_file.ini" ); - } - - /** - * @expectedException MWException - * @group SeleniumFramework - */ - public function testErrorOnMissingConfigFile() { - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - global $wgSeleniumConfigFile; - $wgSeleniumConfigFile = ''; - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites ); - } - - /** - * @group SeleniumFramework - */ - public function testUsesGlobalVarForConfigFile() { - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - global $wgSeleniumConfigFile; - $this->writeToTempFile( $this->testConfig0 ); - $wgSeleniumConfigFile = $this->tempFileName; - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites ); - $this->assertEquals( $seleniumSettings, $this->testSettings0, - 'The selenium settings should have been read from the file defined in $wgSeleniumConfigFile' - ); - $this->assertEquals( $seleniumBrowsers, $this->testBrowsers0, - 'The available browsers should have been read from the file defined in $wgSeleniumConfigFile' - ); - $this->assertEquals( $seleniumTestSuites, $this->testSuites0, - 'The test suites should have been read from the file defined in $wgSeleniumConfigFile' - ); - } - - /** - * @group SeleniumFramework - * @dataProvider sampleConfigs - */ - public function testgetSeleniumSettings( $sampleConfig, $expectedSettings, $expectedBrowsers, $expectedSuites ) { - $this->writeToTempFile( $sampleConfig ); - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = null; - - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites, - $this->tempFileName ); - - $this->assertEquals( $seleniumSettings, $expectedSettings, - "The selenium settings for the following test configuration was not retrieved correctly" . $sampleConfig - ); - $this->assertEquals( $seleniumBrowsers, $expectedBrowsers, - "The available browsers for the following test configuration was not retrieved correctly" . $sampleConfig - ); - $this->assertEquals( $seleniumTestSuites, $expectedSuites, - "The test suites for the following test configuration was not retrieved correctly" . $sampleConfig - ); - } - - /** - * create a temp file and write text to it. - * @param $testToWrite the text to write to the temp file - */ - private function writeToTempFile( $textToWrite ) { - $this->tempFileName = tempnam( sys_get_temp_dir(), 'test_settings.' ); - $tempFile = fopen( $this->tempFileName, "w" ); - fwrite( $tempFile, $textToWrite ); - fclose( $tempFile ); - } - - /** - * Returns an array containing: - * The contents of the selenium cingiguration ini file - * The expected selenium configuration array that getSeleniumSettings should return - * The expected available browsers array that getSeleniumSettings should return - * The expected test suites arrya that getSeleniumSettings should return - */ - public function sampleConfigs() { - return array( - array( $this->testConfig0, $this->testSettings0, $this->testBrowsers0, $this->testSuites0 ), - array( $this->testConfig1, $this->testSettings1, $this->testBrowsers1, $this->testSuites1 ) - ); - } -} diff --git a/tests/phpunit/includes/SiteConfigurationTest.php b/tests/phpunit/includes/SiteConfigurationTest.php index fc7d8d09..053d8a7d 100644 --- a/tests/phpunit/includes/SiteConfigurationTest.php +++ b/tests/phpunit/includes/SiteConfigurationTest.php @@ -10,6 +10,7 @@ function getSiteParams( $conf, $wiki ) { break; } } + return array( 'suffix' => $site, 'lang' => $lang, @@ -23,14 +24,18 @@ function getSiteParams( $conf, $wiki ) { } class SiteConfigurationTest extends MediaWikiTestCase { - var $mConf; + + /** + * @var SiteConfiguration + */ + protected $mConf; protected function setUp() { parent::setUp(); $this->mConf = new SiteConfiguration; - $this->mConf->suffixes = array( 'wiki' ); + $this->mConf->suffixes = array( 'wikipedia' => 'wiki' ); $this->mConf->wikis = array( 'enwiki', 'dewiki', 'frwiki' ); $this->mConf->settings = array( 'simple' => array( @@ -94,7 +99,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { $GLOBALS['global'] = array( 'global' => 'global' ); } - function testSiteFromDb() { + /** + * @covers SiteConfiguration::siteFromDB + */ + public function testSiteFromDb() { $this->assertEquals( array( 'wikipedia', 'en' ), $this->mConf->siteFromDB( 'enwiki' ), @@ -119,7 +127,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testGetLocalDatabases() { + /** + * @covers SiteConfiguration::getLocalDatabases + */ + public function testGetLocalDatabases() { $this->assertEquals( array( 'enwiki', 'dewiki', 'frwiki' ), $this->mConf->getLocalDatabases(), @@ -127,7 +138,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testGetConfVariables() { + /** + * @covers SiteConfiguration::get + */ + public function testGetConfVariables() { $this->assertEquals( 'enwiki', $this->mConf->get( 'simple', 'enwiki', 'wiki' ), @@ -239,7 +253,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testSiteFromDbWithCallback() { + /** + * @covers SiteConfiguration::siteFromDB + */ + public function testSiteFromDbWithCallback() { $this->mConf->siteParamsCallback = 'getSiteParams'; $this->assertEquals( @@ -259,7 +276,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testParameterReplacement() { + /** + * @covers SiteConfiguration::get + */ + public function testParameterReplacement() { $this->mConf->siteParamsCallback = 'getSiteParams'; $this->assertEquals( @@ -289,7 +309,10 @@ class SiteConfigurationTest extends MediaWikiTestCase { ); } - function testGetAllGlobals() { + /** + * @covers SiteConfiguration::getAll + */ + public function testGetAllGlobals() { $this->mConf->siteParamsCallback = 'getSiteParams'; $getall = array( diff --git a/tests/phpunit/includes/StringUtilsTest.php b/tests/phpunit/includes/StringUtilsTest.php index db3d2655..89759e5c 100644 --- a/tests/phpunit/includes/StringUtilsTest.php +++ b/tests/phpunit/includes/StringUtilsTest.php @@ -3,13 +3,13 @@ class StringUtilsTest extends MediaWikiTestCase { /** - * This test StringUtils::isUtf8 whenever we have mbstring extension + * This tests StringUtils::isUtf8 whenever we have the mbstring extension * loaded. * * @covers StringUtils::isUtf8 * @dataProvider provideStringsForIsUtf8Check */ - function testIsUtf8WithMbstring( $expected, $string ) { + public function testIsUtf8WithMbstring( $expected, $string ) { if ( !function_exists( 'mb_check_encoding' ) ) { $this->markTestSkipped( 'Test requires the mbstring PHP extension' ); } @@ -20,16 +20,16 @@ class StringUtilsTest extends MediaWikiTestCase { } /** - * This test StringUtils::isUtf8 making sure we use the pure PHP + * This tests StringUtils::isUtf8 making sure we use the pure PHP * implementation used as a fallback when mb_check_encoding() is * not available. * * @covers StringUtils::isUtf8 * @dataProvider provideStringsForIsUtf8Check */ - function testIsUtf8WithPhpFallbackImplementation( $expected, $string ) { + public function testIsUtf8WithPhpFallbackImplementation( $expected, $string ) { $this->assertEquals( $expected, - StringUtils::isUtf8( $string, /** disable mbstring: */ true ), + StringUtils::isUtf8( $string, /** disable mbstring: */true ), 'Testing string "' . $this->escaped( $string ) . '" with pure PHP implementation' ); } @@ -49,6 +49,7 @@ class StringUtilsTest extends MediaWikiTestCase { $escaped .= $char; } } + return $escaped; } @@ -57,87 +58,90 @@ class StringUtilsTest extends MediaWikiTestCase { * Markus Kuhn: * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */ - function provideStringsForIsUtf8Check() { + public static function provideStringsForIsUtf8Check() { // Expected return values for StringUtils::isUtf8() $PASS = true; $FAIL = false; return array( - array( $PASS, 'Some ASCII' ), - array( $PASS, "Euro sign €" ), - - # First possible sequences - array( $PASS, "\x00" ), - array( $PASS, "\xc2\x80" ), - array( $PASS, "\xe0\xa0\x80" ), - array( $PASS, "\xf0\x90\x80\x80" ), - array( $PASS, "\xf8\x88\x80\x80\x80" ), - array( $PASS, "\xfc\x84\x80\x80\x80\x80" ), - - # Last possible sequence - array( $PASS, "\x7f" ), - array( $PASS, "\xdf\xbf" ), - array( $PASS, "\xef\xbf\xbf" ), - array( $PASS, "\xf7\xbf\xbf\xbf" ), - array( $PASS, "\xfb\xbf\xbf\xbf\xbf" ), - array( $FAIL, "\xfd\xbf\xbf\xbf\xbf\xbf" ), - - # boundaries: - array( $PASS, "\xed\x9f\xbf" ), - array( $PASS, "\xee\x80\x80" ), - array( $PASS, "\xef\xbf\xbd" ), - array( $PASS, "\xf4\x8f\xbf\xbf" ), - array( $PASS, "\xf4\x90\x80\x80" ), - - # Malformed - array( $FAIL, "\x80" ), - array( $FAIL, "\xBF" ), - array( $FAIL, "\x80\xbf" ), - array( $FAIL, "\x80\xbf\x80" ), - array( $FAIL, "\x80\xbf\x80\xbf" ), - array( $FAIL, "\x80\xbf\x80\xbf\x80" ), - array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf" ), - array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf\x80" ), - - # last byte missing - array( $FAIL, "\xc0" ), - array( $FAIL, "\xe0\x80" ), - array( $FAIL, "\xf0\x80\x80" ), - array( $FAIL, "\xf8\x80\x80\x80" ), - array( $FAIL, "\xfc\x80\x80\x80\x80" ), - array( $FAIL, "\xdf" ), - array( $FAIL, "\xef\xbf" ), - array( $FAIL, "\xf7\xbf\xbf" ), - array( $FAIL, "\xfb\xbf\xbf\xbf" ), - array( $FAIL, "\xfd\xbf\xbf\xbf\xbf" ), - - # impossible bytes - array( $FAIL, "\xfe" ), - array( $FAIL, "\xff" ), - array( $FAIL, "\xfe\xfe\xff\xff" ), - - /** - # The PHP implementation does not handle characters - # being represented in a form which is too long :( - - # overlong sequences - array( $FAIL, "\xc0\xaf" ), - array( $FAIL, "\xe0\x80\xaf" ), - array( $FAIL, "\xf0\x80\x80\xaf" ), - array( $FAIL, "\xf8\x80\x80\x80\xaf" ), - array( $FAIL, "\xfc\x80\x80\x80\x80\xaf" ), - - # Maximum overlong sequences - array( $FAIL, "\xc1\xbf" ), - array( $FAIL, "\xe0\x9f\xbf" ), - array( $FAIL, "\xf0\x8F\xbf\xbf" ), - array( $FAIL, "\xf8\x87\xbf\xbf" ), - array( $FAIL, "\xfc\x83\xbf\xbf\xbf\xbf" ), - **/ - - # non characters - array( $PASS, "\xef\xbf\xbe" ), - array( $PASS, "\xef\xbf\xbf" ), + 'some ASCII' => array( $PASS, 'Some ASCII' ), + 'euro sign' => array( $PASS, "Euro sign €" ), + + 'first possible sequence 1 byte' => array( $PASS, "\x00" ), + 'first possible sequence 2 bytes' => array( $PASS, "\xc2\x80" ), + 'first possible sequence 3 bytes' => array( $PASS, "\xe0\xa0\x80" ), + 'first possible sequence 4 bytes' => array( $PASS, "\xf0\x90\x80\x80" ), + 'first possible sequence 5 bytes' => array( $FAIL, "\xf8\x88\x80\x80\x80" ), + 'first possible sequence 6 bytes' => array( $FAIL, "\xfc\x84\x80\x80\x80\x80" ), + + 'last possible sequence 1 byte' => array( $PASS, "\x7f" ), + 'last possible sequence 2 bytes' => array( $PASS, "\xdf\xbf" ), + 'last possible sequence 3 bytes' => array( $PASS, "\xef\xbf\xbf" ), + 'last possible sequence 4 bytes (U+1FFFFF)' => array( $FAIL, "\xf7\xbf\xbf\xbf" ), + 'last possible sequence 5 bytes' => array( $FAIL, "\xfb\xbf\xbf\xbf\xbf" ), + 'last possible sequence 6 bytes' => array( $FAIL, "\xfd\xbf\xbf\xbf\xbf\xbf" ), + + 'boundary 1' => array( $PASS, "\xed\x9f\xbf" ), + 'boundary 2' => array( $PASS, "\xee\x80\x80" ), + 'boundary 3' => array( $PASS, "\xef\xbf\xbd" ), + 'boundary 4' => array( $PASS, "\xf2\x80\x80\x80" ), + 'boundary 5 (U+FFFFF)' => array( $PASS, "\xf3\xbf\xbf\xbf" ), + 'boundary 6 (U+100000)' => array( $PASS, "\xf4\x80\x80\x80" ), + 'boundary 7 (U+10FFFF)' => array( $PASS, "\xf4\x8f\xbf\xbf" ), + 'boundary 8 (U+110000)' => array( $FAIL, "\xf4\x90\x80\x80" ), + + 'malformed 1' => array( $FAIL, "\x80" ), + 'malformed 2' => array( $FAIL, "\xbf" ), + 'malformed 3' => array( $FAIL, "\x80\xbf" ), + 'malformed 4' => array( $FAIL, "\x80\xbf\x80" ), + 'malformed 5' => array( $FAIL, "\x80\xbf\x80\xbf" ), + 'malformed 6' => array( $FAIL, "\x80\xbf\x80\xbf\x80" ), + 'malformed 7' => array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf" ), + 'malformed 8' => array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf\x80" ), + + 'last byte missing 1' => array( $FAIL, "\xc0" ), + 'last byte missing 2' => array( $FAIL, "\xe0\x80" ), + 'last byte missing 3' => array( $FAIL, "\xf0\x80\x80" ), + 'last byte missing 4' => array( $FAIL, "\xf8\x80\x80\x80" ), + 'last byte missing 5' => array( $FAIL, "\xfc\x80\x80\x80\x80" ), + 'last byte missing 6' => array( $FAIL, "\xdf" ), + 'last byte missing 7' => array( $FAIL, "\xef\xbf" ), + 'last byte missing 8' => array( $FAIL, "\xf7\xbf\xbf" ), + 'last byte missing 9' => array( $FAIL, "\xfb\xbf\xbf\xbf" ), + 'last byte missing 10' => array( $FAIL, "\xfd\xbf\xbf\xbf\xbf" ), + + 'extra continuation byte 1' => array( $FAIL, "e\xaf" ), + 'extra continuation byte 2' => array( $FAIL, "\xc3\x89\xaf" ), + 'extra continuation byte 3' => array( $FAIL, "\xef\xbc\xa5\xaf" ), + 'extra continuation byte 4' => array( $FAIL, "\xf0\x9d\x99\xb4\xaf" ), + + 'impossible bytes 1' => array( $FAIL, "\xfe" ), + 'impossible bytes 2' => array( $FAIL, "\xff" ), + 'impossible bytes 3' => array( $FAIL, "\xfe\xfe\xff\xff" ), + + 'overlong sequences 1' => array( $FAIL, "\xc0\xaf" ), + 'overlong sequences 2' => array( $FAIL, "\xc1\xaf" ), + 'overlong sequences 3' => array( $FAIL, "\xe0\x80\xaf" ), + 'overlong sequences 4' => array( $FAIL, "\xf0\x80\x80\xaf" ), + 'overlong sequences 5' => array( $FAIL, "\xf8\x80\x80\x80\xaf" ), + 'overlong sequences 6' => array( $FAIL, "\xfc\x80\x80\x80\x80\xaf" ), + + 'maximum overlong sequences 1' => array( $FAIL, "\xc1\xbf" ), + 'maximum overlong sequences 2' => array( $FAIL, "\xe0\x9f\xbf" ), + 'maximum overlong sequences 3' => array( $FAIL, "\xf0\x8f\xbf\xbf" ), + 'maximum overlong sequences 4' => array( $FAIL, "\xf8\x87\xbf\xbf" ), + 'maximum overlong sequences 5' => array( $FAIL, "\xfc\x83\xbf\xbf\xbf\xbf" ), + + 'surrogates 1 (U+D799)' => array( $PASS, "\xed\x9f\xbf" ), + 'surrogates 2 (U+E000)' => array( $PASS, "\xee\x80\x80" ), + 'surrogates 3 (U+D800)' => array( $FAIL, "\xed\xa0\x80" ), + 'surrogates 4 (U+DBFF)' => array( $FAIL, "\xed\xaf\xbf" ), + 'surrogates 5 (U+DC00)' => array( $FAIL, "\xed\xb0\x80" ), + 'surrogates 6 (U+DFFF)' => array( $FAIL, "\xed\xbf\xbf" ), + 'surrogates 7 (U+D800 U+DC00)' => array( $FAIL, "\xed\xa0\x80\xed\xb0\x80" ), + + 'noncharacters 1' => array( $PASS, "\xef\xbf\xbe" ), + 'noncharacters 2' => array( $PASS, "\xef\xbf\xbf" ), ); } } diff --git a/tests/phpunit/includes/TemplateCategoriesTest.php b/tests/phpunit/includes/TemplateCategoriesTest.php index a793babb..fb63a564 100644 --- a/tests/phpunit/includes/TemplateCategoriesTest.php +++ b/tests/phpunit/includes/TemplateCategoriesTest.php @@ -7,20 +7,37 @@ require __DIR__ . "/../../../maintenance/runJobs.php"; class TemplateCategoriesTest extends MediaWikiLangTestCase { - function testTemplateCategories() { + /** + * @covers Title::getParentCategories + */ + public function testTemplateCategories() { $title = Title::newFromText( "Categorized from template" ); $page = WikiPage::factory( $title ); $user = new User(); $user->mRights = array( 'createpage', 'edit', 'purge' ); - $status = $page->doEditContent( new WikitextContent( '{{Categorising template}}' ), 'Create a page with a template', 0, false, $user ); + $page->doEditContent( + new WikitextContent( '{{Categorising template}}' ), + 'Create a page with a template', + 0, + false, + $user + ); + $this->assertEquals( array() , $title->getParentCategories() ); $template = WikiPage::factory( Title::newFromText( 'Template:Categorising template' ) ); - $status = $template->doEditContent( new WikitextContent( '[[Category:Solved bugs]]' ), 'Add a category through a template', 0, false, $user ); + + $template->doEditContent( + new WikitextContent( '[[Category:Solved bugs]]' ), + 'Add a category through a template', + 0, + false, + $user + ); // Run the job queue JobQueueGroup::destroySingletons(); @@ -33,5 +50,4 @@ class TemplateCategoriesTest extends MediaWikiLangTestCase { , $title->getParentCategories() ); } - } diff --git a/tests/phpunit/includes/TestUser.php b/tests/phpunit/includes/TestUser.php index c4d89455..23e65031 100644 --- a/tests/phpunit/includes/TestUser.php +++ b/tests/phpunit/includes/TestUser.php @@ -1,6 +1,8 @@ <?php -/* Wraps the user object, so we can also retain full access to properties like password if we log in via the API */ +/** + * Wraps the user object, so we can also retain full access to properties like password if we log in via the API + */ class TestUser { public $username; public $password; @@ -8,7 +10,7 @@ class TestUser { public $groups; public $user; - function __construct( $username, $realname = 'Real Name', $email = 'sample@example.com', $groups = array() ) { + public function __construct( $username, $realname = 'Real Name', $email = 'sample@example.com', $groups = array() ) { $this->username = $username; $this->realname = $realname; $this->email = $email; @@ -53,6 +55,5 @@ class TestUser { } } $this->user->saveSettings(); - } } diff --git a/tests/phpunit/includes/TimeAdjustTest.php b/tests/phpunit/includes/TimeAdjustTest.php index a58702b2..0b368c25 100644 --- a/tests/phpunit/includes/TimeAdjustTest.php +++ b/tests/phpunit/includes/TimeAdjustTest.php @@ -4,22 +4,28 @@ class TimeAdjustTest extends MediaWikiLangTestCase { protected function setUp() { parent::setUp(); - $this->setMwGlobals( array( - 'wgLocalTZoffset' => null, - 'wgContLang' => Language::factory( 'en' ), - 'wgLanguageCode' => 'en', - ) ); - $this->iniSet( 'precision', 15 ); } - # Test offset usage for a given language::userAdjust - function testUserAdjust() { - global $wgLocalTZoffset, $wgContLang; + /** + * Test offset usage for a given Language::userAdjust + * @dataProvider dataUserAdjust + * @covers Language::userAdjust + */ + public function testUserAdjust( $date, $localTZoffset, $expected ) { + global $wgContLang; + + $this->setMwGlobals( 'wgLocalTZoffset', $localTZoffset ); - # Collection of parameters for Language_t_Offset. - # Format: date to be formatted, localTZoffset value, expected date - $userAdjust_tests = array( + $this->assertEquals( + strval( $expected ), + strval( $wgContLang->userAdjust( $date, '' ) ), + "User adjust {$date} by {$localTZoffset} minutes should give {$expected}" + ); + } + + public static function dataUserAdjust() { + return array( array( 20061231235959, 0, 20061231235959 ), array( 20061231235959, 5, 20070101000459 ), array( 20061231235959, 15, 20070101001459 ), @@ -31,15 +37,5 @@ class TimeAdjustTest extends MediaWikiLangTestCase { array( 20061231235959, -30, 20061231232959 ), array( 20061231235959, -60, 20061231225959 ), ); - - foreach ( $userAdjust_tests as $data ) { - $wgLocalTZoffset = $data[1]; - - $this->assertEquals( - strval( $data[2] ), - strval( $wgContLang->userAdjust( $data[0], '' ) ), - "User adjust {$data[0]} by {$data[1]} minutes should give {$data[2]}" - ); - } } } diff --git a/tests/phpunit/includes/TimestampTest.php b/tests/phpunit/includes/TimestampTest.php index 0690683a..53388392 100644 --- a/tests/phpunit/includes/TimestampTest.php +++ b/tests/phpunit/includes/TimestampTest.php @@ -3,23 +3,20 @@ /** * Tests timestamp parsing and output. */ -class TimestampTest extends MediaWikiTestCase { +class TimestampTest extends MediaWikiLangTestCase { protected function setUp() { parent::setUp(); - $this->setMwGlobals( array( - 'wgLanguageCode' => 'en', - 'wgContLang' => Language::factory( 'en' ), - 'wgLang' => Language::factory( 'en' ), - ) ); + RequestContext::getMain()->setLanguage( Language::factory( 'en' ) ); } /** * Test parsing of valid timestamps and outputing to MW format. * @dataProvider provideValidTimestamps + * @covers MWTimestamp::getTimestamp */ - function testValidParse( $format, $original, $expected ) { + public function testValidParse( $format, $original, $expected ) { $timestamp = new MWTimestamp( $original ); $this->assertEquals( $expected, $timestamp->getTimestamp( TS_MW ) ); } @@ -27,8 +24,9 @@ class TimestampTest extends MediaWikiTestCase { /** * Test outputting valid timestamps to different formats. * @dataProvider provideValidTimestamps + * @covers MWTimestamp::getTimestamp */ - function testValidOutput( $format, $expected, $original ) { + public function testValidOutput( $format, $expected, $original ) { $timestamp = new MWTimestamp( $original ); $this->assertEquals( $expected, (string)$timestamp->getTimestamp( $format ) ); } @@ -36,33 +34,23 @@ class TimestampTest extends MediaWikiTestCase { /** * Test an invalid timestamp. * @expectedException TimestampException + * @covers MWTimestamp */ - function testInvalidParse() { - $timestamp = new MWTimestamp( "This is not a timestamp." ); + public function testInvalidParse() { + new MWTimestamp( "This is not a timestamp." ); } /** * Test requesting an invalid output format. * @expectedException TimestampException + * @covers MWTimestamp::getTimestamp */ - function testInvalidOutput() { + public function testInvalidOutput() { $timestamp = new MWTimestamp( '1343761268' ); $timestamp->getTimestamp( 98 ); } /** - * Test human readable timestamp format. - */ - function testHumanOutput() { - $timestamp = new MWTimestamp( time() - 3600 ); - $this->assertEquals( "1 hour ago", $timestamp->getHumanTimestamp()->inLanguage( 'en' )->text() ); - $timestamp = new MWTimestamp( time() - 5184000 ); - $this->assertEquals( "2 months ago", $timestamp->getHumanTimestamp()->inLanguage( 'en' )->text() ); - $timestamp = new MWTimestamp( time() - 31536000 ); - $this->assertEquals( "1 year ago", $timestamp->getHumanTimestamp()->inLanguage( 'en' )->text() ); - } - - /** * Returns a list of valid timestamps in the format: * array( type, timestamp_of_type, timestamp_in_MW ) */ @@ -83,4 +71,234 @@ class TimestampTest extends MediaWikiTestCase { array( TS_UNIX, '-62135596801', '00001231235959' ) ); } + + /** + * @dataProvider provideHumanTimestampTests + * @covers MWTimestamp::getHumanTimestamp + */ + public function testHumanTimestamp( + $tsTime, // The timestamp to format + $currentTime, // The time to consider "now" + $timeCorrection, // The time offset to use + $dateFormat, // The date preference to use + $expectedOutput, // The expected output + $desc // Description + ) { + $user = $this->getMock( 'User' ); + $user->expects( $this->any() ) + ->method( 'getOption' ) + ->with( 'timecorrection' ) + ->will( $this->returnValue( $timeCorrection ) ); + + $user->expects( $this->any() ) + ->method( 'getDatePreference' ) + ->will( $this->returnValue( $dateFormat ) ); + + $tsTime = new MWTimestamp( $tsTime ); + $currentTime = new MWTimestamp( $currentTime ); + + $this->assertEquals( + $expectedOutput, + $tsTime->getHumanTimestamp( $currentTime, $user ), + $desc + ); + } + + public static function provideHumanTimestampTests() { + return array( + array( + '20111231170000', + '20120101000000', + 'Offset|0', + 'mdy', + 'Yesterday at 17:00', + '"Yesterday" across years', + ), + array( + '20120717190900', + '20120717190929', + 'Offset|0', + 'mdy', + 'just now', + '"Just now"', + ), + array( + '20120717190900', + '20120717191530', + 'Offset|0', + 'mdy', + '6 minutes ago', + 'X minutes ago', + ), + array( + '20121006173100', + '20121006173200', + 'Offset|0', + 'mdy', + '1 minute ago', + '"1 minute ago"', + ), + array( + '20120617190900', + '20120717190900', + 'Offset|0', + 'mdy', + 'June 17', + 'Another month' + ), + array( + '19910130151500', + '20120716193700', + 'Offset|0', + 'mdy', + '15:15, January 30, 1991', + 'Different year', + ), + array( + '20120101050000', + '20120101080000', + 'Offset|-360', + 'mdy', + 'Yesterday at 23:00', + '"Yesterday" across years with time correction', + ), + array( + '20120714184300', + '20120716184300', + 'Offset|-420', + 'mdy', + 'Saturday at 11:43', + 'Recent weekday with time correction', + ), + array( + '20120714184300', + '20120715040000', + 'Offset|-420', + 'mdy', + '11:43', + 'Today at another time with time correction', + ), + array( + '20120617190900', + '20120717190900', + 'Offset|0', + 'dmy', + '17 June', + 'Another month with dmy' + ), + array( + '20120617190900', + '20120717190900', + 'Offset|0', + 'ISO 8601', + '06-17', + 'Another month with ISO-8601' + ), + array( + '19910130151500', + '20120716193700', + 'Offset|0', + 'ISO 8601', + '1991-01-30T15:15:00', + 'Different year with ISO-8601', + ), + ); + } + + /** + * @dataProvider provideRelativeTimestampTests + * @covers MWTimestamp::getRelativeTimestamp + */ + public function testRelativeTimestamp( + $tsTime, // The timestamp to format + $currentTime, // The time to consider "now" + $timeCorrection, // The time offset to use + $dateFormat, // The date preference to use + $expectedOutput, // The expected output + $desc // Description + ) { + $user = $this->getMock( 'User' ); + $user->expects( $this->any() ) + ->method( 'getOption' ) + ->with( 'timecorrection' ) + ->will( $this->returnValue( $timeCorrection ) ); + + $tsTime = new MWTimestamp( $tsTime ); + $currentTime = new MWTimestamp( $currentTime ); + + $this->assertEquals( + $expectedOutput, + $tsTime->getRelativeTimestamp( $currentTime, $user ), + $desc + ); + } + + public static function provideRelativeTimestampTests() { + return array( + array( + '20111231170000', + '20120101000000', + 'Offset|0', + 'mdy', + '7 hours ago', + '"Yesterday" across years', + ), + array( + '20120717190900', + '20120717190929', + 'Offset|0', + 'mdy', + '29 seconds ago', + '"Just now"', + ), + array( + '20120717190900', + '20120717191530', + 'Offset|0', + 'mdy', + '6 minutes and 30 seconds ago', + 'Combination of multiple units', + ), + array( + '20121006173100', + '20121006173200', + 'Offset|0', + 'mdy', + '1 minute ago', + '"1 minute ago"', + ), + array( + '19910130151500', + '20120716193700', + 'Offset|0', + 'mdy', + '2 decades, 1 year, 168 days, 2 hours, 8 minutes and 48 seconds ago', + 'A long time ago', + ), + array( + '20120101050000', + '20120101080000', + 'Offset|-360', + 'mdy', + '3 hours ago', + '"Yesterday" across years with time correction', + ), + array( + '20120714184300', + '20120716184300', + 'Offset|-420', + 'mdy', + '2 days ago', + 'Recent weekday with time correction', + ), + array( + '20120714184300', + '20120715040000', + 'Offset|-420', + 'mdy', + '9 hours and 17 minutes ago', + 'Today at another time with time correction', + ), + ); + } } diff --git a/tests/phpunit/includes/TitleMethodsTest.php b/tests/phpunit/includes/TitleMethodsTest.php index 89812c90..3079d73a 100644 --- a/tests/phpunit/includes/TitleMethodsTest.php +++ b/tests/phpunit/includes/TitleMethodsTest.php @@ -6,11 +6,10 @@ * * @note: We don't make assumptions about the main namespace. * But we do expect the Help namespace to contain Wikitext. - * */ class TitleMethodsTest extends MediaWikiTestCase { - public function setup() { + public function setUp() { global $wgContLang; parent::setUp(); @@ -34,7 +33,7 @@ class TitleMethodsTest extends MediaWikiTestCase { $wgContLang->resetNamespaces(); # reset namespace cache } - public function teardown() { + public function tearDown() { global $wgContLang; parent::tearDown(); @@ -57,6 +56,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideEquals + * @covers Title::equals */ public function testEquals( $titleA, $titleB, $expectedBool ) { $titleA = Title::newFromText( $titleA ); @@ -81,12 +81,16 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideInNamespace + * @covers Title::inNamespace */ public function testInNamespace( $title, $ns, $expectedBool ) { $title = Title::newFromText( $title ); $this->assertEquals( $expectedBool, $title->inNamespace( $ns ) ); } + /** + * @covers Title::inNamespaces + */ public function testInNamespaces() { $mainpage = Title::newFromText( 'Main Page' ); $this->assertTrue( $mainpage->inNamespaces( NS_MAIN, NS_USER ) ); @@ -110,6 +114,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideHasSubjectNamespace + * @covers Title::hasSubjectNamespace */ public function testHasSubjectNamespace( $title, $ns, $expectedBool ) { $title = Title::newFromText( $title ); @@ -143,6 +148,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider dataGetContentModel + * @covers Title::getContentModel */ public function testGetContentModel( $title, $expectedModelId ) { $title = Title::newFromText( $title ); @@ -151,6 +157,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider dataGetContentModel + * @covers Title::hasContentModel */ public function testHasContentModel( $title, $expectedModelId ) { $title = Title::newFromText( $title ); @@ -181,13 +188,13 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsCssOrJsPage + * @covers Title::isCssOrJsPage */ public function testIsCssOrJsPage( $title, $expectedBool ) { $title = Title::newFromText( $title ); $this->assertEquals( $expectedBool, $title->isCssOrJsPage() ); } - public static function provideIsCssJsSubpage() { return array( array( 'Help:Foo', false ), @@ -210,6 +217,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsCssJsSubpage + * @covers Title::isCssJsSubpage */ public function testIsCssJsSubpage( $title, $expectedBool ) { $title = Title::newFromText( $title ); @@ -230,6 +238,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsCssSubpage + * @covers Title::isCssSubpage */ public function testIsCssSubpage( $title, $expectedBool ) { $title = Title::newFromText( $title ); @@ -250,6 +259,7 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsJsSubpage + * @covers Title::isJsSubpage */ public function testIsJsSubpage( $title, $expectedBool ) { $title = Title::newFromText( $title ); @@ -281,10 +291,10 @@ class TitleMethodsTest extends MediaWikiTestCase { /** * @dataProvider provideIsWikitextPage + * @covers Title::isWikitextPage */ public function testIsWikitextPage( $title, $expectedBool ) { $title = Title::newFromText( $title ); $this->assertEquals( $expectedBool, $title->isWikitextPage() ); } - } diff --git a/tests/phpunit/includes/TitlePermissionTest.php b/tests/phpunit/includes/TitlePermissionTest.php index e2c079a7..f15c1772 100644 --- a/tests/phpunit/includes/TitlePermissionTest.php +++ b/tests/phpunit/includes/TitlePermissionTest.php @@ -2,6 +2,7 @@ /** * @group Database + * @todo covers tags */ class TitlePermissionTest extends MediaWikiLangTestCase { @@ -66,10 +67,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->user = $this->userUser; } - } - function setUserPerm( $perm ) { + protected function setUserPerm( $perm ) { // Setting member variables is evil!!! if ( is_array( $perm ) ) { @@ -79,11 +79,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { } } - function setTitle( $ns, $title = "Main_Page" ) { + protected function setTitle( $ns, $title = "Main_Page" ) { $this->title = Title::makeTitle( $ns, $title ); } - function setUser( $userName = null ) { + protected function setUser( $userName = null ) { if ( $userName === 'anon' ) { $this->user = $this->anonUser; } elseif ( $userName === null || $userName === $this->userName ) { @@ -93,7 +93,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { } } - function testQuickPermissions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testQuickPermissions() { global $wgContLang; $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); @@ -234,7 +238,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { if ( $this->isWikitextNS( NS_MAIN ) ) { //NOTE: some content models don't allow moving - //@todo: find a Wikitext namespace for testing + // @todo find a Wikitext namespace for testing $this->setTitle( NS_MAIN ); $this->setUser( 'anon' ); @@ -317,12 +321,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->userCan( $action, $this->user, true ) ); $this->assertEquals( $check[$action][3], $this->title->quickUserCan( $action, $this->user ) ); - # count( User::getGroupsWithPermissions( $action ) ) < 1 } } - function runGroupPermissions( $action, $result, $result2 = null ) { + protected function runGroupPermissions( $action, $result, $result2 = null ) { global $wgGroupPermissions; if ( $result2 === null ) { @@ -350,7 +353,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->assertEquals( $result2, $res ); } - function testSpecialsAndNSPermissions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testSpecialsAndNSPermissions() { global $wgNamespaceProtection; $this->setUser( $this->userName ); @@ -401,44 +408,85 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->userCan( 'bogus', $this->user ) ); } - function testCssAndJavascriptPermissions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testCssAndJavascriptPermissions() { $this->setUser( $this->userName ); + $this->setTitle( NS_USER, $this->userName . '/test.js' ); + $this->runCSSandJSPermissions( + array( array( 'badaccess-group0' ), array( 'mycustomjsprotected' ) ), + array( array( 'badaccess-group0' ), array( 'mycustomjsprotected' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ), array( 'mycustomjsprotected' ) ), + array( array( 'badaccess-group0' ) ) + ); + + $this->setTitle( NS_USER, $this->userName . '/test.css' ); + $this->runCSSandJSPermissions( + array( array( 'badaccess-group0' ), array( 'mycustomcssprotected' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ), array( 'mycustomcssprotected' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ), array( 'mycustomcssprotected' ) ) + ); + $this->setTitle( NS_USER, $this->altUserName . '/test.js' ); $this->runCSSandJSPermissions( array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), - array( array( 'badaccess-group0' ) ) ); + array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), + array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), + array( array( 'badaccess-group0' ) ) + ); $this->setTitle( NS_USER, $this->altUserName . '/test.css' ); $this->runCSSandJSPermissions( array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ), + array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ), + array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ), array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ) ); + array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ) + ); $this->setTitle( NS_USER, $this->altUserName . '/tempo' ); $this->runCSSandJSPermissions( array( array( 'badaccess-group0' ) ), array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ) ) ); + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ) ) + ); } - function runCSSandJSPermissions( $result0, $result1, $result2 ) { + protected function runCSSandJSPermissions( $result0, $result1, $result2, $result3, $result4 ) { $this->setUserPerm( '' ); $this->assertEquals( $result0, $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->setUserPerm( 'editusercss' ); + $this->setUserPerm( 'editmyusercss' ); $this->assertEquals( $result1, $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->setUserPerm( 'edituserjs' ); + $this->setUserPerm( 'editmyuserjs' ); $this->assertEquals( $result2, $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); + $this->setUserPerm( 'editusercss' ); + $this->assertEquals( $result3, + $this->title->getUserPermissionsErrors( 'bogus', + $this->user ) ); + + $this->setUserPerm( 'edituserjs' ); + $this->assertEquals( $result4, + $this->title->getUserPermissionsErrors( 'bogus', + $this->user ) ); + $this->setUserPerm( 'editusercssjs' ); $this->assertEquals( array( array( 'badaccess-group0' ) ), $this->title->getUserPermissionsErrors( 'bogus', @@ -450,7 +498,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->user ) ); } - function testPageRestrictions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testPageRestrictions() { global $wgContLang; $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); @@ -471,39 +523,59 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->assertEquals( array( array( 'badaccess-group0' ), array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'editprotected' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'editprotected' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); $this->setUserPerm( "" ); $this->assertEquals( array( array( 'badaccess-group0' ), array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'editprotected' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ), array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'editprotected' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); $this->setUserPerm( array( "edit", "editprotected" ) ); $this->assertEquals( array( array( 'badaccess-group0' ), array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->assertEquals( array(), + $this->assertEquals( array( + array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'protect' ) ), $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); + $this->title->mCascadeRestriction = true; + $this->setUserPerm( "edit" ); + $this->assertEquals( false, + $this->title->quickUserCan( 'bogus', $this->user ) ); + $this->assertEquals( false, + $this->title->quickUserCan( 'edit', $this->user ) ); + $this->assertEquals( array( array( 'badaccess-group0' ), + array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'editprotected' ), + array( 'protectedpagetext', 'protect' ) ), + $this->title->getUserPermissionsErrors( 'bogus', + $this->user ) ); + $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'editprotected' ), + array( 'protectedpagetext', 'protect' ) ), + $this->title->getUserPermissionsErrors( 'edit', + $this->user ) ); + + $this->setUserPerm( array( "edit", "editprotected" ) ); $this->assertEquals( false, $this->title->quickUserCan( 'bogus', $this->user ) ); $this->assertEquals( false, @@ -521,7 +593,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->user ) ); } - function testCascadingSourcesRestrictions() { + public function testCascadingSourcesRestrictions() { $this->setTitle( NS_MAIN, "test page" ); $this->setUserPerm( array( "edit", "bogus" ) ); @@ -531,6 +603,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->assertEquals( false, $this->title->userCan( 'bogus', $this->user ) ); $this->assertEquals( array( array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ), + array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ), array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ), $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); @@ -538,10 +611,13 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->userCan( 'edit', $this->user ) ); $this->assertEquals( array(), $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); - } - function testActionPermissions() { + /** + * @todo This test method should be split up into separate test methods and + * data providers + */ + public function testActionPermissions() { $this->setUserPerm( array( "createpage" ) ); $this->setTitle( NS_MAIN, "test page" ); $this->title->mTitleProtection['pt_create_perm'] = ''; @@ -557,12 +633,17 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->mTitleProtection['pt_create_perm'] = 'sysop'; $this->setUserPerm( array( 'createpage', 'protect' ) ); + $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), + $this->title->getUserPermissionsErrors( 'create', $this->user ) ); + $this->assertEquals( false, + $this->title->userCan( 'create', $this->user ) ); + + $this->setUserPerm( array( 'createpage', 'editprotected' ) ); $this->assertEquals( array(), $this->title->getUserPermissionsErrors( 'create', $this->user ) ); $this->assertEquals( true, $this->title->userCan( 'create', $this->user ) ); - $this->setUserPerm( array( 'createpage' ) ); $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), $this->title->getUserPermissionsErrors( 'create', $this->user ) ); @@ -605,10 +686,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); $this->assertEquals( false, $this->title->userCan( 'move-target', $this->user ) ); - } - function testUserBlock() { + public function testUserBlock() { global $wgEmailConfirmToEdit, $wgEmailAuthentication; $wgEmailConfirmToEdit = true; $wgEmailAuthentication = true; @@ -648,13 +728,13 @@ class TitlePermissionTest extends MediaWikiLangTestCase { global $wgLocalTZoffset; $wgLocalTZoffset = -60; $this->user->mBlockedby = $this->user->getName(); - $this->user->mBlock = new Block( '127.0.8.1', 0, 1, 'no reason given', $now, 0, 10 ); + $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(), + 'no reason given', $now, 0, 10 ); $this->assertEquals( array( array( 'blockedtext', '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', 'Useruser', null, '23:00, 31 December 1969', '127.0.8.1', $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ) ), $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this ) # $user->blockedFor() == '' # $user->mBlock->mExpiry == 'infinity' diff --git a/tests/phpunit/includes/TitleTest.php b/tests/phpunit/includes/TitleTest.php index a9067852..6bfe5453 100644 --- a/tests/phpunit/includes/TitleTest.php +++ b/tests/phpunit/includes/TitleTest.php @@ -1,7 +1,6 @@ <?php /** - * * @group Database * ^--- needed for language cache stuff */ @@ -19,7 +18,10 @@ class TitleTest extends MediaWikiTestCase { ) ); } - function testLegalChars() { + /** + * @covers Title::legalChars + */ + public function testLegalChars() { $titlechars = Title::legalChars(); foreach ( range( 1, 255 ) as $num ) { @@ -33,12 +35,160 @@ class TitleTest extends MediaWikiTestCase { } /** + * See also mediawiki.Title.test.js + * @covers Title::secureAndSplit + * @todo This method should be split into 2 separate tests each with a provider + */ + public function testSecureAndSplit() { + // Valid + foreach ( array( + 'Sandbox', + 'A "B"', + 'A \'B\'', + '.com', + '~', + '"', + '\'', + 'Talk:Sandbox', + 'Talk:Foo:Sandbox', + 'File:Example.svg', + 'File_talk:Example.svg', + 'Foo/.../Sandbox', + 'Sandbox/...', + 'A~~', + // Length is 256 total, but only title part matters + 'Category:' . str_repeat( 'x', 248 ), + str_repeat( 'x', 252 ) + ) as $text ) { + $this->assertInstanceOf( 'Title', Title::newFromText( $text ), "Valid: $text" ); + } + + // Invalid + foreach ( array( + '', + '__ __', + ' __ ', + // Bad characters forbidden regardless of wgLegalTitleChars + 'A [ B', + 'A ] B', + 'A { B', + 'A } B', + 'A < B', + 'A > B', + 'A | B', + // URL encoding + 'A%20B', + 'A%23B', + 'A%2523B', + // XML/HTML character entity references + // Note: Commented out because they are not marked invalid by the PHP test as + // Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first. + //'A é B', + //'A é B', + //'A é B', + // Subject of NS_TALK does not roundtrip to NS_MAIN + 'Talk:File:Example.svg', + // Directory navigation + '.', + '..', + './Sandbox', + '../Sandbox', + 'Foo/./Sandbox', + 'Foo/../Sandbox', + 'Sandbox/.', + 'Sandbox/..', + // Tilde + 'A ~~~ Name', + 'A ~~~~ Signature', + 'A ~~~~~ Timestamp', + str_repeat( 'x', 256 ), + // Namespace prefix without actual title + // ':', // bug 54044 + 'Talk:', + 'Category: ', + 'Category: #bar' + ) as $text ) { + $this->assertNull( Title::newFromText( $text ), "Invalid: $text" ); + } + } + + public static function provideConvertByteClassToUnicodeClass() { + return array( + array( + ' %!"$&\'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+', + ' %!"$&\'()*,\\-./0-9:;=?@A-Z\\\\\\^_`a-z~+\\u0080-\\uFFFF', + ), + array( + 'QWERTYf-\\xFF+', + 'QWERTYf-\\x7F+\\u0080-\\uFFFF', + ), + array( + 'QWERTY\\x66-\\xFD+', + 'QWERTYf-\\x7F+\\u0080-\\uFFFF', + ), + array( + 'QWERTYf-y+', + 'QWERTYf-y+', + ), + array( + 'QWERTYf-\\x80+', + 'QWERTYf-\\x7F+\\u0080-\\uFFFF', + ), + array( + 'QWERTY\\x66-\\x80+\\x23', + 'QWERTYf-\\x7F+#\\u0080-\\uFFFF', + ), + array( + 'QWERTY\\x66-\\x80+\\xD3', + 'QWERTYf-\\x7F+\\u0080-\\uFFFF', + ), + array( + '\\\\\\x99', + '\\\\\\u0080-\\uFFFF', + ), + array( + '-\\x99', + '\\-\\u0080-\\uFFFF', + ), + array( + 'QWERTY\\-\\x99', + 'QWERTY\\-\\u0080-\\uFFFF', + ), + array( + '\\\\x99', + '\\\\x99', + ), + array( + 'A-\\x9F', + 'A-\\x7F\\u0080-\\uFFFF', + ), + array( + '\\x66-\\x77QWERTY\\x88-\\x91FXZ', + 'f-wQWERTYFXZ\\u0080-\\uFFFF', + ), + array( + '\\x66-\\x99QWERTY\\xAA-\\xEEFXZ', + 'f-\\x7FQWERTYFXZ\\u0080-\\uFFFF', + ), + ); + } + + /** + * @dataProvider provideConvertByteClassToUnicodeClass + * @covers Title::convertByteClassToUnicodeClass + */ + public function testConvertByteClassToUnicodeClass( $byteClass, $unicodeClass ) { + $this->assertEquals( $unicodeClass, Title::convertByteClassToUnicodeClass( $byteClass ) ); + } + + /** * @dataProvider provideBug31100 + * @covers Title::fixSpecialName */ - function testBug31100FixSpecialName( $text, $expectedParam ) { + public function testBug31100FixSpecialName( $text, $expectedParam ) { $title = Title::newFromText( $text ); $fixed = $title->fixSpecialName(); - $stuff = explode( '/', $fixed->getDbKey(), 2 ); + $stuff = explode( '/', $fixed->getDBkey(), 2 ); if ( count( $stuff ) == 2 ) { $par = $stuff[1]; } else { @@ -61,10 +211,11 @@ class TitleTest extends MediaWikiTestCase { * @group Database * @param string $source * @param string $target - * @param array|string|true $expected Required error + * @param array|string|bool $expected Required error * @dataProvider provideTestIsValidMoveOperation + * @covers Title::isValidMoveOperation */ - function testIsValidMoveOperation( $source, $target, $expected ) { + public function testIsValidMoveOperation( $source, $target, $expected ) { $title = Title::newFromText( $source ); $nt = Title::newFromText( $target ); $errors = $title->isValidMoveOperation( $nt, false ); @@ -81,7 +232,7 @@ class TitleTest extends MediaWikiTestCase { /** * Provides test parameter values for testIsValidMoveOperation() */ - function dataTestIsValidMoveOperation() { + public function dataTestIsValidMoveOperation() { return array( array( 'Test', 'Test', 'selfmove' ), array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ) @@ -94,12 +245,12 @@ class TitleTest extends MediaWikiTestCase { * @param array $whitelistRegexp * @param string $source * @param string $action - * @param array|string|true $expected Required error + * @param array|string|bool $expected Required error * * @covers Title::checkReadPermissions * @dataProvider dataWgWhitelistReadRegexp */ - function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) { + public function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) { // $wgWhitelistReadRegexp must be an array. Since the provided test cases // usually have only one regex, it is more concise to write the lonely regex // as a string. Thus we cast to an array() to honor $wgWhitelistReadRegexp @@ -156,7 +307,7 @@ class TitleTest extends MediaWikiTestCase { /** * Provides test parameter values for testWgWhitelistReadRegexp() */ - function dataWgWhitelistReadRegexp() { + public function dataWgWhitelistReadRegexp() { $ALLOWED = true; $DISALLOWED = false; @@ -192,11 +343,12 @@ class TitleTest extends MediaWikiTestCase { ); } - function flattenErrorsArray( $errors ) { + public function flattenErrorsArray( $errors ) { $result = array(); foreach ( $errors as $error ) { $result[] = $error[0]; } + return $result; } @@ -208,9 +360,10 @@ class TitleTest extends MediaWikiTestCase { } /** - * @dataProvider provideCasesForGetpageviewlanguage + * @dataProvider provideGetPageViewLanguage + * @covers Title::getPageViewLanguage */ - function testGetpageviewlanguage( $expected, $titleText, $contLang, $lang, $variant, $msg = '' ) { + public function testGetPageViewLanguage( $expected, $titleText, $contLang, $lang, $variant, $msg = '' ) { global $wgLanguageCode, $wgContLang, $wgLang, $wgDefaultLanguageVariant, $wgAllowUserJs; // Setup environnement for this test @@ -230,7 +383,7 @@ class TitleTest extends MediaWikiTestCase { ); } - function provideCasesForGetpageviewlanguage() { + public static function provideGetPageViewLanguage() { # Format: # - expected # - Title name @@ -271,8 +424,9 @@ class TitleTest extends MediaWikiTestCase { /** * @dataProvider provideBaseTitleCases + * @covers Title::getBaseText */ - function testExtractingBaseTextFromTitle( $title, $expected, $msg = '' ) { + public function testGetBaseText( $title, $expected, $msg = '' ) { $title = Title::newFromText( $title ); $this->assertEquals( $expected, $title->getBaseText(), @@ -280,7 +434,7 @@ class TitleTest extends MediaWikiTestCase { ); } - function provideBaseTitleCases() { + public static function provideBaseTitleCases() { return array( # Title, expected base, optional message array( 'User:John_Doe/subOne/subTwo', 'John Doe/subOne' ), @@ -290,8 +444,9 @@ class TitleTest extends MediaWikiTestCase { /** * @dataProvider provideRootTitleCases + * @covers Title::getRootText */ - function testExtractingRootTextFromTitle( $title, $expected, $msg = '' ) { + public function testGetRootText( $title, $expected, $msg = '' ) { $title = Title::newFromText( $title ); $this->assertEquals( $expected, $title->getRootText(), @@ -310,8 +465,9 @@ class TitleTest extends MediaWikiTestCase { /** * @todo Handle $wgNamespacesWithSubpages cases * @dataProvider provideSubpageTitleCases + * @covers Title::getSubpageText */ - function testExtractingSubpageTextFromTitle( $title, $expected, $msg = '' ) { + public function testGetSubpageText( $title, $expected, $msg = '' ) { $title = Title::newFromText( $title ); $this->assertEquals( $expected, $title->getSubpageText(), @@ -319,7 +475,7 @@ class TitleTest extends MediaWikiTestCase { ); } - function provideSubpageTitleCases() { + public static function provideSubpageTitleCases() { return array( # Title, expected base, optional message array( 'User:John_Doe/subOne/subTwo', 'subTwo' ), diff --git a/tests/phpunit/includes/UIDGeneratorTest.php b/tests/phpunit/includes/UIDGeneratorTest.php index 23553ca7..8f78ae51 100644 --- a/tests/phpunit/includes/UIDGeneratorTest.php +++ b/tests/phpunit/includes/UIDGeneratorTest.php @@ -1,8 +1,11 @@ <?php class UIDGeneratorTest extends MediaWikiTestCase { + /** * @dataProvider provider_testTimestampedUID + * @covers UIDGenerator::newTimestampedUID128 + * @covers UIDGenerator::newTimestampedUID88 */ public function testTimestampedUID( $method, $digitlen, $bits, $tbits, $hostbits ) { $id = call_user_func( array( 'UIDGenerator', $method ) ); @@ -46,6 +49,7 @@ class UIDGeneratorTest extends MediaWikiTestCase { /** * array( method, length, bits, hostbits ) + * NOTE: When adding a new method name here please update the covers tags for the tests! */ public static function provider_testTimestampedUID() { return array( @@ -55,22 +59,40 @@ class UIDGeneratorTest extends MediaWikiTestCase { ); } + /** + * @covers UIDGenerator::newUUIDv4 + */ public function testUUIDv4() { for ( $i = 0; $i < 100; $i++ ) { $id = UIDGenerator::newUUIDv4(); $this->assertEquals( true, preg_match( '!^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$!', $id ), "UID $id has the right format" ); + } + } + /** + * @covers UIDGenerator::newRawUUIDv4 + */ + public function testRawUUIDv4() { + for ( $i = 0; $i < 100; $i++ ) { $id = UIDGenerator::newRawUUIDv4(); $this->assertEquals( true, preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ), "UID $id has the right format" ); + } + } + /** + * @covers UIDGenerator::newRawUUIDv4 + */ + public function testRawUUIDv4QuickRand() { + for ( $i = 0; $i < 100; $i++ ) { $id = UIDGenerator::newRawUUIDv4( UIDGenerator::QUICK_RAND ); $this->assertEquals( true, preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ), "UID $id has the right format" ); } } + } diff --git a/tests/phpunit/includes/UserMailerTest.php b/tests/phpunit/includes/UserMailerTest.php new file mode 100644 index 00000000..278edfaa --- /dev/null +++ b/tests/phpunit/includes/UserMailerTest.php @@ -0,0 +1,14 @@ +<?php + +class UserMailerTest extends MediaWikiLangTestCase { + + /** + * @covers UserMailer::quotedPrintable + */ + public function testQuotedPrintable() { + $this->assertEquals( + "=?UTF-8?Q?=C4=88u=20legebla=3F?=", + UserMailer::quotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) ); + } + +}
\ No newline at end of file diff --git a/tests/phpunit/includes/UserTest.php b/tests/phpunit/includes/UserTest.php index e777179a..ff33e825 100644 --- a/tests/phpunit/includes/UserTest.php +++ b/tests/phpunit/includes/UserTest.php @@ -46,8 +46,16 @@ class UserTest extends MediaWikiTestCase { $wgRevokePermissions['formertesters'] = array( 'runtest' => true, ); + + # For the options test + $wgGroupPermissions['*'] = array( + 'editmyoptions' => true, + ); } + /** + * @covers User::getGroupPermissions + */ public function testGroupPermissions() { $rights = User::getGroupPermissions( array( 'unittesters' ) ); $this->assertContains( 'runtest', $rights ); @@ -62,6 +70,9 @@ class UserTest extends MediaWikiTestCase { $this->assertNotContains( 'nukeworld', $rights ); } + /** + * @covers User::getGroupPermissions + */ public function testRevokePermissions() { $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) ); $this->assertNotContains( 'runtest', $rights ); @@ -70,6 +81,9 @@ class UserTest extends MediaWikiTestCase { $this->assertNotContains( 'nukeworld', $rights ); } + /** + * @covers User::getRights + */ public function testUserPermissions() { $rights = $this->user->getRights(); $this->assertContains( 'runtest', $rights ); @@ -80,6 +94,7 @@ class UserTest extends MediaWikiTestCase { /** * @dataProvider provideGetGroupsWithPermission + * @covers User::getGroupsWithPermission */ public function testGetGroupsWithPermission( $expected, $right ) { $result = User::getGroupsWithPermission( $right ); @@ -112,6 +127,7 @@ class UserTest extends MediaWikiTestCase { /** * @dataProvider provideUserNames + * @covers User::isValidUserName */ public function testIsValidUserName( $username, $result, $message ) { $this->assertEquals( $this->user->isValidUserName( $username ), $result, $message ); @@ -166,6 +182,7 @@ class UserTest extends MediaWikiTestCase { /** * Test User::editCount * @group medium + * @covers User::getEditCount */ public function testEditCount() { $user = User::newFromName( 'UnitTestUser' ); @@ -190,6 +207,8 @@ class UserTest extends MediaWikiTestCase { /** * Test changing user options. + * @covers User::setOption + * @covers User::getOption */ public function testOptions() { $user = User::newFromName( 'UnitTestUser' ); @@ -207,6 +226,7 @@ class UserTest extends MediaWikiTestCase { /** * Bug 37963 * Make sure defaults are loaded when setOption is called. + * @covers User::loadOptions */ public function testAnonOptions() { global $wgDefaultUserOptions; diff --git a/tests/phpunit/includes/WebRequestTest.php b/tests/phpunit/includes/WebRequestTest.php index 46f80255..f8ed14b6 100644 --- a/tests/phpunit/includes/WebRequestTest.php +++ b/tests/phpunit/includes/WebRequestTest.php @@ -1,5 +1,8 @@ <?php +/** + * @group WebRequest + */ class WebRequestTest extends MediaWikiTestCase { protected $oldServer; @@ -17,8 +20,9 @@ class WebRequestTest extends MediaWikiTestCase { /** * @dataProvider provideDetectServer + * @covers WebRequest::detectServer */ - function testDetectServer( $expected, $input, $description ) { + public function testDetectServer( $expected, $input, $description ) { $_SERVER = $input; $result = WebRequest::detectServer(); $this->assertEquals( $expected, $result, $description ); @@ -100,12 +104,23 @@ class WebRequestTest extends MediaWikiTestCase { /** * @dataProvider provideGetIP + * @covers WebRequest::getIP */ - function testGetIP( $expected, $input, $squid, $private, $description ) { - global $wgSquidServersNoPurge, $wgUsePrivateIPs; + public function testGetIP( $expected, $input, $squid, $xffList, $private, $description ) { $_SERVER = $input; - $wgSquidServersNoPurge = $squid; - $wgUsePrivateIPs = $private; + $this->setMwGlobals( array( + 'wgSquidServersNoPurge' => $squid, + 'wgUsePrivateIPs' => $private, + 'wgHooks' => array( + 'IsTrustedProxy' => array( + function( &$ip, &$trusted ) use ( $xffList ) { + $trusted = $trusted || in_array( $ip, $xffList ); + return true; + } + ) + ) + ) ); + $request = new WebRequest(); $result = $request->getIP(); $this->assertEquals( $expected, $result, $description ); @@ -119,6 +134,7 @@ class WebRequestTest extends MediaWikiTestCase { 'REMOTE_ADDR' => '127.0.0.1' ), array(), + array(), false, 'Simple IPv4' ), @@ -128,16 +144,29 @@ class WebRequestTest extends MediaWikiTestCase { 'REMOTE_ADDR' => '::1' ), array(), + array(), false, 'Simple IPv6' ), array( + '12.0.0.1', + array( + 'REMOTE_ADDR' => 'abcd:0001:002:03:4:555:6666:7777', + 'HTTP_X_FORWARDED_FOR' => '12.0.0.1, abcd:0001:002:03:4:555:6666:7777', + ), + array( 'ABCD:1:2:3:4:555:6666:7777' ), + array(), + false, + 'IPv6 normalisation' + ), + array( '12.0.0.3', array( 'REMOTE_ADDR' => '12.0.0.1', 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' ), array( '12.0.0.1', '12.0.0.2' ), + array(), false, 'With X-Forwaded-For' ), @@ -148,6 +177,7 @@ class WebRequestTest extends MediaWikiTestCase { 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' ), array(), + array(), false, 'With X-Forwaded-For and disallowed server' ), @@ -158,36 +188,95 @@ class WebRequestTest extends MediaWikiTestCase { 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' ), array( '12.0.0.1' ), + array(), false, 'With multiple X-Forwaded-For and only one allowed server' ), array( - '12.0.0.2', + '10.0.0.3', array( 'REMOTE_ADDR' => '12.0.0.2', - 'HTTP_X_FORWARDED_FOR' => '10.0.0.3, 12.0.0.2' + 'HTTP_X_FORWARDED_FOR' => '10.0.0.4, 10.0.0.3, 12.0.0.2' ), array( '12.0.0.1', '12.0.0.2' ), + array(), false, - 'With X-Forwaded-For and private IP' + 'With X-Forwaded-For and private IP (from cache proxy)' ), array( - '10.0.0.3', + '10.0.0.4', array( 'REMOTE_ADDR' => '12.0.0.2', - 'HTTP_X_FORWARDED_FOR' => '10.0.0.3, 12.0.0.2' + 'HTTP_X_FORWARDED_FOR' => '10.0.0.4, 10.0.0.3, 12.0.0.2' + ), + array( '12.0.0.1', '12.0.0.2', '10.0.0.3' ), + array(), + true, + 'With X-Forwaded-For and private IP (allowed)' + ), + array( + '10.0.0.4', + array( + 'REMOTE_ADDR' => '12.0.0.2', + 'HTTP_X_FORWARDED_FOR' => '10.0.0.4, 10.0.0.3, 12.0.0.2' ), array( '12.0.0.1', '12.0.0.2' ), + array( '10.0.0.3' ), true, 'With X-Forwaded-For and private IP (allowed)' ), + array( + '10.0.0.3', + array( + 'REMOTE_ADDR' => '12.0.0.2', + 'HTTP_X_FORWARDED_FOR' => '10.0.0.4, 10.0.0.3, 12.0.0.2' + ), + array( '12.0.0.1', '12.0.0.2' ), + array( '10.0.0.3' ), + false, + 'With X-Forwaded-For and private IP (disallowed)' + ), + array( + '12.0.0.3', + array( + 'REMOTE_ADDR' => '12.0.0.1', + 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' + ), + array(), + array( '12.0.0.1', '12.0.0.2' ), + false, + 'With X-Forwaded-For' + ), + array( + '12.0.0.2', + array( + 'REMOTE_ADDR' => '12.0.0.1', + 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' + ), + array(), + array( '12.0.0.1' ), + false, + 'With multiple X-Forwaded-For and only one allowed server' + ), + array( + '12.0.0.2', + array( + 'REMOTE_ADDR' => '12.0.0.2', + 'HTTP_X_FORWARDED_FOR' => '10.0.0.3, 12.0.0.2' + ), + array(), + array( '12.0.0.2' ), + false, + 'With X-Forwaded-For and private IP and hook (disallowed)' + ), ); } /** * @expectedException MWException + * @covers WebRequest::getIP */ - function testGetIpLackOfRemoteAddrThrowAnException() { + public function testGetIpLackOfRemoteAddrThrowAnException() { $request = new WebRequest(); # Next call throw an exception about lacking an IP $request->getIP(); @@ -211,8 +300,9 @@ class WebRequestTest extends MediaWikiTestCase { /** * @dataProvider provideLanguageData + * @covers WebRequest::getAcceptLang */ - function testAcceptLang( $acceptLanguageHeader, $expectedLanguages, $description ) { + public function testAcceptLang( $acceptLanguageHeader, $expectedLanguages, $description ) { $_SERVER = array( 'HTTP_ACCEPT_LANGUAGE' => $acceptLanguageHeader ); $request = new WebRequest(); $this->assertSame( $request->getAcceptLang(), $expectedLanguages, $description ); diff --git a/tests/phpunit/includes/WikiPageTest.php b/tests/phpunit/includes/WikiPageTest.php index 2501be33..e0d786b9 100644 --- a/tests/phpunit/includes/WikiPageTest.php +++ b/tests/phpunit/includes/WikiPageTest.php @@ -1,16 +1,16 @@ <?php + /** * @group ContentHandler * @group Database * ^--- important, causes temporary tables to be used instead of the real database * @group medium **/ - class WikiPageTest extends MediaWikiLangTestCase { - var $pages_to_delete; + protected $pages_to_delete; - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed = array_merge( @@ -90,6 +90,9 @@ class WikiPageTest extends MediaWikiLangTestCase { return $page; } + /** + * @covers WikiPage::doEditContent + */ public function testDoEditContent() { $page = $this->newPage( "WikiPageTest_testDoEditContent" ); $title = $page->getTitle(); @@ -143,6 +146,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' ); } + /** + * @covers WikiPage::doEdit + */ public function testDoEdit() { $this->hideDeprecated( "WikiPage::doEdit" ); $this->hideDeprecated( "WikiPage::getText" ); @@ -200,6 +206,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' ); } + /** + * @covers WikiPage::doQuickEdit + */ public function testDoQuickEdit() { global $wgUser; @@ -216,6 +225,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( $text, $page->getText() ); } + /** + * @covers WikiPage::doQuickEditContent + */ public function testDoQuickEditContent() { global $wgUser; @@ -229,6 +241,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertTrue( $content->equals( $page->getContent() ) ); } + /** + * @covers WikiPage::doDeleteArticle + */ public function testDoDeleteArticle() { $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo", CONTENT_MODEL_WIKITEXT ); $id = $page->getId(); @@ -253,6 +268,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' ); } + /** + * @covers WikiPage::doDeleteUpdates + */ public function testDoDeleteUpdates() { $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo", CONTENT_MODEL_WIKITEXT ); $id = $page->getId(); @@ -268,6 +286,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' ); } + /** + * @covers WikiPage::getRevision + */ public function testGetRevision() { $page = $this->newPage( "WikiPageTest_testGetRevision" ); @@ -283,6 +304,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( "some text", $rev->getContent()->getNativeData() ); } + /** + * @covers WikiPage::getContent + */ public function testGetContent() { $page = $this->newPage( "WikiPageTest_testGetContent" ); @@ -296,6 +320,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( "some text", $content->getNativeData() ); } + /** + * @covers WikiPage::getText + */ public function testGetText() { $this->hideDeprecated( "WikiPage::getText" ); @@ -311,6 +338,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( "some text", $text ); } + /** + * @covers WikiPage::getRawText + */ public function testGetRawText() { $this->hideDeprecated( "WikiPage::getRawText" ); @@ -326,6 +356,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( "some text", $text ); } + /** + * @covers WikiPage::getContentModel + */ public function testGetContentModel() { global $wgContentHandlerUseDB; @@ -339,6 +372,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() ); } + /** + * @covers WikiPage::getContentHandler + */ public function testGetContentHandler() { global $wgContentHandlerUseDB; @@ -352,6 +388,9 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertEquals( 'JavaScriptContentHandler', get_class( $page->getContentHandler() ) ); } + /** + * @covers WikiPage::exists + */ public function testExists() { $page = $this->newPage( "WikiPageTest_testExists" ); $this->assertFalse( $page->exists() ); @@ -383,6 +422,7 @@ class WikiPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideHasViewableContent + * @covers WikiPage::hasViewableContent */ public function testHasViewableContent( $title, $viewable, $create = false ) { $page = $this->newPage( $title ); @@ -406,6 +446,7 @@ class WikiPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideGetRedirectTarget + * @covers WikiPage::getRedirectTarget */ public function testGetRedirectTarget( $title, $model, $text, $target ) { $page = $this->createPage( $title, $text, $model ); @@ -421,6 +462,7 @@ class WikiPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideGetRedirectTarget + * @covers WikiPage::isRedirect */ public function testIsRedirect( $title, $model, $text, $target ) { $page = $this->createPage( $title, $text, $model ); @@ -537,6 +579,7 @@ class WikiPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideIsCountable + * @covers WikiPage::isCountable */ public function testIsCountable( $title, $model, $text, $mode, $expected ) { global $wgContentHandlerUseDB; @@ -569,12 +612,13 @@ class WikiPageTest extends MediaWikiLangTestCase { public static function provideGetParserOutput() { return array( array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ), - // @todo: more...? + // @todo more...? ); } /** * @dataProvider provideGetParserOutput + * @covers WikiPage::getParserOutput */ public function testGetParserOutput( $model, $text, $expectedHtml ) { $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text, $model ); @@ -587,9 +631,13 @@ class WikiPageTest extends MediaWikiLangTestCase { $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us $this->assertEquals( $expectedHtml, $text ); + return $po; } + /** + * @covers WikiPage::getParserOutput + */ public function testGetParserOutput_nonexisting() { static $count = 0; $count++; @@ -602,13 +650,16 @@ class WikiPageTest extends MediaWikiLangTestCase { $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." ); } + /** + * @covers WikiPage::getParserOutput + */ public function testGetParserOutput_badrev() { $page = $this->createPage( 'WikiPageTest_testGetParserOutput', "dummy", CONTENT_MODEL_WIKITEXT ); $opt = new ParserOptions(); $po = $page->getParserOutput( $opt, $page->getLatest() + 1234 ); - //@todo: would be neat to also test deleted revision + // @todo would be neat to also test deleted revision $this->assertFalse( $po, "getParserOutput() shall return false for non-existing revisions." ); } @@ -678,6 +729,7 @@ more stuff /** * @dataProvider dataReplaceSection + * @covers WikiPage::replaceSection */ public function testReplaceSection( $title, $model, $text, $section, $with, $sectionTitle, $expected ) { $this->hideDeprecated( "WikiPage::replaceSection" ); @@ -691,6 +743,7 @@ more stuff /** * @dataProvider dataReplaceSection + * @covers WikiPage::replaceSectionContent */ public function testReplaceSectionContent( $title, $model, $text, $section, $with, $sectionTitle, $expected ) { $page = $this->createPage( $title, $text, $model ); @@ -801,6 +854,7 @@ more stuff /** * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason. + * @covers WikiPage::doRollback */ public function testDoRollback() { $admin = new User(); @@ -877,6 +931,7 @@ more stuff /** * @dataProvider provideGetAutoSummary + * @covers WikiPage::getAutosummary */ public function testGetAutosummary( $old, $new, $flags, $expected ) { $this->hideDeprecated( "WikiPage::getAutosummary" ); @@ -949,6 +1004,7 @@ more stuff /** * @dataProvider provideGetAutoDeleteReason + * @covers WikiPage::getAutoDeleteReason */ public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) { global $wgUser; @@ -1002,6 +1058,7 @@ more stuff /** * @dataProvider providePreSaveTransform + * @covers WikiPage::preSaveTransform */ public function testPreSaveTransform( $text, $expected ) { $this->hideDeprecated( 'WikiPage::preSaveTransform' ); @@ -1014,5 +1071,4 @@ more stuff $this->assertEquals( $expected, $text ); } - } diff --git a/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php b/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php index 1d937e9b..2a723e85 100644 --- a/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php +++ b/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php @@ -6,16 +6,10 @@ * ^--- important, causes temporary tables to be used instead of the real database */ class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { - var $saveContentHandlerNoDB = null; - - function setUp() { - global $wgContentHandlerUseDB; + protected function setUp() { parent::setUp(); - - $this->saveContentHandlerNoDB = $wgContentHandlerUseDB; - - $wgContentHandlerUseDB = false; + $this->setMwGlobals( 'wgContentHandlerUseDB', false ); $dbw = wfGetDB( DB_MASTER ); @@ -32,14 +26,9 @@ class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { } } - function tearDown() { - global $wgContentHandlerUseDB; - - $wgContentHandlerUseDB = $this->saveContentHandlerNoDB; - - parent::tearDown(); - } - + /** + * @covers WikiPage::getContentModel + */ public function testGetContentModel() { $page = $this->createPage( "WikiPageTest_testGetContentModel", "some text", CONTENT_MODEL_JAVASCRIPT ); @@ -50,6 +39,9 @@ class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { $this->assertEquals( CONTENT_MODEL_WIKITEXT, $page->getContentModel() ); } + /** + * @covers WikiPage::getContentHandler + */ public function testGetContentHandler() { $page = $this->createPage( "WikiPageTest_testGetContentHandler", "some text", CONTENT_MODEL_JAVASCRIPT ); @@ -58,5 +50,4 @@ class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { $page = new WikiPage( $page->getTitle() ); $this->assertEquals( 'WikitextContentHandler', get_class( $page->getContentHandler() ) ); } - } diff --git a/tests/phpunit/includes/XmlJsTest.php b/tests/phpunit/includes/XmlJsTest.php index c5b411fb..161468e2 100644 --- a/tests/phpunit/includes/XmlJsTest.php +++ b/tests/phpunit/includes/XmlJsTest.php @@ -1,9 +1,24 @@ <?php + +/** + * @group Xml + */ class XmlJs extends MediaWikiTestCase { - public function testConstruction() { - $obj = new XmlJsCode( null ); - $this->assertNull( $obj->value ); - $obj = new XmlJsCode( '' ); - $this->assertSame( $obj->value, '' ); + + /** + * @covers XmlJsCode::__construct + * @dataProvider provideConstruction + */ + public function testConstruction( $value ) { + $obj = new XmlJsCode( $value ); + $this->assertEquals( $value, $obj->value ); } + + public function provideConstruction(){ + return array( + array( null ), + array( '' ), + ); + } + } diff --git a/tests/phpunit/includes/XmlSelectTest.php b/tests/phpunit/includes/XmlSelectTest.php index d7227b4d..56d28b54 100644 --- a/tests/phpunit/includes/XmlSelectTest.php +++ b/tests/phpunit/includes/XmlSelectTest.php @@ -1,13 +1,18 @@ <?php -// TODO +/** + * @group Xml + */ class XmlSelectTest extends MediaWikiTestCase { + + /** + * @var XmlSelect + */ protected $select; protected function setUp() { parent::setUp(); $this->setMwGlobals( array( - 'wgHtml5' => true, 'wgWellFormedXml' => true, ) ); $this->select = new XmlSelect(); @@ -18,8 +23,9 @@ class XmlSelectTest extends MediaWikiTestCase { $this->select = null; } - ### START OF TESTS ### - + /** + * @covers XmlSelect::__construct + */ public function testConstructWithoutParameters() { $this->assertEquals( '<select></select>', $this->select->getHTML() ); } @@ -27,6 +33,7 @@ class XmlSelectTest extends MediaWikiTestCase { /** * Parameters are $name (false), $id (false), $default (false) * @dataProvider provideConstructionParameters + * @covers XmlSelect::__construct */ public function testConstructParameters( $name, $id, $default, $expected ) { $this->select = new XmlSelect( $name, $id, $default ); @@ -40,7 +47,6 @@ class XmlSelectTest extends MediaWikiTestCase { * - $id (default: false) * - $default (default: false) * Provides a fourth parameters representing the expected HTML output - * */ public static function provideConstructionParameters() { return array( @@ -61,29 +67,41 @@ class XmlSelectTest extends MediaWikiTestCase { ); } - # Begin XmlSelect::addOption() similar to Xml::option + /** + * @covers XmlSelect::addOption + */ public function testAddOption() { $this->select->addOption( 'foo' ); $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() ); } + /** + * @covers XmlSelect::addOption + */ public function testAddOptionWithDefault() { $this->select->addOption( 'foo', true ); $this->assertEquals( '<select><option value="1">foo</option></select>', $this->select->getHTML() ); } + /** + * @covers XmlSelect::addOption + */ public function testAddOptionWithFalse() { $this->select->addOption( 'foo', false ); $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() ); } + /** + * @covers XmlSelect::addOption + */ public function testAddOptionWithValueZero() { $this->select->addOption( 'foo', 0 ); $this->assertEquals( '<select><option value="0">foo</option></select>', $this->select->getHTML() ); } - # End XmlSelect::addOption() similar to Xml::option - + /** + * @covers XmlSelect::setDefault + */ public function testSetDefault() { $this->select->setDefault( 'bar1' ); $this->select->addOption( 'foo1' ); @@ -99,6 +117,7 @@ class XmlSelectTest extends MediaWikiTestCase { * Adding default later on should set the correct selection or * raise an exception. * To handle this, we need to render the options in getHtml() + * @covers XmlSelect::setDefault */ public function testSetDefaultAfterAddingOptions() { $this->select->addOption( 'foo1' ); @@ -111,6 +130,10 @@ class XmlSelectTest extends MediaWikiTestCase { '<option value="foo2">foo2</option></select>', $this->select->getHTML() ); } + /** + * @covers XmlSelect::setAttribute + * @covers XmlSelect::getAttribute + */ public function testGetAttributes() { # create some attributes $this->select->setAttribute( 'dummy', 0x777 ); diff --git a/tests/phpunit/includes/XmlTest.php b/tests/phpunit/includes/XmlTest.php index f4823287..8205029f 100644 --- a/tests/phpunit/includes/XmlTest.php +++ b/tests/phpunit/includes/XmlTest.php @@ -1,8 +1,9 @@ <?php +/** + * @group Xml + */ class XmlTest extends MediaWikiTestCase { - private static $oldLang; - private static $oldNamespaces; protected function setUp() { parent::setUp(); @@ -29,11 +30,13 @@ class XmlTest extends MediaWikiTestCase { $this->setMwGlobals( array( 'wgLang' => $langObj, - 'wgHtml5' => true, 'wgWellFormedXml' => true, ) ); } + /** + * @covers Xml::expandAttributes + */ public function testExpandAttributes() { $this->assertNull( Xml::expandAttributes( null ), 'Converting a null list of attributes' @@ -43,12 +46,18 @@ class XmlTest extends MediaWikiTestCase { ); } + /** + * @covers Xml::expandAttributes + */ public function testExpandAttributesException() { $this->setExpectedException( 'MWException' ); Xml::expandAttributes( 'string' ); } - function testElementOpen() { + /** + * @covers Xml::element + */ + public function testElementOpen() { $this->assertEquals( '<element>', Xml::element( 'element', null, null ), @@ -56,7 +65,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testElementEmpty() { + /** + * @covers Xml::element + */ + public function testElementEmpty() { $this->assertEquals( '<element />', Xml::element( 'element', null, '' ), @@ -64,7 +76,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testElementInputCanHaveAValueOfZero() { + /** + * @covers Xml::input + */ + public function testElementInputCanHaveAValueOfZero() { $this->assertEquals( '<input name="name" value="0" />', Xml::input( 'name', false, 0 ), @@ -72,7 +87,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testElementEscaping() { + /** + * @covers Xml::element + */ + public function testElementEscaping() { $this->assertEquals( '<element>hello <there> you & you</element>', Xml::element( 'element', null, 'hello <there> you & you' ), @@ -80,13 +98,19 @@ class XmlTest extends MediaWikiTestCase { ); } + /** + * @covers Xml::escapeTagsOnly + */ public function testEscapeTagsOnly() { $this->assertEquals( '"><', Xml::escapeTagsOnly( '"><' ), 'replace " > and < with their HTML entitites' ); } - function testElementAttributes() { + /** + * @covers Xml::element + */ + public function testElementAttributes() { $this->assertEquals( '<element key="value" <>="<>">', Xml::element( 'element', array( 'key' => 'value', '<>' => '<>' ), null ), @@ -94,7 +118,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testOpenElement() { + /** + * @covers Xml::openElement + */ + public function testOpenElement() { $this->assertEquals( '<element k="v">', Xml::openElement( 'element', array( 'k' => 'v' ) ), @@ -102,10 +129,16 @@ class XmlTest extends MediaWikiTestCase { ); } - function testCloseElement() { + /** + * @covers Xml::closeElement + */ + public function testCloseElement() { $this->assertEquals( '</element>', Xml::closeElement( 'element' ), 'closeElement() shortcut' ); } + /** + * @covers Xml::dateMenu + */ public function testDateMenu() { $curYear = intval( gmdate( 'Y' ) ); $prevYear = $curYear - 1; @@ -186,10 +219,10 @@ class XmlTest extends MediaWikiTestCase { ); } - # - # textarea - # - function testTextareaNoContent() { + /** + * @covers Xml::textarea + */ + public function testTextareaNoContent() { $this->assertEquals( '<textarea name="name" id="name" cols="40" rows="5"></textarea>', Xml::textarea( 'name', '' ), @@ -197,7 +230,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testTextareaAttribs() { + /** + * @covers Xml::textarea + */ + public function testTextareaAttribs() { $this->assertEquals( '<textarea name="name" id="name" cols="20" rows="10"><txt></textarea>', Xml::textarea( 'name', '<txt>', 20, 10 ), @@ -205,10 +241,10 @@ class XmlTest extends MediaWikiTestCase { ); } - # - # input and label - # - function testLabelCreation() { + /** + * @covers Xml::label + */ + public function testLabelCreation() { $this->assertEquals( '<label for="id">name</label>', Xml::label( 'name', 'id' ), @@ -216,7 +252,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testLabelAttributeCanOnlyBeClassOrTitle() { + /** + * @covers Xml::label + */ + public function testLabelAttributeCanOnlyBeClassOrTitle() { $this->assertEquals( '<label for="id">name</label>', Xml::label( 'name', 'id', array( 'generated' => true ) ), @@ -245,7 +284,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testLanguageSelector() { + /** + * @covers Xml::languageSelector + */ + public function testLanguageSelector() { $select = Xml::languageSelector( 'en', true, null, array( 'id' => 'testlang' ), wfMessage( 'yourlanguage' ) ); $this->assertEquals( @@ -254,10 +296,10 @@ class XmlTest extends MediaWikiTestCase { ); } - # - # JS - # - function testEscapeJsStringSpecialChars() { + /** + * @covers Xml::escapeJsString + */ + public function testEscapeJsStringSpecialChars() { $this->assertEquals( '\\\\\r\n', Xml::escapeJsString( "\\\r\n" ), @@ -265,7 +307,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarBoolean() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarBoolean() { $this->assertEquals( 'true', Xml::encodeJsVar( true ), @@ -273,7 +318,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarNull() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarNull() { $this->assertEquals( 'null', Xml::encodeJsVar( null ), @@ -281,7 +329,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarArray() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarArray() { $this->assertEquals( '["a",1]', Xml::encodeJsVar( array( 'a', 1 ) ), @@ -294,7 +345,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarObject() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarObject() { $this->assertEquals( '{"a":"a","b":1}', Xml::encodeJsVar( (object)array( 'a' => 'a', 'b' => 1 ) ), @@ -302,7 +356,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarInt() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarInt() { $this->assertEquals( '123456', Xml::encodeJsVar( 123456 ), @@ -310,7 +367,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarFloat() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarFloat() { $this->assertEquals( '1.23456', Xml::encodeJsVar( 1.23456 ), @@ -318,7 +378,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarIntString() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarIntString() { $this->assertEquals( '"123456"', Xml::encodeJsVar( '123456' ), @@ -326,7 +389,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testEncodeJsVarFloatString() { + /** + * @covers Xml::encodeJsVar + */ + public function testEncodeJsVarFloatString() { $this->assertEquals( '"1.23456"', Xml::encodeJsVar( '1.23456' ), diff --git a/tests/phpunit/includes/XmlTypeCheckTest.php b/tests/phpunit/includes/XmlTypeCheckTest.php new file mode 100644 index 00000000..8d6f1ed7 --- /dev/null +++ b/tests/phpunit/includes/XmlTypeCheckTest.php @@ -0,0 +1,30 @@ +<?php +/** + * PHPUnit tests for XMLTypeCheck. + * @author physikerwelt + * @group Xml + * @covers XMLTypeCheck + */ +class XmlTypeCheckTest extends MediaWikiTestCase { + const WELL_FORMED_XML = "<root><child /></root>"; + const MAL_FORMED_XML = "<root><child /></error>"; + + /** + * @covers XMLTypeCheck::newFromString + * @covers XMLTypeCheck::getRootElement + */ + public function testWellFormedXML() { + $testXML = XmlTypeCheck::newFromString( self::WELL_FORMED_XML ); + $this->assertTrue( $testXML->wellFormed ); + $this->assertEquals( 'root', $testXML->getRootElement() ); + } + + /** + * @covers XMLTypeCheck::newFromString + */ + public function testMalFormedXML() { + $testXML = XmlTypeCheck::newFromString( self::MAL_FORMED_XML ); + $this->assertFalse( $testXML->wellFormed ); + } + +} diff --git a/tests/phpunit/includes/ZipDirectoryReaderTest.php b/tests/phpunit/includes/ZipDirectoryReaderTest.php index 3fea57a0..2627a417 100644 --- a/tests/phpunit/includes/ZipDirectoryReaderTest.php +++ b/tests/phpunit/includes/ZipDirectoryReaderTest.php @@ -1,7 +1,12 @@ <?php +/** + * @covers ZipDirectoryReader + * NOTE: this test is more like an integration test than a unit test + */ class ZipDirectoryReaderTest extends MediaWikiTestCase { - var $zipDir, $entries; + protected $zipDir; + protected $entries; protected function setUp() { parent::setUp(); @@ -24,21 +29,21 @@ class ZipDirectoryReaderTest extends MediaWikiTestCase { $this->assertTrue( $status->isOK(), $assertMessage ); } - function testEmpty() { + public function testEmpty() { $this->readZipAssertSuccess( 'empty.zip', 'Empty zip' ); } - function testMultiDisk0() { + public function testMultiDisk0() { $this->readZipAssertError( 'split.zip', 'zip-unsupported', 'Split zip error' ); } - function testNoSignature() { + public function testNoSignature() { $this->readZipAssertError( 'nosig.zip', 'zip-wrong-format', 'No signature should give "wrong format" error' ); } - function testSimple() { + public function testSimple() { $this->readZipAssertSuccess( 'class.zip', 'Simple ZIP' ); $this->assertEquals( $this->entries, array( array( 'name' => 'Class.class', @@ -47,33 +52,33 @@ class ZipDirectoryReaderTest extends MediaWikiTestCase { ) ) ); } - function testBadCentralEntrySignature() { + public function testBadCentralEntrySignature() { $this->readZipAssertError( 'wrong-central-entry-sig.zip', 'zip-bad', 'Bad central entry error' ); } - function testTrailingBytes() { + public function testTrailingBytes() { $this->readZipAssertError( 'trail.zip', 'zip-bad', 'Trailing bytes error' ); } - function testWrongCDStart() { + public function testWrongCDStart() { $this->readZipAssertError( 'wrong-cd-start-disk.zip', 'zip-unsupported', 'Wrong CD start disk error' ); } - function testCentralDirectoryGap() { + public function testCentralDirectoryGap() { $this->readZipAssertError( 'cd-gap.zip', 'zip-bad', 'CD gap error' ); } - function testCentralDirectoryTruncated() { + public function testCentralDirectoryTruncated() { $this->readZipAssertError( 'cd-truncated.zip', 'zip-bad', 'CD truncated error (should hit unpack() overrun)' ); } - function testLooksLikeZip64() { + public function testLooksLikeZip64() { $this->readZipAssertError( 'looks-like-zip64.zip', 'zip-unsupported', 'A file which looks like ZIP64 but isn\'t, should give error' ); } diff --git a/tests/phpunit/includes/api/ApiAccountCreationTest.php b/tests/phpunit/includes/api/ApiAccountCreationTest.php index 94082e5a..68f80ac9 100644 --- a/tests/phpunit/includes/api/ApiAccountCreationTest.php +++ b/tests/phpunit/includes/api/ApiAccountCreationTest.php @@ -20,7 +20,7 @@ class ApiCreateAccountTest extends ApiTestCase { * a bit slow. Raise the default timeout. * @group medium */ - function testValid() { + public function testValid() { global $wgServer; if ( !isset( $wgServer ) ) { @@ -47,13 +47,16 @@ class ApiCreateAccountTest extends ApiTestCase { $token = $a['token']; // Finally create the account - $ret = $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'Apitestnew', - 'password' => $password, - 'token' => $token, - 'email' => 'test@domain.test', - 'realname' => 'Test Name' ), $ret[2] + $ret = $this->doApiRequest( + array( + 'action' => 'createaccount', + 'name' => 'Apitestnew', + 'password' => $password, + 'token' => $token, + 'email' => 'test@domain.test', + 'realname' => 'Test Name' + ), + $ret[2] ); $result = $ret[0]; @@ -65,8 +68,7 @@ class ApiCreateAccountTest extends ApiTestCase { 'action' => 'login', 'lgname' => 'Apitestnew', 'lgpassword' => $password, - ) - ); + ) ); $result = $ret[0]; $this->assertNotInternalType( 'bool', $result ); @@ -76,12 +78,14 @@ class ApiCreateAccountTest extends ApiTestCase { $this->assertEquals( 'NeedToken', $a ); $token = $result['login']['token']; - $ret = $this->doApiRequest( array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => 'Apitestnew', - 'lgpassword' => $password, - ), $ret[2] + $ret = $this->doApiRequest( + array( + 'action' => 'login', + 'lgtoken' => $token, + 'lgname' => 'Apitestnew', + 'lgpassword' => $password, + ), + $ret[2] ); $result = $ret[0]; @@ -92,9 +96,11 @@ class ApiCreateAccountTest extends ApiTestCase { $this->assertEquals( 'Success', $a ); // log out to destroy the session - $ret = $this->doApiRequest( array( - 'action' => 'logout', - ), $ret[2] + $ret = $this->doApiRequest( + array( + 'action' => 'logout', + ), + $ret[2] ); $this->assertEquals( array(), $ret[0] ); } @@ -103,8 +109,8 @@ class ApiCreateAccountTest extends ApiTestCase { * Make sure requests with no names are invalid. * @expectedException UsageException */ - function testNoName() { - $ret = $this->doApiRequest( array( + public function testNoName() { + $this->doApiRequest( array( 'action' => 'createaccount', 'token' => LoginForm::getCreateaccountToken(), 'password' => 'password', @@ -115,8 +121,8 @@ class ApiCreateAccountTest extends ApiTestCase { * Make sure requests with no password are invalid. * @expectedException UsageException */ - function testNoPassword() { - $ret = $this->doApiRequest( array( + public function testNoPassword() { + $this->doApiRequest( array( 'action' => 'createaccount', 'name' => 'testName', 'token' => LoginForm::getCreateaccountToken(), @@ -127,7 +133,7 @@ class ApiCreateAccountTest extends ApiTestCase { * Make sure requests with existing users are invalid. * @expectedException UsageException */ - function testExistingUser() { + public function testExistingUser() { $this->doApiRequest( array( 'action' => 'createaccount', 'name' => 'Apitestsysop', @@ -141,7 +147,7 @@ class ApiCreateAccountTest extends ApiTestCase { * Make sure requests with invalid emails are invalid. * @expectedException UsageException */ - function testInvalidEmail() { + public function testInvalidEmail() { $this->doApiRequest( array( 'action' => 'createaccount', 'name' => 'Test User', diff --git a/tests/phpunit/includes/api/ApiBlockTest.php b/tests/phpunit/includes/api/ApiBlockTest.php index 94643b10..8afb748a 100644 --- a/tests/phpunit/includes/api/ApiBlockTest.php +++ b/tests/phpunit/includes/api/ApiBlockTest.php @@ -6,7 +6,6 @@ * @group medium */ class ApiBlockTest extends ApiTestCase { - protected function setUp() { parent::setUp(); $this->doLogin(); @@ -35,9 +34,8 @@ class ApiBlockTest extends ApiTestCase { * Which made the Block/Unblock API to actually verify the token * previously always considered valid (bug 34212). */ - function testMakeNormalBlock() { - - $data = $this->getTokens(); + public function testMakeNormalBlock() { + $tokens = $this->getTokens(); $user = User::newFromName( 'UTApiBlockee' ); @@ -45,19 +43,15 @@ class ApiBlockTest extends ApiTestCase { $this->markTestIncomplete( "The user UTApiBlockee does not exist" ); } - if ( !isset( $data[0]['query']['pages'] ) ) { + if ( !array_key_exists( 'blocktoken', $tokens ) ) { $this->markTestIncomplete( "No block token found" ); } - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - $pageinfo = $data[0]['query']['pages'][$key]; - - $data = $this->doApiRequest( array( + $this->doApiRequest( array( 'action' => 'block', 'user' => 'UTApiBlockee', 'reason' => 'Some reason', - 'token' => $pageinfo['blocktoken'] ), null, false, self::$users['sysop']->user ); + 'token' => $tokens['blocktoken'] ), null, false, self::$users['sysop']->user ); $block = Block::newFromTarget( 'UTApiBlockee' ); @@ -66,7 +60,6 @@ class ApiBlockTest extends ApiTestCase { $this->assertEquals( 'UTApiBlockee', (string)$block->getTarget() ); $this->assertEquals( 'Some reason', $block->mReason ); $this->assertEquals( 'infinity', $block->mExpiry ); - } /** @@ -77,7 +70,7 @@ class ApiBlockTest extends ApiTestCase { * @dataProvider provideBlockUnblockAction * @expectedException UsageException */ - function testBlockingActionWithNoToken( $action ) { + public function testBlockingActionWithNoToken( $action ) { $this->doApiRequest( array( 'action' => $action, @@ -93,7 +86,7 @@ class ApiBlockTest extends ApiTestCase { /** * Just provide the 'block' and 'unblock' action to test both API calls */ - function provideBlockUnblockAction() { + public static function provideBlockUnblockAction() { return array( array( 'block' ), array( 'unblock' ), diff --git a/tests/phpunit/includes/api/ApiEditPageTest.php b/tests/phpunit/includes/api/ApiEditPageTest.php index 1efbaeaf..0c49b12b 100644 --- a/tests/phpunit/includes/api/ApiEditPageTest.php +++ b/tests/phpunit/includes/api/ApiEditPageTest.php @@ -11,10 +11,10 @@ */ class ApiEditPageTest extends ApiTestCase { - public function setup() { + public function setUp() { global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - parent::setup(); + parent::setUp(); $wgExtraNamespaces[12312] = 'Dummy'; $wgExtraNamespaces[12313] = 'Dummy_talk'; @@ -28,7 +28,7 @@ class ApiEditPageTest extends ApiTestCase { $this->doLogin(); } - public function teardown() { + public function tearDown() { global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; unset( $wgExtraNamespaces[12312] ); @@ -40,10 +40,10 @@ class ApiEditPageTest extends ApiTestCase { MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache $wgContLang->resetNamespaces(); # reset namespace cache - parent::teardown(); + parent::tearDown(); } - function testEdit() { + public function testEdit() { $name = 'Help:ApiEditPageTest_testEdit'; // assume Help namespace to default to wikitext // -- test new page -------------------------------------------- @@ -97,7 +97,7 @@ class ApiEditPageTest extends ApiTestCase { ); } - function testNonTextEdit() { + public function testNonTextEdit() { $name = 'Dummy:ApiEditPageTest_testNonTextEdit'; $data = serialize( 'some bla bla text' ); @@ -124,7 +124,7 @@ class ApiEditPageTest extends ApiTestCase { $this->assertEquals( $data, $page->getContent()->serialize() ); } - static function provideEditAppend() { + public static function provideEditAppend() { return array( array( #0: append 'foo', 'append', 'bar', "foobar" @@ -150,7 +150,7 @@ class ApiEditPageTest extends ApiTestCase { /** * @dataProvider provideEditAppend */ - function testEditAppend( $text, $op, $append, $expected ) { + public function testEditAppend( $text, $op, $append, $expected ) { static $count = 0; $count++; @@ -161,13 +161,13 @@ class ApiEditPageTest extends ApiTestCase { if ( $text !== null ) { if ( $text === '' ) { // can't create an empty page, so create it with some content - list( $re, , ) = $this->doApiRequestWithToken( array( + $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $name, 'text' => '(dummy)', ) ); } - list( $re, , ) = $this->doApiRequestWithToken( array( + list( $re ) = $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $name, 'text' => $text, ) ); @@ -176,7 +176,7 @@ class ApiEditPageTest extends ApiTestCase { } // -- try append/prepend -------------------------------------------- - list( $re, , ) = $this->doApiRequestWithToken( array( + list( $re ) = $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $name, $op . 'text' => $append, ) ); @@ -193,15 +193,80 @@ class ApiEditPageTest extends ApiTestCase { $this->assertEquals( $expected, $text ); } - function testEditSection() { - $this->markTestIncomplete( "not yet implemented" ); + /** + * Test editing of sections + */ + public function testEditSection() { + $name = 'Help:ApiEditPageTest_testEditSection'; + $page = WikiPage::factory( Title::newFromText( $name ) ); + $text = "==section 1==\ncontent 1\n==section 2==\ncontent2"; + // Preload the page with some text + $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), 'summary' ); + + list( $re ) = $this->doApiRequestWithToken( array( + 'action' => 'edit', + 'title' => $name, + 'section' => '1', + 'text' => "==section 1==\nnew content 1", + ) ); + $this->assertEquals( 'Success', $re['edit']['result'] ); + $newtext = WikiPage::factory( Title::newFromText( $name) )->getContent( Revision::RAW )->getNativeData(); + $this->assertEquals( $newtext, "==section 1==\nnew content 1\n\n==section 2==\ncontent2" ); + + // Test that we raise a 'nosuchsection' error + try { + $this->doApiRequestWithToken( array( + 'action' => 'edit', + 'title' => $name, + 'section' => '9999', + 'text' => 'text', + ) ); + $this->fail( "Should have raised a UsageException" ); + } catch ( UsageException $e ) { + $this->assertEquals( $e->getCodeString(), 'nosuchsection' ); + } } - function testUndo() { - $this->markTestIncomplete( "not yet implemented" ); + /** + * Test action=edit§ion=new + * Run it twice so we test adding a new section on a + * page that doesn't exist (bug 52830) and one that + * does exist + */ + public function testEditNewSection() { + $name = 'Help:ApiEditPageTest_testEditNewSection'; + + // Test on a page that does not already exist + $this->assertFalse( Title::newFromText( $name )->exists() ); + list( $re ) = $this->doApiRequestWithToken( array( + 'action' => 'edit', + 'title' => $name, + 'section' => 'new', + 'text' => 'test', + 'summary' => 'header', + )); + + $this->assertEquals( 'Success', $re['edit']['result'] ); + // Check the page text is correct + $text = WikiPage::factory( Title::newFromText( $name ) )->getContent( Revision::RAW )->getNativeData(); + $this->assertEquals( $text, "== header ==\n\ntest" ); + + // Now on one that does + $this->assertTrue( Title::newFromText( $name )->exists() ); + list( $re2 ) = $this->doApiRequestWithToken( array( + 'action' => 'edit', + 'title' => $name, + 'section' => 'new', + 'text' => 'test', + 'summary' => 'header', + )); + + $this->assertEquals( 'Success', $re2['edit']['result'] ); + $text = WikiPage::factory( Title::newFromText( $name ) )->getContent( Revision::RAW )->getNativeData(); + $this->assertEquals( $text, "== header ==\n\ntest\n\n== header ==\n\ntest" ); } - function testEditConflict() { + public function testEditConflict() { static $count = 0; $count++; @@ -224,7 +289,7 @@ class ApiEditPageTest extends ApiTestCase { // try to save edit, expect conflict try { - list( $re, , ) = $this->doApiRequestWithToken( array( + $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $name, 'text' => 'nix bar!', @@ -237,7 +302,7 @@ class ApiEditPageTest extends ApiTestCase { } } - function testEditConflict_redirect() { + public function testEditConflict_redirect() { static $count = 0; $count++; @@ -280,7 +345,7 @@ class ApiEditPageTest extends ApiTestCase { // try again, without following the redirect. Should fail. try { - list( $re, , ) = $this->doApiRequestWithToken( array( + $this->doApiRequestWithToken( array( 'action' => 'edit', 'title' => $rname, 'text' => 'nix bar!', @@ -293,13 +358,13 @@ class ApiEditPageTest extends ApiTestCase { } } - function testEditConflict_bug41990() { + public function testEditConflict_bug41990() { static $count = 0; $count++; /* * bug 41990: if the target page has a newer revision than the redirect, then editing the - * redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erronously + * redirect while specifying 'redirect' and *not* specifying 'basetimestamp' erroneously * caused an edit conflict to be detected. */ diff --git a/tests/phpunit/includes/api/ApiOptionsTest.php b/tests/phpunit/includes/api/ApiOptionsTest.php index 902b7b85..ad1e73ab 100644 --- a/tests/phpunit/includes/api/ApiOptionsTest.php +++ b/tests/phpunit/includes/api/ApiOptionsTest.php @@ -20,9 +20,11 @@ class ApiOptionsTest extends MediaWikiLangTestCase { ->disableOriginalConstructor() ->getMock(); - // Set up groups + // Set up groups and rights $this->mUserMock->expects( $this->any() ) ->method( 'getEffectiveGroups' )->will( $this->returnValue( array( '*', 'user' ) ) ); + $this->mUserMock->expects( $this->any() ) + ->method( 'isAllowed' )->will( $this->returnValue( true ) ); // Set up callback for User::getOptionKinds $this->mUserMock->expects( $this->any() ) @@ -116,6 +118,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $mapping[$key] = 'unused'; } } + return $mapping; } @@ -126,12 +129,14 @@ class ApiOptionsTest extends MediaWikiLangTestCase { 'optionname' => null, 'optionvalue' => null, ); + return array_merge( $request, $custom ); } private function executeQuery( $request ) { $this->mContext->setRequest( new FauxRequest( $request, true, $this->mSession ) ); $this->mTested->execute(); + return $this->mTested->getResult()->getData(); } @@ -156,6 +161,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { } catch ( UsageException $e ) { $this->assertEquals( 'notloggedin', $e->getCodeString() ); $this->assertEquals( 'Anonymous users cannot change preferences', $e->getMessage() ); + return; } $this->fail( "UsageException was not thrown" ); @@ -169,6 +175,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { } catch ( UsageException $e ) { $this->assertEquals( 'nooptionname', $e->getCodeString() ); $this->assertEquals( 'The optionname parameter must be set', $e->getMessage() ); + return; } $this->fail( "UsageException was not thrown" ); @@ -191,6 +198,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { } catch ( UsageException $e ) { $this->assertEquals( 'nochanges', $e->getCodeString() ); $this->assertEquals( 'No changes were requested', $e->getMessage() ); + return; } $this->fail( "UsageException was not thrown" ); @@ -274,21 +282,21 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $this->mUserMock->expects( $this->at( 2 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 3 ) ) + $this->mUserMock->expects( $this->at( 4 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'willBeNull' ), $this->identicalTo( null ) ); - $this->mUserMock->expects( $this->at( 4 ) ) + $this->mUserMock->expects( $this->at( 5 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 5 ) ) + $this->mUserMock->expects( $this->at( 6 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'willBeEmpty' ), $this->equalTo( '' ) ); - $this->mUserMock->expects( $this->at( 6 ) ) + $this->mUserMock->expects( $this->at( 7 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 7 ) ) + $this->mUserMock->expects( $this->at( 8 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); @@ -306,17 +314,17 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $this->mUserMock->expects( $this->once() ) ->method( 'resetOptions' ); - $this->mUserMock->expects( $this->at( 3 ) ) + $this->mUserMock->expects( $this->at( 4 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 4 ) ) + $this->mUserMock->expects( $this->at( 5 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); - $this->mUserMock->expects( $this->at( 5 ) ) + $this->mUserMock->expects( $this->at( 6 ) ) ->method( 'getOptions' ); - $this->mUserMock->expects( $this->at( 6 ) ) + $this->mUserMock->expects( $this->at( 7 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); @@ -339,19 +347,19 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $this->mUserMock->expects( $this->never() ) ->method( 'resetOptions' ); - $this->mUserMock->expects( $this->at( 2 ) ) + $this->mUserMock->expects( $this->at( 3 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'testmultiselect-opt1' ), $this->identicalTo( true ) ); - $this->mUserMock->expects( $this->at( 3 ) ) + $this->mUserMock->expects( $this->at( 4 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'testmultiselect-opt2' ), $this->identicalTo( null ) ); - $this->mUserMock->expects( $this->at( 4 ) ) + $this->mUserMock->expects( $this->at( 5 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'testmultiselect-opt3' ), $this->identicalTo( false ) ); - $this->mUserMock->expects( $this->at( 5 ) ) + $this->mUserMock->expects( $this->at( 6 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'testmultiselect-opt4' ), $this->identicalTo( false ) ); @@ -394,7 +402,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase { $this->mUserMock->expects( $this->never() ) ->method( 'resetOptions' ); - $this->mUserMock->expects( $this->at( 2 ) ) + $this->mUserMock->expects( $this->at( 3 ) ) ->method( 'setOption' ) ->with( $this->equalTo( 'userjs-option' ), $this->equalTo( '1' ) ); diff --git a/tests/phpunit/includes/api/ApiParseTest.php b/tests/phpunit/includes/api/ApiParseTest.php index a42e5aa5..2d714e65 100644 --- a/tests/phpunit/includes/api/ApiParseTest.php +++ b/tests/phpunit/includes/api/ApiParseTest.php @@ -12,11 +12,11 @@ class ApiParseTest extends ApiTestCase { $this->doLogin(); } - function testParseNonexistentPage() { + public function testParseNonexistentPage() { $somePage = mt_rand(); try { - $data = $this->doApiRequest( array( + $this->doApiRequest( array( 'action' => 'parse', 'page' => $somePage ) ); @@ -26,5 +26,4 @@ class ApiParseTest extends ApiTestCase { "Parse request for nonexistent page must give 'missingtitle' error: " . var_export( $ex->getMessageArray(), true ) ); } } - } diff --git a/tests/phpunit/includes/api/ApiPurgeTest.php b/tests/phpunit/includes/api/ApiPurgeTest.php index a7f9229d..28b5ff4d 100644 --- a/tests/phpunit/includes/api/ApiPurgeTest.php +++ b/tests/phpunit/includes/api/ApiPurgeTest.php @@ -15,7 +15,7 @@ class ApiPurgeTest extends ApiTestCase { /** * @group Broken */ - function testPurgeMainPage() { + public function testPurgeMainPage() { if ( !Title::newFromText( 'UTPage' )->exists() ) { $this->markTestIncomplete( "The article [[UTPage]] does not exist" ); } @@ -37,5 +37,4 @@ class ApiPurgeTest extends ApiTestCase { $this->assertArrayHasKey( $pages[$v['title']], $v ); } } - } diff --git a/tests/phpunit/includes/api/ApiTest.php b/tests/phpunit/includes/api/ApiTest.php index 22770288..472f8c4a 100644 --- a/tests/phpunit/includes/api/ApiTest.php +++ b/tests/phpunit/includes/api/ApiTest.php @@ -7,7 +7,7 @@ */ class ApiTest extends ApiTestCase { - function testRequireOnlyOneParameterDefault() { + public function testRequireOnlyOneParameterDefault() { $mock = new MockApi(); $this->assertEquals( @@ -18,7 +18,7 @@ class ApiTest extends ApiTestCase { /** * @expectedException UsageException */ - function testRequireOnlyOneParameterZero() { + public function testRequireOnlyOneParameterZero() { $mock = new MockApi(); $this->assertEquals( @@ -29,7 +29,7 @@ class ApiTest extends ApiTestCase { /** * @expectedException UsageException */ - function testRequireOnlyOneParameterTrue() { + public function testRequireOnlyOneParameterTrue() { $mock = new MockApi(); $this->assertEquals( @@ -43,7 +43,7 @@ class ApiTest extends ApiTestCase { * * @expectedException UsageException */ - function testApi() { + public function testApi() { $api = new ApiMain( new FauxRequest( array( 'action' => 'help', 'format' => 'xml' ) ) ); @@ -61,14 +61,14 @@ class ApiTest extends ApiTestCase { /** * Test result of attempted login with an empty username */ - function testApiLoginNoName() { + public function testApiLoginNoName() { $data = $this->doApiRequest( array( 'action' => 'login', 'lgname' => '', 'lgpassword' => self::$users['sysop']->password, ) ); $this->assertEquals( 'NoName', $data[0]['login']['result'] ); } - function testApiLoginBadPass() { + public function testApiLoginBadPass() { global $wgServer; $user = self::$users['sysop']; @@ -81,8 +81,7 @@ class ApiTest extends ApiTestCase { "action" => "login", "lgname" => $user->username, "lgpassword" => "bad", - ) - ); + ) ); $result = $ret[0]; @@ -110,7 +109,7 @@ class ApiTest extends ApiTestCase { $this->assertEquals( "WrongPass", $a ); } - function testApiLoginGoodPass() { + public function testApiLoginGoodPass() { global $wgServer; if ( !isset( $wgServer ) ) { @@ -136,7 +135,7 @@ class ApiTest extends ApiTestCase { $token = $result["login"]["token"]; $ret = $this->doApiRequest( - array( + array( "action" => "login", "lgtoken" => $token, "lgname" => $user->username, @@ -156,7 +155,7 @@ class ApiTest extends ApiTestCase { /** * @group Broken */ - function testApiGotCookie() { + public function testApiGotCookie() { $this->markTestIncomplete( "The server can't do external HTTP requests, and the internal one won't give cookies" ); global $wgServer, $wgScriptPath; @@ -202,7 +201,7 @@ class ApiTest extends ApiTestCase { return $cj; } - function testRunLogin() { + public function testRunLogin() { $sysopUser = self::$users['sysop']; $data = $this->doApiRequest( array( 'action' => 'login', @@ -228,39 +227,33 @@ class ApiTest extends ApiTestCase { return $data; } - function testGettingToken() { + public function testGettingToken() { foreach ( self::$users as $user ) { $this->runTokenTest( $user ); } } function runTokenTest( $user ) { - $data = $this->getTokenList( $user ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); + $tokens = $this->getTokenList( $user ); $rights = $user->user->getRights(); - $this->assertArrayHasKey( $key, $data[0]['query']['pages'] ); - $this->assertArrayHasKey( 'edittoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'movetoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'edittoken', $tokens ); + $this->assertArrayHasKey( 'movetoken', $tokens ); if ( isset( $rights['delete'] ) ) { - $this->assertArrayHasKey( 'deletetoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'deletetoken', $tokens ); } if ( isset( $rights['block'] ) ) { - $this->assertArrayHasKey( 'blocktoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'unblocktoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'blocktoken', $tokens ); + $this->assertArrayHasKey( 'unblocktoken', $tokens ); } if ( isset( $rights['protect'] ) ) { - $this->assertArrayHasKey( 'protecttoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'protecttoken', $tokens ); } - return $data; + return $tokens; } } diff --git a/tests/phpunit/includes/api/ApiTestCase.php b/tests/phpunit/includes/api/ApiTestCase.php index 552fbfbf..94ef9c68 100644 --- a/tests/phpunit/includes/api/ApiTestCase.php +++ b/tests/phpunit/includes/api/ApiTestCase.php @@ -52,6 +52,7 @@ abstract class ApiTestCase extends MediaWikiLangTestCase { protected function editPage( $pageName, $text, $summary = '', $defaultNs = NS_MAIN ) { $title = Title::newFromText( $pageName, $defaultNs ); $page = WikiPage::factory( $title ); + return $page->doEditContent( ContentHandler::makeContent( $text, $title ), $summary ); } @@ -131,17 +132,22 @@ abstract class ApiTestCase extends MediaWikiLangTestCase { $session['wsEditToken'] = $session['wsToken']; // add token to request parameters $params['token'] = md5( $session['wsToken'] ) . User::EDIT_TOKEN_SUFFIX; + return $this->doApiRequest( $params, $session, false, $user ); } else { throw new Exception( "request data not in right format" ); } } - protected function doLogin() { + protected function doLogin( $user = 'sysop' ) { + if ( !array_key_exists( $user, self::$users ) ) { + throw new MWException( "Can not log in to undefined user $user" ); + } + $data = $this->doApiRequest( array( 'action' => 'login', - 'lgname' => self::$users['sysop']->username, - 'lgpassword' => self::$users['sysop']->password ) ); + 'lgname' => self::$users[ $user ]->username, + 'lgpassword' => self::$users[ $user ]->password ) ); $token = $data[0]['login']['token']; @@ -149,8 +155,8 @@ abstract class ApiTestCase extends MediaWikiLangTestCase { array( 'action' => 'login', 'lgtoken' => $token, - 'lgname' => self::$users['sysop']->username, - 'lgpassword' => self::$users['sysop']->password, + 'lgname' => self::$users[ $user ]->username, + 'lgpassword' => self::$users[ $user ]->password, ), $data[2] ); @@ -160,11 +166,15 @@ abstract class ApiTestCase extends MediaWikiLangTestCase { protected function getTokenList( $user, $session = null ) { $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => 'Main Page', - 'intoken' => 'edit|delete|protect|move|block|unblock|watch', - 'prop' => 'info' ), $session, false, $user->user ); - return $data; + 'action' => 'tokens', + 'type' => 'edit|delete|protect|move|block|unblock|watch' + ), $session, false, $user->user ); + + if ( !array_key_exists( 'tokens', $data[0] ) ) { + throw new MWException( 'Api failed to return a token list' ); + } + + return $data[0]['tokens']; } public function testApiTestGroup() { @@ -204,11 +214,14 @@ class UserWrapper { } class MockApi extends ApiBase { - public function execute() {} + public function execute() { + } - public function getVersion() {} + public function getVersion() { + } - public function __construct() {} + public function __construct() { + } public function getAllowedParams() { return array( @@ -234,6 +247,7 @@ class ApiTestContext extends RequestContext { if ( $user !== null ) { $context->setUser( $user ); } + return $context; } } diff --git a/tests/phpunit/includes/api/ApiTestCaseUpload.php b/tests/phpunit/includes/api/ApiTestCaseUpload.php index 80284917..7e18b6ed 100644 --- a/tests/phpunit/includes/api/ApiTestCaseUpload.php +++ b/tests/phpunit/includes/api/ApiTestCaseUpload.php @@ -47,6 +47,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase { // see if it now doesn't exist; reload $title = Title::newFromText( $title->getText(), NS_FILE ); } + return !( $title && $title instanceof Title && $title->exists() ); } @@ -69,6 +70,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase { foreach ( $dupes as $dupe ) { $success &= $this->deleteFileByTitle( $dupe->getTitle() ); } + return $success; } @@ -105,7 +107,6 @@ abstract class ApiTestCaseUpload extends ApiTestCase { ); return true; - } function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ) { @@ -145,5 +146,4 @@ abstract class ApiTestCaseUpload extends ApiTestCase { function clearFakeUploads() { $_FILES = array(); } - } diff --git a/tests/phpunit/includes/api/ApiUploadTest.php b/tests/phpunit/includes/api/ApiUploadTest.php index 0d98b04d..1540af55 100644 --- a/tests/phpunit/includes/api/ApiUploadTest.php +++ b/tests/phpunit/includes/api/ApiUploadTest.php @@ -16,7 +16,7 @@ // TODO: port the other Upload tests, and other API tests to this framework -require_once( 'ApiTestCaseUpload.php' ); +require_once 'ApiTestCaseUpload.php'; /** * @group Database @@ -27,12 +27,11 @@ require_once( 'ApiTestCaseUpload.php' ); * This is pretty sucky... needs to be prettified. */ class ApiUploadTest extends ApiTestCaseUpload { - /** * Testing login * XXX this is a funny way of getting session context */ - function testLogin() { + public function testLogin() { $user = self::$users['uploader']; $params = array( @@ -59,8 +58,8 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->assertArrayHasKey( 'lgtoken', $result['login'] ); $this->assertNotEmpty( $session, 'API Login must return a session' ); - return $session; + return $session; } /** @@ -118,7 +117,6 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->deleteFileByFileName( $fileName ); $this->deleteFileByContent( $filePath ); - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { $this->markTestIncomplete( "Couldn't upload file!\n" ); } @@ -140,7 +138,7 @@ class ApiUploadTest extends ApiTestCaseUpload { } $this->assertTrue( isset( $result['upload'] ) ); $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertEquals( $fileSize, ( int )$result['upload']['imageinfo']['size'] ); + $this->assertEquals( $fileSize, (int)$result['upload']['imageinfo']['size'] ); $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); $this->assertFalse( $exception ); @@ -298,7 +296,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $exception = true; @@ -307,7 +305,6 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->assertEquals( 'Success', $result['upload']['result'] ); $this->assertFalse( $exception ); - // second upload with the same content (but different name) if ( !$this->fakeUploadFile( 'file', $fileNames[1], $mimeType, $filePaths[0] ) ) { @@ -324,7 +321,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); // FIXME: leaks a temporary file } catch ( UsageException $e ) { $exception = true; @@ -341,7 +338,6 @@ class ApiUploadTest extends ApiTestCaseUpload { unlink( $filePaths[0] ); } - /** * @depends testLogin */ @@ -382,7 +378,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); // FIXME: leaks a temporary file } catch ( UsageException $e ) { $exception = true; @@ -390,7 +386,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->assertFalse( $exception ); $this->assertTrue( isset( $result['upload'] ) ); $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertEquals( $fileSize, ( int )$result['upload']['imageinfo']['size'] ); + $this->assertEquals( $fileSize, (int)$result['upload']['imageinfo']['size'] ); $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); $this->assertTrue( isset( $result['upload']['filekey'] ) ); $this->assertEquals( $result['upload']['sessionkey'], $result['upload']['filekey'] ); @@ -411,7 +407,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->clearFakeUploads(); $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $exception = true; @@ -454,7 +450,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->deleteFileByFileName( $fileName ); $this->deleteFileByContent( $filePath ); - // Base upload params: + // Base upload params: $params = array( 'action' => 'upload', 'stash' => 1, @@ -466,7 +462,7 @@ class ApiUploadTest extends ApiTestCaseUpload { // Upload chunks $chunkSessionKey = false; $resultOffset = 0; - // Open the file: + // Open the file: $handle = @fopen( $filePath, "r" ); if ( $handle === false ) { $this->markTestIncomplete( "could not open file: $filePath" ); @@ -482,15 +478,15 @@ class ApiUploadTest extends ApiTestCaseUpload { if ( !$chunkSessionKey ) { // Upload fist chunk ( and get the session key ) try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $this->markTestIncomplete( $e->getMessage() ); } - // Make sure we got a valid chunk continue: + // Make sure we got a valid chunk continue: $this->assertTrue( isset( $result['upload'] ) ); $this->assertTrue( isset( $result['upload']['filekey'] ) ); - // If we don't get a session key mark test incomplete. + // If we don't get a session key mark test incomplete. if ( !isset( $result['upload']['filekey'] ) ) { $this->markTestIncomplete( "no filekey provided" ); } @@ -509,16 +505,16 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->assertEquals( $resultOffset, $params['offset'] ); // Upload current chunk try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $this->markTestIncomplete( $e->getMessage() ); } - // Make sure we got a valid chunk continue: + // Make sure we got a valid chunk continue: $this->assertTrue( isset( $result['upload'] ) ); $this->assertTrue( isset( $result['upload']['filekey'] ) ); - // Check if we were on the last chunk: + // Check if we were on the last chunk: if ( $params['offset'] + $chunkSize >= $fileSize ) { $this->assertEquals( 'Success', $result['upload']['result'] ); break; @@ -548,7 +544,7 @@ class ApiUploadTest extends ApiTestCaseUpload { $this->clearFakeUploads(); $exception = false; try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, + list( $result ) = $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); } catch ( UsageException $e ) { $exception = true; @@ -559,7 +555,7 @@ class ApiUploadTest extends ApiTestCaseUpload { // clean up $this->deleteFileByFilename( $fileName ); - // don't remove downloaded temporary file for fast subquent tests. + // don't remove downloaded temporary file for fast subquent tests. //unlink( $filePath ); } } diff --git a/tests/phpunit/includes/api/ApiWatchTest.php b/tests/phpunit/includes/api/ApiWatchTest.php index aefd9398..028ea9ff 100644 --- a/tests/phpunit/includes/api/ApiWatchTest.php +++ b/tests/phpunit/includes/api/ApiWatchTest.php @@ -7,32 +7,25 @@ * @todo This test suite is severly broken and need a full review */ class ApiWatchTest extends ApiTestCase { - protected function setUp() { parent::setUp(); $this->doLogin(); } function getTokens() { - $data = $this->getTokenList( self::$users['sysop'] ); - - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - $pageinfo = $data[0]['query']['pages'][$key]; - - return $pageinfo; + return $this->getTokenList( self::$users['sysop'] ); } /** */ - function testWatchEdit() { - $pageinfo = $this->getTokens(); + public function testWatchEdit() { + $tokens = $this->getTokens(); $data = $this->doApiRequest( array( 'action' => 'edit', 'title' => 'Help:UTPage', // Help namespace is hopefully wikitext 'text' => 'new text', - 'token' => $pageinfo['edittoken'], + 'token' => $tokens['edittoken'], 'watchlist' => 'watch' ) ); $this->assertArrayHasKey( 'edit', $data[0] ); $this->assertArrayHasKey( 'result', $data[0]['edit'] ); @@ -44,9 +37,8 @@ class ApiWatchTest extends ApiTestCase { /** * @depends testWatchEdit */ - function testWatchClear() { - - $pageinfo = $this->getTokens(); + public function testWatchClear() { + $tokens = $this->getTokens(); $data = $this->doApiRequest( array( 'action' => 'query', @@ -60,7 +52,7 @@ class ApiWatchTest extends ApiTestCase { 'action' => 'watch', 'title' => $page['title'], 'unwatch' => true, - 'token' => $pageinfo['watchtoken'] ) ); + 'token' => $tokens['watchtoken'] ) ); } } $data = $this->doApiRequest( array( @@ -75,13 +67,12 @@ class ApiWatchTest extends ApiTestCase { /** */ - function testWatchProtect() { - - $pageinfo = $this->getTokens(); + public function testWatchProtect() { + $tokens = $this->getTokens(); $data = $this->doApiRequest( array( 'action' => 'protect', - 'token' => $pageinfo['protecttoken'], + 'token' => $tokens['protecttoken'], 'title' => 'Help:UTPage', 'protections' => 'edit=sysop', 'watchlist' => 'unwatch' ) ); @@ -94,9 +85,8 @@ class ApiWatchTest extends ApiTestCase { /** */ - function testGetRollbackToken() { - - $pageinfo = $this->getTokens(); + public function testGetRollbackToken() { + $this->getTokens(); if ( !Title::newFromText( 'Help:UTPage' )->exists() ) { $this->markTestSkipped( "The article [[Help:UTPage]] does not exist" ); //TODO: just create it? @@ -131,7 +121,7 @@ class ApiWatchTest extends ApiTestCase { * * @depends testGetRollbackToken */ - function testWatchRollback( $data ) { + public function testWatchRollback( $data ) { $keys = array_keys( $data[0]['query']['pages'] ); $key = array_pop( $keys ); $pageinfo = $data[0]['query']['pages'][$key]; @@ -155,23 +145,4 @@ class ApiWatchTest extends ApiTestCase { } } } - - /** - */ - function testWatchDelete() { - $pageinfo = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'delete', - 'token' => $pageinfo['deletetoken'], - 'title' => 'Help:UTPage' ) ); - $this->assertArrayHasKey( 'delete', $data[0] ); - $this->assertArrayHasKey( 'title', $data[0]['delete'] ); - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ) ); - - $this->markTestIncomplete( 'This test needs to verify the deleted article was added to the users watchlist' ); - } } diff --git a/tests/phpunit/includes/api/RandomImageGenerator.php b/tests/phpunit/includes/api/RandomImageGenerator.php index 30407582..59756b21 100644 --- a/tests/phpunit/includes/api/RandomImageGenerator.php +++ b/tests/phpunit/includes/api/RandomImageGenerator.php @@ -34,7 +34,7 @@ class RandomImageGenerator { private $shapesToDraw = 5; /** - * Orientations: 0th row, 0th column, EXIF orientation code, rotation 2x2 matrix that is opposite of orientation + * Orientations: 0th row, 0th column, Exif orientation code, rotation 2x2 matrix that is opposite of orientation * n.b. we do not handle the 'flipped' orientations, which is why there is no entry for 2, 4, 5, or 7. Those * seem to be rare in real images anyway * (we also would need a non-symmetric shape for the images to test those, like a letter F) @@ -108,6 +108,7 @@ class RandomImageGenerator { foreach ( $filenames as $filename ) { $this->{$imageWriteMethod}( $this->getImageSpec(), $format, $filename ); } + return $filenames; } @@ -156,7 +157,6 @@ class RandomImageGenerator { } return $filenames; - } @@ -196,7 +196,6 @@ class RandomImageGenerator { array( 'x' => $originX, 'y' => $originY - $radius ) ); $draws[] = $draw; - } $spec['draws'] = $draws; @@ -216,6 +215,7 @@ class RandomImageGenerator { foreach ( $shape as $point ) { $points[] = $point['x'] . ',' . $point['y']; } + return join( " ", $points ); } @@ -304,7 +304,7 @@ class RandomImageGenerator { /** * Given an image specification, produce rotated version - * This is used when simulating a rotated image capture with EXIF orientation + * This is used when simulating a rotated image capture with Exif orientation * @param $spec Object returned by getImageSpec * @param $matrix 2x2 transformation matrix * @return transformed Spec @@ -337,6 +337,7 @@ class RandomImageGenerator { } $tSpec['draws'][] = $tDraw; } + return $tSpec; } @@ -384,6 +385,7 @@ class RandomImageGenerator { $command = wfEscapeShellArg( $wgImageMagickConvertCommand ) . " " . implode( " ", $args ); $retval = null; wfShellExec( $command, $retval ); + return ( $retval === 0 ); } @@ -397,6 +399,7 @@ class RandomImageGenerator { for ( $i = 0; $i <= 2; $i++ ) { $components[] = mt_rand( 0, 255 ); } + return 'rgb(' . join( ', ', $components ) . ')'; } @@ -414,6 +417,7 @@ class RandomImageGenerator { for ( $i = 0; $i < $count; $i += 2 ) { $pairs[] = array( $lines[$i], $lines[$i + 1] ); } + return $pairs; } @@ -461,5 +465,4 @@ class RandomImageGenerator { return $lines; } - } diff --git a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php b/tests/phpunit/includes/api/format/ApiFormatPhpTest.php index a59983d8..a0bbb2dc 100644 --- a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php +++ b/tests/phpunit/includes/api/format/ApiFormatPhpTest.php @@ -7,13 +7,11 @@ */ class ApiFormatPhpTest extends ApiFormatTestBase { - function testValidPhpSyntax() { + public function testValidPhpSyntax() { $data = $this->apiRequest( 'php', array( 'action' => 'query', 'meta' => 'siteinfo' ) ); $this->assertInternalType( 'array', unserialize( $data ) ); $this->assertGreaterThan( 0, count( (array)$data ) ); - } - } diff --git a/tests/phpunit/includes/api/generateRandomImages.php b/tests/phpunit/includes/api/generateRandomImages.php index bdd15c48..87f5c4c0 100644 --- a/tests/phpunit/includes/api/generateRandomImages.php +++ b/tests/phpunit/includes/api/generateRandomImages.php @@ -6,8 +6,8 @@ */ // Start up MediaWiki in command-line mode -require_once( __DIR__ . "/../../../../maintenance/Maintenance.php" ); -require( __DIR__ . "/RandomImageGenerator.php" ); +require_once __DIR__ . "/../../../../maintenance/Maintenance.php"; +require __DIR__ . "/RandomImageGenerator.php"; class GenerateRandomImages extends Maintenance { @@ -43,4 +43,4 @@ class GenerateRandomImages extends Maintenance { } $maintClass = 'GenerateRandomImages'; -require( RUN_MAINTENANCE_IF_MAIN ); +require RUN_MAINTENANCE_IF_MAIN; diff --git a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php b/tests/phpunit/includes/api/query/ApiQueryBasicTest.php index 6d4e3711..1a2aa832 100644 --- a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php +++ b/tests/phpunit/includes/api/query/ApiQueryBasicTest.php @@ -24,7 +24,7 @@ * @file */ -require_once( 'ApiQueryTestBase.php' ); +require_once 'ApiQueryTestBase.php'; /** These tests validate basic functionality of the api query module * @@ -67,7 +67,10 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'title' => 'AQBT-All', 'links' => array( array( 'ns' => 0, 'title' => 'AQBT-Links' ), - ) ) ) ) ); + ) + ) + ) ) + ); private static $templates = array( array( 'prop' => 'templates', 'titles' => 'AQBT-All' ), @@ -78,7 +81,10 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'title' => 'AQBT-All', 'templates' => array( array( 'ns' => 10, 'title' => 'Template:AQBT-T' ), - ) ) ) ) ); + ) + ) + ) ) + ); private static $categories = array( array( 'prop' => 'categories', 'titles' => 'AQBT-All' ), @@ -89,7 +95,10 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'title' => 'AQBT-All', 'categories' => array( array( 'ns' => 14, 'title' => 'Category:AQBT-Cat' ), - ) ) ) ) ); + ) + ) + ) ) + ); private static $allpages = array( array( 'list' => 'allpages', 'apprefix' => 'AQBT-' ), @@ -98,7 +107,8 @@ class ApiQueryBasicTest extends ApiQueryTestBase { array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ), array( 'pageid' => 3, 'ns' => 0, 'title' => 'AQBT-Links' ), array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $alllinks = array( array( 'list' => 'alllinks', 'alprefix' => 'AQBT-' ), @@ -107,40 +117,46 @@ class ApiQueryBasicTest extends ApiQueryTestBase { array( 'ns' => 0, 'title' => 'AQBT-Categories' ), array( 'ns' => 0, 'title' => 'AQBT-Links' ), array( 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $alltransclusions = array( array( 'list' => 'alltransclusions', 'atprefix' => 'AQBT-' ), array( 'alltransclusions' => array( array( 'ns' => 10, 'title' => 'Template:AQBT-T' ), array( 'ns' => 10, 'title' => 'Template:AQBT-T' ), - ) ) ); + ) ) + ); private static $allcategories = array( array( 'list' => 'allcategories', 'acprefix' => 'AQBT-' ), array( 'allcategories' => array( array( '*' => 'AQBT-Cat' ), - ) ) ); + ) ) + ); private static $backlinks = array( array( 'list' => 'backlinks', 'bltitle' => 'AQBT-Links' ), array( 'backlinks' => array( array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ), - ) ) ); + ) ) + ); private static $embeddedin = array( array( 'list' => 'embeddedin', 'eititle' => 'Template:AQBT-T' ), array( 'embeddedin' => array( array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ), array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $categorymembers = array( array( 'list' => 'categorymembers', 'cmtitle' => 'Category:AQBT-Cat' ), array( 'categorymembers' => array( array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ), array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ), - ) ) ); + ) ) + ); private static $generatorAllpages = array( array( 'generator' => 'allpages', 'gapprefix' => 'AQBT-' ), @@ -161,7 +177,8 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $generatorLinks = array( array( 'generator' => 'links', 'titles' => 'AQBT-Links' ), @@ -178,14 +195,17 @@ class ApiQueryBasicTest extends ApiQueryTestBase { 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ), - ) ) ); + ) ) + ); private static $generatorLinksPropLinks = array( array( 'prop' => 'links' ), array( 'pages' => array( '1' => array( 'links' => array( array( 'ns' => 0, 'title' => 'AQBT-Links' ), - ) ) ) ) ); + ) ) + ) ) + ); private static $generatorLinksPropTemplates = array( array( 'prop' => 'templates' ), @@ -194,7 +214,8 @@ class ApiQueryBasicTest extends ApiQueryTestBase { array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ), '4' => array( 'templates' => array( array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ), - ) ) ); + ) ) + ); /** * Test basic props @@ -300,6 +321,32 @@ class ApiQueryBasicTest extends ApiQueryTestBase { } /** + * Test bug 51821 + */ + public function testGeneratorRedirects() { + $this->editPage( 'AQBT-Target', 'test' ); + $this->editPage( 'AQBT-Redir', '#REDIRECT [[AQBT-Target]]' ); + $this->check( array( + array( 'generator' => 'backlinks', 'gbltitle' => 'AQBT-Target', 'redirects' => '1' ), + array( + 'redirects' => array( + array( + 'from' => 'AQBT-Redir', + 'to' => 'AQBT-Target', + ) + ), + 'pages' => array( + '6' => array( + 'pageid' => 6, + 'ns' => 0, + 'title' => 'AQBT-Target', + ) + ), + ) + ) ); + } + + /** * Recursively merges the expected values in the $item into the $all */ private function mergeExpected( &$all, $item ) { diff --git a/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php b/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php index 0a3ac1da..4d5ddbae 100644 --- a/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php +++ b/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php @@ -18,7 +18,7 @@ * http://www.gnu.org/copyleft/gpl.html */ -require_once( 'ApiQueryContinueTestBase.php' ); +require_once 'ApiQueryContinueTestBase.php'; /** * @group API @@ -48,7 +48,7 @@ class ApiQueryContinue2Test extends ApiQueryContinueTestBase { */ public function testA() { $this->mVerbose = false; - $mk = function( $g, $p, $gDir ) { + $mk = function ( $g, $p, $gDir ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT73462-', @@ -59,10 +59,10 @@ class ApiQueryContinue2Test extends ApiQueryContinueTestBase { ); }; // generator + 1 prop + 1 list - $data = $this->query( $mk(99,99,true), 1, 'g1p', false ); - $this->checkC( $data, $mk(1,1,true), 6, 'g1p-11t' ); - $this->checkC( $data, $mk(2,2,true), 3, 'g1p-22t' ); - $this->checkC( $data, $mk(1,1,false), 6, 'g1p-11f' ); - $this->checkC( $data, $mk(2,2,false), 3, 'g1p-22f' ); + $data = $this->query( $mk( 99, 99, true ), 1, 'g1p', false ); + $this->checkC( $data, $mk( 1, 1, true ), 6, 'g1p-11t' ); + $this->checkC( $data, $mk( 2, 2, true ), 3, 'g1p-22t' ); + $this->checkC( $data, $mk( 1, 1, false ), 6, 'g1p-11f' ); + $this->checkC( $data, $mk( 2, 2, false ), 3, 'g1p-22f' ); } } diff --git a/tests/phpunit/includes/api/query/ApiQueryContinueTest.php b/tests/phpunit/includes/api/query/ApiQueryContinueTest.php index cb8f1812..f494e9ca 100644 --- a/tests/phpunit/includes/api/query/ApiQueryContinueTest.php +++ b/tests/phpunit/includes/api/query/ApiQueryContinueTest.php @@ -18,7 +18,7 @@ * http://www.gnu.org/copyleft/gpl.html */ -require_once( 'ApiQueryContinueTestBase.php' ); +require_once 'ApiQueryContinueTestBase.php'; /** * These tests validate the new continue functionality of the api query module by @@ -58,21 +58,21 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function test1List() { $this->mVerbose = false; - $mk = function( $l ) { + $mk = function ( $l ) { return array( 'list' => 'allpages', 'apprefix' => 'AQCT-', 'aplimit' => "$l", ); }; - $data = $this->query( $mk(99), 1, '1L', false ); + $data = $this->query( $mk( 99 ), 1, '1L', false ); // 1 list - $this->checkC( $data, $mk(1), 5, '1L-1' ); - $this->checkC( $data, $mk(2), 3, '1L-2' ); - $this->checkC( $data, $mk(3), 2, '1L-3' ); - $this->checkC( $data, $mk(4), 2, '1L-4' ); - $this->checkC( $data, $mk(5), 1, '1L-5' ); + $this->checkC( $data, $mk( 1 ), 5, '1L-1' ); + $this->checkC( $data, $mk( 2 ), 3, '1L-2' ); + $this->checkC( $data, $mk( 3 ), 2, '1L-3' ); + $this->checkC( $data, $mk( 4 ), 2, '1L-4' ); + $this->checkC( $data, $mk( 5 ), 1, '1L-5' ); } /** @@ -81,7 +81,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function test2Lists() { $this->mVerbose = false; - $mk = function( $l1, $l2 ) { + $mk = function ( $l1, $l2 ) { return array( 'list' => 'allpages|alltransclusions', 'apprefix' => 'AQCT-', @@ -92,12 +92,12 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // 2 lists - $data = $this->query( $mk(99,99), 1, '2L', false ); - $this->checkC( $data, $mk(1,1), 5, '2L-11' ); - $this->checkC( $data, $mk(2,2), 3, '2L-22' ); - $this->checkC( $data, $mk(3,3), 2, '2L-33' ); - $this->checkC( $data, $mk(4,4), 2, '2L-44' ); - $this->checkC( $data, $mk(5,5), 1, '2L-55' ); + $data = $this->query( $mk( 99, 99 ), 1, '2L', false ); + $this->checkC( $data, $mk( 1, 1 ), 5, '2L-11' ); + $this->checkC( $data, $mk( 2, 2 ), 3, '2L-22' ); + $this->checkC( $data, $mk( 3, 3 ), 2, '2L-33' ); + $this->checkC( $data, $mk( 4, 4 ), 2, '2L-44' ); + $this->checkC( $data, $mk( 5, 5 ), 1, '2L-55' ); } /** @@ -106,7 +106,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testGen1Prop() { $this->mVerbose = false; - $mk = function( $g, $p ) { + $mk = function ( $g, $p ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -116,12 +116,12 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 prop - $data = $this->query( $mk(99,99), 1, 'G1P', false ); - $this->checkC( $data, $mk(1,1), 11, 'G1P-11' ); - $this->checkC( $data, $mk(2,2), 6, 'G1P-22' ); - $this->checkC( $data, $mk(3,3), 4, 'G1P-33' ); - $this->checkC( $data, $mk(4,4), 3, 'G1P-44' ); - $this->checkC( $data, $mk(5,5), 2, 'G1P-55' ); + $data = $this->query( $mk( 99, 99 ), 1, 'G1P', false ); + $this->checkC( $data, $mk( 1, 1 ), 11, 'G1P-11' ); + $this->checkC( $data, $mk( 2, 2 ), 6, 'G1P-22' ); + $this->checkC( $data, $mk( 3, 3 ), 4, 'G1P-33' ); + $this->checkC( $data, $mk( 4, 4 ), 3, 'G1P-44' ); + $this->checkC( $data, $mk( 5, 5 ), 2, 'G1P-55' ); } /** @@ -130,7 +130,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testGen2Prop() { $this->mVerbose = false; - $mk = function( $g, $p1, $p2 ) { + $mk = function ( $g, $p1, $p2 ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -141,17 +141,17 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 2 props - $data = $this->query( $mk(99,99,99), 1, 'G2P', false ); - $this->checkC( $data, $mk(1,1,1), 16, 'G2P-111' ); - $this->checkC( $data, $mk(2,2,2), 9, 'G2P-222' ); - $this->checkC( $data, $mk(3,3,3), 6, 'G2P-333' ); - $this->checkC( $data, $mk(4,4,4), 4, 'G2P-444' ); - $this->checkC( $data, $mk(5,5,5), 2, 'G2P-555' ); - $this->checkC( $data, $mk(5,1,1), 10, 'G2P-511' ); - $this->checkC( $data, $mk(4,2,2), 7, 'G2P-422' ); - $this->checkC( $data, $mk(2,3,3), 7, 'G2P-233' ); - $this->checkC( $data, $mk(2,4,4), 5, 'G2P-244' ); - $this->checkC( $data, $mk(1,5,5), 5, 'G2P-155' ); + $data = $this->query( $mk( 99, 99, 99 ), 1, 'G2P', false ); + $this->checkC( $data, $mk( 1, 1, 1 ), 16, 'G2P-111' ); + $this->checkC( $data, $mk( 2, 2, 2 ), 9, 'G2P-222' ); + $this->checkC( $data, $mk( 3, 3, 3 ), 6, 'G2P-333' ); + $this->checkC( $data, $mk( 4, 4, 4 ), 4, 'G2P-444' ); + $this->checkC( $data, $mk( 5, 5, 5 ), 2, 'G2P-555' ); + $this->checkC( $data, $mk( 5, 1, 1 ), 10, 'G2P-511' ); + $this->checkC( $data, $mk( 4, 2, 2 ), 7, 'G2P-422' ); + $this->checkC( $data, $mk( 2, 3, 3 ), 7, 'G2P-233' ); + $this->checkC( $data, $mk( 2, 4, 4 ), 5, 'G2P-244' ); + $this->checkC( $data, $mk( 1, 5, 5 ), 5, 'G2P-155' ); } /** @@ -160,7 +160,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testGen1Prop1List() { $this->mVerbose = false; - $mk = function( $g, $p, $l ) { + $mk = function ( $g, $p, $l ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -174,24 +174,24 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 prop + 1 list - $data = $this->query( $mk(99,99,99), 1, 'G1P1L', false ); - $this->checkC( $data, $mk(1,1,1), 11, 'G1P1L-111' ); - $this->checkC( $data, $mk(2,2,2), 6, 'G1P1L-222' ); - $this->checkC( $data, $mk(3,3,3), 4, 'G1P1L-333' ); - $this->checkC( $data, $mk(4,4,4), 3, 'G1P1L-444' ); - $this->checkC( $data, $mk(5,5,5), 2, 'G1P1L-555' ); - $this->checkC( $data, $mk(5,5,1), 4, 'G1P1L-551' ); - $this->checkC( $data, $mk(5,5,2), 2, 'G1P1L-552' ); + $data = $this->query( $mk( 99, 99, 99 ), 1, 'G1P1L', false ); + $this->checkC( $data, $mk( 1, 1, 1 ), 11, 'G1P1L-111' ); + $this->checkC( $data, $mk( 2, 2, 2 ), 6, 'G1P1L-222' ); + $this->checkC( $data, $mk( 3, 3, 3 ), 4, 'G1P1L-333' ); + $this->checkC( $data, $mk( 4, 4, 4 ), 3, 'G1P1L-444' ); + $this->checkC( $data, $mk( 5, 5, 5 ), 2, 'G1P1L-555' ); + $this->checkC( $data, $mk( 5, 5, 1 ), 4, 'G1P1L-551' ); + $this->checkC( $data, $mk( 5, 5, 2 ), 2, 'G1P1L-552' ); } /** * Test smart continue - generator=allpages, prop=links|templates, - * list=alllinks|alltransclusions, meta=siteinfo + * list=alllinks|alltransclusions, meta=siteinfo * @medium */ public function testGen2Prop2List1Meta() { $this->mVerbose = false; - $mk = function( $g, $p1, $p2, $l1, $l2 ) { + $mk = function ( $g, $p1, $p2, $l1, $l2 ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -211,16 +211,16 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 prop + 1 list - $data = $this->query( $mk(99,99,99,99,99), 1, 'G2P2L1M', false ); - $this->checkC( $data, $mk(1,1,1,1,1), 16, 'G2P2L1M-11111' ); - $this->checkC( $data, $mk(2,2,2,2,2), 9, 'G2P2L1M-22222' ); - $this->checkC( $data, $mk(3,3,3,3,3), 6, 'G2P2L1M-33333' ); - $this->checkC( $data, $mk(4,4,4,4,4), 4, 'G2P2L1M-44444' ); - $this->checkC( $data, $mk(5,5,5,5,5), 2, 'G2P2L1M-55555' ); - $this->checkC( $data, $mk(5,5,5,1,1), 4, 'G2P2L1M-55511' ); - $this->checkC( $data, $mk(5,5,5,2,2), 2, 'G2P2L1M-55522' ); - $this->checkC( $data, $mk(5,1,1,5,5), 10, 'G2P2L1M-51155' ); - $this->checkC( $data, $mk(5,2,2,5,5), 5, 'G2P2L1M-52255' ); + $data = $this->query( $mk( 99, 99, 99, 99, 99 ), 1, 'G2P2L1M', false ); + $this->checkC( $data, $mk( 1, 1, 1, 1, 1 ), 16, 'G2P2L1M-11111' ); + $this->checkC( $data, $mk( 2, 2, 2, 2, 2 ), 9, 'G2P2L1M-22222' ); + $this->checkC( $data, $mk( 3, 3, 3, 3, 3 ), 6, 'G2P2L1M-33333' ); + $this->checkC( $data, $mk( 4, 4, 4, 4, 4 ), 4, 'G2P2L1M-44444' ); + $this->checkC( $data, $mk( 5, 5, 5, 5, 5 ), 2, 'G2P2L1M-55555' ); + $this->checkC( $data, $mk( 5, 5, 5, 1, 1 ), 4, 'G2P2L1M-55511' ); + $this->checkC( $data, $mk( 5, 5, 5, 2, 2 ), 2, 'G2P2L1M-55522' ); + $this->checkC( $data, $mk( 5, 1, 1, 5, 5 ), 10, 'G2P2L1M-51155' ); + $this->checkC( $data, $mk( 5, 2, 2, 5, 5 ), 5, 'G2P2L1M-52255' ); } /** @@ -229,7 +229,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testSameGenAndProp() { $this->mVerbose = false; - $mk = function( $g, $gDir, $p, $pDir ) { + $mk = function ( $g, $gDir, $p, $pDir ) { return array( 'titles' => 'AQCT-1', 'generator' => 'templates', @@ -241,31 +241,31 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 prop - $data = $this->query( $mk(99,true,99,true), 1, 'G=P', false ); + $data = $this->query( $mk( 99, true, 99, true ), 1, 'G=P', false ); - $this->checkC( $data, $mk(1,true,1,true), 4, 'G=P-1t1t' ); - $this->checkC( $data, $mk(2,true,2,true), 2, 'G=P-2t2t' ); - $this->checkC( $data, $mk(3,true,3,true), 2, 'G=P-3t3t' ); - $this->checkC( $data, $mk(1,true,3,true), 4, 'G=P-1t3t' ); - $this->checkC( $data, $mk(3,true,1,true), 2, 'G=P-3t1t' ); + $this->checkC( $data, $mk( 1, true, 1, true ), 4, 'G=P-1t1t' ); + $this->checkC( $data, $mk( 2, true, 2, true ), 2, 'G=P-2t2t' ); + $this->checkC( $data, $mk( 3, true, 3, true ), 2, 'G=P-3t3t' ); + $this->checkC( $data, $mk( 1, true, 3, true ), 4, 'G=P-1t3t' ); + $this->checkC( $data, $mk( 3, true, 1, true ), 2, 'G=P-3t1t' ); - $this->checkC( $data, $mk(1,true,1,false), 4, 'G=P-1t1f' ); - $this->checkC( $data, $mk(2,true,2,false), 2, 'G=P-2t2f' ); - $this->checkC( $data, $mk(3,true,3,false), 2, 'G=P-3t3f' ); - $this->checkC( $data, $mk(1,true,3,false), 4, 'G=P-1t3f' ); - $this->checkC( $data, $mk(3,true,1,false), 2, 'G=P-3t1f' ); + $this->checkC( $data, $mk( 1, true, 1, false ), 4, 'G=P-1t1f' ); + $this->checkC( $data, $mk( 2, true, 2, false ), 2, 'G=P-2t2f' ); + $this->checkC( $data, $mk( 3, true, 3, false ), 2, 'G=P-3t3f' ); + $this->checkC( $data, $mk( 1, true, 3, false ), 4, 'G=P-1t3f' ); + $this->checkC( $data, $mk( 3, true, 1, false ), 2, 'G=P-3t1f' ); - $this->checkC( $data, $mk(1,false,1,true), 4, 'G=P-1f1t' ); - $this->checkC( $data, $mk(2,false,2,true), 2, 'G=P-2f2t' ); - $this->checkC( $data, $mk(3,false,3,true), 2, 'G=P-3f3t' ); - $this->checkC( $data, $mk(1,false,3,true), 4, 'G=P-1f3t' ); - $this->checkC( $data, $mk(3,false,1,true), 2, 'G=P-3f1t' ); + $this->checkC( $data, $mk( 1, false, 1, true ), 4, 'G=P-1f1t' ); + $this->checkC( $data, $mk( 2, false, 2, true ), 2, 'G=P-2f2t' ); + $this->checkC( $data, $mk( 3, false, 3, true ), 2, 'G=P-3f3t' ); + $this->checkC( $data, $mk( 1, false, 3, true ), 4, 'G=P-1f3t' ); + $this->checkC( $data, $mk( 3, false, 1, true ), 2, 'G=P-3f1t' ); - $this->checkC( $data, $mk(1,false,1,false), 4, 'G=P-1f1f' ); - $this->checkC( $data, $mk(2,false,2,false), 2, 'G=P-2f2f' ); - $this->checkC( $data, $mk(3,false,3,false), 2, 'G=P-3f3f' ); - $this->checkC( $data, $mk(1,false,3,false), 4, 'G=P-1f3f' ); - $this->checkC( $data, $mk(3,false,1,false), 2, 'G=P-3f1f' ); + $this->checkC( $data, $mk( 1, false, 1, false ), 4, 'G=P-1f1f' ); + $this->checkC( $data, $mk( 2, false, 2, false ), 2, 'G=P-2f2f' ); + $this->checkC( $data, $mk( 3, false, 3, false ), 2, 'G=P-3f3f' ); + $this->checkC( $data, $mk( 1, false, 3, false ), 4, 'G=P-1f3f' ); + $this->checkC( $data, $mk( 3, false, 1, false ), 2, 'G=P-3f1f' ); } /** @@ -274,7 +274,7 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { */ public function testSameGenList() { $this->mVerbose = false; - $mk = function( $g, $gDir, $l, $pDir ) { + $mk = function ( $g, $gDir, $l, $pDir ) { return array( 'generator' => 'allpages', 'gapprefix' => 'AQCT-', @@ -287,27 +287,27 @@ class ApiQueryContinueTest extends ApiQueryContinueTestBase { ); }; // generator + 1 list - $data = $this->query( $mk(99,true,99,true), 1, 'G=L', false ); + $data = $this->query( $mk( 99, true, 99, true ), 1, 'G=L', false ); - $this->checkC( $data, $mk(1,true,1,true), 5, 'G=L-1t1t' ); - $this->checkC( $data, $mk(2,true,2,true), 3, 'G=L-2t2t' ); - $this->checkC( $data, $mk(3,true,3,true), 2, 'G=L-3t3t' ); - $this->checkC( $data, $mk(1,true,3,true), 5, 'G=L-1t3t' ); - $this->checkC( $data, $mk(3,true,1,true), 5, 'G=L-3t1t' ); - $this->checkC( $data, $mk(1,true,1,false), 5, 'G=L-1t1f' ); - $this->checkC( $data, $mk(2,true,2,false), 3, 'G=L-2t2f' ); - $this->checkC( $data, $mk(3,true,3,false), 2, 'G=L-3t3f' ); - $this->checkC( $data, $mk(1,true,3,false), 5, 'G=L-1t3f' ); - $this->checkC( $data, $mk(3,true,1,false), 5, 'G=L-3t1f' ); - $this->checkC( $data, $mk(1,false,1,true), 5, 'G=L-1f1t' ); - $this->checkC( $data, $mk(2,false,2,true), 3, 'G=L-2f2t' ); - $this->checkC( $data, $mk(3,false,3,true), 2, 'G=L-3f3t' ); - $this->checkC( $data, $mk(1,false,3,true), 5, 'G=L-1f3t' ); - $this->checkC( $data, $mk(3,false,1,true), 5, 'G=L-3f1t' ); - $this->checkC( $data, $mk(1,false,1,false), 5, 'G=L-1f1f' ); - $this->checkC( $data, $mk(2,false,2,false), 3, 'G=L-2f2f' ); - $this->checkC( $data, $mk(3,false,3,false), 2, 'G=L-3f3f' ); - $this->checkC( $data, $mk(1,false,3,false), 5, 'G=L-1f3f' ); - $this->checkC( $data, $mk(3,false,1,false), 5, 'G=L-3f1f' ); + $this->checkC( $data, $mk( 1, true, 1, true ), 5, 'G=L-1t1t' ); + $this->checkC( $data, $mk( 2, true, 2, true ), 3, 'G=L-2t2t' ); + $this->checkC( $data, $mk( 3, true, 3, true ), 2, 'G=L-3t3t' ); + $this->checkC( $data, $mk( 1, true, 3, true ), 5, 'G=L-1t3t' ); + $this->checkC( $data, $mk( 3, true, 1, true ), 5, 'G=L-3t1t' ); + $this->checkC( $data, $mk( 1, true, 1, false ), 5, 'G=L-1t1f' ); + $this->checkC( $data, $mk( 2, true, 2, false ), 3, 'G=L-2t2f' ); + $this->checkC( $data, $mk( 3, true, 3, false ), 2, 'G=L-3t3f' ); + $this->checkC( $data, $mk( 1, true, 3, false ), 5, 'G=L-1t3f' ); + $this->checkC( $data, $mk( 3, true, 1, false ), 5, 'G=L-3t1f' ); + $this->checkC( $data, $mk( 1, false, 1, true ), 5, 'G=L-1f1t' ); + $this->checkC( $data, $mk( 2, false, 2, true ), 3, 'G=L-2f2t' ); + $this->checkC( $data, $mk( 3, false, 3, true ), 2, 'G=L-3f3t' ); + $this->checkC( $data, $mk( 1, false, 3, true ), 5, 'G=L-1f3t' ); + $this->checkC( $data, $mk( 3, false, 1, true ), 5, 'G=L-3f1t' ); + $this->checkC( $data, $mk( 1, false, 1, false ), 5, 'G=L-1f1f' ); + $this->checkC( $data, $mk( 2, false, 2, false ), 3, 'G=L-2f2f' ); + $this->checkC( $data, $mk( 3, false, 3, false ), 2, 'G=L-3f3f' ); + $this->checkC( $data, $mk( 1, false, 3, false ), 5, 'G=L-1f3f' ); + $this->checkC( $data, $mk( 3, false, 1, false ), 5, 'G=L-3f1f' ); } } diff --git a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php b/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php index 47174796..fbb1e640 100644 --- a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php +++ b/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php @@ -24,7 +24,7 @@ * @file */ -require_once( 'ApiQueryTestBase.php' ); +require_once 'ApiQueryTestBase.php'; abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { @@ -36,7 +36,7 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { /** * Run query() and compare against expected values */ - protected function checkC( $expected, $params, $expectedCount, $id, $continue = true ) { + protected function checkC( $expected, $params, $expectedCount, $id, $continue = true ) { $result = $this->query( $params, $expectedCount, $id, $continue ); $this->assertResult( $expected, $result, $id ); } @@ -52,7 +52,7 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { */ protected function query( $params, $expectedCount, $id, $useContinue = true ) { if ( isset( $params['action'] ) ) { - $this->assertEquals( 'query', $params['action'], 'Invalid query action'); + $this->assertEquals( 'query', $params['action'], 'Invalid query action' ); } else { $params['action'] = 'query'; } @@ -64,17 +64,18 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { $continue = array(); do { $request = array_merge( $params, $continue ); - uksort( $request, function( $a, $b ) { + uksort( $request, function ( $a, $b ) { // put 'continue' params at the end - lazy method $a = strpos( $a, 'continue' ) !== false ? 'zzz ' . $a : $a; $b = strpos( $b, 'continue' ) !== false ? 'zzz ' . $b : $b; + return strcmp( $a, $b ); } ); $reqStr = http_build_query( $request ); //$reqStr = str_replace( '&', ' & ', $reqStr ); $this->assertLessThan( $expectedCount, $count, "$id more data: $reqStr" ); if ( $this->mVerbose ) { - print ("$id (#$count): $reqStr\n"); + print "$id (#$count): $reqStr\n"; } try { $data = $this->doApiRequest( $request ); @@ -103,52 +104,57 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { if ( $expectedCount > $count ) { print "***** $id Finished early in $count turns. $expectedCount was expected\n"; } + return $result; } elseif ( !$useContinue ) { $this->assertFalse( 'Non-smart query must be requested all at once' ); } - } while( true ); + } while ( true ); } private function printResult( $data ) { $q = $data['query']; $print = array(); - if (isset($q['pages'])) { - foreach ($q['pages'] as $p) { + if ( isset( $q['pages'] ) ) { + foreach ( $q['pages'] as $p ) { $m = $p['title']; - if (isset($p['links'])) { - $m .= '/[' . implode(',', array_map( - function ($v) { + if ( isset( $p['links'] ) ) { + $m .= '/[' . implode( ',', array_map( + function ( $v ) { return $v['title']; }, - $p['links'])) . ']'; + $p['links'] ) ) . ']'; } - if (isset($p['categories'])) { - $m .= '/(' . implode(',', array_map( - function ($v) { - return str_replace('Category:', '', $v['title']); + if ( isset( $p['categories'] ) ) { + $m .= '/(' . implode( ',', array_map( + function ( $v ) { + return str_replace( 'Category:', '', $v['title'] ); }, - $p['categories'])) . ')'; + $p['categories'] ) ) . ')'; } $print[] = $m; } } - if (isset($q['allcategories'])) { - $print[] = '*Cats/(' . implode(',', array_map( - function ($v) { return $v['*']; }, - $q['allcategories'])) . ')'; + if ( isset( $q['allcategories'] ) ) { + $print[] = '*Cats/(' . implode( ',', array_map( + function ( $v ) { + return $v['*']; + }, + $q['allcategories'] ) ) . ')'; } self::GetItems( $q, 'allpages', 'Pages', $print ); self::GetItems( $q, 'alllinks', 'Links', $print ); self::GetItems( $q, 'alltransclusions', 'Trnscl', $print ); - print(' ' . implode(' ', $print) . "\n"); + print ' ' . implode( ' ', $print ) . "\n"; } private static function GetItems( $q, $moduleName, $name, &$print ) { - if (isset($q[$moduleName])) { - $print[] = "*$name/[" . implode(',', - array_map( function ($v) { return $v['title']; }, - $q[$moduleName])) . ']'; + if ( isset( $q[$moduleName] ) ) { + $print[] = "*$name/[" . implode( ',', + array_map( function ( $v ) { + return $v['title']; + }, + $q[$moduleName] ) ) . ']'; } } @@ -164,12 +170,12 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { $this->assertEquals( $results, $newResult, 'Repeated result must be the same as before' ); } else { $sort = null; - foreach( $newResult as $key => $value ) { + foreach ( $newResult as $key => $value ) { if ( !$numericIds && $sort === null ) { if ( !is_array( $value ) ) { $sort = false; } elseif ( array_key_exists( 'title', $value ) ) { - $sort = function( $a, $b ) { + $sort = function ( $a, $b ) { return strcmp( $a['title'], $b['title'] ); }; } else { diff --git a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php b/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php index 7f5fe91c..1bca2256 100644 --- a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php +++ b/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php @@ -10,7 +10,7 @@ class ApiQueryRevisionsTest extends ApiTestCase { /** * @group medium */ - function testContentComesWithContentModelAndFormat() { + public function testContentComesWithContentModelAndFormat() { $pageName = 'Help:' . __METHOD__; $title = Title::newFromText( $pageName ); $page = WikiPage::factory( $title ); diff --git a/tests/phpunit/includes/api/query/ApiQueryTest.php b/tests/phpunit/includes/api/query/ApiQueryTest.php index 7fb53073..f5645555 100644 --- a/tests/phpunit/includes/api/query/ApiQueryTest.php +++ b/tests/phpunit/includes/api/query/ApiQueryTest.php @@ -12,7 +12,7 @@ class ApiQueryTest extends ApiTestCase { $this->doLogin(); } - function testTitlesGetNormalized() { + public function testTitlesGetNormalized() { global $wgMetaNamespace; @@ -20,7 +20,6 @@ class ApiQueryTest extends ApiTestCase { 'action' => 'query', 'titles' => 'Project:articleA|article_B' ) ); - $this->assertArrayHasKey( 'query', $data[0] ); $this->assertArrayHasKey( 'normalized', $data[0]['query'] ); @@ -42,10 +41,9 @@ class ApiQueryTest extends ApiTestCase { ), $data[0]['query']['normalized'][1] ); - } - function testTitlesAreRejectedIfInvalid() { + public function testTitlesAreRejectedIfInvalid() { $title = false; while ( !$title || Title::newFromText( $title )->exists() ) { $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) ); @@ -65,5 +63,4 @@ class ApiQueryTest extends ApiTestCase { $this->assertArrayHasKey( 'missing', $data[0]['query']['pages'][-2] ); $this->assertArrayHasKey( 'invalid', $data[0]['query']['pages'][-1] ); } - } diff --git a/tests/phpunit/includes/api/query/ApiQueryTestBase.php b/tests/phpunit/includes/api/query/ApiQueryTestBase.php index 7b9f8ede..8ee8ea96 100644 --- a/tests/phpunit/includes/api/query/ApiQueryTestBase.php +++ b/tests/phpunit/includes/api/query/ApiQueryTestBase.php @@ -24,7 +24,6 @@ * @file */ - /** This class has some common functionality for testing query module */ abstract class ApiQueryTestBase extends ApiTestCase { @@ -43,11 +42,12 @@ STR; protected function merge( /*...*/ ) { $request = array(); $expected = array(); - foreach ( func_get_args() as $v ) { + foreach ( func_get_args() as $v ) { list( $req, $exp ) = $this->validateRequestExpectedPair( $v ); $request = array_merge_recursive( $request, $req ); $this->mergeExpected( $expected, $exp ); } + return array( $request, $expected ); } @@ -57,11 +57,12 @@ STR; */ private function validateRequestExpectedPair( $v ) { $this->assertType( 'array', $v, self::PARAM_ASSERT ); - $this->assertEquals( 2, count($v), self::PARAM_ASSERT ); + $this->assertEquals( 2, count( $v ), self::PARAM_ASSERT ); $this->assertArrayHasKey( 0, $v, self::PARAM_ASSERT ); $this->assertArrayHasKey( 1, $v, self::PARAM_ASSERT ); $this->assertType( 'array', $v[0], self::PARAM_ASSERT ); $this->assertType( 'array', $v[1], self::PARAM_ASSERT ); + return $v; } @@ -71,7 +72,7 @@ STR; private function mergeExpected( &$all, $item ) { foreach ( $item as $k => $v ) { if ( array_key_exists( $k, $all ) ) { - if ( is_array ( $all[$k] ) ) { + if ( is_array( $all[$k] ) ) { $this->mergeExpected( $all[$k], $v ); } else { $this->assertEquals( $all[$k], $v ); @@ -108,10 +109,10 @@ STR; if ( is_array( $message ) ) { $message = http_build_query( $message ); } - print( "\nRequest: $message\n" ); - print( "\nExpected:\n" ); + print "\nRequest: $message\n"; + print "\nExpected:\n"; print_r( $exp ); - print( "\nResult:\n" ); + print "\nResult:\n"; print_r( $result ); throw $e; // rethrow it } diff --git a/tests/phpunit/includes/cache/GenderCacheTest.php b/tests/phpunit/includes/cache/GenderCacheTest.php index ee3db3e8..ce2db5d7 100644 --- a/tests/phpunit/includes/cache/GenderCacheTest.php +++ b/tests/phpunit/includes/cache/GenderCacheTest.php @@ -46,8 +46,9 @@ class GenderCacheTest extends MediaWikiLangTestCase { * test usernames * * @dataProvider provideUserGenders + * @covers GenderCache::getGenderOf */ - function testUserName( $username, $expectedGender ) { + public function testUserName( $username, $expectedGender ) { $genderCache = GenderCache::singleton(); $gender = $genderCache->getGenderOf( $username ); $this->assertEquals( $gender, $expectedGender, "GenderCache normal" ); @@ -57,8 +58,9 @@ class GenderCacheTest extends MediaWikiLangTestCase { * genderCache should work with user objects, too * * @dataProvider provideUserGenders + * @covers GenderCache::getGenderOf */ - function testUserObjects( $username, $expectedGender ) { + public function testUserObjects( $username, $expectedGender ) { $genderCache = GenderCache::singleton(); $user = User::newFromName( $username ); $gender = $genderCache->getGenderOf( $user ); @@ -82,8 +84,9 @@ class GenderCacheTest extends MediaWikiLangTestCase { * against the never existing username * * @dataProvider provideStripSubpages + * @covers GenderCache::getGenderOf */ - function testStripSubpages( $pageWithSubpage, $expectedGender ) { + public function testStripSubpages( $pageWithSubpage, $expectedGender ) { $genderCache = GenderCache::singleton(); $gender = $genderCache->getGenderOf( $pageWithSubpage ); $this->assertEquals( $gender, $expectedGender, "GenderCache must strip of subpages" ); diff --git a/tests/phpunit/includes/cache/MessageCacheTest.php b/tests/phpunit/includes/cache/MessageCacheTest.php new file mode 100644 index 00000000..803acf73 --- /dev/null +++ b/tests/phpunit/includes/cache/MessageCacheTest.php @@ -0,0 +1,128 @@ +<?php + +/** + * @group Database + * @group Cache + * @covers MessageCache + */ +class MessageCacheTest extends MediaWikiLangTestCase { + + protected function setUp() { + parent::setUp(); + $this->configureLanguages(); + MessageCache::singleton()->enable(); + } + + /** + * Helper function -- setup site language for testing + */ + protected function configureLanguages() { + // for the test, we need the content language to be anything but English, + // let's choose e.g. German (de) + $langCode = 'de'; + $langObj = Language::factory( $langCode ); + + $this->setMwGlobals( array( + 'wgLanguageCode' => $langCode, + 'wgLang' => $langObj, + 'wgContLang' => $langObj, + ) ); + } + + function addDBData() { + $this->configureLanguages(); + + // Set up messages and fallbacks ab -> ru -> de + $this->makePage( 'FallbackLanguageTest-Full', 'ab' ); + $this->makePage( 'FallbackLanguageTest-Full', 'ru' ); + $this->makePage( 'FallbackLanguageTest-Full', 'de' ); + + // Fallbacks where ab does not exist + $this->makePage( 'FallbackLanguageTest-Partial', 'ru' ); + $this->makePage( 'FallbackLanguageTest-Partial', 'de' ); + + // Fallback to the content language + $this->makePage( 'FallbackLanguageTest-ContLang', 'de' ); + + // Add customizations for an existing message. + $this->makePage( 'sunday', 'ru' ); + + // Full key tests -- always want russian + $this->makePage( 'MessageCacheTest-FullKeyTest', 'ab' ); + $this->makePage( 'MessageCacheTest-FullKeyTest', 'ru' ); + + // In content language -- get base if no derivative + $this->makePage( 'FallbackLanguageTest-NoDervContLang', 'de', 'de/none', false ); + } + + /** + * Helper function for addDBData -- adds a simple page to the database + * + * @param string $title Title of page to be created + * @param string $lang Language and content of the created page + * @param string|null $content Content of the created page, or null for a generic string + * @param bool $createSubPage Set to false if a root page should be created + */ + protected function makePage( $title, $lang, $content = null, $createSubPage = true ) { + global $wgContLang; + + if ( $content === null ) { + $content = $lang; + } + if ( $lang !== $wgContLang->getCode() || $createSubPage ) { + $title = "$title/$lang"; + } + + $title = Title::newFromText( $title, NS_MEDIAWIKI ); + $wikiPage = new WikiPage( $title ); + $contentHandler = ContentHandler::makeContent( $content, $title ); + $wikiPage->doEditContent( $contentHandler, "$lang translation test case" ); + } + + /** + * Test message fallbacks, bug #1495 + * + * @dataProvider provideMessagesForFallback + */ + public function testMessageFallbacks( $message, $lang, $expectedContent ) { + $result = MessageCache::singleton()->get( $message, true, $lang ); + $this->assertEquals( $expectedContent, $result, "Message fallback failed." ); + } + + function provideMessagesForFallback() { + return array( + array( 'FallbackLanguageTest-Full', 'ab', 'ab' ), + array( 'FallbackLanguageTest-Partial', 'ab', 'ru' ), + array( 'FallbackLanguageTest-ContLang', 'ab', 'de' ), + array( 'FallbackLanguageTest-None', 'ab', false ), + + // Existing message with customizations on the fallbacks + array( 'sunday', 'ab', 'амҽыш' ), + + // bug 46579 + array( 'FallbackLanguageTest-NoDervContLang', 'de', 'de/none' ), + // UI language different from content language should only use de/none as last option + array( 'FallbackLanguageTest-NoDervContLang', 'fit', 'de/none' ), + ); + } + + /** + * There's a fallback case where the message key is given as fully qualified -- this + * should ignore the passed $lang and use the language from the key + * + * @dataProvider provideMessagesForFullKeys + */ + public function testFullKeyBehaviour( $message, $lang, $expectedContent ) { + $result = MessageCache::singleton()->get( $message, true, $lang, true ); + $this->assertEquals( $expectedContent, $result, "Full key message fallback failed." ); + } + + function provideMessagesForFullKeys() { + return array( + array( 'MessageCacheTest-FullKeyTest/ru', 'ru', 'ru' ), + array( 'MessageCacheTest-FullKeyTest/ru', 'ab', 'ru' ), + array( 'MessageCacheTest-FullKeyTest/ru/foo', 'ru', false ), + ); + } + +} diff --git a/tests/phpunit/includes/cache/ProcessCacheLRUTest.php b/tests/phpunit/includes/cache/ProcessCacheLRUTest.php index c7e75d99..d3793d83 100644 --- a/tests/phpunit/includes/cache/ProcessCacheLRUTest.php +++ b/tests/phpunit/includes/cache/ProcessCacheLRUTest.php @@ -52,13 +52,14 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { for ( $i = $firstKey; $i <= $lastKey; $i++ ) { $expected["cache-key-$i"] = array( "prop-$i" => "value-$i" ); } + return $expected; } /** * Highlight diff between assertEquals and assertNotSame */ - function testPhpUnitArrayEquality() { + public function testPhpUnitArrayEquality() { $one = array( 'A' => 1, 'B' => 2 ); $two = array( 'B' => 2, 'A' => 1 ); $this->assertEquals( $one, $two ); // == @@ -69,8 +70,8 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { * @dataProvider provideInvalidConstructorArg * @expectedException MWException */ - function testConstructorGivenInvalidValue( $maxSize ) { - $c = new ProcessCacheLRUTestable( $maxSize ); + public function testConstructorGivenInvalidValue( $maxSize ) { + new ProcessCacheLRUTestable( $maxSize ); } /** @@ -87,7 +88,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { ); } - function testAddAndGetAKey() { + public function testAddAndGetAKey() { $oneCache = new ProcessCacheLRUTestable( 1 ); $this->assertCacheEmpty( $oneCache ); @@ -98,7 +99,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { $this->assertEquals( 'value1', $oneCache->get( 'cache-key', 'prop1' ) ); } - function testDeleteOldKey() { + public function testDeleteOldKey() { $oneCache = new ProcessCacheLRUTestable( 1 ); $this->assertCacheEmpty( $oneCache ); @@ -116,7 +117,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { * @param $cacheMaxEntries Maximum entry the created cache will hold * @param $entryToFill Number of entries to insert in the created cache. */ - function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) { + public function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) { $cache = new ProcessCacheLRUTestable( $cacheMaxEntries ); $this->fillCache( $cache, $entryToFill ); @@ -125,7 +126,6 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { $cache->getCache(), "Filling a $cacheMaxEntries entries cache with $entryToFill entries" ); - } /** @@ -145,7 +145,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { * Create a cache with only one remaining entry then update * the first inserted entry. Should bump it to the top. */ - function testReplaceExistingKeyShouldBumpEntryToTop() { + public function testReplaceExistingKeyShouldBumpEntryToTop() { $maxEntries = 3; $cache = new ProcessCacheLRUTestable( $maxEntries ); @@ -164,7 +164,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { ); } - function testRecentlyAccessedKeyStickIn() { + public function testRecentlyAccessedKeyStickIn() { $cache = new ProcessCacheLRUTestable( 2 ); $cache->set( 'first', 'prop1', 'value1' ); $cache->set( 'second', 'prop2', 'value2' ); @@ -183,7 +183,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { * Given a cache having 1,2,3 as key, updating 2 should bump 2 to * the top of the queue with the new value: 1,3,2* (* = updated). */ - function testReplaceExistingKeyInAFullCacheShouldBumpToTop() { + public function testReplaceExistingKeyInAFullCacheShouldBumpToTop() { $maxEntries = 3; $cache = new ProcessCacheLRUTestable( $maxEntries ); @@ -204,7 +204,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { ); } - function testBumpExistingKeyToTop() { + public function testBumpExistingKeyToTop() { $cache = new ProcessCacheLRUTestable( 3 ); $this->fillCache( $cache, 3 ); @@ -218,9 +218,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase { ), $cache->getCache() ); - } - } /** diff --git a/tests/phpunit/includes/content/ContentHandlerTest.php b/tests/phpunit/includes/content/ContentHandlerTest.php index 19ceadd5..aedf594d 100644 --- a/tests/phpunit/includes/content/ContentHandlerTest.php +++ b/tests/phpunit/includes/content/ContentHandlerTest.php @@ -10,9 +10,9 @@ */ class ContentHandlerTest extends MediaWikiTestCase { - public function setup() { + public function setUp() { global $wgContLang; - parent::setup(); + parent::setUp(); $this->setMwGlobals( array( 'wgExtraNamespaces' => array( @@ -70,6 +70,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataGetDefaultModelFor + * @covers ContentHandler::getDefaultModelFor */ public function testGetDefaultModelFor( $title, $expectedModelId ) { $title = Title::newFromText( $title ); @@ -78,6 +79,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataGetDefaultModelFor + * @covers ContentHandler::getForTitle */ public function testGetForTitle( $title, $expectedContentModel ) { $title = Title::newFromText( $title ); @@ -97,6 +99,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataGetLocalizedName + * @covers ContentHandler::getLocalizedName */ public function testGetLocalizedName( $id, $expected ) { $name = ContentHandler::getLocalizedName( $id ); @@ -131,6 +134,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataGetPageLanguage + * @covers ContentHandler::getPageLanguage */ public function testGetPageLanguage( $title, $expected ) { if ( is_string( $title ) ) { @@ -145,62 +149,81 @@ class ContentHandlerTest extends MediaWikiTestCase { $this->assertEquals( $expected->getCode(), $lang->getCode() ); } - public function testGetContentText_Null() { - global $wgContentHandlerTextFallback; + public static function dataGetContentText_Null() { + return array( + array( 'fail' ), + array( 'serialize' ), + array( 'ignore' ), + ); + } - $content = null; + /** + * @dataProvider dataGetContentText_Null + * @covers ContentHandler::getContentText + */ + public function testGetContentText_Null( $contentHandlerTextFallback ) { + $this->setMwGlobals( 'wgContentHandlerTextFallback', $contentHandlerTextFallback ); - $wgContentHandlerTextFallback = 'fail'; - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( '', $text ); + $content = null; - $wgContentHandlerTextFallback = 'serialize'; $text = ContentHandler::getContentText( $content ); $this->assertEquals( '', $text ); + } - $wgContentHandlerTextFallback = 'ignore'; - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( '', $text ); + public static function dataGetContentText_TextContent() { + return array( + array( 'fail' ), + array( 'serialize' ), + array( 'ignore' ), + ); } - public function testGetContentText_TextContent() { - global $wgContentHandlerTextFallback; + /** + * @dataProvider dataGetContentText_TextContent + * @covers ContentHandler::getContentText + */ + public function testGetContentText_TextContent( $contentHandlerTextFallback ) { + $this->setMwGlobals( 'wgContentHandlerTextFallback', $contentHandlerTextFallback ); $content = new WikitextContent( "hello world" ); - $wgContentHandlerTextFallback = 'fail'; - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( $content->getNativeData(), $text ); - - $wgContentHandlerTextFallback = 'serialize'; - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( $content->serialize(), $text ); - - $wgContentHandlerTextFallback = 'ignore'; $text = ContentHandler::getContentText( $content ); $this->assertEquals( $content->getNativeData(), $text ); } - public function testGetContentText_NonTextContent() { - global $wgContentHandlerTextFallback; + /** + * ContentHandler::getContentText should have thrown an exception for non-text Content object + * @expectedException MWException + * @covers ContentHandler::getContentText + */ + public function testGetContentText_NonTextContent_fail() { + $this->setMwGlobals( 'wgContentHandlerTextFallback', 'fail' ); $content = new DummyContentForTesting( "hello world" ); - $wgContentHandlerTextFallback = 'fail'; + ContentHandler::getContentText( $content ); + } - try { - $text = ContentHandler::getContentText( $content ); + /** + * @covers ContentHandler::getContentText + */ + public function testGetContentText_NonTextContent_serialize() { + $this->setMwGlobals( 'wgContentHandlerTextFallback', 'serialize' ); - $this->fail( "ContentHandler::getContentText should have thrown an exception for non-text Content object" ); - } catch ( MWException $ex ) { - // as expected - } + $content = new DummyContentForTesting( "hello world" ); - $wgContentHandlerTextFallback = 'serialize'; $text = ContentHandler::getContentText( $content ); $this->assertEquals( $content->serialize(), $text ); + } + + /** + * @covers ContentHandler::getContentText + */ + public function testGetContentText_NonTextContent_ignore() { + $this->setMwGlobals( 'wgContentHandlerTextFallback', 'ignore' ); + + $content = new DummyContentForTesting( "hello world" ); - $wgContentHandlerTextFallback = 'ignore'; $text = ContentHandler::getContentText( $content ); $this->assertNull( $text ); } @@ -231,6 +254,7 @@ class ContentHandlerTest extends MediaWikiTestCase { /** * @dataProvider dataMakeContent + * @covers ContentHandler::makeContent */ public function testMakeContent( $data, $title, $modelId, $format, $expectedModelId, $expectedNativeData, $shouldFail ) { $title = Title::newFromText( $title ); @@ -247,8 +271,7 @@ class ContentHandlerTest extends MediaWikiTestCase { } catch ( MWException $ex ) { if ( !$shouldFail ) { $this->fail( "ContentHandler::makeContent failed unexpectedly: " . $ex->getMessage() ); - } - else { + } else { // dummy, so we don't get the "test did not perform any assertions" message. $this->assertTrue( true ); } @@ -261,6 +284,9 @@ class ContentHandlerTest extends MediaWikiTestCase { } */ + /** + * @covers ContentHandler::runLegacyHooks + */ public function testRunLegacyHooks() { Hooks::register( 'testRunLegacyHooks', __CLASS__ . '::dummyHookHandler' ); @@ -308,6 +334,7 @@ class DummyContentHandlerForTesting extends ContentHandler { */ public function unserializeContent( $blob, $format = null ) { $d = unserialize( $blob ); + return new DummyContentForTesting( $d ); } diff --git a/tests/phpunit/includes/content/CssContentTest.php b/tests/phpunit/includes/content/CssContentTest.php index 8f53dd3e..bd6d41fe 100644 --- a/tests/phpunit/includes/content/CssContentTest.php +++ b/tests/phpunit/includes/content/CssContentTest.php @@ -50,12 +50,18 @@ class CssContentTest extends MediaWikiTestCase { ); } + /** + * @covers CssContent::getModel + */ public function testGetModel() { $content = $this->newContent( 'hello world.' ); $this->assertEquals( CONTENT_MODEL_CSS, $content->getModel() ); } + /** + * @covers CssContent::getContentHandler + */ public function testGetContentHandler() { $content = $this->newContent( 'hello world.' ); @@ -73,9 +79,9 @@ class CssContentTest extends MediaWikiTestCase { /** * @dataProvider dataEquals + * @covers CssContent::equals */ public function testEquals( Content $a, Content $b = null, $equal = false ) { $this->assertEquals( $equal, $a->equals( $b ) ); } - } diff --git a/tests/phpunit/includes/content/JavaScriptContentTest.php b/tests/phpunit/includes/content/JavaScriptContentTest.php index 2d693feb..c8616ff0 100644 --- a/tests/phpunit/includes/content/JavaScriptContentTest.php +++ b/tests/phpunit/includes/content/JavaScriptContentTest.php @@ -89,6 +89,9 @@ class JavaScriptContentTest extends TextContentTest { ); } + /** + * @covers JavaScriptContent::addSectionHeader + */ public function testAddSectionHeader() { $content = $this->newContent( 'hello world' ); $c = $content->addSectionHeader( 'test' ); @@ -137,7 +140,7 @@ class JavaScriptContentTest extends TextContentTest { } /** - * @todo: test needs database! + * @todo Test needs database! */ /* public function getRedirectChain() { @@ -147,7 +150,7 @@ class JavaScriptContentTest extends TextContentTest { */ /** - * @todo: test needs database! + * @todo Test needs database! */ /* public function getUltimateRedirectTarget() { @@ -233,6 +236,9 @@ class JavaScriptContentTest extends TextContentTest { ); } + /** + * @covers JavaScriptContent::matchMagicWord + */ public function testMatchMagicWord() { $mw = MagicWord::get( "staticredirect" ); @@ -240,6 +246,9 @@ class JavaScriptContentTest extends TextContentTest { $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word, since it's not wikitext" ); } + /** + * @covers JavaScriptContent::updateRedirect + */ public function testUpdateRedirect() { $target = Title::newFromText( "testUpdateRedirect_target" ); @@ -249,12 +258,18 @@ class JavaScriptContentTest extends TextContentTest { $this->assertTrue( $content->equals( $newContent ), "content should be unchanged since it's not wikitext" ); } + /** + * @covers JavaScriptContent::getModel + */ public function testGetModel() { $content = $this->newContent( "hello world." ); $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getModel() ); } + /** + * @covers JavaScriptContent::getContentHandler + */ public function testGetContentHandler() { $content = $this->newContent( "hello world." ); @@ -269,5 +284,4 @@ class JavaScriptContentTest extends TextContentTest { array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "HALLO" ), false ), ); } - } diff --git a/tests/phpunit/includes/content/TextContentTest.php b/tests/phpunit/includes/content/TextContentTest.php index 382f71a8..a1f099f3 100644 --- a/tests/phpunit/includes/content/TextContentTest.php +++ b/tests/phpunit/includes/content/TextContentTest.php @@ -51,6 +51,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetParserOutput + * @covers TextContent::getParserOutput */ public function testGetParserOutput( $title, $model, $text, $expectedHtml, $expectedFields = null ) { $title = Title::newFromText( $title ); @@ -96,6 +97,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataPreSaveTransform + * @covers TextContent::preSaveTransform */ public function testPreSaveTransform( $text, $expected ) { global $wgContLang; @@ -119,6 +121,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataPreloadTransform + * @covers TextContent::preloadTransform */ public function testPreloadTransform( $text, $expected ) { global $wgContLang; @@ -140,6 +143,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetRedirectTarget + * @covers TextContent::getRedirectTarget */ public function testGetRedirectTarget( $text, $expected ) { $content = $this->newContent( $text ); @@ -154,6 +158,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetRedirectTarget + * @covers TextContent::isRedirect */ public function testIsRedirect( $text, $expected ) { $content = $this->newContent( $text ); @@ -162,7 +167,7 @@ class TextContentTest extends MediaWikiLangTestCase { } /** - * @todo: test needs database! Should be done by a test class in the Database group. + * @todo Test needs database! Should be done by a test class in the Database group. */ /* public function getRedirectChain() { @@ -172,7 +177,7 @@ class TextContentTest extends MediaWikiLangTestCase { */ /** - * @todo: test needs database! Should be done by a test class in the Database group. + * @todo Test needs database! Should be done by a test class in the Database group. */ /* public function getUltimateRedirectTarget() { @@ -209,17 +214,14 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataIsCountable * @group Database + * @covers TextContent::isCountable */ public function testIsCountable( $text, $hasLinks, $mode, $expected ) { - global $wgArticleCountMethod; - - $old = $wgArticleCountMethod; - $wgArticleCountMethod = $mode; + $this->setMwGlobals( 'wgArticleCountMethod', $mode ); $content = $this->newContent( $text ); $v = $content->isCountable( $hasLinks, $this->context->getTitle() ); - $wgArticleCountMethod = $old; $this->assertEquals( $expected, $v, 'isCountable() returned unexpected value ' . var_export( $v, true ) . ' instead of ' . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); @@ -244,6 +246,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetTextForSummary + * @covers TextContent::getTextForSummary */ public function testGetTextForSummary( $text, $maxlength, $expected ) { $content = $this->newContent( $text ); @@ -251,12 +254,18 @@ class TextContentTest extends MediaWikiLangTestCase { $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) ); } + /** + * @covers TextContent::getTextForSearchIndex + */ public function testGetTextForSearchIndex() { $content = $this->newContent( 'hello world.' ); $this->assertEquals( 'hello world.', $content->getTextForSearchIndex() ); } + /** + * @covers TextContent::copy + */ public function testCopy() { $content = $this->newContent( 'hello world.' ); $copy = $content->copy(); @@ -265,30 +274,45 @@ class TextContentTest extends MediaWikiLangTestCase { $this->assertEquals( 'hello world.', $copy->getNativeData() ); } + /** + * @covers TextContent::getSize + */ public function testGetSize() { $content = $this->newContent( 'hello world.' ); $this->assertEquals( 12, $content->getSize() ); } + /** + * @covers TextContent::getNativeData + */ public function testGetNativeData() { $content = $this->newContent( 'hello world.' ); $this->assertEquals( 'hello world.', $content->getNativeData() ); } + /** + * @covers TextContent::getWikitextForTransclusion + */ public function testGetWikitextForTransclusion() { $content = $this->newContent( 'hello world.' ); $this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() ); } + /** + * @covers TextContent::getModel + */ public function testGetModel() { $content = $this->newContent( "hello world." ); $this->assertEquals( CONTENT_MODEL_TEXT, $content->getModel() ); } + /** + * @covers TextContent::getContentHandler + */ public function testGetContentHandler() { $content = $this->newContent( "hello world." ); @@ -306,6 +330,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataIsEmpty + * @covers TextContent::isEmpty */ public function testIsEmpty( $text, $empty ) { $content = $this->newContent( $text ); @@ -325,6 +350,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataEquals + * @covers TextContent::equals */ public function testEquals( Content $a, Content $b = null, $equal = false ) { $this->assertEquals( $equal, $a->equals( $b ) ); @@ -346,6 +372,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetDeletionUpdates + * @covers TextContent::getDeletionUpdates */ public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) { $ns = $this->getDefaultWikitextNS(); @@ -414,6 +441,7 @@ class TextContentTest extends MediaWikiLangTestCase { /** * @dataProvider provideConvert + * @covers TextContent::convert */ public function testConvert( $text, $model, $lossy, $expectedNative ) { $content = $this->newContent( $text ); @@ -427,5 +455,4 @@ class TextContentTest extends MediaWikiLangTestCase { $this->assertEquals( $expectedNative, $converted->getNativeData() ); } } - } diff --git a/tests/phpunit/includes/content/WikitextContentHandlerTest.php b/tests/phpunit/includes/content/WikitextContentHandlerTest.php index 0f6a968b..75a72784 100644 --- a/tests/phpunit/includes/content/WikitextContentHandlerTest.php +++ b/tests/phpunit/includes/content/WikitextContentHandlerTest.php @@ -16,6 +16,9 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { $this->handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT ); } + /** + * @covers WikitextContentHandler::serializeContent + */ public function testSerializeContent() { $content = new WikitextContent( 'hello world' ); @@ -30,6 +33,9 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { } } + /** + * @covers WikitextContentHandler::unserializeContent + */ public function testUnserializeContent() { $content = $this->handler->unserializeContent( 'hello world' ); $this->assertEquals( 'hello world', $content->getNativeData() ); @@ -45,6 +51,9 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { } } + /** + * @covers WikitextContentHandler::makeEmptyContent + */ public function testMakeEmptyContent() { $content = $this->handler->makeEmptyContent(); @@ -61,7 +70,39 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { } /** + * @dataProvider provideMakeRedirectContent + * @param Title|string $title Title object or string for Title::newFromText() + * @param string $expected Serialized form of the content object built + * @covers WikitextContentHandler::makeRedirectContent + */ + public function testMakeRedirectContent( $title, $expected ) { + global $wgContLang; + $wgContLang->resetNamespaces(); + + if ( is_string( $title ) ) { + $title = Title::newFromText( $title ); + } + $content = $this->handler->makeRedirectContent( $title ); + $this->assertEquals( $expected, $content->serialize() ); + } + + public static function provideMakeRedirectContent() { + return array( + array( 'Hello', '#REDIRECT [[Hello]]' ), + array( 'Template:Hello', '#REDIRECT [[Template:Hello]]' ), + array( 'Hello#section', '#REDIRECT [[Hello#section]]' ), + array( 'user:john_doe#section', '#REDIRECT [[User:John doe#section]]' ), + array( 'MEDIAWIKI:FOOBAR', '#REDIRECT [[MediaWiki:FOOBAR]]' ), + array( 'Category:Foo', '#REDIRECT [[:Category:Foo]]' ), + array( Title::makeTitle( NS_MAIN, 'en:Foo' ), '#REDIRECT [[en:Foo]]' ), + array( Title::makeTitle( NS_MAIN, 'Foo', '', 'en' ), '#REDIRECT [[:en:Foo]]' ), + array( Title::makeTitle( NS_MAIN, 'Bar', 'fragment', 'google' ), '#REDIRECT [[google:Bar#fragment]]' ), + ); + } + + /** * @dataProvider dataIsSupportedFormat + * @covers WikitextContentHandler::isSupportedFormat */ public function testIsSupportedFormat( $format, $supported ) { $this->assertEquals( $supported, $this->handler->isSupportedFormat( $format ) ); @@ -101,6 +142,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { /** * @dataProvider dataMerge3 + * @covers WikitextContentHandler::merge3 */ public function testMerge3( $old, $mine, $yours, $expected ) { $this->checkHasDiff3(); @@ -158,6 +200,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { /** * @dataProvider dataGetAutosummary + * @covers WikitextContentHandler::getAutosummary */ public function testGetAutosummary( $old, $new, $flags, $expected ) { $oldContent = is_null( $old ) ? null : new WikitextContent( $old ); @@ -181,5 +224,4 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase { /* public function testGetUndoContent( Revision $current, Revision $undo, Revision $undoafter = null ) {} */ - } diff --git a/tests/phpunit/includes/content/WikitextContentTest.php b/tests/phpunit/includes/content/WikitextContentTest.php index c9eecf7f..9f20073d 100644 --- a/tests/phpunit/includes/content/WikitextContentTest.php +++ b/tests/phpunit/includes/content/WikitextContentTest.php @@ -64,6 +64,7 @@ more stuff /** * @dataProvider dataGetSecondaryDataUpdates * @group Database + * @covers WikitextContent::getSecondaryDataUpdates */ public function testGetSecondaryDataUpdates( $title, $model, $text, $expectedStuff ) { $ns = $this->getDefaultWikitextNS(); @@ -116,6 +117,7 @@ just a test" /** * @dataProvider dataGetSection + * @covers WikitextContent::getSection */ public function testGetSection( $text, $sectionId, $expectedText ) { $content = $this->newContent( $text ); @@ -167,6 +169,7 @@ just a test" /** * @dataProvider dataReplaceSection + * @covers WikitextContent::replaceSection */ public function testReplaceSection( $text, $section, $with, $sectionTitle, $expected ) { $content = $this->newContent( $text ); @@ -175,6 +178,9 @@ just a test" $this->assertEquals( $expected, is_null( $c ) ? null : $c->getNativeData() ); } + /** + * @covers WikitextContent::addSectionHeader + */ public function testAddSectionHeader() { $content = $this->newContent( 'hello world' ); $content = $content->addSectionHeader( 'test' ); @@ -240,7 +246,7 @@ just a test" } /** - * @todo: test needs database! Should be done by a test class in the Database group. + * @todo Test needs database! Should be done by a test class in the Database group. */ /* public function getRedirectChain() { @@ -250,7 +256,7 @@ just a test" */ /** - * @todo: test needs database! Should be done by a test class in the Database group. + * @todo Test needs database! Should be done by a test class in the Database group. */ /* public function getUltimateRedirectTarget() { @@ -319,6 +325,9 @@ just a test" ); } + /** + * @covers WikitextContent::matchMagicWord + */ public function testMatchMagicWord() { $mw = MagicWord::get( "staticredirect" ); @@ -329,6 +338,9 @@ just a test" $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word" ); } + /** + * @covers WikitextContent::updateRedirect + */ public function testUpdateRedirect() { $target = Title::newFromText( "testUpdateRedirect_target" ); @@ -348,12 +360,18 @@ just a test" $this->assertEquals( $target->getFullText(), $newContent->getRedirectTarget()->getFullText() ); } + /** + * @covers WikitextContent::getModel + */ public function testGetModel() { $content = $this->newContent( "hello world." ); $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModel() ); } + /** + * @covers WikitextContent::getContentHandler + */ public function testGetContentHandler() { $content = $this->newContent( "hello world." ); @@ -380,7 +398,7 @@ just a test" CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n", array( 'LinksDeletionUpdate' => array() ) ), - // @todo: more...? + // @todo more...? ); } } diff --git a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php new file mode 100644 index 00000000..ba63c091 --- /dev/null +++ b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php @@ -0,0 +1,209 @@ +<?php +/** + * Holds tests for DatabaseMysqlBase MediaWiki class. + * + * @section LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @author Antoine Musso + * @author Bryan Davis + * @copyright © 2013 Antoine Musso + * @copyright © 2013 Bryan Davis + * @copyright © 2013 Wikimedia Foundation Inc. + */ + +/** + * Fake class around abstract class so we can call concrete methods. + */ +class FakeDatabaseMysqlBase extends DatabaseMysqlBase { + // From DatabaseBase + protected function closeConnection() {} + protected function doQuery( $sql ) {} + + // From DatabaseMysql + protected function mysqlConnect( $realServer ) {} + protected function mysqlFreeResult( $res ) {} + protected function mysqlFetchObject( $res ) {} + protected function mysqlFetchArray( $res ) {} + protected function mysqlNumRows( $res ) {} + protected function mysqlNumFields( $res ) {} + protected function mysqlFieldName( $res, $n ) {} + protected function mysqlDataSeek( $res, $row ) {} + protected function mysqlError( $conn = null ) {} + protected function mysqlFetchField( $res, $n ) {} + protected function mysqlPing() {} + + // From interface DatabaseType + function insertId() {} + function lastErrno() {} + function affectedRows() {} + function getServerVersion() {} +} + +class DatabaseMysqlBaseTest extends MediaWikiTestCase { + + /** + * @dataProvider provideDiapers + * @covers DatabaseMysqlBase::addIdentifierQuotes + */ + public function testAddIdentifierQuotes( $expected, $in ) { + $db = new FakeDatabaseMysqlBase(); + $quoted = $db->addIdentifierQuotes( $in ); + $this->assertEquals($expected, $quoted); + } + + + /** + * Feeds testAddIdentifierQuotes + * + * Named per bug 20281 convention. + */ + function provideDiapers() { + return array( + // Format: expected, input + array( '``', '' ), + + // Yeah I really hate loosely typed PHP idiocies nowadays + array( '``', null ), + + // Dear codereviewer, guess what addIdentifierQuotes() + // will return with thoses: + array( '``', false ), + array( '`1`', true ), + + // We never know what could happen + array( '`0`', 0 ), + array( '`1`', 1 ), + + // Whatchout! Should probably use something more meaningful + array( "`'`", "'" ), # single quote + array( '`"`', '"' ), # double quote + array( '````', '`' ), # backtick + array( '`’`', '’' ), # apostrophe (look at your encyclopedia) + + // sneaky NUL bytes are lurking everywhere + array( '``', "\0" ), + array( '`xyzzy`', "\0x\0y\0z\0z\0y\0" ), + + // unicode chars + array( + self::createUnicodeString( '`\u0001a\uFFFFb`' ), + self::createUnicodeString( '\u0001a\uFFFFb' ) + ), + array( + self::createUnicodeString( '`\u0001\uFFFF`' ), + self::createUnicodeString( '\u0001\u0000\uFFFF\u0000' ) + ), + array( '`☃`', '☃' ), + array( '`メインページ`', 'メインページ' ), + array( '`Басты_бет`', 'Басты_бет' ), + + // Real world: + array( '`Alix`', 'Alix' ), # while( ! $recovered ) { sleep(); } + array( '`Backtick: ```', 'Backtick: `' ), + array( '`This is a test`', 'This is a test' ), + ); + } + + private static function createUnicodeString($str) { + return json_decode( '"' . $str . '"' ); + } + + function getMockForViews() { + $db = $this->getMockBuilder( 'DatabaseMysql' ) + ->disableOriginalConstructor() + ->setMethods( array( 'fetchRow', 'query' ) ) + ->getMock(); + + $db->expects( $this->any() ) + ->method( 'query' ) + ->with( $this->anything() ) + ->will( + $this->returnValue( null ) + ); + + $db->expects( $this->any() ) + ->method( 'fetchRow' ) + ->with( $this->anything() ) + ->will( $this->onConsecutiveCalls( + array( 'Tables_in_' => 'view1' ), + array( 'Tables_in_' => 'view2' ), + array( 'Tables_in_' => 'myview' ), + false # no more rows + )); + return $db; + } + /** + * @covers DatabaseMysqlBase::listViews + */ + function testListviews() { + $db = $this->getMockForViews(); + + // The first call populate an internal cache of views + $this->assertEquals( array( 'view1', 'view2', 'myview'), + $db->listViews() ); + $this->assertEquals( array( 'view1', 'view2', 'myview'), + $db->listViews() ); + + // Prefix filtering + $this->assertEquals( array( 'view1', 'view2' ), + $db->listViews( 'view' ) ); + $this->assertEquals( array( 'myview' ), + $db->listViews( 'my' ) ); + $this->assertEquals( array(), + $db->listViews( 'UNUSED_PREFIX' ) ); + $this->assertEquals( array( 'view1', 'view2', 'myview'), + $db->listViews( '' ) ); + } + + /** + * @covers DatabaseMysqlBase::isView + * @dataProvider provideViewExistanceChecks + */ + function testIsView( $isView, $viewName ) { + $db = $this->getMockForViews(); + + switch( $isView ) { + case true: + $this->assertTrue( $db->isView( $viewName ), + "$viewName should be considered a view" ); + break; + + case false: + $this->assertFalse( $db->isView( $viewName ), + "$viewName has not been defined as a view" ); + break; + } + + } + + function provideViewExistanceChecks() { + return array( + // format: whether it is a view, view name + array( true, 'view1' ), + array( true, 'view2' ), + array( true, 'myview' ), + + array( false, 'user' ), + + array( false, 'view10' ), + array( false, 'my' ), + array( false, 'OH_MY_GOD' ), # they killed kenny! + ); + } + +} diff --git a/tests/phpunit/includes/db/DatabaseSQLTest.php b/tests/phpunit/includes/db/DatabaseSQLTest.php index 09792438..bdd567e7 100644 --- a/tests/phpunit/includes/db/DatabaseSQLTest.php +++ b/tests/phpunit/includes/db/DatabaseSQLTest.php @@ -2,35 +2,44 @@ /** * Test the abstract database layer - * Using Mysql for the sql at the moment TODO - * - * @group Database + * This is a non DBMS depending test. */ class DatabaseSQLTest extends MediaWikiTestCase { + /** + * @var DatabaseTestHelper + */ + private $database; + protected function setUp() { parent::setUp(); - // TODO support other DBMS or find another way to do it - if ( $this->db->getType() !== 'mysql' ) { - $this->markTestSkipped( 'No mysql database' ); - } + $this->database = new DatabaseTestHelper( __CLASS__ ); + } + + protected function assertLastSql( $sqlText ) { + $this->assertEquals( + $this->database->getLastSqls(), + $sqlText + ); } /** - * @dataProvider provideSelectSQLText + * @dataProvider provideSelect + * @covers DatabaseBase::select */ - function testSelectSQLText( $sql, $sqlText ) { - $this->assertEquals( trim( $this->db->selectSQLText( - isset( $sql['tables'] ) ? $sql['tables'] : array(), - isset( $sql['fields'] ) ? $sql['fields'] : array(), + public function testSelect( $sql, $sqlText ) { + $this->database->select( + $sql['tables'], + $sql['fields'], isset( $sql['conds'] ) ? $sql['conds'] : array(), __METHOD__, isset( $sql['options'] ) ? $sql['options'] : array(), isset( $sql['join_conds'] ) ? $sql['join_conds'] : array() - ) ), $sqlText ); + ); + $this->assertLastSql( $sqlText ); } - public static function provideSelectSQLText() { + public static function provideSelect() { return array( array( array( @@ -38,8 +47,8 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'fields' => array( 'field', 'alias' => 'field2' ), 'conds' => array( 'alias' => 'text' ), ), - "SELECT field,field2 AS alias " . - "FROM `unittest_table` " . + "SELECT field,field2 AS alias " . + "FROM table " . "WHERE alias = 'text'" ), array( @@ -49,9 +58,9 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'conds' => array( 'alias' => 'text' ), 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), ), - "SELECT field,field2 AS alias " . - "FROM `unittest_table` " . - "WHERE alias = 'text' " . + "SELECT field,field2 AS alias " . + "FROM table " . + "WHERE alias = 'text' " . "ORDER BY field " . "LIMIT 1" ), @@ -65,9 +74,9 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'LEFT JOIN', 'tid = t2.id' ) ), ), - "SELECT tid,field,field2 AS alias,t2.id " . - "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . - "WHERE alias = 'text' " . + "SELECT tid,field,field2 AS alias,t2.id " . + "FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " . + "WHERE alias = 'text' " . "ORDER BY field " . "LIMIT 1" ), @@ -81,9 +90,9 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'LEFT JOIN', 'tid = t2.id' ) ), ), - "SELECT tid,field,field2 AS alias,t2.id " . - "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . - "WHERE alias = 'text' " . + "SELECT tid,field,field2 AS alias,t2.id " . + "FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " . + "WHERE alias = 'text' " . "GROUP BY field HAVING COUNT(*) > 1 " . "LIMIT 1" ), @@ -97,20 +106,457 @@ class DatabaseSQLTest extends MediaWikiTestCase { 'LEFT JOIN', 'tid = t2.id' ) ), ), - "SELECT tid,field,field2 AS alias,t2.id " . - "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . - "WHERE alias = 'text' " . + "SELECT tid,field,field2 AS alias,t2.id " . + "FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " . + "WHERE alias = 'text' " . "GROUP BY field,field2 HAVING (COUNT(*) > 1) AND field = '1' " . "LIMIT 1" ), + array( + array( + 'tables' => array( 'table' ), + 'fields' => array( 'alias' => 'field' ), + 'conds' => array( 'alias' => array( 1, 2, 3, 4 ) ), + ), + "SELECT field AS alias " . + "FROM table " . + "WHERE alias IN ('1','2','3','4')" + ), + ); + } + + /** + * @dataProvider provideUpdate + * @covers DatabaseBase::update + */ + public function testUpdate( $sql, $sqlText ) { + $this->database->update( + $sql['table'], + $sql['values'], + $sql['conds'], + __METHOD__, + isset( $sql['options'] ) ? $sql['options'] : array() + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideUpdate() { + return array( + array( + array( + 'table' => 'table', + 'values' => array( 'field' => 'text', 'field2' => 'text2' ), + 'conds' => array( 'alias' => 'text' ), + ), + "UPDATE table " . + "SET field = 'text'" . + ",field2 = 'text2' " . + "WHERE alias = 'text'" + ), + array( + array( + 'table' => 'table', + 'values' => array( 'field = other', 'field2' => 'text2' ), + 'conds' => array( 'id' => '1' ), + ), + "UPDATE table " . + "SET field = other" . + ",field2 = 'text2' " . + "WHERE id = '1'" + ), + array( + array( + 'table' => 'table', + 'values' => array( 'field = other', 'field2' => 'text2' ), + 'conds' => '*', + ), + "UPDATE table " . + "SET field = other" . + ",field2 = 'text2'" + ), + ); + } + + /** + * @dataProvider provideDelete + * @covers DatabaseBase::delete + */ + public function testDelete( $sql, $sqlText ) { + $this->database->delete( + $sql['table'], + $sql['conds'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideDelete() { + return array( + array( + array( + 'table' => 'table', + 'conds' => array( 'alias' => 'text' ), + ), + "DELETE FROM table " . + "WHERE alias = 'text'" + ), + array( + array( + 'table' => 'table', + 'conds' => '*', + ), + "DELETE FROM table" + ), + ); + } + + /** + * @dataProvider provideUpsert + * @covers DatabaseBase::upsert + */ + public function testUpsert( $sql, $sqlText ) { + $this->database->upsert( + $sql['table'], + $sql['rows'], + $sql['uniqueIndexes'], + $sql['set'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideUpsert() { + return array( + array( + array( + 'table' => 'upsert_table', + 'rows' => array( 'field' => 'text', 'field2' => 'text2' ), + 'uniqueIndexes' => array( 'field' ), + 'set' => array( 'field' => 'set' ), + ), + "BEGIN; " . + "UPDATE upsert_table " . + "SET field = 'set' " . + "WHERE ((field = 'text')); " . + "INSERT IGNORE INTO upsert_table " . + "(field,field2) " . + "VALUES ('text','text2'); " . + "COMMIT" + ), + ); + } + + /** + * @dataProvider provideDeleteJoin + * @covers DatabaseBase::deleteJoin + */ + public function testDeleteJoin( $sql, $sqlText ) { + $this->database->deleteJoin( + $sql['delTable'], + $sql['joinTable'], + $sql['delVar'], + $sql['joinVar'], + $sql['conds'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideDeleteJoin() { + return array( + array( + array( + 'delTable' => 'table', + 'joinTable' => 'table_join', + 'delVar' => 'field', + 'joinVar' => 'field_join', + 'conds' => array( 'alias' => 'text' ), + ), + "DELETE FROM table " . + "WHERE field IN (" . + "SELECT field_join FROM table_join WHERE alias = 'text'" . + ")" + ), + array( + array( + 'delTable' => 'table', + 'joinTable' => 'table_join', + 'delVar' => 'field', + 'joinVar' => 'field_join', + 'conds' => '*', + ), + "DELETE FROM table " . + "WHERE field IN (" . + "SELECT field_join FROM table_join " . + ")" + ), + ); + } + + /** + * @dataProvider provideInsert + * @covers DatabaseBase::insert + */ + public function testInsert( $sql, $sqlText ) { + $this->database->insert( + $sql['table'], + $sql['rows'], + __METHOD__, + isset( $sql['options'] ) ? $sql['options'] : array() + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideInsert() { + return array( + array( + array( + 'table' => 'table', + 'rows' => array( 'field' => 'text', 'field2' => 2 ), + ), + "INSERT INTO table " . + "(field,field2) " . + "VALUES ('text','2')" + ), + array( + array( + 'table' => 'table', + 'rows' => array( 'field' => 'text', 'field2' => 2 ), + 'options' => 'IGNORE', + ), + "INSERT IGNORE INTO table " . + "(field,field2) " . + "VALUES ('text','2')" + ), + array( + array( + 'table' => 'table', + 'rows' => array( + array( 'field' => 'text', 'field2' => 2 ), + array( 'field' => 'multi', 'field2' => 3 ), + ), + 'options' => 'IGNORE', + ), + "INSERT IGNORE INTO table " . + "(field,field2) " . + "VALUES " . + "('text','2')," . + "('multi','3')" + ), + ); + } + + /** + * @dataProvider provideInsertSelect + * @covers DatabaseBase::insertSelect + */ + public function testInsertSelect( $sql, $sqlText ) { + $this->database->insertSelect( + $sql['destTable'], + $sql['srcTable'], + $sql['varMap'], + $sql['conds'], + __METHOD__, + isset( $sql['insertOptions'] ) ? $sql['insertOptions'] : array(), + isset( $sql['selectOptions'] ) ? $sql['selectOptions'] : array() + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideInsertSelect() { + return array( + array( + array( + 'destTable' => 'insert_table', + 'srcTable' => 'select_table', + 'varMap' => array( 'field_insert' => 'field_select', 'field' => 'field2' ), + 'conds' => '*', + ), + "INSERT INTO insert_table " . + "(field_insert,field) " . + "SELECT field_select,field2 " . + "FROM select_table" + ), + array( + array( + 'destTable' => 'insert_table', + 'srcTable' => 'select_table', + 'varMap' => array( 'field_insert' => 'field_select', 'field' => 'field2' ), + 'conds' => array( 'field' => 2 ), + ), + "INSERT INTO insert_table " . + "(field_insert,field) " . + "SELECT field_select,field2 " . + "FROM select_table " . + "WHERE field = '2'" + ), + array( + array( + 'destTable' => 'insert_table', + 'srcTable' => 'select_table', + 'varMap' => array( 'field_insert' => 'field_select', 'field' => 'field2' ), + 'conds' => array( 'field' => 2 ), + 'insertOptions' => 'IGNORE', + 'selectOptions' => array( 'ORDER BY' => 'field' ), + ), + "INSERT IGNORE INTO insert_table " . + "(field_insert,field) " . + "SELECT field_select,field2 " . + "FROM select_table " . + "WHERE field = '2' " . + "ORDER BY field" + ), + ); + } + + /** + * @dataProvider provideReplace + * @covers DatabaseBase::replace + */ + public function testReplace( $sql, $sqlText ) { + $this->database->replace( + $sql['table'], + $sql['uniqueIndexes'], + $sql['rows'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideReplace() { + return array( + array( + array( + 'table' => 'replace_table', + 'uniqueIndexes' => array( 'field' ), + 'rows' => array( 'field' => 'text', 'field2' => 'text2' ), + ), + "DELETE FROM replace_table " . + "WHERE ( field='text' ); " . + "INSERT INTO replace_table " . + "(field,field2) " . + "VALUES ('text','text2')" + ), + array( + array( + 'table' => 'module_deps', + 'uniqueIndexes' => array( array( 'md_module', 'md_skin' ) ), + 'rows' => array( + 'md_module' => 'module', + 'md_skin' => 'skin', + 'md_deps' => 'deps', + ), + ), + "DELETE FROM module_deps " . + "WHERE ( md_module='module' AND md_skin='skin' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module','skin','deps')" + ), + array( + array( + 'table' => 'module_deps', + 'uniqueIndexes' => array( array( 'md_module', 'md_skin' ) ), + 'rows' => array( + array( + 'md_module' => 'module', + 'md_skin' => 'skin', + 'md_deps' => 'deps', + ), array( + 'md_module' => 'module2', + 'md_skin' => 'skin2', + 'md_deps' => 'deps2', + ), + ), + ), + "DELETE FROM module_deps " . + "WHERE ( md_module='module' AND md_skin='skin' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module','skin','deps'); " . + "DELETE FROM module_deps " . + "WHERE ( md_module='module2' AND md_skin='skin2' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module2','skin2','deps2')" + ), + array( + array( + 'table' => 'module_deps', + 'uniqueIndexes' => array( 'md_module', 'md_skin' ), + 'rows' => array( + array( + 'md_module' => 'module', + 'md_skin' => 'skin', + 'md_deps' => 'deps', + ), array( + 'md_module' => 'module2', + 'md_skin' => 'skin2', + 'md_deps' => 'deps2', + ), + ), + ), + "DELETE FROM module_deps " . + "WHERE ( md_module='module' ) OR ( md_skin='skin' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module','skin','deps'); " . + "DELETE FROM module_deps " . + "WHERE ( md_module='module2' ) OR ( md_skin='skin2' ); " . + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module2','skin2','deps2')" + ), + array( + array( + 'table' => 'module_deps', + 'uniqueIndexes' => array(), + 'rows' => array( + 'md_module' => 'module', + 'md_skin' => 'skin', + 'md_deps' => 'deps', + ), + ), + "INSERT INTO module_deps " . + "(md_module,md_skin,md_deps) " . + "VALUES ('module','skin','deps')" + ), + ); + } + + /** + * @dataProvider provideNativeReplace + * @covers DatabaseBase::nativeReplace + */ + public function testNativeReplace( $sql, $sqlText ) { + $this->database->nativeReplace( + $sql['table'], + $sql['rows'], + __METHOD__ + ); + $this->assertLastSql( $sqlText ); + } + + public static function provideNativeReplace() { + return array( + array( + array( + 'table' => 'replace_table', + 'rows' => array( 'field' => 'text', 'field2' => 'text2' ), + ), + "REPLACE INTO replace_table " . + "(field,field2) " . + "VALUES ('text','text2')" + ), ); } /** * @dataProvider provideConditional + * @covers DatabaseBase::conditional */ - function testConditional( $sql, $sqlText ) { - $this->assertEquals( trim( $this->db->conditional( + public function testConditional( $sql, $sqlText ) { + $this->assertEquals( trim( $this->database->conditional( $sql['conds'], $sql['true'], $sql['false'] @@ -145,4 +591,131 @@ class DatabaseSQLTest extends MediaWikiTestCase { ), ); } + + /** + * @dataProvider provideBuildConcat + * @covers DatabaseBase::buildConcat + */ + public function testBuildConcat( $stringList, $sqlText ) { + $this->assertEquals( trim( $this->database->buildConcat( + $stringList + ) ), $sqlText ); + } + + public static function provideBuildConcat() { + return array( + array( + array( 'field', 'field2' ), + "CONCAT(field,field2)" + ), + array( + array( "'test'", 'field2' ), + "CONCAT('test',field2)" + ), + ); + } + + /** + * @dataProvider provideBuildLike + * @covers DatabaseBase::buildLike + */ + public function testBuildLike( $array, $sqlText ) { + $this->assertEquals( trim( $this->database->buildLike( + $array + ) ), $sqlText ); + } + + public static function provideBuildLike() { + return array( + array( + 'text', + "LIKE 'text'" + ), + array( + array( 'text', new LikeMatch( '%' ) ), + "LIKE 'text%'" + ), + array( + array( 'text', new LikeMatch( '%' ), 'text2' ), + "LIKE 'text%text2'" + ), + array( + array( 'text', new LikeMatch( '_' ) ), + "LIKE 'text_'" + ), + ); + } + + /** + * @dataProvider provideUnionQueries + * @covers DatabaseBase::unionQueries + */ + public function testUnionQueries( $sql, $sqlText ) { + $this->assertEquals( trim( $this->database->unionQueries( + $sql['sqls'], + $sql['all'] + ) ), $sqlText ); + } + + public static function provideUnionQueries() { + return array( + array( + array( + 'sqls' => array( 'RAW SQL', 'RAW2SQL' ), + 'all' => true, + ), + "(RAW SQL) UNION ALL (RAW2SQL)" + ), + array( + array( + 'sqls' => array( 'RAW SQL', 'RAW2SQL' ), + 'all' => false, + ), + "(RAW SQL) UNION (RAW2SQL)" + ), + array( + array( + 'sqls' => array( 'RAW SQL', 'RAW2SQL', 'RAW3SQL' ), + 'all' => false, + ), + "(RAW SQL) UNION (RAW2SQL) UNION (RAW3SQL)" + ), + ); + } + + /** + * @covers DatabaseBase::commit + */ + public function testTransactionCommit() { + $this->database->begin( __METHOD__ ); + $this->database->commit( __METHOD__ ); + $this->assertLastSql( 'BEGIN; COMMIT' ); + } + + /** + * @covers DatabaseBase::rollback + */ + public function testTransactionRollback() { + $this->database->begin( __METHOD__ ); + $this->database->rollback( __METHOD__ ); + $this->assertLastSql( 'BEGIN; ROLLBACK' ); + } + + /** + * @covers DatabaseBase::dropTable + */ + public function testDropTable() { + $this->database->setExistingTables( array( 'table' ) ); + $this->database->dropTable( 'table', __METHOD__ ); + $this->assertLastSql( 'DROP TABLE table' ); + } + + /** + * @covers DatabaseBase::dropTable + */ + public function testDropNonExistingTable() { + $this->assertFalse( + $this->database->dropTable( 'non_existing', __METHOD__ ) + ); + } } diff --git a/tests/phpunit/includes/db/DatabaseSqliteTest.php b/tests/phpunit/includes/db/DatabaseSqliteTest.php index 7b84d471..70ee9465 100644 --- a/tests/phpunit/includes/db/DatabaseSqliteTest.php +++ b/tests/phpunit/includes/db/DatabaseSqliteTest.php @@ -9,6 +9,7 @@ class MockDatabaseSqlite extends DatabaseSqliteStandalone { function query( $sql, $fname = '', $tempIgnore = false ) { $this->lastQuery = $sql; + return true; } @@ -26,6 +27,10 @@ class MockDatabaseSqlite extends DatabaseSqliteStandalone { * @group medium */ class DatabaseSqliteTest extends MediaWikiTestCase { + + /** + * @var MockDatabaseSqlite + */ var $db; protected function setUp() { @@ -82,6 +87,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase { /** * @dataProvider provideAddQuotes() + * @covers DatabaseSqlite::addQuotes */ public function testAddQuotes( $value, $expected ) { // check quoting @@ -104,6 +110,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { } } + /** + * @covers DatabaseSqlite::replaceVars + */ public function testReplaceVars() { $this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" ); @@ -142,6 +151,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { ); } + /** + * @covers DatabaseSqlite::tableName + */ public function testTableName() { // @todo Moar! $db = new DatabaseSqliteStandalone( ':memory:' ); @@ -152,6 +164,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { $this->assertEquals( 'foobar', $db->tableName( 'bar' ) ); } + /** + * @covers DatabaseSqlite::duplicateTableStructure + */ public function testDuplicateTableStructure() { $db = new DatabaseSqliteStandalone( ':memory:' ); $db->query( 'CREATE TABLE foo(foo, barfoo)' ); @@ -173,6 +188,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { ); } + /** + * @covers DatabaseSqlite::duplicateTableStructure + */ public function testDuplicateTableStructureVirtual() { $db = new DatabaseSqliteStandalone( ':memory:' ); if ( $db->getFulltextSearchModule() != 'FTS3' ) { @@ -193,6 +211,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase { ); } + /** + * @covers DatabaseSqlite::deleteJoin + */ public function testDeleteJoin() { $db = new DatabaseSqliteStandalone( ':memory:' ); $db->query( 'CREATE TABLE a (a_1)', __METHOD__ ); @@ -232,7 +253,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase { /** * Runs upgrades of older databases and compares results with current schema - * @todo: currently only checks list of tables + * @todo Currently only checks list of tables */ public function testUpgrades() { global $IP, $wgVersion, $wgProfileToDatabase; @@ -305,13 +326,19 @@ class DatabaseSqliteTest extends MediaWikiTestCase { } } + /** + * @covers DatabaseSqlite::insertId + */ public function testInsertIdType() { $db = new DatabaseSqliteStandalone( ':memory:' ); - $this->assertInstanceOf( 'ResultWrapper', - $db->query( 'CREATE TABLE a ( a_1 )', __METHOD__ ), "Database creationg" ); - $this->assertTrue( $db->insert( 'a', array( 'a_1' => 10 ), __METHOD__ ), - "Insertion worked" ); - $this->assertEquals( "integer", gettype( $db->insertId() ), "Actual typecheck" ); + + $databaseCreation = $db->query( 'CREATE TABLE a ( a_1 )', __METHOD__ ); + $this->assertInstanceOf( 'ResultWrapper', $databaseCreation, "Database creation" ); + + $insertion = $db->insert( 'a', array( 'a_1' => 10 ), __METHOD__ ); + $this->assertTrue( $insertion, "Insertion worked" ); + + $this->assertInternalType( 'integer', $db->insertId(), "Actual typecheck" ); $this->assertTrue( $db->close(), "closing database" ); } @@ -327,12 +354,14 @@ class DatabaseSqliteTest extends MediaWikiTestCase { $db->sourceFile( "$IP/tests/phpunit/data/db/sqlite/tables-$version.sql" ); $updater = DatabaseUpdater::newForDB( $db, false, $maint ); $updater->doUpdates( array( 'core' ) ); + return $db; } private function getTables( $db ) { $list = array_flip( $db->listTables() ); $excluded = array( + 'external_user', // removed from core in 1.22 'math', // moved out of core in 1.18 'trackbacks', // removed from core in 1.19 'searchindex', @@ -348,6 +377,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase { } $list = array_flip( $list ); sort( $list ); + return $list; } @@ -359,6 +389,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase { $cols[$col->name] = $col; } ksort( $cols ); + return $cols; } @@ -376,10 +407,11 @@ class DatabaseSqliteTest extends MediaWikiTestCase { $indexes[$index->name] = $index; } ksort( $indexes ); + return $indexes; } - function testCaseInsensitiveLike() { + public function testCaseInsensitiveLike() { // TODO: Test this for all databases $db = new DatabaseSqliteStandalone( ':memory:' ); $res = $db->query( 'SELECT "a" LIKE "A" AS a' ); diff --git a/tests/phpunit/includes/db/DatabaseTest.php b/tests/phpunit/includes/db/DatabaseTest.php index 65c80d1d..301fc990 100644 --- a/tests/phpunit/includes/db/DatabaseTest.php +++ b/tests/phpunit/includes/db/DatabaseTest.php @@ -5,7 +5,11 @@ * @group DatabaseBase */ class DatabaseTest extends MediaWikiTestCase { - var $db, $functionTest = false; + /** + * @var DatabaseBase + */ + var $db; + var $functionTest = false; protected function setUp() { parent::setUp(); @@ -19,8 +23,10 @@ class DatabaseTest extends MediaWikiTestCase { $this->functionTest = false; } } - - function testAddQuotesNull() { + /** + * @covers DatabaseBase::dropTable + */ + public function testAddQuotesNull() { $check = "NULL"; if ( $this->db->getType() === 'sqlite' || $this->db->getType() === 'oracle' ) { $check = "''"; @@ -28,7 +34,7 @@ class DatabaseTest extends MediaWikiTestCase { $this->assertEquals( $check, $this->db->addQuotes( null ) ); } - function testAddQuotesInt() { + public function testAddQuotesInt() { # returning just "1234" should be ok too, though... # maybe $this->assertEquals( @@ -36,20 +42,20 @@ class DatabaseTest extends MediaWikiTestCase { $this->db->addQuotes( 1234 ) ); } - function testAddQuotesFloat() { + public function testAddQuotesFloat() { # returning just "1234.5678" would be ok too, though $this->assertEquals( "'1234.5678'", $this->db->addQuotes( 1234.5678 ) ); } - function testAddQuotesString() { + public function testAddQuotesString() { $this->assertEquals( "'string'", $this->db->addQuotes( 'string' ) ); } - function testAddQuotesStringQuote() { + public function testAddQuotesStringQuote() { $check = "'string''s cause trouble'"; if ( $this->db->getType() === 'mysql' ) { $check = "'string\'s cause trouble'"; @@ -84,36 +90,46 @@ class DatabaseTest extends MediaWikiTestCase { $quote = ''; } elseif ( $this->db->getType() === 'mysql' ) { $quote = '`'; + } elseif ( $this->db->getType() === 'oracle' ) { + $quote = '/*Q*/'; } else { $quote = '"'; } if ( $database !== null ) { - $database = $quote . $database . $quote . '.'; + if ( $this->db->getType() === 'oracle' ) { + $database = $quote . $database . '.'; + } else { + $database = $quote . $database . $quote . '.'; + } } if ( $prefix === null ) { $prefix = $this->dbPrefix(); } - return $database . $quote . $prefix . $table . $quote; + if ( $this->db->getType() === 'oracle' ) { + return strtoupper($database . $quote . $prefix . $table); + } else { + return $database . $quote . $prefix . $table . $quote; + } } - function testTableNameLocal() { + public function testTableNameLocal() { $this->assertEquals( $this->prefixAndQuote( 'tablename' ), $this->db->tableName( 'tablename' ) ); } - function testTableNameRawLocal() { + public function testTableNameRawLocal() { $this->assertEquals( $this->prefixAndQuote( 'tablename', null, null, 'raw' ), $this->db->tableName( 'tablename', 'raw' ) ); } - function testTableNameShared() { + public function testTableNameShared() { $this->assertEquals( $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_' ), $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_' ) @@ -125,7 +141,7 @@ class DatabaseTest extends MediaWikiTestCase { ); } - function testTableNameRawShared() { + public function testTableNameRawShared() { $this->assertEquals( $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_', 'raw' ), $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_', 'raw' ) @@ -137,21 +153,21 @@ class DatabaseTest extends MediaWikiTestCase { ); } - function testTableNameForeign() { + public function testTableNameForeign() { $this->assertEquals( $this->prefixAndQuote( 'tablename', 'databasename', '' ), $this->db->tableName( 'databasename.tablename' ) ); } - function testTableNameRawForeign() { + public function testTableNameRawForeign() { $this->assertEquals( $this->prefixAndQuote( 'tablename', 'databasename', '', 'raw' ), $this->db->tableName( 'databasename.tablename', 'raw' ) ); } - function testFillPreparedEmpty() { + public function testFillPreparedEmpty() { $sql = $this->db->fillPrepared( 'SELECT * FROM interwiki', array() ); $this->assertEquals( @@ -159,7 +175,7 @@ class DatabaseTest extends MediaWikiTestCase { $sql ); } - function testFillPreparedQuestion() { + public function testFillPreparedQuestion() { $sql = $this->db->fillPrepared( 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?', array( 4, "Snicker's_paradox" ) ); @@ -171,7 +187,7 @@ class DatabaseTest extends MediaWikiTestCase { $this->assertEquals( $check, $sql ); } - function testFillPreparedBang() { + public function testFillPreparedBang() { $sql = $this->db->fillPrepared( 'SELECT user_id FROM ! WHERE user_name=?', array( '"user"', "Slash's Dot" ) ); @@ -183,7 +199,7 @@ class DatabaseTest extends MediaWikiTestCase { $this->assertEquals( $check, $sql ); } - function testFillPreparedRaw() { + public function testFillPreparedRaw() { $sql = $this->db->fillPrepared( "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'", array( '"user"', "Slash's Dot" ) ); @@ -192,7 +208,7 @@ class DatabaseTest extends MediaWikiTestCase { $sql ); } - function testStoredFunctions() { + public function testStoredFunctions() { if ( !in_array( wfGetDB( DB_MASTER )->getType(), array( 'mysql', 'postgres' ) ) ) { $this->markTestSkipped( 'MySQL or Postgres required' ); } @@ -209,4 +225,10 @@ class DatabaseTest extends MediaWikiTestCase { . ( $this->db->getType() == 'postgres' ? '()' : '' ) ); } + + public function testUnknownTableCorruptsResults() { + $res = $this->db->select( 'page', '*', array( 'page_id' => 1 ) ); + $this->assertFalse( $this->db->tableExists( 'foobarbaz' ) ); + $this->assertInternalType( 'int', $res->numRows() ); + } } diff --git a/tests/phpunit/includes/db/DatabaseTestHelper.php b/tests/phpunit/includes/db/DatabaseTestHelper.php new file mode 100644 index 00000000..790f273c --- /dev/null +++ b/tests/phpunit/includes/db/DatabaseTestHelper.php @@ -0,0 +1,166 @@ +<?php + +/** + * Helper for testing the methods from the DatabaseBase class + * @since 1.22 + */ +class DatabaseTestHelper extends DatabaseBase { + + /** + * __CLASS__ of the test suite, + * used to determine, if the function name is passed every time to query() + */ + protected $testName = array(); + + /** + * Array of lastSqls passed to query(), + * This is an array since some methods in DatabaseBase can do more than one + * query. Cleared when calling getLastSqls(). + */ + protected $lastSqls = array(); + + /** + * Array of tables to be considered as existing by tableExist() + * Use setExistingTables() to alter. + */ + protected $tablesExists; + + public function __construct( $testName ) { + $this->testName = $testName; + } + + /** + * Returns SQL queries grouped by '; ' + * Clear the list of queries that have been done so far. + */ + public function getLastSqls() { + $lastSqls = implode( '; ', $this->lastSqls ); + $this->lastSqls = array(); + + return $lastSqls; + } + + public function setExistingTables( $tablesExists ) { + $this->tablesExists = (array)$tablesExists; + } + + protected function addSql( $sql ) { + // clean up spaces before and after some words and the whole string + $this->lastSqls[] = trim( preg_replace( + '/\s{2,}(?=FROM|WHERE|GROUP BY|ORDER BY|LIMIT)|(?<=SELECT|INSERT|UPDATE)\s{2,}/', + ' ', $sql + ) ); + } + + protected function checkFunctionName( $fname ) { + if ( substr( $fname, 0, strlen( $this->testName ) ) !== $this->testName ) { + throw new MWException( 'function name does not start with test class. ' . + $fname . ' vs. ' . $this->testName . '. ' . + 'Please provide __METHOD__ to database methods.' ); + } + } + + function strencode( $s ) { + // Choose apos to avoid handling of escaping double quotes in quoted text + return str_replace( "'", "\'", $s ); + } + + public function addIdentifierQuotes( $s ) { + // no escaping to avoid handling of double quotes in quoted text + return $s; + } + + public function query( $sql, $fname = '', $tempIgnore = false ) { + $this->checkFunctionName( $fname ); + $this->addSql( $sql ); + + return parent::query( $sql, $fname, $tempIgnore ); + } + + public function tableExists( $table, $fname = __METHOD__ ) { + $this->checkFunctionName( $fname ); + + return in_array( $table, (array)$this->tablesExists ); + } + + // Redeclare parent method to make it public + public function nativeReplace( $table, $rows, $fname ) { + return parent::nativeReplace( $table, $rows, $fname ); + } + + function getType() { + return 'test'; + } + + function open( $server, $user, $password, $dbName ) { + return false; + } + + function fetchObject( $res ) { + return false; + } + + function fetchRow( $res ) { + return false; + } + + function numRows( $res ) { + return -1; + } + + function numFields( $res ) { + return -1; + } + + function fieldName( $res, $n ) { + return 'test'; + } + + function insertId() { + return -1; + } + + function dataSeek( $res, $row ) { + /* nop */ + } + + function lastErrno() { + return -1; + } + + function lastError() { + return 'test'; + } + + function fieldInfo( $table, $field ) { + return false; + } + + function indexInfo( $table, $index, $fname = 'Database::indexInfo' ) { + return false; + } + + function affectedRows() { + return -1; + } + + function getSoftwareLink() { + return 'test'; + } + + function getServerVersion() { + return 'test'; + } + + function getServerInfo() { + return 'test'; + } + + protected function closeConnection() { + return false; + } + + protected function doQuery( $sql ) { + return array(); + } +} diff --git a/tests/phpunit/includes/db/ORMRowTest.php b/tests/phpunit/includes/db/ORMRowTest.php index 596d0bd0..27d4d0e8 100644 --- a/tests/phpunit/includes/db/ORMRowTest.php +++ b/tests/phpunit/includes/db/ORMRowTest.php @@ -76,6 +76,7 @@ abstract class ORMRowTest extends \MediaWikiTestCase { */ protected function getRowInstance( array $data, $loadDefaults ) { $class = $this->getRowClass(); + return new $class( $this->getTableInstance(), $data, $loadDefaults ); } diff --git a/tests/phpunit/includes/db/ORMTableTest.php b/tests/phpunit/includes/db/ORMTableTest.php index 4cadf31c..e583d1bc 100644 --- a/tests/phpunit/includes/db/ORMTableTest.php +++ b/tests/phpunit/includes/db/ORMTableTest.php @@ -45,6 +45,7 @@ class ORMTableTest extends MediaWikiTestCase { */ public function getTable() { $class = $this->getTableClass(); + return $class::singleton(); } @@ -84,7 +85,6 @@ class ORMTableTest extends MediaWikiTestCase { $db->ignoreErrors( false ); } - } /** diff --git a/tests/phpunit/includes/db/TestORMRowTest.php b/tests/phpunit/includes/db/TestORMRowTest.php index 263553ac..f65642b8 100644 --- a/tests/phpunit/includes/db/TestORMRowTest.php +++ b/tests/phpunit/includes/db/TestORMRowTest.php @@ -64,23 +64,40 @@ class TestORMRowTest extends ORMRowTest { $dbw = wfGetDB( DB_MASTER ); $isSqlite = $GLOBALS['wgDBtype'] === 'sqlite'; + $isPostgres = $GLOBALS['wgDBtype'] === 'postgres'; $idField = $isSqlite ? 'INTEGER' : 'INT unsigned'; $primaryKey = $isSqlite ? 'PRIMARY KEY AUTOINCREMENT' : 'auto_increment PRIMARY KEY'; - $dbw->query( - 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . '( - test_id ' . $idField . ' NOT NULL ' . $primaryKey . ', - test_name VARCHAR(255) NOT NULL, - test_age TINYINT unsigned NOT NULL, - test_height FLOAT NOT NULL, - test_awesome TINYINT unsigned NOT NULL, - test_stuff BLOB NOT NULL, - test_moarstuff BLOB NOT NULL, - test_time varbinary(14) NOT NULL - );', - __METHOD__ - ); + if ( $isPostgres ) { + $dbw->query( + 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . "( + test_id serial PRIMARY KEY, + test_name TEXT NOT NULL DEFAULT '', + test_age INTEGER NOT NULL DEFAULT 0, + test_height REAL NOT NULL DEFAULT 0, + test_awesome INTEGER NOT NULL DEFAULT 0, + test_stuff BYTEA, + test_moarstuff BYTEA, + test_time TIMESTAMPTZ + );", + __METHOD__ + ); + } else { + $dbw->query( + 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . '( + test_id ' . $idField . ' NOT NULL ' . $primaryKey . ', + test_name VARCHAR(255) NOT NULL, + test_age TINYINT unsigned NOT NULL, + test_height FLOAT NOT NULL, + test_awesome TINYINT unsigned NOT NULL, + test_stuff BLOB NOT NULL, + test_moarstuff BLOB NOT NULL, + test_time varbinary(14) NOT NULL + );', + __METHOD__ + ); + } } protected function tearDown() { @@ -91,11 +108,12 @@ class TestORMRowTest extends ORMRowTest { } public function constructorTestProvider() { + $dbw = wfGetDB( DB_MASTER ); return array( array( array( 'name' => 'Foobar', - 'time' => '20120101020202', + 'time' => $dbw->timestamp( '20120101020202' ), 'age' => 42, 'height' => 9000.1, 'awesome' => true, @@ -122,10 +140,10 @@ class TestORMRowTest extends ORMRowTest { 'blob' => new stdClass() ); } - } -class TestORMRow extends ORMRow {} +class TestORMRow extends ORMRow { +} class TestORMTable extends ORMTable { @@ -194,6 +212,4 @@ class TestORMTable extends ORMTable { protected function getFieldPrefix() { return 'test_'; } - - } diff --git a/tests/phpunit/includes/debug/MWDebugTest.php b/tests/phpunit/includes/debug/MWDebugTest.php index 9026cb90..6926b1c8 100644 --- a/tests/phpunit/includes/debug/MWDebugTest.php +++ b/tests/phpunit/includes/debug/MWDebugTest.php @@ -21,7 +21,7 @@ class MWDebugTest extends MediaWikiTestCase { parent::tearDown(); } - function testAddLog() { + public function testAddLog() { MWDebug::log( 'logging a string' ); $this->assertEquals( array( array( @@ -33,7 +33,7 @@ class MWDebugTest extends MediaWikiTestCase { ); } - function testAddWarning() { + public function testAddWarning() { MWDebug::warning( 'Warning message' ); $this->assertEquals( array( array( @@ -45,7 +45,7 @@ class MWDebugTest extends MediaWikiTestCase { ); } - function testAvoidDuplicateDeprecations() { + public function testAvoidDuplicateDeprecations() { MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); @@ -56,7 +56,7 @@ class MWDebugTest extends MediaWikiTestCase { ); } - function testAvoidNonConsecutivesDuplicateDeprecations() { + public function testAvoidNonConsecutivesDuplicateDeprecations() { MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); MWDebug::warning( 'some warning' ); MWDebug::log( 'we could have logged something too' ); diff --git a/tests/phpunit/includes/filebackend/FileBackendTest.php b/tests/phpunit/includes/filebackend/FileBackendTest.php index 9fbf7bb0..fcfa724f 100644 --- a/tests/phpunit/includes/filebackend/FileBackendTest.php +++ b/tests/phpunit/includes/filebackend/FileBackendTest.php @@ -6,14 +6,21 @@ * @group medium */ class FileBackendTest extends MediaWikiTestCase { - private $backend, $multiBackend; + + /** @var FileBackend */ + private $backend; + /** @var FileBackendMultiWrite */ + private $multiBackend; + /** @var FSFileBackend */ + public $singleBackend; private $filesToPrune = array(); private static $backendToUse; protected function setUp() { global $wgFileBackends; parent::setUp(); - $tmpPrefix = wfTempDir() . '/filebackend-unittest-' . time() . '-' . mt_rand(); + $uniqueId = time() . '-' . mt_rand(); + $tmpPrefix = wfTempDir() . '/filebackend-unittest-' . $uniqueId; if ( $this->getCliArg( 'use-filebackend=' ) ) { if ( self::$backendToUse ) { $this->singleBackend = self::$backendToUse; @@ -36,32 +43,34 @@ class FileBackendTest extends MediaWikiTestCase { } } else { $this->singleBackend = new FSFileBackend( array( - 'name' => 'localtesting', + 'name' => 'localtesting', 'lockManager' => 'fsLockManager', #'parallelize' => 'implicit', + 'wikiId' => wfWikiID() . $uniqueId, 'containerPaths' => array( 'unittest-cont1' => "{$tmpPrefix}-localtesting-cont1", 'unittest-cont2' => "{$tmpPrefix}-localtesting-cont2" ) ) ); } $this->multiBackend = new FileBackendMultiWrite( array( - 'name' => 'localtesting', + 'name' => 'localtesting', 'lockManager' => 'fsLockManager', 'parallelize' => 'implicit', - 'backends' => array( + 'wikiId' => wfWikiId() . $uniqueId, + 'backends' => array( array( - 'name' => 'localmultitesting1', - 'class' => 'FSFileBackend', - 'lockManager' => 'nullLockManager', + 'name' => 'localmultitesting1', + 'class' => 'FSFileBackend', + 'lockManager' => 'nullLockManager', 'containerPaths' => array( 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti1-cont1", 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti1-cont2" ), 'isMultiMaster' => false ), array( - 'name' => 'localmultitesting2', - 'class' => 'FSFileBackend', - 'lockManager' => 'nullLockManager', + 'name' => 'localmultitesting2', + 'class' => 'FSFileBackend', + 'lockManager' => 'nullLockManager', 'containerPaths' => array( 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti2-cont1", 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti2-cont2" ), @@ -82,13 +91,14 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testIsStoragePath + * @covers FileBackend::isStoragePath */ public function testIsStoragePath( $path, $isStorePath ) { $this->assertEquals( $isStorePath, FileBackend::isStoragePath( $path ), "FileBackend::isStoragePath on path '$path'" ); } - function provider_testIsStoragePath() { + public static function provider_testIsStoragePath() { return array( array( 'mwstore://', true ), array( 'mwstore://backend', true ), @@ -106,13 +116,14 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testSplitStoragePath + * @covers FileBackend::splitStoragePath */ public function testSplitStoragePath( $path, $res ) { $this->assertEquals( $res, FileBackend::splitStoragePath( $path ), "FileBackend::splitStoragePath on path '$path'" ); } - function provider_testSplitStoragePath() { + public static function provider_testSplitStoragePath() { return array( array( 'mwstore://backend/container', array( 'backend', 'container', '' ) ), array( 'mwstore://backend/container/', array( 'backend', 'container', '' ) ), @@ -130,13 +141,14 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_normalizeStoragePath + * @covers FileBackend::normalizeStoragePath */ public function testNormalizeStoragePath( $path, $res ) { $this->assertEquals( $res, FileBackend::normalizeStoragePath( $path ), "FileBackend::normalizeStoragePath on path '$path'" ); } - function provider_normalizeStoragePath() { + public static function provider_normalizeStoragePath() { return array( array( 'mwstore://backend/container', 'mwstore://backend/container' ), array( 'mwstore://backend/container/', 'mwstore://backend/container' ), @@ -156,13 +168,14 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testParentStoragePath + * @covers FileBackend::parentStoragePath */ public function testParentStoragePath( $path, $res ) { $this->assertEquals( $res, FileBackend::parentStoragePath( $path ), "FileBackend::parentStoragePath on path '$path'" ); } - function provider_testParentStoragePath() { + public static function provider_testParentStoragePath() { return array( array( 'mwstore://backend/container/path/to/obj', 'mwstore://backend/container/path/to' ), array( 'mwstore://backend/container/path/to', 'mwstore://backend/container/path' ), @@ -177,6 +190,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testExtensionFromPath + * @covers FileBackend::extensionFromPath */ public function testExtensionFromPath( $path, $res ) { $this->assertEquals( $res, FileBackend::extensionFromPath( $path ), @@ -210,6 +224,9 @@ class FileBackendTest extends MediaWikiTestCase { $this->tearDownFiles(); } + /** + * @covers FileBackend::doOperation + */ private function doTestStore( $op ) { $backendName = $this->backendClass(); @@ -281,6 +298,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testCopy + * @covers FileBackend::doOperation */ public function testCopy( $op ) { $this->backend = $this->singleBackend; @@ -312,6 +330,7 @@ class FileBackendTest extends MediaWikiTestCase { "Source file $source does not exist ($backendName)." ); $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $dest ) ), "Destination file $dest does not exist ($backendName)." ); + return; // done } @@ -400,6 +419,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testMove + * @covers FileBackend::doOperation */ public function testMove( $op ) { $this->backend = $this->singleBackend; @@ -431,6 +451,7 @@ class FileBackendTest extends MediaWikiTestCase { "Source file $source does not exist ($backendName)." ); $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $dest ) ), "Destination file $dest does not exist ($backendName)." ); + return; // done } @@ -520,6 +541,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testDelete + * @covers FileBackend::doOperation */ public function testDelete( $op, $withSource, $okStatus ) { $this->backend = $this->singleBackend; @@ -611,6 +633,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testDescribe + * @covers FileBackend::doOperation */ public function testDescribe( $op, $withSource, $okStatus ) { $this->backend = $this->singleBackend; @@ -678,6 +701,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testCreate + * @covers FileBackend::doOperation */ public function testCreate( $op, $alreadyExists, $okStatus, $newSize ) { $this->backend = $this->singleBackend; @@ -798,6 +822,9 @@ class FileBackendTest extends MediaWikiTestCase { return $cases; } + /** + * @covers FileBackend::doQuickOperations + */ public function testDoQuickOperations() { $this->backend = $this->singleBackend; $this->doTestDoQuickOperations(); @@ -817,32 +844,66 @@ class FileBackendTest extends MediaWikiTestCase { "$base/unittest-cont1/e/fileB.a", "$base/unittest-cont1/e/fileC.a" ); - $ops = array(); + $createOps = array(); $purgeOps = array(); foreach ( $files as $path ) { $status = $this->prepare( array( 'dir' => dirname( $path ) ) ); $this->assertGoodStatus( $status, "Preparing $path succeeded without warnings ($backendName)." ); - $ops[] = array( 'op' => 'create', 'dst' => $path, 'content' => mt_rand(0, 50000) ); + $createOps[] = array( 'op' => 'create', 'dst' => $path, 'content' => mt_rand( 0, 50000 ) ); + $copyOps[] = array( 'op' => 'copy', 'src' => $path, 'dst' => "$path-2" ); + $moveOps[] = array( 'op' => 'move', 'src' => "$path-2", 'dst' => "$path-3" ); $purgeOps[] = array( 'op' => 'delete', 'src' => $path ); + $purgeOps[] = array( 'op' => 'delete', 'src' => "$path-3" ); } $purgeOps[] = array( 'op' => 'null' ); - $status = $this->backend->doQuickOperations( $ops ); - $this->assertGoodStatus( $status, - "Creation of source files succeeded ($backendName)." ); + $this->assertGoodStatus( + $this->backend->doQuickOperations( $createOps ), + "Creation of source files succeeded ($backendName)." ); foreach ( $files as $file ) { $this->assertTrue( $this->backend->fileExists( array( 'src' => $file ) ), "File $file exists." ); } - $status = $this->backend->doQuickOperations( $purgeOps ); - $this->assertGoodStatus( $status, - "Quick deletion of source files succeeded ($backendName)." ); + $this->assertGoodStatus( + $this->backend->doQuickOperations( $copyOps ), + "Quick copy of source files succeeded ($backendName)." ); + foreach ( $files as $file ) { + $this->assertTrue( $this->backend->fileExists( array( 'src' => "$file-2" ) ), + "File $file-2 exists." ); + } + $this->assertGoodStatus( + $this->backend->doQuickOperations( $moveOps ), + "Quick move of source files succeeded ($backendName)." ); + foreach ( $files as $file ) { + $this->assertTrue( $this->backend->fileExists( array( 'src' => "$file-3" ) ), + "File $file-3 move in." ); + $this->assertFalse( $this->backend->fileExists( array( 'src' => "$file-2" ) ), + "File $file-2 moved away." ); + } + + $this->assertGoodStatus( + $this->backend->quickCopy( array( 'src' => $files[0], 'dst' => $files[0] ) ), + "Copy of file {$files[0]} over itself succeeded ($backendName)." ); + $this->assertTrue( $this->backend->fileExists( array( 'src' => $files[0] ) ), + "File {$files[0]} still exists." ); + + $this->assertGoodStatus( + $this->backend->quickMove( array( 'src' => $files[0], 'dst' => $files[0] ) ), + "Move of file {$files[0]} over itself succeeded ($backendName)." ); + $this->assertTrue( $this->backend->fileExists( array( 'src' => $files[0] ) ), + "File {$files[0]} still exists." ); + + $this->assertGoodStatus( + $this->backend->doQuickOperations( $purgeOps ), + "Quick deletion of source files succeeded ($backendName)." ); foreach ( $files as $file ) { $this->assertFalse( $this->backend->fileExists( array( 'src' => $file ) ), "File $file purged." ); + $this->assertFalse( $this->backend->fileExists( array( 'src' => "$file-3" ) ), + "File $file-3 purged." ); } } @@ -855,6 +916,7 @@ class FileBackendTest extends MediaWikiTestCase { $this->backend = $this->singleBackend; $this->tearDownFiles(); $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ); + $this->filesToPrune[] = $op['dst']; # avoid file leaking $this->tearDownFiles(); $this->backend = $this->multiBackend; @@ -873,8 +935,8 @@ class FileBackendTest extends MediaWikiTestCase { foreach ( $srcs as $i => $source ) { $this->prepare( array( 'dir' => dirname( $source ) ) ); $ops[] = array( - 'op' => 'create', // operation - 'dst' => $source, // source + 'op' => 'create', // operation + 'dst' => $source, // source 'content' => $srcsContent[$i] ); $expContent .= $srcsContent[$i]; @@ -927,7 +989,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testConcatenate() { + public static function provider_testConcatenate() { $cases = array(); $rand = mt_rand( 0, 2000000000 ) . time(); @@ -979,6 +1041,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetFileStat + * @covers FileBackend::getFileStat */ public function testGetFileStat( $path, $content, $alreadyExists ) { $this->backend = $this->singleBackend; @@ -1041,7 +1104,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testGetFileStat() { + public static function provider_testGetFileStat() { $cases = array(); $base = self::baseStorePath(); @@ -1054,6 +1117,8 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetFileContents + * @covers FileBackend::getFileContents + * @covers FileBackend::getFileContentsMulti */ public function testGetFileContents( $source, $content ) { $this->backend = $this->singleBackend; @@ -1096,7 +1161,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testGetFileContents() { + public static function provider_testGetFileContents() { $cases = array(); $base = self::baseStorePath(); @@ -1113,6 +1178,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetLocalCopy + * @covers FileBackend::getLocalCopy */ public function testGetLocalCopy( $source, $content ) { $this->backend = $this->singleBackend; @@ -1164,7 +1230,7 @@ class FileBackendTest extends MediaWikiTestCase { $tmpFile->bind( $obj ); } - function provider_testGetLocalCopy() { + public static function provider_testGetLocalCopy() { $cases = array(); $base = self::baseStorePath(); @@ -1182,6 +1248,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetLocalReference + * @covers FileBackend::getLocalReference */ public function testGetLocalReference( $source, $content ) { $this->backend = $this->singleBackend; @@ -1230,7 +1297,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testGetLocalReference() { + public static function provider_testGetLocalReference() { $cases = array(); $base = self::baseStorePath(); @@ -1246,6 +1313,10 @@ class FileBackendTest extends MediaWikiTestCase { return $cases; } + /** + * @covers FileBackend::getLocalCopy + * @covers FileBackend::getLocalReference + */ public function testGetLocalCopyAndReference404() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1274,6 +1345,7 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testGetFileHttpUrl + * @covers FileBackend::getFileHttpUrl */ public function testGetFileHttpUrl( $source, $content ) { $this->backend = $this->singleBackend; @@ -1305,7 +1377,7 @@ class FileBackendTest extends MediaWikiTestCase { } } - function provider_testGetFileHttpUrl() { + public static function provider_testGetFileHttpUrl() { $cases = array(); $base = self::baseStorePath(); @@ -1318,6 +1390,8 @@ class FileBackendTest extends MediaWikiTestCase { /** * @dataProvider provider_testPrepareAndClean + * @covers FileBackend::prepare + * @covers FileBackend::clean */ public function testPrepareAndClean( $path, $isOK ) { $this->backend = $this->singleBackend; @@ -1329,8 +1403,9 @@ class FileBackendTest extends MediaWikiTestCase { $this->tearDownFiles(); } - function provider_testPrepareAndClean() { + public static function provider_testPrepareAndClean() { $base = self::baseStorePath(); + return array( array( "$base/unittest-cont1/e/a/z/some_file1.txt", true ), array( "$base/unittest-cont2/a/z/some_file2.txt", true ), @@ -1375,6 +1450,9 @@ class FileBackendTest extends MediaWikiTestCase { $this->tearDownFiles(); } + /** + * @covers FileBackend::clean + */ private function doTestRecursiveClean() { $backendName = $this->backendClass(); @@ -1419,8 +1497,11 @@ class FileBackendTest extends MediaWikiTestCase { } } - // @TODO: testSecure + // @todo testSecure + /** + * @covers FileBackend::doOperations + */ public function testDoOperations() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1508,6 +1589,9 @@ class FileBackendTest extends MediaWikiTestCase { "Correct file SHA-1 of $fileC" ); } + /** + * @covers FileBackend::doOperations + */ public function testDoOperationsPipeline() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1607,6 +1691,9 @@ class FileBackendTest extends MediaWikiTestCase { "Correct file SHA-1 of $fileC" ); } + /** + * @covers FileBackend::doOperations + */ public function testDoOperationsFailing() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1681,6 +1768,9 @@ class FileBackendTest extends MediaWikiTestCase { "Correct file SHA-1 of $fileA" ); } + /** + * @covers FileBackend::getFileList + */ public function testGetFileList() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -1729,7 +1819,7 @@ class FileBackendTest extends MediaWikiTestCase { $this->assertEquals( true, $status->isOK(), "Creation of files succeeded with OK status ($backendName)." ); - // Expected listing + // Expected listing at root $expected = array( "e/test1.txt", "e/test2.txt", @@ -1748,27 +1838,28 @@ class FileBackendTest extends MediaWikiTestCase { ); sort( $expected ); - // Actual listing (no trailing slash) - $list = array(); + // Actual listing (no trailing slash) at root $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } + $list = $this->listToArray( $iter ); sort( $list ); + $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); + // Actual listing (no trailing slash) at root with advise + $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1", 'adviseStat' => 1 ) ); + $list = $this->listToArray( $iter ); + sort( $list ); $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - // Actual listing (with trailing slash) + // Actual listing (with trailing slash) at root $list = array(); $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/" ) ); foreach ( $iter as $file ) { $list[] = $file; } sort( $list ); - $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - // Expected listing + // Expected listing at subdir $expected = array( "test1.txt", "test2.txt", @@ -1780,36 +1871,39 @@ class FileBackendTest extends MediaWikiTestCase { ); sort( $expected ); - // Actual listing (no trailing slash) - $list = array(); + // Actual listing (no trailing slash) at subdir $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } + $list = $this->listToArray( $iter ); sort( $list ); + $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); + // Actual listing (no trailing slash) at subdir with advise + $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir", 'adviseStat' => 1 ) ); + $list = $this->listToArray( $iter ); + sort( $list ); $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - // Actual listing (with trailing slash) + // Actual listing (with trailing slash) at subdir $list = array(); $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir/" ) ); foreach ( $iter as $file ) { $list[] = $file; } sort( $list ); - $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); // Actual listing (using iterator second time) - $list = array(); - foreach ( $iter as $file ) { - $list[] = $file; - } + $list = $this->listToArray( $iter ); sort( $list ); - $this->assertEquals( $expected, $list, "Correct file listing ($backendName), second iteration." ); - // Expected listing (top files only) + // Actual listing (top files only) at root + $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1" ) ); + $list = $this->listToArray( $iter ); + sort( $list ); + $this->assertEquals( array(), $list, "Correct top file listing ($backendName)." ); + + // Expected listing (top files only) at subdir $expected = array( "test1.txt", "test2.txt", @@ -1819,14 +1913,16 @@ class FileBackendTest extends MediaWikiTestCase { ); sort( $expected ); - // Actual listing (top files only) - $list = array(); + // Actual listing (top files only) at subdir $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } + $list = $this->listToArray( $iter ); sort( $list ); + $this->assertEquals( $expected, $list, "Correct top file listing ($backendName)." ); + // Actual listing (top files only) at subdir with advise + $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir", 'adviseStat' => 1 ) ); + $list = $this->listToArray( $iter ); + sort( $list ); $this->assertEquals( $expected, $list, "Correct top file listing ($backendName)." ); foreach ( $files as $file ) { // clean up @@ -1834,9 +1930,15 @@ class FileBackendTest extends MediaWikiTestCase { } $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - foreach ( $iter as $iter ) {} // no errors + foreach ( $iter as $iter ) { + // no errors + } } + /** + * @covers FileBackend::getTopDirectoryList + * @covers FileBackend::getDirectoryList + */ public function testGetDirectoryList() { $this->backend = $this->singleBackend; $this->tearDownFiles(); @@ -2023,7 +2125,7 @@ class FileBackendTest extends MediaWikiTestCase { $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir1" ) ); - $items = is_array( $iter ) ? $iter : iterator_to_array( $iter ); + $items = $this->listToArray( $iter ); $this->assertEquals( array(), $items, "Directory listing is empty." ); foreach ( $files as $file ) { // clean up @@ -2031,15 +2133,22 @@ class FileBackendTest extends MediaWikiTestCase { } $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - foreach ( $iter as $file ) {} // no errors - $items = is_array( $iter ) ? $iter : iterator_to_array( $iter ); + foreach ( $iter as $file ) { + // no errors + } + + $items = $this->listToArray( $iter ); $this->assertEquals( array(), $items, "Directory listing is empty." ); $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/not/exists" ) ); - $items = is_array( $iter ) ? $iter : iterator_to_array( $iter ); + $items = $this->listToArray( $iter ); $this->assertEquals( array(), $items, "Directory listing is empty." ); } + /** + * @covers FileBackend::lockFiles + * @covers FileBackend::unlockFiles + */ public function testLockCalls() { $this->backend = $this->singleBackend; $this->doTestLockCalls(); @@ -2071,7 +2180,7 @@ class FileBackendTest extends MediaWikiTestCase { "subdir2/subdir/sub/120-px-file.txt", ); - for ( $i=0; $i<25; $i++ ) { + for ( $i = 0; $i < 25; $i++ ) { $status = $this->backend->lockFiles( $paths, LockManager::LOCK_EX ); $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), "Locking of files succeeded ($backendName) ($i)." ); @@ -2141,6 +2250,11 @@ class FileBackendTest extends MediaWikiTestCase { "Scoped unlocking of files succeeded with OK status ($backendName)." ); } + // helper function + private function listToArray( $iter ) { + return is_array( $iter ) ? $iter : iterator_to_array( $iter ); + } + // test helper wrapper for backend prepare() function private function prepare( array $params ) { return $this->backend->prepare( $params ); @@ -2149,12 +2263,15 @@ class FileBackendTest extends MediaWikiTestCase { // test helper wrapper for backend prepare() function private function create( array $params ) { $params['op'] = 'create'; + return $this->backend->doQuickOperations( array( $params ) ); } function tearDownFiles() { foreach ( $this->filesToPrune as $file ) { - @unlink( $file ); + if ( is_file( $file ) ) { + unlink( $file ); + } } $containers = array( 'unittest-cont1', 'unittest-cont2' ); foreach ( $containers as $container ) { diff --git a/tests/phpunit/includes/filerepo/FileRepoTest.php b/tests/phpunit/includes/filerepo/FileRepoTest.php index 7cc25b1b..e3a75567 100644 --- a/tests/phpunit/includes/filerepo/FileRepoTest.php +++ b/tests/phpunit/includes/filerepo/FileRepoTest.php @@ -4,37 +4,44 @@ class FileRepoTest extends MediaWikiTestCase { /** * @expectedException MWException + * @covers FileRepo::__construct */ - function testFileRepoConstructionOptionCanNotBeNull() { - $f = new FileRepo(); + public function testFileRepoConstructionOptionCanNotBeNull() { + new FileRepo(); } /** * @expectedException MWException + * @covers FileRepo::__construct */ - function testFileRepoConstructionOptionCanNotBeAnEmptyArray() { - $f = new FileRepo( array() ); + public function testFileRepoConstructionOptionCanNotBeAnEmptyArray() { + new FileRepo( array() ); } /** * @expectedException MWException + * @covers FileRepo::__construct */ - function testFileRepoConstructionOptionNeedNameKey() { - $f = new FileRepo( array( + public function testFileRepoConstructionOptionNeedNameKey() { + new FileRepo( array( 'backend' => 'foobar' ) ); } /** * @expectedException MWException + * @covers FileRepo::__construct */ - function testFileRepoConstructionOptionNeedBackendKey() { - $f = new FileRepo( array( + public function testFileRepoConstructionOptionNeedBackendKey() { + new FileRepo( array( 'name' => 'foobar' ) ); } - function testFileRepoConstructionWithRequiredOptions() { + /** + * @covers FileRepo::__construct + */ + public function testFileRepoConstructionWithRequiredOptions() { $f = new FileRepo( array( 'name' => 'FileRepoTestRepository', 'backend' => new FSFileBackend( array( diff --git a/tests/phpunit/includes/filerepo/StoreBatchTest.php b/tests/phpunit/includes/filerepo/StoreBatchTest.php index a89ef98e..b33c1bbb 100644 --- a/tests/phpunit/includes/filerepo/StoreBatchTest.php +++ b/tests/phpunit/includes/filerepo/StoreBatchTest.php @@ -1,10 +1,16 @@ <?php + /** * @group FileRepo * @group medium */ class StoreBatchTest extends MediaWikiTestCase { + protected $createdFiles; + protected $date; + /** @var FileRepo */ + protected $repo; + protected function setUp() { global $wgFileBackends; parent::setUp(); @@ -60,6 +66,7 @@ class StoreBatchTest extends MediaWikiTestCase { * @param $originalName string The title of the image * @param $srcPath string The filepath or virtual URL * @param $flags integer Flags to pass into repo::store(). + * @return FileRepoStatus */ private function storeit( $originalName, $srcPath, $flags ) { $hashPath = $this->repo->getHashPath( $originalName ); @@ -69,6 +76,7 @@ class StoreBatchTest extends MediaWikiTestCase { $result = $this->repo->store( $srcPath, 'temp', $dstRel, $flags ); $result->value = $this->repo->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel; $this->createdFiles[] = $result->value; + return $result; } @@ -78,7 +86,7 @@ class StoreBatchTest extends MediaWikiTestCase { * @param $fn string The title of the image * @param $infn string The name of the file (in the filesystem) * @param $otherfn string The name of the different file (in the filesystem) - * @param $fromrepo logical 'true' if we want to copy from a virtual URL out of the Repo. + * @param $fromrepo bool 'true' if we want to copy from a virtual URL out of the Repo. */ private function storecohort( $fn, $infn, $otherfn, $fromrepo ) { $f = $this->storeit( $fn, $infn, 0 ); @@ -115,6 +123,9 @@ class StoreBatchTest extends MediaWikiTestCase { $this->assertEquals( $f->successCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); } + /** + * @covers FileRepo::store + */ public function teststore() { global $IP; $this->storecohort( "Test1.png", "$IP/skins/monobook/wiki.png", "$IP/skins/monobook/video.png", false ); diff --git a/tests/phpunit/includes/installer/InstallDocFormatterTest.php b/tests/phpunit/includes/installer/InstallDocFormatterTest.php index 74b921a5..0e5f2671 100644 --- a/tests/phpunit/includes/installer/InstallDocFormatterTest.php +++ b/tests/phpunit/includes/installer/InstallDocFormatterTest.php @@ -1,5 +1,5 @@ <?php -/* +/* * To change this template, choose Tools | Templates * and open the template in the editor. */ @@ -9,7 +9,7 @@ class InstallDocFormatterTest extends MediaWikiTestCase { * @covers InstallDocFormatter::format * @dataProvider provideDocFormattingTests */ - function testFormat( $expected, $unformattedText, $message = '' ) { + public function testFormat( $expected, $unformattedText, $message = '' ) { $this->assertEquals( $expected, InstallDocFormatter::format( $unformattedText ), @@ -20,13 +20,14 @@ class InstallDocFormatterTest extends MediaWikiTestCase { /** * Provider for testFormat() */ - function provideDocFormattingTests() { + public static function provideDocFormattingTests() { # Format: (expected string, unformattedText string, optional message) return array( # Escape some wikitext array( 'Install <tag>', 'Install <tag>', 'Escaping <' ), array( 'Install {{template}}', 'Install {{template}}', 'Escaping [[' ), array( 'Install [[page]]', 'Install [[page]]', 'Escaping {{' ), + array( 'Install __TOC__', 'Install __TOC__', 'Escaping __' ), array( 'Install ', "Install \r", 'Removing \r' ), # Transform \t{1,2} into :{1,2} diff --git a/tests/phpunit/includes/installer/OracleInstallerTest.php b/tests/phpunit/includes/installer/OracleInstallerTest.php new file mode 100644 index 00000000..66e65592 --- /dev/null +++ b/tests/phpunit/includes/installer/OracleInstallerTest.php @@ -0,0 +1,48 @@ +<?php + +/** + * Tests for OracleInstaller + * + * @group Database + * @group Installer + */ + +class OracleInstallerTest extends MediaWikiTestCase { + + /** + * @dataProvider provideOracleConnectStrings + * @covers OracleInstaller::checkConnectStringFormat + */ + public function testCheckConnectStringFormat( $expected, $connectString, $msg = '' ) { + $validity = $expected ? 'should be valid' : 'should NOT be valid'; + $msg = "'$connectString' ($msg) $validity."; + $this->assertEquals( $expected, + OracleInstaller::checkConnectStringFormat( $connectString ), + $msg + ); + } + + /** + * Provider to test OracleInstaller::checkConnectStringFormat() + */ + function provideOracleConnectStrings() { + // expected result, connectString[, message] + return array( + array( true, 'simple_01', 'Simple TNS name' ), + array( true, 'simple_01.world', 'TNS name with domain' ), + array( true, 'simple_01.domain.net', 'TNS name with domain' ), + array( true, 'host123', 'Host only' ), + array( true, 'host123.domain.net', 'FQDN only' ), + array( true, '//host123.domain.net', 'FQDN URL only' ), + array( true, '123.223.213.132', 'Host IP only' ), + array( true, 'host:1521', 'Host and port' ), + array( true, 'host:1521/service', 'Host, port and service' ), + array( true, 'host:1521/service:shared', 'Host, port, service and shared server type' ), + array( true, 'host:1521/service:dedicated', 'Host, port, service and dedicated server type' ), + array( true, 'host:1521/service:pooled', 'Host, port, service and pooled server type' ), + array( true, 'host:1521/service:shared/instance1', 'Host, port, service, server type and instance' ), + array( true, 'host:1521//instance1', 'Host, port and instance' ), + ); + } + +} diff --git a/tests/phpunit/includes/jobqueue/JobQueueTest.php b/tests/phpunit/includes/jobqueue/JobQueueTest.php index 453cec31..4e51c4fc 100644 --- a/tests/phpunit/includes/jobqueue/JobQueueTest.php +++ b/tests/phpunit/includes/jobqueue/JobQueueTest.php @@ -8,19 +8,19 @@ class JobQueueTest extends MediaWikiTestCase { protected $key; protected $queueRand, $queueRandTTL, $queueFifo, $queueFifoTTL; - protected $old = array(); - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed[] = 'job'; } protected function setUp() { - global $wgMemc, $wgJobTypeConf; + global $wgJobTypeConf; parent::setUp(); - $this->old['wgMemc'] = $wgMemc; - $wgMemc = new HashBagOStuff(); + + $this->setMwGlobals( 'wgMemc', new HashBagOStuff() ); + if ( $this->getCliArg( 'use-jobqueue=' ) ) { $name = $this->getCliArg( 'use-jobqueue=' ); if ( !isset( $wgJobTypeConf[$name] ) ) { @@ -32,44 +32,50 @@ class JobQueueTest extends MediaWikiTestCase { } $baseConfig['type'] = 'null'; $baseConfig['wiki'] = wfWikiID(); - $this->queueRand = JobQueue::factory( - array( 'order' => 'random', 'claimTTL' => 0 ) + $baseConfig ); - $this->queueRandTTL = JobQueue::factory( - array( 'order' => 'random', 'claimTTL' => 10 ) + $baseConfig ); - $this->queueFifo = JobQueue::factory( - array( 'order' => 'fifo', 'claimTTL' => 0 ) + $baseConfig ); - $this->queueFifoTTL = JobQueue::factory( - array( 'order' => 'fifo', 'claimTTL' => 10 ) + $baseConfig ); - if ( $baseConfig['class'] !== 'JobQueueDB' ) { // DB namespace with prefix or temp tables - foreach ( array( 'queueRand', 'queueRandTTL', 'queueFifo', 'queueFifoTTL' ) as $q ) { - $this->$q->setTestingPrefix( 'unittests-' . wfRandomString( 32 ) ); - } + $variants = array( + 'queueRand' => array( 'order' => 'random', 'claimTTL' => 0 ), + 'queueRandTTL' => array( 'order' => 'random', 'claimTTL' => 10 ), + 'queueTimestamp' => array( 'order' => 'timestamp', 'claimTTL' => 0 ), + 'queueTimestampTTL' => array( 'order' => 'timestamp', 'claimTTL' => 10 ), + 'queueFifo' => array( 'order' => 'fifo', 'claimTTL' => 0 ), + 'queueFifoTTL' => array( 'order' => 'fifo', 'claimTTL' => 10 ), + ); + foreach ( $variants as $q => $settings ) { + try { + $this->$q = JobQueue::factory( $settings + $baseConfig ); + if ( !( $this->$q instanceof JobQueueDB ) ) { + $this->$q->setTestingPrefix( 'unittests-' . wfRandomString( 32 ) ); + } + } catch ( MWException $e ) { + // unsupported? + // @todo What if it was another error? + }; } } protected function tearDown() { - global $wgMemc; parent::tearDown(); - foreach ( array( 'queueRand', 'queueRandTTL', 'queueFifo', 'queueFifoTTL' ) as $q ) { - do { - $job = $this->$q->pop(); - if ( $job ) { - $this->$q->ack( $job ); - } - } while ( $job ); + foreach ( + array( + 'queueRand', 'queueRandTTL', 'queueTimestamp', 'queueTimestampTTL', + 'queueFifo', 'queueFifoTTL' + ) as $q + ) { + if ( $this->$q ) { + $this->$q->delete(); + } + $this->$q = null; } - $this->queueRand = null; - $this->queueRandTTL = null; - $this->queueFifo = null; - $this->queueFifoTTL = null; - $wgMemc = $this->old['wgMemc']; } /** * @dataProvider provider_queueLists */ - function testProperties( $queue, $order, $recycles, $desc ) { + public function testProperties( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } $this->assertEquals( wfWikiID(), $queue->getWiki(), "Proper wiki ID ($desc)" ); $this->assertEquals( 'null', $queue->getType(), "Proper job type ($desc)" ); @@ -78,8 +84,12 @@ class JobQueueTest extends MediaWikiTestCase { /** * @dataProvider provider_queueLists */ - function testBasicOperations( $queue, $order, $recycles, $desc ) { + public function testBasicOperations( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } + $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); $queue->flushCaches(); @@ -94,6 +104,8 @@ class JobQueueTest extends MediaWikiTestCase { $queue->flushCaches(); $this->assertEquals( 2, $queue->getSize(), "Queue size is correct ($desc)" ); $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); + $jobs = iterator_to_array( $queue->getAllQueuedJobs() ); + $this->assertEquals( 2, count( $jobs ), "Queue iterator size is correct ($desc)" ); $job1 = $queue->pop(); $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); @@ -132,13 +144,25 @@ class JobQueueTest extends MediaWikiTestCase { $queue->flushCaches(); $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); + + $this->assertTrue( $queue->batchPush( array( $this->newJob(), $this->newJob() ) ), + "Push worked ($desc)" ); + $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); + + $queue->delete(); + $queue->flushCaches(); + $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); + $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); } /** * @dataProvider provider_queueLists */ - function testBasicDeduplication( $queue, $order, $recycles, $desc ) { + public function testBasicDeduplication( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); @@ -146,8 +170,10 @@ class JobQueueTest extends MediaWikiTestCase { $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" ); - $this->assertTrue( $queue->batchPush( - array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) ), + $this->assertTrue( + $queue->batchPush( + array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) + ), "Push worked ($desc)" ); $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); @@ -156,9 +182,12 @@ class JobQueueTest extends MediaWikiTestCase { $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" ); $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); - $this->assertTrue( $queue->batchPush( - array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) ), - "Push worked ($desc)" ); + $this->assertTrue( + $queue->batchPush( + array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) + ), + "Push worked ($desc)" + ); $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); @@ -186,8 +215,11 @@ class JobQueueTest extends MediaWikiTestCase { /** * @dataProvider provider_queueLists */ - function testRootDeduplication( $queue, $order, $recycles, $desc ) { + public function testRootDeduplication( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); @@ -236,8 +268,11 @@ class JobQueueTest extends MediaWikiTestCase { /** * @dataProvider provider_fifoQueueLists */ - function testJobOrder( $queue, $recycles, $desc ) { + public function testJobOrder( $queue, $recycles, $desc ) { $queue = $this->$queue; + if ( !$queue ) { + $this->markTestSkipped( $desc ); + } $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); @@ -264,16 +299,18 @@ class JobQueueTest extends MediaWikiTestCase { $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); } - function provider_queueLists() { + public static function provider_queueLists() { return array( - array( 'queueRand', 'rand', false, 'Random queue without ack()' ), - array( 'queueRandTTL', 'rand', true, 'Random queue with ack()' ), - array( 'queueFifo', 'fifo', false, 'Ordered queue without ack()' ), - array( 'queueFifoTTL', 'fifo', true, 'Ordered queue with ack()' ) + array( 'queueRand', false, 'Random queue without ack()' ), + array( 'queueRandTTL', true, 'Random queue with ack()' ), + array( 'queueTimestamp', false, 'Time ordered queue without ack()' ), + array( 'queueTimestampTTL', true, 'Time ordered queue with ack()' ), + array( 'queueFifo', false, 'FIFO ordered queue without ack()' ), + array( 'queueFifoTTL', true, 'FIFO ordered queue with ack()' ) ); } - function provider_fifoQueueLists() { + public static function provider_fifoQueueLists() { return array( array( 'queueFifo', false, 'Ordered queue without ack()' ), array( 'queueFifoTTL', true, 'Ordered queue with ack()' ) diff --git a/tests/phpunit/includes/json/FormatJsonTest.php b/tests/phpunit/includes/json/FormatJsonTest.php new file mode 100644 index 00000000..149be05b --- /dev/null +++ b/tests/phpunit/includes/json/FormatJsonTest.php @@ -0,0 +1,161 @@ +<?php + +class FormatJsonTest extends MediaWikiTestCase { + + public function testEncoderPrettyPrinting() { + $obj = array( + 'emptyObject' => new stdClass, + 'emptyArray' => array(), + 'string' => 'foobar\\', + 'filledArray' => array( + array( + 123, + 456, + ), + // Nested json works without problems + '"7":["8",{"9":"10"}]', + // Whitespace clean up doesn't touch strings that look alike + "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}", + ), + ); + + // 4 space indent, no trailing whitespace, no trailing linefeed + $json = '{ + "emptyObject": {}, + "emptyArray": [], + "string": "foobar\\\\", + "filledArray": [ + [ + 123, + 456 + ], + "\"7\":[\"8\",{\"9\":\"10\"}]", + "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}" + ] +}'; + + $json = str_replace( "\r", '', $json ); // Windows compat + $this->assertSame( $json, FormatJson::encode( $obj, true ) ); + } + + public static function provideEncodeDefault() { + return self::getEncodeTestCases( array() ); + } + + /** + * @dataProvider provideEncodeDefault + */ + public function testEncodeDefault( $from, $to ) { + $this->assertSame( $to, FormatJson::encode( $from ) ); + } + + public static function provideEncodeUtf8() { + return self::getEncodeTestCases( array( 'unicode' ) ); + } + + /** + * @dataProvider provideEncodeUtf8 + */ + public function testEncodeUtf8( $from, $to ) { + $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::UTF8_OK ) ); + } + + public static function provideEncodeXmlMeta() { + return self::getEncodeTestCases( array( 'xmlmeta' ) ); + } + + /** + * @dataProvider provideEncodeXmlMeta + */ + public function testEncodeXmlMeta( $from, $to ) { + $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::XMLMETA_OK ) ); + } + + public static function provideEncodeAllOk() { + return self::getEncodeTestCases( array( 'unicode', 'xmlmeta' ) ); + } + + /** + * @dataProvider provideEncodeAllOk + */ + public function testEncodeAllOk( $from, $to ) { + $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::ALL_OK ) ); + } + + public function testEncodePhpBug46944() { + $this->assertNotEquals( + '\ud840\udc00', + strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ), + 'Test encoding an broken json_encode character (U+20000)' + ); + } + + public function testDecodeReturnType() { + $this->assertInternalType( + 'object', + FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ), + 'Default to object' + ); + + $this->assertInternalType( + 'array', + FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ), + 'Optional array' + ); + } + + /** + * Generate a set of test cases for a particular combination of encoder options. + * + * @param array $unescapedGroups List of character groups to leave unescaped + * @return array: Arrays of unencoded strings and corresponding encoded strings + */ + private static function getEncodeTestCases( array $unescapedGroups ) { + $groups = array( + 'always' => array( + // Forward slash (always unescaped) + '/' => '/', + + // Control characters + "\0" => '\u0000', + "\x08" => '\b', + "\t" => '\t', + "\n" => '\n', + "\r" => '\r', + "\f" => '\f', + "\x1f" => '\u001f', // representative example + + // Double quotes + '"' => '\"', + + // Backslashes + '\\' => '\\\\', + '\\\\' => '\\\\\\\\', + '\\u00e9' => '\\\u00e9', // security check for Unicode unescaping + + // Line terminators + "\xe2\x80\xa8" => '\u2028', + "\xe2\x80\xa9" => '\u2029', + ), + 'unicode' => array( + "\xc3\xa9" => '\u00e9', + "\xf0\x9d\x92\x9e" => '\ud835\udc9e', // U+1D49E, outside the BMP + ), + 'xmlmeta' => array( + '<' => '\u003C', // JSON_HEX_TAG uses uppercase hex digits + '>' => '\u003E', + '&' => '\u0026', + ), + ); + + $cases = array(); + foreach ( $groups as $name => $rules ) { + $leaveUnescaped = in_array( $name, $unescapedGroups ); + foreach ( $rules as $from => $to ) { + $cases[] = array( $from, '"' . ( $leaveUnescaped ? $from : $to ) . '"' ); + } + } + + return $cases; + } +} diff --git a/tests/phpunit/includes/json/ServicesJsonTest.php b/tests/phpunit/includes/json/ServicesJsonTest.php deleted file mode 100644 index 56dc6488..00000000 --- a/tests/phpunit/includes/json/ServicesJsonTest.php +++ /dev/null @@ -1,93 +0,0 @@ -<?php -/* - * Test cases for our Services_Json library. Requires PHP json support as well, - * so we can compare output - */ -class ServicesJsonTest extends MediaWikiTestCase { - /** - * Test to make sure core json_encode() and our Services_Json()->encode() - * produce the same output - * - * @dataProvider provideValuesToEncode - */ - public function testJsonEncode( $input, $desc ) { - if ( !function_exists( 'json_encode' ) ) { - $this->markTestIncomplete( 'No PHP json support, unable to test' ); - return; - } elseif ( strtolower( json_encode( "\xf0\xa0\x80\x80" ) ) != '"\ud840\udc00"' ) { - $this->markTestIncomplete( 'Have buggy PHP json support, unable to test' ); - return; - } else { - $jsonObj = new Services_JSON(); - $this->assertEquals( - $jsonObj->encode( $input ), - json_encode( $input ), - $desc - ); - } - } - - /** - * Test to make sure core json_decode() and our Services_Json()->decode() - * produce the same output - * - * @dataProvider provideValuesToDecode - */ - public function testJsonDecode( $input, $desc ) { - if ( !function_exists( 'json_decode' ) ) { - $this->markTestIncomplete( 'No PHP json support, unable to test' ); - return; - } else { - $jsonObj = new Services_JSON(); - $this->assertEquals( - $jsonObj->decode( $input ), - json_decode( $input ), - $desc - ); - } - } - - function provideValuesToEncode() { - $obj = new stdClass(); - $obj->property = 'value'; - $obj->property2 = null; - $obj->property3 = 1.234; - return array( - array( 1, 'basic integer' ), - array( -1, 'negative integer' ), - array( 1.1, 'basic float' ), - array( true, 'basic bool true' ), - array( false, 'basic bool false' ), - array( 'some string', 'basic string test' ), - array( "some string\nwith newline", 'newline string test' ), - array( '♥ü', 'unicode string test' ), - array( array( 'some', 'string', 'values' ), 'basic array of strings' ), - array( array( 'key1' => 'val1', 'key2' => 'val2' ), 'array with string keys' ), - array( array( 1 => 'val1', 3 => 'val2', '2' => 'val3' ), 'out of order numbered array test' ), - array( array(), 'empty array test' ), - array( $obj, 'basic object test' ), - array( new stdClass, 'empty object test' ), - array( null, 'null test' ), - ); - } - - function provideValuesToDecode() { - return array( - array( '1', 'basic integer' ), - array( '-1', 'negative integer' ), - array( '1.1', 'basic float' ), - array( '1.1e1', 'scientific float' ), - array( 'true', 'basic bool true' ), - array( 'false', 'basic bool false' ), - array( '"some string"', 'basic string test' ), - array( '"some string\nwith newline"', 'newline string test' ), - array( '"♥ü"', 'unicode character string test' ), - array( '"\u2665"', 'unicode \\u string test' ), - array( '["some","string","values"]', 'basic array of strings' ), - array( '[]', 'empty array test' ), - array( '{"key":"value"}', 'Basic key => value test' ), - array( '{}', 'empty object test' ), - array( 'null', 'null test' ), - ); - } -} diff --git a/tests/phpunit/includes/libs/CSSJanusTest.php b/tests/phpunit/includes/libs/CSSJanusTest.php index 26747b91..5a3c1619 100644 --- a/tests/phpunit/includes/libs/CSSJanusTest.php +++ b/tests/phpunit/includes/libs/CSSJanusTest.php @@ -4,12 +4,14 @@ * CSSJanus libary: * http://code.google.com/p/cssjanus/source/browse/trunk/cssjanus_test.py * Ported to PHP for ResourceLoader and has been extended since. + * + * @covers CSSJanus */ class CSSJanusTest extends MediaWikiTestCase { /** * @dataProvider provideTransformCases */ - function testTransform( $cssA, $cssB = null ) { + public function testTransform( $cssA, $cssB = null ) { if ( $cssB ) { $transformedA = CSSJanus::transform( $cssA ); @@ -28,7 +30,7 @@ class CSSJanusTest extends MediaWikiTestCase { /** * @dataProvider provideTransformAdvancedCases */ - function testTransformAdvanced( $code, $expectedOutput, $options = array() ) { + public function testTransformAdvanced( $code, $expectedOutput, $options = array() ) { $swapLtrRtlInURL = isset( $options['swapLtrRtlInURL'] ) ? $options['swapLtrRtlInURL'] : false; $swapLeftRightInURL = isset( $options['swapLeftRightInURL'] ) ? $options['swapLeftRightInURL'] : false; @@ -44,7 +46,7 @@ class CSSJanusTest extends MediaWikiTestCase { * @dataProvider provideTransformBrokenCases * @group Broken */ - function testTransformBroken( $code, $expectedOutput ) { + public function testTransformBroken( $code, $expectedOutput ) { $flipped = CSSJanus::transform( $code ); $this->assertEquals( $expectedOutput, $flipped, 'Test flipping' ); @@ -54,7 +56,7 @@ class CSSJanusTest extends MediaWikiTestCase { * These transform cases are tested *in both directions* * No need to declare a principle twice in both directions here. */ - function provideTransformCases() { + public static function provideTransformCases() { return array( // Property keys array( @@ -137,11 +139,16 @@ class CSSJanusTest extends MediaWikiTestCase { '.foo { padding: 1px inherit 3px auto; }', '.foo { padding: 1px auto 3px inherit; }' ), + // border-radius assigns different meanings to the values array( '.foo { border-radius: .25em 15px 0pt 0ex; }', - '.foo { border-radius: .25em 0ex 0pt 15px; }' + '.foo { border-radius: 15px .25em 0ex 0pt; }' ), array( + '.foo { border-radius: 0px 0px 5px 5px; }', + ), + // Ensure the rule doesn't break other stuff + array( '.foo { x-unknown: a b c d; }' ), array( @@ -151,14 +158,26 @@ class CSSJanusTest extends MediaWikiTestCase { '#settings td p strong' ), array( - # Not sure how 4+ values should behave, - # testing to make sure changes are detected - '.foo { x-unknown: 1 2 3 4 5; }', - '.foo { x-unknown: 1 4 3 2 5; }', + // Color names + '.foo { border-color: red green blue white }', + '.foo { border-color: red white blue green }', + ), + array( + // Color name, hexdecimal, RGB & RGBA + '.foo { border-color: red #f00 rgb(255, 0, 0) rgba(255, 0, 0, 0.5) }', + '.foo { border-color: red rgba(255, 0, 0, 0.5) rgb(255, 0, 0) #f00 }', + ), + array( + // Color name, hexdecimal, HSL & HSLA + '.foo { border-color: red #f00 hsl(0, 100%, 50%) hsla(0, 100%, 50%, 0.5) }', + '.foo { border-color: red hsla(0, 100%, 50%, 0.5) hsl(0, 100%, 50%) #f00 }', ), array( - '.foo { x-unknown: 1 2 3 4 5 6; }', - '.foo { x-unknown: 1 4 3 2 5 6; }', + // Do not mangle 5 or more values + '.foo { -x-unknown: 1 2 3 4 5; }' + ), + array( + '.foo { -x-unknown: 1 2 3 4 5 6; }' ), // Shorthand / Three notation @@ -179,6 +198,28 @@ class CSSJanusTest extends MediaWikiTestCase { '.foo { padding: 1px; }' ), + // text-shadow and box-shadow + array( + '.foo { box-shadow: -6px 3px 8px 5px rgba(0, 0, 0, 0.25); }', + '.foo { box-shadow: 6px 3px 8px 5px rgba(0, 0, 0, 0.25); }', + ), + array( + '.foo { box-shadow: inset -6px 3px 8px 5px rgba(0, 0, 0, 0.25); }', + '.foo { box-shadow: inset 6px 3px 8px 5px rgba(0, 0, 0, 0.25); }', + ), + array( + '.foo { text-shadow: orange 2px 0; }', + '.foo { text-shadow: orange -2px 0; }', + ), + array( + '.foo { text-shadow: 2px 0 orange; }', + '.foo { text-shadow: -2px 0 orange; }', + ), + array( + // Don't mangle zeroes + '.foo { text-shadow: orange 0 2px; }' + ), + // Direction // Note: This differs from the Python implementation, // see also CSSJanus::fixDirection for more info. @@ -377,6 +418,11 @@ class CSSJanusTest extends MediaWikiTestCase { '/* @noflip */ div { float: left; } .foo { float: right; }' ), array( + // support parentheses in selector + '/* @noflip */ .test:not(:first) { margin-right: -0.25em; margin-left: 0.25em; }', + '/* @noflip */ .test:not(:first) { margin-right: -0.25em; margin-left: 0.25em; }' + ), + array( // after multiple rules '.foo { float: left; } /* @noflip */ div { float: left; }', '.foo { float: right; } /* @noflip */ div { float: left; }' @@ -476,7 +522,7 @@ class CSSJanusTest extends MediaWikiTestCase { * If both ways can be tested, either put both versions in here or move * it to provideTransformCases(). */ - function provideTransformAdvancedCases() { + public static function provideTransformAdvancedCases() { $bgPairs = array( # [ - _ . ] <-> [ left right ltr rtl ] 'foo.jpg' => 'foo.jpg', @@ -542,7 +588,7 @@ class CSSJanusTest extends MediaWikiTestCase { * Cases that are currently failing, but * should be looked at in the future as enhancements and/or bug fix */ - function provideTransformBrokenCases() { + public static function provideTransformBrokenCases() { return array( // Guard against selectors that look flippable array( diff --git a/tests/phpunit/includes/libs/CSSMinTest.php b/tests/phpunit/includes/libs/CSSMinTest.php index 57017a84..951dd7b9 100644 --- a/tests/phpunit/includes/libs/CSSMinTest.php +++ b/tests/phpunit/includes/libs/CSSMinTest.php @@ -21,13 +21,13 @@ class CSSMinTest extends MediaWikiTestCase { /** * @dataProvider provideMinifyCases */ - function testMinify( $code, $expectedOutput ) { + public function testMinify( $code, $expectedOutput ) { $minified = CSSMin::minify( $code ); $this->assertEquals( $expectedOutput, $minified, 'Minified output should be in the form expected.' ); } - function provideMinifyCases() { + public static function provideMinifyCases() { return array( // Whitespace array( "\r\t\f \v\n\r", "" ), @@ -70,14 +70,14 @@ class CSSMinTest extends MediaWikiTestCase { /** * @dataProvider provideRemapCases */ - function testRemap( $message, $params, $expectedOutput ) { + public function testRemap( $message, $params, $expectedOutput ) { $remapped = call_user_func_array( 'CSSMin::remap', $params ); $messageAdd = " Case: $message"; $this->assertEquals( $expectedOutput, $remapped, 'CSSMin::remap should return the expected url form.' . $messageAdd ); } - function provideRemapCases() { + public static function provideRemapCases() { // Parameter signature: // CSSMin::remap( $code, $local, $remote, $embedData = true ) return array( @@ -115,11 +115,11 @@ class CSSMinTest extends MediaWikiTestCase { * @group Broken * @dataProvider provideStringCases */ - function testMinifyWithCSSStringValues( $code, $expectedOutput ) { + public function testMinifyWithCSSStringValues( $code, $expectedOutput ) { $this->testMinifyOutput( $code, $expectedOutput ); } - function provideStringCases() { + public static function provideStringCases() { return array( // String values should be respected // - More than one space in a string value diff --git a/tests/phpunit/includes/libs/GenericArrayObjectTest.php b/tests/phpunit/includes/libs/GenericArrayObjectTest.php index 37a9b347..7436c43c 100644 --- a/tests/phpunit/includes/libs/GenericArrayObjectTest.php +++ b/tests/phpunit/includes/libs/GenericArrayObjectTest.php @@ -73,6 +73,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase { */ protected function getNew( array $elements = array() ) { $class = $this->getInstanceClass(); + return new $class( $elements ); } @@ -197,6 +198,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase { public function testOffsetSet( array $elements ) { if ( $elements === array() ) { $this->assertTrue( true ); + return; } @@ -258,5 +260,4 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase { $this->assertArrayEquals( $list, $copy, true, true ); } - } diff --git a/tests/phpunit/includes/libs/IEUrlExtensionTest.php b/tests/phpunit/includes/libs/IEUrlExtensionTest.php index d04dd7d4..66fe915a 100644 --- a/tests/phpunit/includes/libs/IEUrlExtensionTest.php +++ b/tests/phpunit/includes/libs/IEUrlExtensionTest.php @@ -4,7 +4,7 @@ * Tests for IEUrlExtension::findIE6Extension */ class IEUrlExtensionTest extends MediaWikiTestCase { - function testSimple() { + public function testSimple() { $this->assertEquals( 'y', IEUrlExtension::findIE6Extension( 'x.y' ), @@ -12,7 +12,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testSimpleNoExt() { + public function testSimpleNoExt() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( 'x' ), @@ -20,7 +20,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testEmpty() { + public function testEmpty() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( '' ), @@ -28,7 +28,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testQuestionMark() { + public function testQuestionMark() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( '?' ), @@ -36,7 +36,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testExtQuestionMark() { + public function testExtQuestionMark() { $this->assertEquals( 'x', IEUrlExtension::findIE6Extension( '.x?' ), @@ -44,7 +44,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testQuestionMarkExt() { + public function testQuestionMarkExt() { $this->assertEquals( 'x', IEUrlExtension::findIE6Extension( '?.x' ), @@ -52,7 +52,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testInvalidChar() { + public function testInvalidChar() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( '.x*' ), @@ -60,7 +60,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testInvalidCharThenExtension() { + public function testInvalidCharThenExtension() { $this->assertEquals( 'x', IEUrlExtension::findIE6Extension( '*.x' ), @@ -68,7 +68,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testMultipleQuestionMarks() { + public function testMultipleQuestionMarks() { $this->assertEquals( 'c', IEUrlExtension::findIE6Extension( 'a?b?.c?.d?e?f' ), @@ -76,7 +76,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testExeException() { + public function testExeException() { $this->assertEquals( 'd', IEUrlExtension::findIE6Extension( 'a?b?.exe?.d?.e' ), @@ -84,7 +84,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testExeException2() { + public function testExeException2() { $this->assertEquals( 'exe', IEUrlExtension::findIE6Extension( 'a?b?.exe' ), @@ -92,7 +92,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testHash() { + public function testHash() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( 'a#b.c' ), @@ -100,7 +100,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testHash2() { + public function testHash2() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( 'a?#b.c' ), @@ -108,7 +108,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testDotAtEnd() { + public function testDotAtEnd() { $this->assertEquals( '', IEUrlExtension::findIE6Extension( '.' ), @@ -116,7 +116,7 @@ class IEUrlExtensionTest extends MediaWikiTestCase { ); } - function testTwoDots() { + public function testTwoDots() { $this->assertEquals( 'z', IEUrlExtension::findIE6Extension( 'x.y.z' ), diff --git a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php b/tests/phpunit/includes/libs/JavaScriptMinifierTest.php index 1f550795..ab72e361 100644 --- a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php +++ b/tests/phpunit/includes/libs/JavaScriptMinifierTest.php @@ -2,7 +2,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase { - function provideCases() { + public static function provideCases() { return array( // Basic whitespace and comments that should be stripped entirely @@ -119,7 +119,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase { /** * @dataProvider provideCases */ - function testJavaScriptMinifierOutput( $code, $expectedOutput ) { + public function testJavaScriptMinifierOutput( $code, $expectedOutput ) { $minified = JavaScriptMinifier::minify( $code ); // JSMin+'s parser will throw an exception if output is not valid JS. @@ -132,7 +132,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase { $this->assertEquals( $expectedOutput, $minified, "Minified output should be in the form expected." ); } - function provideBug32548() { + public static function provideBug32548() { return array( array( // This one gets interpreted all together by the prior code; @@ -153,7 +153,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase { /** * @dataProvider provideBug32548 */ - function testBug32548Exponent( $num ) { + public function testBug32548Exponent( $num ) { // Long line breaking was being incorrectly done between the base and // exponent part of a number, causing a syntax error. The line should // instead break at the start of the number. diff --git a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php b/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php index b221b832..a0e63a8a 100644 --- a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php +++ b/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php @@ -16,18 +16,17 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { * Basically the file has IPTC and XMP metadata, the * IPTC should override the XMP, except for the multilingual * translation (to en) where XMP should win. + * @covers BitmapMetadataHandler::Jpeg */ public function testMultilingualCascade() { - global $wgShowEXIF; - - if ( !wfDl( 'exif' ) ) { + if ( !extension_loaded( 'exif' ) ) { $this->markTestSkipped( "This test needs the exif extension." ); } - if ( !wfDl( 'xml' ) ) { + if ( !extension_loaded( 'xml' ) ) { $this->markTestSkipped( "This test needs the xml extension." ); } - $wgShowEXIF = true; + $this->setMwGlobals( 'wgShowEXIF', true ); $meta = BitmapMetadataHandler::Jpeg( $this->filePath . '/Xmp-exif-multilingual_test.jpg' ); @@ -50,6 +49,7 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { * * There's more extensive tests of comment extraction in * JpegMetadataExtractorTests.php + * @covers BitmapMetadataHandler::Jpeg */ public function testJpegComment() { $meta = BitmapMetadataHandler::Jpeg( $this->filePath . @@ -62,6 +62,7 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { /** * Make sure a bad iptc block doesn't stop the other metadata * from being extracted. + * @covers BitmapMetadataHandler::Jpeg */ public function testBadIPTC() { $meta = BitmapMetadataHandler::Jpeg( $this->filePath . @@ -69,6 +70,9 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { $this->assertEquals( 'Created with GIMP', $meta['JPEGFileComment'][0] ); } + /** + * @covers BitmapMetadataHandler::Jpeg + */ public function testIPTCDates() { $meta = BitmapMetadataHandler::Jpeg( $this->filePath . 'iptc-timetest.jpg' ); @@ -80,6 +84,7 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { /** * File has an invalid time (+ one valid but really weird time) * that shouldn't be included + * @covers BitmapMetadataHandler::Jpeg */ public function testIPTCDatesInvalid() { $meta = BitmapMetadataHandler::Jpeg( $this->filePath . @@ -93,6 +98,8 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { * XMP data should take priority over iptc data * when hash has been updated, but not when * the hash is wrong. + * @covers BitmapMetadataHandler::addMetadata + * @covers BitmapMetadataHandler::getMetadataArray */ public function testMerging() { $merger = new BitmapMetadataHandler(); @@ -116,8 +123,11 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { $this->assertEquals( $expected, $actual ); } + /** + * @covers BitmapMetadataHandler::png + */ public function testPNGXMP() { - if ( !wfDl( 'xml' ) ) { + if ( !extension_loaded( 'xml' ) ) { $this->markTestSkipped( "This test needs the xml extension." ); } $handler = new BitmapMetadataHandler(); @@ -136,6 +146,9 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { $this->assertEquals( $expected, $result ); } + /** + * @covers BitmapMetadataHandler::png + */ public function testPNGNative() { $handler = new BitmapMetadataHandler(); $result = $handler->png( $this->filePath . 'Png-native-test.png' ); @@ -143,10 +156,12 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase { $this->assertEquals( $expected, $result['metadata']['Identifier']['x-default'] ); } + /** + * @covers BitmapMetadataHandler::getTiffByteOrder + */ public function testTiffByteOrder() { $handler = new BitmapMetadataHandler(); $res = $handler->getTiffByteOrder( $this->filePath . 'test.tiff' ); $this->assertEquals( 'LE', $res ); } - } diff --git a/tests/phpunit/includes/media/BitmapScalingTest.php b/tests/phpunit/includes/media/BitmapScalingTest.php index 3de60b73..9395b660 100644 --- a/tests/phpunit/includes/media/BitmapScalingTest.php +++ b/tests/phpunit/includes/media/BitmapScalingTest.php @@ -13,8 +13,9 @@ class BitmapScalingTest extends MediaWikiTestCase { /** * @dataProvider provideNormaliseParams + * @covers BitmapHandler::normaliseParams */ - function testNormaliseParams( $fileDimensions, $expectedParams, $params, $msg ) { + public function testNormaliseParams( $fileDimensions, $expectedParams, $params, $msg ) { $file = new FakeDimensionFile( $fileDimensions ); $handler = new BitmapHandler; $valid = $handler->normaliseParams( $file, $params ); @@ -22,7 +23,7 @@ class BitmapScalingTest extends MediaWikiTestCase { $this->assertEquals( $expectedParams, $params, $msg ); } - function provideNormaliseParams() { + public static function provideNormaliseParams() { return array( /* Regular resize operations */ array( @@ -102,7 +103,10 @@ class BitmapScalingTest extends MediaWikiTestCase { ); } - function testTooBigImage() { + /** + * @covers BitmapHandler::doTransform + */ + public function testTooBigImage() { $file = new FakeDimensionFile( array( 4000, 4000 ) ); $handler = new BitmapHandler; $params = array( 'width' => '3700' ); // Still bigger than max size. @@ -110,7 +114,10 @@ class BitmapScalingTest extends MediaWikiTestCase { get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); } - function testTooBigMustRenderImage() { + /** + * @covers BitmapHandler::doTransform + */ + public function testTooBigMustRenderImage() { $file = new FakeDimensionFile( array( 4000, 4000 ) ); $file->mustRender = true; $handler = new BitmapHandler; @@ -119,36 +126,12 @@ class BitmapScalingTest extends MediaWikiTestCase { get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); } - function testImageArea() { + /** + * @covers BitmapHandler::getImageArea + */ + public function testImageArea() { $file = new FakeDimensionFile( array( 7, 9 ) ); $handler = new BitmapHandler; $this->assertEquals( 63, $handler->getImageArea( $file ) ); } } - -class FakeDimensionFile extends File { - public $mustRender = false; - - public function __construct( $dimensions ) { - parent::__construct( Title::makeTitle( NS_FILE, 'Test' ), - new NullRepo( null ) ); - - $this->dimensions = $dimensions; - } - - public function getWidth( $page = 1 ) { - return $this->dimensions[0]; - } - - public function getHeight( $page = 1 ) { - return $this->dimensions[1]; - } - - public function mustRender() { - return $this->mustRender; - } - - public function getPath() { - return ''; - } -} diff --git a/tests/phpunit/includes/media/ExifBitmapTest.php b/tests/phpunit/includes/media/ExifBitmapTest.php index 1109c478..a2e0eb62 100644 --- a/tests/phpunit/includes/media/ExifBitmapTest.php +++ b/tests/phpunit/includes/media/ExifBitmapTest.php @@ -2,53 +2,79 @@ class ExifBitmapTest extends MediaWikiTestCase { + /** + * @var ExifBitmapHandler + */ + protected $handler; + protected function setUp() { parent::setUp(); + if ( !extension_loaded( 'exif' ) ) { + $this->markTestSkipped( "This test needs the exif extension." ); + } $this->setMwGlobals( 'wgShowEXIF', true ); $this->handler = new ExifBitmapHandler; - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } + } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testIsOldBroken() { $res = $this->handler->isMetadataValid( null, ExifBitmapHandler::OLD_BROKEN_FILE ); $this->assertEquals( ExifBitmapHandler::METADATA_COMPATIBLE, $res ); } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testIsBrokenFile() { $res = $this->handler->isMetadataValid( null, ExifBitmapHandler::BROKEN_FILE ); $this->assertEquals( ExifBitmapHandler::METADATA_GOOD, $res ); } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testIsInvalid() { $res = $this->handler->isMetadataValid( null, 'Something Invalid Here.' ); $this->assertEquals( ExifBitmapHandler::METADATA_BAD, $res ); } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testGoodMetadata() { $meta = 'a:16:{s:10:"ImageWidth";i:20;s:11:"ImageLength";i:20;s:13:"BitsPerSample";a:3:{i:0;i:8;i:1;i:8;i:2;i:8;}s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:16:"ImageDescription";s:17:"Created with GIMP";s:12:"StripOffsets";i:8;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:3;s:12:"RowsPerStrip";i:64;s:15:"StripByteCounts";i:238;s:11:"XResolution";s:19:"1207959552/16777216";s:11:"YResolution";s:19:"1207959552/16777216";s:19:"PlanarConfiguration";i:1;s:14:"ResolutionUnit";i:2;s:22:"MEDIAWIKI_EXIF_VERSION";i:2;}'; $res = $this->handler->isMetadataValid( null, $meta ); $this->assertEquals( ExifBitmapHandler::METADATA_GOOD, $res ); } + /** + * @covers ExifBitmapHandler::isMetadataValid + */ public function testIsOldGood() { $meta = 'a:16:{s:10:"ImageWidth";i:20;s:11:"ImageLength";i:20;s:13:"BitsPerSample";a:3:{i:0;i:8;i:1;i:8;i:2;i:8;}s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:16:"ImageDescription";s:17:"Created with GIMP";s:12:"StripOffsets";i:8;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:3;s:12:"RowsPerStrip";i:64;s:15:"StripByteCounts";i:238;s:11:"XResolution";s:19:"1207959552/16777216";s:11:"YResolution";s:19:"1207959552/16777216";s:19:"PlanarConfiguration";i:1;s:14:"ResolutionUnit";i:2;s:22:"MEDIAWIKI_EXIF_VERSION";i:1;}'; $res = $this->handler->isMetadataValid( null, $meta ); $this->assertEquals( ExifBitmapHandler::METADATA_COMPATIBLE, $res ); } - // Handle metadata from paged tiff handler (gotten via instant commons) - // gracefully. + /** + * Handle metadata from paged tiff handler (gotten via instant commons) gracefully. + * @covers ExifBitmapHandler::isMetadataValid + */ public function testPagedTiffHandledGracefully() { $meta = 'a:6:{s:9:"page_data";a:1:{i:1;a:5:{s:5:"width";i:643;s:6:"height";i:448;s:5:"alpha";s:4:"true";s:4:"page";i:1;s:6:"pixels";i:288064;}}s:10:"page_count";i:1;s:10:"first_page";i:1;s:9:"last_page";i:1;s:4:"exif";a:9:{s:10:"ImageWidth";i:643;s:11:"ImageLength";i:448;s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:4;s:12:"RowsPerStrip";i:50;s:19:"PlanarConfiguration";i:1;s:22:"MEDIAWIKI_EXIF_VERSION";i:1;}s:21:"TIFF_METADATA_VERSION";s:3:"1.4";}'; $res = $this->handler->isMetadataValid( null, $meta ); $this->assertEquals( ExifBitmapHandler::METADATA_BAD, $res ); } - function testConvertMetadataLatest() { + /** + * @covers ExifBitmapHandler::convertMetadataVersion + */ + public function testConvertMetadataLatest() { $metadata = array( 'foo' => array( 'First', 'Second', '_type' => 'ol' ), 'MEDIAWIKI_EXIF_VERSION' => 2 @@ -57,7 +83,10 @@ class ExifBitmapTest extends MediaWikiTestCase { $this->assertEquals( $metadata, $res ); } - function testConvertMetadataToOld() { + /** + * @covers ExifBitmapHandler::convertMetadataVersion + */ + public function testConvertMetadataToOld() { $metadata = array( 'foo' => array( 'First', 'Second', '_type' => 'ol' ), 'bar' => array( 'First', 'Second', '_type' => 'ul' ), @@ -76,7 +105,10 @@ class ExifBitmapTest extends MediaWikiTestCase { $this->assertEquals( $expected, $res ); } - function testConvertMetadataSoftware() { + /** + * @covers ExifBitmapHandler::convertMetadataVersion + */ + public function testConvertMetadataSoftware() { $metadata = array( 'Software' => array( array( 'GIMP', '1.1' ) ), 'MEDIAWIKI_EXIF_VERSION' => 2, @@ -89,7 +121,10 @@ class ExifBitmapTest extends MediaWikiTestCase { $this->assertEquals( $expected, $res ); } - function testConvertMetadataSoftwareNormal() { + /** + * @covers ExifBitmapHandler::convertMetadataVersion + */ + public function testConvertMetadataSoftwareNormal() { $metadata = array( 'Software' => array( "GIMP 1.2", "vim" ), 'MEDIAWIKI_EXIF_VERSION' => 2, diff --git a/tests/phpunit/includes/media/ExifRotationTest.php b/tests/phpunit/includes/media/ExifRotationTest.php index db29d17c..64276d92 100644 --- a/tests/phpunit/includes/media/ExifRotationTest.php +++ b/tests/phpunit/includes/media/ExifRotationTest.php @@ -3,11 +3,17 @@ * Tests related to auto rotation. * * @group medium + * + * @todo covers tags */ class ExifRotationTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); + if ( !extension_loaded( 'exif' ) ) { + $this->markTestSkipped( "This test needs the exif extension." ); + } + $this->handler = new BitmapHandler(); $filePath = __DIR__ . '/../../data/media'; @@ -22,31 +28,17 @@ class ExifRotationTest extends MediaWikiTestCase { 'containerPaths' => array( 'temp-thumb' => $tmpDir, 'data' => $filePath ) ) ) ) ); - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - global $wgShowEXIF; - $this->show = $wgShowEXIF; - $wgShowEXIF = true; - global $wgEnableAutoRotation; - $this->oldAuto = $wgEnableAutoRotation; - $wgEnableAutoRotation = true; - } - - protected function tearDown() { - global $wgShowEXIF, $wgEnableAutoRotation; - $wgShowEXIF = $this->show; - $wgEnableAutoRotation = $this->oldAuto; - - parent::tearDown(); + $this->setMwGlobals( array( + 'wgShowEXIF' => true, + 'wgEnableAutoRotation' => true, + ) ); } /** - * * @dataProvider provideFiles */ - function testMetadata( $name, $type, $info ) { + public function testMetadata( $name, $type, $info ) { if ( !BitmapHandler::canRotate() ) { $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); } @@ -59,7 +51,7 @@ class ExifRotationTest extends MediaWikiTestCase { * * @dataProvider provideFiles */ - function testRotationRendering( $name, $type, $info, $thumbs ) { + public function testRotationRendering( $name, $type, $info, $thumbs ) { if ( !BitmapHandler::canRotate() ) { $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); } @@ -138,24 +130,20 @@ class ExifRotationTest extends MediaWikiTestCase { * Same as before, but with auto-rotation disabled. * @dataProvider provideFilesNoAutoRotate */ - function testMetadataNoAutoRotate( $name, $type, $info ) { - global $wgEnableAutoRotation; - $wgEnableAutoRotation = false; + public function testMetadataNoAutoRotate( $name, $type, $info ) { + $this->setMwGlobals( 'wgEnableAutoRotation', false ); $file = $this->dataFile( $name, $type ); $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); - - $wgEnableAutoRotation = true; } /** * * @dataProvider provideFilesNoAutoRotate */ - function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) { - global $wgEnableAutoRotation; - $wgEnableAutoRotation = false; + public function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) { + $this->setMwGlobals( 'wgEnableAutoRotation', false ); foreach ( $thumbs as $size => $out ) { if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) { @@ -187,7 +175,6 @@ class ExifRotationTest extends MediaWikiTestCase { $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" ); } } - $wgEnableAutoRotation = true; } public static function provideFilesNoAutoRotate() { @@ -230,7 +217,7 @@ class ExifRotationTest extends MediaWikiTestCase { /** * @dataProvider provideBitmapExtractPreRotationDimensions */ - function testBitmapExtractPreRotationDimensions( $rotation, $expected ) { + public function testBitmapExtractPreRotationDimensions( $rotation, $expected ) { $result = $this->handler->extractPreRotationDimensions( array( 'physicalWidth' => self::TEST_WIDTH, 'physicalHeight' => self::TEST_HEIGHT, @@ -238,7 +225,7 @@ class ExifRotationTest extends MediaWikiTestCase { $this->assertEquals( $expected, $result ); } - function provideBitmapExtractPreRotationDimensions() { + public static function provideBitmapExtractPreRotationDimensions() { return array( array( 0, diff --git a/tests/phpunit/includes/media/ExifTest.php b/tests/phpunit/includes/media/ExifTest.php index e7e95f7e..dea36b03 100644 --- a/tests/phpunit/includes/media/ExifTest.php +++ b/tests/phpunit/includes/media/ExifTest.php @@ -1,14 +1,18 @@ <?php class ExifTest extends MediaWikiTestCase { + /** @var string */ + protected $mediaPath; + protected function setUp() { parent::setUp(); + if ( !extension_loaded( 'exif' ) ) { + $this->markTestSkipped( "This test needs the exif extension." ); + } $this->mediaPath = __DIR__ . '/../../data/media/'; - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } + $this->setMwGlobals( 'wgShowEXIF', true ); } @@ -39,6 +43,4 @@ class ExifTest extends MediaWikiTestCase { ); $this->assertEquals( $expected, $data ); } - - } diff --git a/tests/phpunit/includes/media/FakeDimensionFile.php b/tests/phpunit/includes/media/FakeDimensionFile.php new file mode 100644 index 00000000..7926000b --- /dev/null +++ b/tests/phpunit/includes/media/FakeDimensionFile.php @@ -0,0 +1,28 @@ +<?php + +class FakeDimensionFile extends File { + public $mustRender = false; + + public function __construct( $dimensions ) { + parent::__construct( Title::makeTitle( NS_FILE, 'Test' ), + new NullRepo( null ) ); + + $this->dimensions = $dimensions; + } + + public function getWidth( $page = 1 ) { + return $this->dimensions[0]; + } + + public function getHeight( $page = 1 ) { + return $this->dimensions[1]; + } + + public function mustRender() { + return $this->mustRender; + } + + public function getPath() { + return ''; + } +}
\ No newline at end of file diff --git a/tests/phpunit/includes/media/FormatMetadataTest.php b/tests/phpunit/includes/media/FormatMetadataTest.php index f26d27ee..a073e4ca 100644 --- a/tests/phpunit/includes/media/FormatMetadataTest.php +++ b/tests/phpunit/includes/media/FormatMetadataTest.php @@ -1,10 +1,19 @@ <?php + +/** + * @todo covers tags + */ class FormatMetadataTest extends MediaWikiTestCase { + /** @var FSFileBackend */ + protected $backend; + /** @var FSRepo */ + protected $repo; + protected function setUp() { parent::setUp(); - if ( !wfDl( 'exif' ) ) { + if ( !extension_loaded( 'exif' ) ) { $this->markTestSkipped( "This test needs the exif extension." ); } $filePath = __DIR__ . '/../../data/media'; diff --git a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php b/tests/phpunit/includes/media/GIFMetadataExtractorTest.php index 86cf3465..9e3f9244 100644 --- a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php +++ b/tests/phpunit/includes/media/GIFMetadataExtractorTest.php @@ -12,6 +12,7 @@ class GIFMetadataExtractorTest extends MediaWikiTestCase { * @param $filename String * @param $expected Array The extracted metadata. * @dataProvider provideGetMetadata + * @covers GIFMetadataExtractor::getMetadata */ public function testGetMetadata( $filename, $expected ) { $actual = GIFMetadataExtractor::getMetadata( $this->mediaPath . $filename ); diff --git a/tests/phpunit/includes/media/GIFTest.php b/tests/phpunit/includes/media/GIFTest.php index 7ea6b7ef..c8e729c8 100644 --- a/tests/phpunit/includes/media/GIFTest.php +++ b/tests/phpunit/includes/media/GIFTest.php @@ -1,6 +1,15 @@ <?php class GIFHandlerTest extends MediaWikiTestCase { + /** @var FSFileBackend */ + protected $backend; + /** @var GIFHandler */ + protected $handler; + /** @var FSRepo */ + protected $repo; + /** @var string */ + protected $filePath; + protected function setUp() { parent::setUp(); @@ -18,6 +27,9 @@ class GIFHandlerTest extends MediaWikiTestCase { $this->handler = new GIFHandler(); } + /** + * @covers GIFHandler::getMetadata + */ public function testInvalidFile() { $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); $this->assertEquals( GIFHandler::BROKEN_FILE, $res ); @@ -27,6 +39,7 @@ class GIFHandlerTest extends MediaWikiTestCase { * @param $filename String basename of the file to check * @param $expected boolean Expected result. * @dataProvider provideIsAnimated + * @covers GIFHandler::isAnimatedImage */ public function testIsAnimanted( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/gif' ); @@ -45,6 +58,7 @@ class GIFHandlerTest extends MediaWikiTestCase { * @param $filename String * @param $expected Integer Total image area * @dataProvider provideGetImageArea + * @covers GIFHandler::getImageArea */ public function testGetImageArea( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/gif' ); @@ -63,6 +77,7 @@ class GIFHandlerTest extends MediaWikiTestCase { * @param $metadata String Serialized metadata * @param $expected Integer One of the class constants of GIFHandler * @dataProvider provideIsMetadataValid + * @covers GIFHandler::isMetadataValid */ public function testIsMetadataValid( $metadata, $expected ) { $actual = $this->handler->isMetadataValid( null, $metadata ); @@ -83,6 +98,7 @@ class GIFHandlerTest extends MediaWikiTestCase { * @param $filename String * @param $expected String Serialized array * @dataProvider provideGetMetadata + * @covers GIFHandler::getMetadata */ public function testGetMetadata( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/gif' ); diff --git a/tests/phpunit/includes/media/IPTCTest.php b/tests/phpunit/includes/media/IPTCTest.php index c9648a79..81c1d287 100644 --- a/tests/phpunit/includes/media/IPTCTest.php +++ b/tests/phpunit/includes/media/IPTCTest.php @@ -1,11 +1,19 @@ <?php + class IPTCTest extends MediaWikiTestCase { + + /** + * @covers IPTC::getCharset + */ public function testRecognizeUtf8() { // utf-8 is the only one used in practise. $res = IPTC::getCharset( "\x1b%G" ); $this->assertEquals( 'UTF-8', $res ); } + /** + * @covers IPTC::Parse + */ public function testIPTCParseNoCharset88591() { // basically IPTC for keyword with value of 0xBC which is 1/4 in iso-8859-1 // This data doesn't specify a charset. We're supposed to guess @@ -15,17 +23,22 @@ class IPTCTest extends MediaWikiTestCase { $this->assertEquals( array( '¼' ), $res['Keywords'] ); } - /* This one contains a sequence that's valid iso 8859-1 but not valid utf8 */ - /* \xC3 = Ã, \xB8 = ¸ */ + /** + * @covers IPTC::Parse + */ public function testIPTCParseNoCharset88591b() { + /* This one contains a sequence that's valid iso 8859-1 but not valid utf8 */ + /* \xC3 = Ã, \xB8 = ¸ */ $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x09\x1c\x02\x19\x00\x04\xC3\xC3\xC3\xB8"; $res = IPTC::Parse( $iptcData ); $this->assertEquals( array( 'ÃÃø' ), $res['Keywords'] ); } - /* Same as testIPTCParseNoCharset88591b, but forcing the charset to utf-8. + /** + * Same as testIPTCParseNoCharset88591b, but forcing the charset to utf-8. * What should happen is the first "\xC3\xC3" should be dropped as invalid, * leaving \xC3\xB8, which is ø + * @covers IPTC::Parse */ public function testIPTCParseForcedUTFButInvalid() { $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x11\x1c\x02\x19\x00\x04\xC3\xC3\xC3\xB8" @@ -34,13 +47,19 @@ class IPTCTest extends MediaWikiTestCase { $this->assertEquals( array( 'ø' ), $res['Keywords'] ); } + /** + * @covers IPTC::Parse + */ public function testIPTCParseNoCharsetUTF8() { $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x07\x1c\x02\x19\x00\x02¼"; $res = IPTC::Parse( $iptcData ); $this->assertEquals( array( '¼' ), $res['Keywords'] ); } - // Testing something that has 2 values for keyword + /** + * Testing something that has 2 values for keyword + * @covers IPTC::Parse + */ public function testIPTCParseMulti() { $iptcData = /* identifier */ "Photoshop 3.0\08BIM\4\4" /* length */ . "\0\0\0\0\0\x0D" @@ -50,11 +69,13 @@ class IPTCTest extends MediaWikiTestCase { $this->assertEquals( array( '¼', '¼½' ), $res['Keywords'] ); } + /** + * @covers IPTC::Parse + */ public function testIPTCParseUTF8() { // This has the magic "\x1c\x01\x5A\x00\x03\x1B\x25\x47" which marks content as UTF8. $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x0F\x1c\x02\x19\x00\x02¼\x1c\x01\x5A\x00\x03\x1B\x25\x47"; $res = IPTC::Parse( $iptcData ); $this->assertEquals( array( '¼' ), $res['Keywords'] ); } - } diff --git a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php b/tests/phpunit/includes/media/JpegMetadataExtractorTest.php index cae7137b..eafc8a2e 100644 --- a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php +++ b/tests/phpunit/includes/media/JpegMetadataExtractorTest.php @@ -5,9 +5,12 @@ * serve as a very good "test". (Adobe photoshop probably creates such files * but it costs money). The implementation of it currently in MediaWiki is based * solely on reading the standard, without any real world test files. + * @todo covers tags */ class JpegMetadataExtractorTest extends MediaWikiTestCase { + protected $filePath; + protected function setUp() { parent::setUp(); @@ -18,7 +21,7 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase { * We also use this test to test padding bytes don't * screw stuff up * - * @param $file filename + * @param string $file filename * * @dataProvider provideUtf8Comment */ diff --git a/tests/phpunit/includes/media/JpegTest.php b/tests/phpunit/includes/media/JpegTest.php index 05d3661e..9af4f1e1 100644 --- a/tests/phpunit/includes/media/JpegTest.php +++ b/tests/phpunit/includes/media/JpegTest.php @@ -1,14 +1,18 @@ <?php +/** + * @todo covers tags + */ class JpegTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); - - $this->filePath = __DIR__ . '/../../data/media/'; - if ( !wfDl( 'exif' ) ) { + if ( !extension_loaded( 'exif' ) ) { $this->markTestSkipped( "This test needs the exif extension." ); } + $this->filePath = __DIR__ . '/../../data/media/'; + + $this->setMwGlobals( 'wgShowEXIF', true ); } diff --git a/tests/phpunit/includes/media/MediaHandlerTest.php b/tests/phpunit/includes/media/MediaHandlerTest.php index 4e4c649f..c28898bb 100644 --- a/tests/phpunit/includes/media/MediaHandlerTest.php +++ b/tests/phpunit/includes/media/MediaHandlerTest.php @@ -1,7 +1,12 @@ <?php class MediaHandlerTest extends MediaWikiTestCase { - function testFitBoxWidth() { + + /** + * @covers MediaHandler::fitBoxWidth + * @todo split into a dataprovider and test method + */ + public function testFitBoxWidth() { $vals = array( array( 'width' => 50, diff --git a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php b/tests/phpunit/includes/media/PNGMetadataExtractorTest.php index 1e912017..939f2cfc 100644 --- a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php +++ b/tests/phpunit/includes/media/PNGMetadataExtractorTest.php @@ -1,4 +1,8 @@ <?php + +/** + * @todo covers tags + */ class PNGMetadataExtractorTest extends MediaWikiTestCase { protected function setUp() { @@ -9,7 +13,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { /** * Tests zTXt tag (compressed textual metadata) */ - function testPngNativetZtxt() { + public function testPngNativetZtxt() { $this->checkPHPExtension( 'zlib' ); $meta = PNGMetadataExtractor::getMetadata( $this->filePath . @@ -26,7 +30,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { /** * Test tEXt tag (Uncompressed textual metadata) */ - function testPngNativeText() { + public function testPngNativeText() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); $expected = "Some long image desc"; @@ -43,7 +47,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { * tEXt tags must be encoded iso-8859-1 (vs iTXt which are utf-8) * Make sure non-ascii characters get converted properly */ - function testPngNativeTextNonAscii() { + public function testPngNativeTextNonAscii() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); @@ -52,7 +56,6 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { // encoded as just \xA9. $expected = "© 2010 Bawolff"; - $this->assertArrayHasKey( 'text', $meta ); $meta = $meta['text']; $this->assertArrayHasKey( 'Copyright', $meta ); @@ -66,7 +69,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { * actual resolution of the image is (aka in dots per meter). */ /* - function testPngPhysTag () { + public function testPngPhysTag() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); @@ -82,7 +85,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { /** * Given a normal static PNG, check the animation metadata returned. */ - function testStaticPngAnimationMetadata() { + public function testStaticPngAnimationMetadata() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); @@ -95,7 +98,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { * Given an animated APNG image file * check it gets animated metadata right. */ - function testApngAnimationMetadata() { + public function testApngAnimationMetadata() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Animated_PNG_example_bouncing_beach_ball.png' ); @@ -105,49 +108,48 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase { $this->assertEquals( 1.5, $meta['duration'], '', 0.00001 ); } - function testPngBitDepth8() { + public function testPngBitDepth8() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); $this->assertEquals( 8, $meta['bitDepth'] ); } - function testPngBitDepth1() { + public function testPngBitDepth1() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . '1bit-png.png' ); $this->assertEquals( 1, $meta['bitDepth'] ); } - function testPngIndexColour() { + public function testPngIndexColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'Png-native-test.png' ); $this->assertEquals( 'index-coloured', $meta['colorType'] ); } - function testPngRgbColour() { + public function testPngRgbColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'rgb-png.png' ); $this->assertEquals( 'truecolour-alpha', $meta['colorType'] ); } - function testPngRgbNoAlphaColour() { + public function testPngRgbNoAlphaColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'rgb-na-png.png' ); $this->assertEquals( 'truecolour', $meta['colorType'] ); } - function testPngGreyscaleColour() { + public function testPngGreyscaleColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'greyscale-png.png' ); $this->assertEquals( 'greyscale-alpha', $meta['colorType'] ); } - function testPngGreyscaleNoAlphaColour() { + public function testPngGreyscaleNoAlphaColour() { $meta = PNGMetadataExtractor::getMetadata( $this->filePath . 'greyscale-na-png.png' ); $this->assertEquals( 'greyscale', $meta['colorType'] ); } - } diff --git a/tests/phpunit/includes/media/PNGTest.php b/tests/phpunit/includes/media/PNGTest.php index 855780da..ad4c2493 100644 --- a/tests/phpunit/includes/media/PNGTest.php +++ b/tests/phpunit/includes/media/PNGTest.php @@ -1,6 +1,15 @@ <?php class PNGHandlerTest extends MediaWikiTestCase { + /** @var PNGHandler */ + protected $handler; + /** @var FSRepo */ + protected $repo; + /** @var FSFileBackend */ + protected $backend; + /** @var string */ + protected $filePath; + protected function setUp() { parent::setUp(); @@ -18,6 +27,9 @@ class PNGHandlerTest extends MediaWikiTestCase { $this->handler = new PNGHandler(); } + /** + * @covers PNGHandler::getMetadata + */ public function testInvalidFile() { $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); $this->assertEquals( PNGHandler::BROKEN_FILE, $res ); @@ -27,6 +39,7 @@ class PNGHandlerTest extends MediaWikiTestCase { * @param $filename String basename of the file to check * @param $expected boolean Expected result. * @dataProvider provideIsAnimated + * @covers PNGHandler::isAnimatedImage */ public function testIsAnimanted( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/png' ); @@ -45,6 +58,7 @@ class PNGHandlerTest extends MediaWikiTestCase { * @param $filename String * @param $expected Integer Total image area * @dataProvider provideGetImageArea + * @covers PNGHandler::getImageArea */ public function testGetImageArea( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/png' ); @@ -65,6 +79,7 @@ class PNGHandlerTest extends MediaWikiTestCase { * @param $metadata String Serialized metadata * @param $expected Integer One of the class constants of PNGHandler * @dataProvider provideIsMetadataValid + * @covers PNGHandler::isMetadataValid */ public function testIsMetadataValid( $metadata, $expected ) { $actual = $this->handler->isMetadataValid( null, $metadata ); @@ -85,6 +100,7 @@ class PNGHandlerTest extends MediaWikiTestCase { * @param $filename String * @param $expected String Serialized array * @dataProvider provideGetMetadata + * @covers PNGHandler::getMetadata */ public function testGetMetadata( $filename, $expected ) { $file = $this->dataFile( $filename, 'image/png' ); diff --git a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php index 97a0000d..257009b0 100644 --- a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php +++ b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php @@ -1,5 +1,8 @@ <?php +/** + * @todo covers tags + */ class SVGMetadataExtractorTest extends MediaWikiTestCase { protected function setUp() { @@ -10,17 +13,18 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase { /** * @dataProvider provideSvgFiles */ - function testGetMetadata( $infile, $expected ) { + public function testGetMetadata( $infile, $expected ) { $this->assertMetadata( $infile, $expected ); } /** * @dataProvider provideSvgFilesWithXMLMetadata */ - function testGetXMLMetadata( $infile, $expected ) { + public function testGetXMLMetadata( $infile, $expected ) { $r = new XMLReader(); if ( !method_exists( $r, 'readInnerXML' ) ) { $this->markTestSkipped( 'XMLReader::readInnerXML() does not exist (libxml >2.6.20 needed).' ); + return; } $this->assertMetadata( $infile, $expected ); @@ -41,6 +45,7 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase { public static function provideSvgFiles() { $base = __DIR__ . '/../../data/media'; + return array( array( "$base/Wikimedia-logo.svg", diff --git a/tests/phpunit/includes/media/TiffTest.php b/tests/phpunit/includes/media/TiffTest.php index 91c35c4b..8d74b98d 100644 --- a/tests/phpunit/includes/media/TiffTest.php +++ b/tests/phpunit/includes/media/TiffTest.php @@ -1,8 +1,16 @@ <?php class TiffTest extends MediaWikiTestCase { + /** @var TiffHandler */ + protected $handler; + /** @var string */ + protected $filePath; + protected function setUp() { parent::setUp(); + if ( !extension_loaded( 'exif' ) ) { + $this->markTestSkipped( "This test needs the exif extension." ); + } $this->setMwGlobals( 'wgShowEXIF', true ); @@ -10,18 +18,18 @@ class TiffTest extends MediaWikiTestCase { $this->handler = new TiffHandler; } + /** + * @covers TiffHandler::getMetadata + */ public function testInvalidFile() { - if ( !wfDl( 'exif' ) ) { - $this->markTestIncomplete( "This test needs the exif extension." ); - } $res = $this->handler->getMetadata( null, $this->filePath . 'README' ); $this->assertEquals( ExifBitmapHandler::BROKEN_FILE, $res ); } + /** + * @covers TiffHandler::getMetadata + */ public function testTiffMetadataExtraction() { - if ( !wfDl( 'exif' ) ) { - $this->markTestIncomplete( "This test needs the exif extension." ); - } $res = $this->handler->getMetadata( null, $this->filePath . 'test.tiff' ); $expected = 'a:16:{s:10:"ImageWidth";i:20;s:11:"ImageLength";i:20;s:13:"BitsPerSample";a:3:{i:0;i:8;i:1;i:8;i:2;i:8;}s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:16:"ImageDescription";s:17:"Created with GIMP";s:12:"StripOffsets";i:8;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:3;s:12:"RowsPerStrip";i:64;s:15:"StripByteCounts";i:238;s:11:"XResolution";s:19:"1207959552/16777216";s:11:"YResolution";s:19:"1207959552/16777216";s:19:"PlanarConfiguration";i:1;s:14:"ResolutionUnit";i:2;s:22:"MEDIAWIKI_EXIF_VERSION";i:2;}'; // Re-unserialize in case there are subtle differences between how versions diff --git a/tests/phpunit/includes/media/XMPTest.php b/tests/phpunit/includes/media/XMPTest.php index 86c722b1..d12e9b00 100644 --- a/tests/phpunit/includes/media/XMPTest.php +++ b/tests/phpunit/includes/media/XMPTest.php @@ -1,9 +1,13 @@ <?php + +/** + * @todo covers tags + */ class XMPTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); - if ( !wfDl( 'xml' ) ) { + if ( !extension_loaded( 'xml' ) ) { $this->markTestSkipped( 'Requires libxml to do XMP parsing' ); } } @@ -15,6 +19,7 @@ class XMPTest extends MediaWikiTestCase { * @param $expected Array expected result of parsing the xmp. * @param $info String Short sentence on what's being tested. * + * @throws Exception * @dataProvider provideXMPParse */ public function testXMPParse( $xmp, $expected, $info ) { @@ -62,9 +67,10 @@ class XMPTest extends MediaWikiTestCase { // result array, but it seems kind of big to put directly in the test // file. $result = null; - include( $xmpPath . $file[0] . '.result.php' ); + include $xmpPath . $file[0] . '.result.php'; $data[] = array( $xmp, $result, '[' . $file[0] . '.xmp] ' . $file[1] ); } + return $data; } @@ -74,7 +80,7 @@ class XMPTest extends MediaWikiTestCase { * @todo This is based on what the standard says. Need to find a real * world example file to double check the support for this is right. */ - function testExtendedXMP() { + public function testExtendedXMP() { $xmpPath = __DIR__ . '/../../data/xmp/'; $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); @@ -104,7 +110,7 @@ class XMPTest extends MediaWikiTestCase { * This test has an extended XMP block with a wrong guid (md5sum) * and thus should only return the StandardXMP, not the ExtendedXMP. */ - function testExtendedXMPWithWrongGUID() { + public function testExtendedXMPWithWrongGUID() { $xmpPath = __DIR__ . '/../../data/xmp/'; $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); @@ -133,7 +139,7 @@ class XMPTest extends MediaWikiTestCase { * Have a high offset to simulate a missing packet, * which should cause it to ignore the ExtendedXMP packet. */ - function testExtendedXMPMissingPacket() { + public function testExtendedXMPMissingPacket() { $xmpPath = __DIR__ . '/../../data/xmp/'; $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); @@ -157,5 +163,4 @@ class XMPTest extends MediaWikiTestCase { $this->assertEquals( $expected, $actual ); } - } diff --git a/tests/phpunit/includes/media/XMPValidateTest.php b/tests/phpunit/includes/media/XMPValidateTest.php index a2b4e1c2..96bf5e47 100644 --- a/tests/phpunit/includes/media/XMPValidateTest.php +++ b/tests/phpunit/includes/media/XMPValidateTest.php @@ -3,8 +3,9 @@ class XMPValidateTest extends MediaWikiTestCase { /** * @dataProvider provideDates + * @covers XMPValidate::validateDate */ - function testValidateDate( $value, $expected ) { + public function testValidateDate( $value, $expected ) { // The method should modify $value. XMPValidate::validateDate( array(), $value, true ); $this->assertEquals( $expected, $value ); @@ -41,7 +42,5 @@ class XMPValidateTest extends MediaWikiTestCase { array( '2001-05-12T15', null ), array( '2001-12T15:13', null ), ); - } - } diff --git a/tests/phpunit/includes/normal/CleanUpTest.php b/tests/phpunit/includes/normal/CleanUpTest.php index 99ec05dd..52dd2ef5 100644 --- a/tests/phpunit/includes/normal/CleanUpTest.php +++ b/tests/phpunit/includes/normal/CleanUpTest.php @@ -30,16 +30,20 @@ * * @ingroup UtfNormal * @group Large + * + * We ignore code coverage for this test suite until they are rewritten + * to use data providers (bug 46561). + * @codeCoverageIgnore */ class CleanUpTest extends MediaWikiTestCase { /** @todo document */ - function testAscii() { + public function testAscii() { $text = 'This is plain ASCII text.'; $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); } /** @todo document */ - function testNull() { + public function testNull() { $text = "a \x00 null"; $expect = "a \xef\xbf\xbd null"; $this->assertEquals( @@ -48,13 +52,13 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testLatin() { + public function testLatin() { $text = "L'\xc3\xa9cole"; $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); } /** @todo document */ - function testLatinNormal() { + public function testLatinNormal() { $text = "L'e\xcc\x81cole"; $expect = "L'\xc3\xa9cole"; $this->assertEquals( $expect, UtfNormal::cleanUp( $text ) ); @@ -101,7 +105,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testAllBytes() { + public function testAllBytes() { $this->doTestBytes( '', '' ); $this->doTestBytes( 'x', '' ); $this->doTestBytes( '', 'x' ); @@ -141,7 +145,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testDoubleBytes() { + public function testDoubleBytes() { $this->doTestDoubleBytes( '', '' ); $this->doTestDoubleBytes( 'x', '' ); $this->doTestDoubleBytes( '', 'x' ); @@ -194,7 +198,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testTripleBytes() { + public function testTripleBytes() { $this->doTestTripleBytes( '', '' ); $this->doTestTripleBytes( 'x', '' ); $this->doTestTripleBytes( '', 'x' ); @@ -272,7 +276,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testChunkRegression() { + public function testChunkRegression() { # Check for regression against a chunking bug $text = "\x46\x55\xb8" . "\xdc\x96" . @@ -295,7 +299,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testInterposeRegression() { + public function testInterposeRegression() { $text = "\x4e\x30" . "\xb1" . # bad tail "\x3a" . @@ -330,7 +334,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testOverlongRegression() { + public function testOverlongRegression() { $text = "\x67" . "\x1a" . # forbidden ascii "\xea" . # bad head @@ -355,7 +359,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testSurrogateRegression() { + public function testSurrogateRegression() { $text = "\xed\xb4\x96" . # surrogate 0xDD16 "\x83" . # bad tail "\xb4" . # bad tail @@ -370,7 +374,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testBomRegression() { + public function testBomRegression() { $text = "\xef\xbf\xbe" . # U+FFFE, illegal char "\xb2" . # bad tail "\xef" . # bad head @@ -385,7 +389,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testForbiddenRegression() { + public function testForbiddenRegression() { $text = "\xef\xbf\xbf"; # U+FFFF, illegal char $expect = "\xef\xbf\xbd"; $this->assertEquals( @@ -394,7 +398,7 @@ class CleanUpTest extends MediaWikiTestCase { } /** @todo document */ - function testHangulRegression() { + public function testHangulRegression() { $text = "\xed\x9c\xaf" . # Hangul char "\xe1\x87\x81"; # followed by another final jamo $expect = $text; # Should *not* change. diff --git a/tests/phpunit/includes/objectcache/BagOStuffTest.php b/tests/phpunit/includes/objectcache/BagOStuffTest.php index 88b07f0a..aa783943 100644 --- a/tests/phpunit/includes/objectcache/BagOStuffTest.php +++ b/tests/phpunit/includes/objectcache/BagOStuffTest.php @@ -15,7 +15,6 @@ class BagOStuffTest extends MediaWikiTestCase { $name = $this->getCliArg( 'use-bagostuff=' ); $this->cache = ObjectCache::newFromId( $name ); - } else { // no type defined - use simple hash $this->cache = new HashBagOStuff; @@ -119,6 +118,18 @@ class BagOStuffTest extends MediaWikiTestCase { $this->assertEquals( $this->cache->get( $key ), $value ); } + /** + * @covers BagOStuff::incr + */ + public function testIncr() { + $key = wfMemcKey( 'test' ); + $this->cache->add( $key, 0 ); + $this->cache->incr( $key ); + $expectedValue = 1; + $actualValue = $this->cache->get( $key ); + $this->assertEquals( $expectedValue, $actualValue, 'Value should be 1 after incrementing' ); + } + public function testGetMulti() { $value1 = array( 'this' => 'is', 'a' => 'test' ); $value2 = array( 'this' => 'is', 'another' => 'test' ); diff --git a/tests/phpunit/includes/parser/MagicVariableTest.php b/tests/phpunit/includes/parser/MagicVariableTest.php index dfcdafde..c2c97c01 100644 --- a/tests/phpunit/includes/parser/MagicVariableTest.php +++ b/tests/phpunit/includes/parser/MagicVariableTest.php @@ -9,11 +9,13 @@ * @author Antoine Musso * @copyright Copyright © 2011, Antoine Musso * @file + * @todo covers tags */ -/** */ class MagicVariableTest extends MediaWikiTestCase { - /** Will contains a parser object*/ + /** + * @var Parser + */ private $testParser = null; /** @@ -51,11 +53,31 @@ class MagicVariableTest extends MediaWikiTestCase { $this->testParser->setTitle( $title ); } - /** destroy parser (TODO: is it really neded?)*/ - protected function tearDown() { - unset( $this->testParser ); + /** + * @param int $num upper limit for numbers + * @return array of numbers from 1 up to $num + */ + private static function createProviderUpTo( $num ) { + $ret = array(); + for ( $i = 1; $i <= $num; $i++ ) { + $ret[] = array( $i ); + } + + return $ret; + } + + /** + * @return array of months numbers (as an integer) + */ + public static function provideMonths() { + return self::createProviderUpTo( 12 ); + } - parent::tearDown(); + /** + * @return array of days numbers (as an integer) + */ + public static function provideDays() { + return self::createProviderUpTo( 31 ); } ############### TESTS ############################################# @@ -65,100 +87,101 @@ class MagicVariableTest extends MediaWikiTestCase { # day - /** @dataProvider MediaWikiProvide::Days */ - function testCurrentdayIsUnPadded( $day ) { + /** @dataProvider provideDays */ + public function testCurrentdayIsUnPadded( $day ) { $this->assertUnPadded( 'currentday', $day ); } - /** @dataProvider MediaWikiProvide::Days */ - function testCurrentdaytwoIsZeroPadded( $day ) { + /** @dataProvider provideDays */ + public function testCurrentdaytwoIsZeroPadded( $day ) { $this->assertZeroPadded( 'currentday2', $day ); } - /** @dataProvider MediaWikiProvide::Days */ - function testLocaldayIsUnPadded( $day ) { + /** @dataProvider provideDays */ + public function testLocaldayIsUnPadded( $day ) { $this->assertUnPadded( 'localday', $day ); } - /** @dataProvider MediaWikiProvide::Days */ - function testLocaldaytwoIsZeroPadded( $day ) { + /** @dataProvider provideDays */ + public function testLocaldaytwoIsZeroPadded( $day ) { $this->assertZeroPadded( 'localday2', $day ); } # month - /** @dataProvider MediaWikiProvide::Months */ - function testCurrentmonthIsZeroPadded( $month ) { + /** @dataProvider provideMonths */ + public function testCurrentmonthIsZeroPadded( $month ) { $this->assertZeroPadded( 'currentmonth', $month ); } - /** @dataProvider MediaWikiProvide::Months */ - function testCurrentmonthoneIsUnPadded( $month ) { + /** @dataProvider provideMonths */ + public function testCurrentmonthoneIsUnPadded( $month ) { $this->assertUnPadded( 'currentmonth1', $month ); } - /** @dataProvider MediaWikiProvide::Months */ - function testLocalmonthIsZeroPadded( $month ) { + /** @dataProvider provideMonths */ + public function testLocalmonthIsZeroPadded( $month ) { $this->assertZeroPadded( 'localmonth', $month ); } - /** @dataProvider MediaWikiProvide::Months */ - function testLocalmonthoneIsUnPadded( $month ) { + /** @dataProvider provideMonths */ + public function testLocalmonthoneIsUnPadded( $month ) { $this->assertUnPadded( 'localmonth1', $month ); } - # revision day - /** @dataProvider MediaWikiProvide::Days */ - function testRevisiondayIsUnPadded( $day ) { + /** @dataProvider provideDays */ + public function testRevisiondayIsUnPadded( $day ) { $this->assertUnPadded( 'revisionday', $day ); } - /** @dataProvider MediaWikiProvide::Days */ - function testRevisiondaytwoIsZeroPadded( $day ) { + /** @dataProvider provideDays */ + public function testRevisiondaytwoIsZeroPadded( $day ) { $this->assertZeroPadded( 'revisionday2', $day ); } # revision month - /** @dataProvider MediaWikiProvide::Months */ - function testRevisionmonthIsZeroPadded( $month ) { + /** @dataProvider provideMonths */ + public function testRevisionmonthIsZeroPadded( $month ) { $this->assertZeroPadded( 'revisionmonth', $month ); } - /** @dataProvider MediaWikiProvide::Months */ - function testRevisionmonthoneIsUnPadded( $month ) { + /** @dataProvider provideMonths */ + public function testRevisionmonthoneIsUnPadded( $month ) { $this->assertUnPadded( 'revisionmonth1', $month ); } /** * Rough tests for {{SERVERNAME}} magic word * Bug 31176 + * @group Database + * @dataProvider provideDataServernameFromDifferentProtocols */ - function testServernameFromDifferentProtocols() { - global $wgServer; - $saved_wgServer = $wgServer; + public function testServernameFromDifferentProtocols( $server ) { + $this->setMwGlobals( 'wgServer', $server ); - $wgServer = 'http://localhost/'; - $this->assertMagic( 'localhost', 'servername' ); - $wgServer = 'https://localhost/'; - $this->assertMagic( 'localhost', 'servername' ); - $wgServer = '//localhost/'; # bug 31176 $this->assertMagic( 'localhost', 'servername' ); + } - $wgServer = $saved_wgServer; + public static function provideDataServernameFromDifferentProtocols() { + return array( + array( 'http://localhost/' ), + array( 'https://localhost/' ), + array( '//localhost/' ), # bug 31176 + ); } ############### HELPERS ############################################ /** assertion helper expecting a magic output which is zero padded */ - PUBLIC function assertZeroPadded( $magic, $value ) { + public function assertZeroPadded( $magic, $value ) { $this->assertMagicPadding( $magic, $value, '%02d' ); } /** assertion helper expecting a magic output which is unpadded */ - PUBLIC function assertUnPadded( $magic, $value ) { + public function assertUnPadded( $magic, $value ) { $this->assertMagicPadding( $magic, $value, '%d' ); } diff --git a/tests/phpunit/includes/parser/MediaWikiParserTest.php b/tests/phpunit/includes/parser/MediaWikiParserTest.php index 067a7c4e..c120ca34 100644 --- a/tests/phpunit/includes/parser/MediaWikiParserTest.php +++ b/tests/phpunit/includes/parser/MediaWikiParserTest.php @@ -1,5 +1,5 @@ <?php -require_once( __DIR__ . '/NewParserTest.php' ); +require_once __DIR__ . '/NewParserTest.php'; /** * The UnitTest must be either a class that inherits from MediaWikiTestCase @@ -11,24 +11,110 @@ require_once( __DIR__ . '/NewParserTest.php' ); */ class MediaWikiParserTest { - public static function suite() { - global $wgParserTestFiles; + /** + * @defgroup filtering_constants Filtering constants + * + * Limit inclusion of parser tests files coming from MediaWiki core + * @{ + */ - $suite = new PHPUnit_Framework_TestSuite; + /** Include files shipped with MediaWiki core */ + const CORE_ONLY = 1; + /** Include non core files as set in $wgParserTestFiles */ + const NO_CORE = 2; + /** Include anything set via $wgParserTestFiles */ + const WITH_ALL = 3; # CORE_ONLY | NO_CORE + + /** @} */ + + /** + * Get a PHPUnit test suite of parser tests. Optionally filtered with + * $flags. + * + * @par Examples: + * Get a suite of parser tests shipped by MediaWiki core: + * @code + * MediaWikiParserTest::suite( MediaWikiParserTest::CORE_ONLY ); + * @endcode + * Get a suite of various parser tests, like extensions: + * @code + * MediaWikiParserTest::suite( MediaWikiParserTest::NO_CORE ); + * @endcode + * Get any test defined via $wgParserTestFiles: + * @code + * MediaWikiParserTest::suite( MediaWikiParserTest::WITH_ALL ); + * @endcode + * + * @param $flags bitwise flag to filter out the $wgParserTestFiles that + * will be included. Default: MediaWikiParserTest::CORE_ONLY + * + * @return PHPUnit_Framework_TestSuite + */ + public static function suite( $flags = self::CORE_ONLY ) { + if ( is_string( $flags ) ) { + $flags = self::CORE_ONLY; + } + global $wgParserTestFiles, $IP; + + $mwTestDir = $IP . '/tests/'; + + # Human friendly helpers + $wantsCore = ( $flags & self::CORE_ONLY ); + $wantsRest = ( $flags & self::NO_CORE ); + + # Will hold the .txt parser test files we will include + $filesToTest = array(); + + # Filter out .txt files + foreach ( $wgParserTestFiles as $parserTestFile ) { + $isCore = ( 0 === strpos( $parserTestFile, $mwTestDir ) ); + + if ( $isCore && $wantsCore ) { + self::debug( "included core parser tests: $parserTestFile" ); + $filesToTest[] = $parserTestFile; + } elseif ( !$isCore && $wantsRest ) { + self::debug( "included non core parser tests: $parserTestFile" ); + $filesToTest[] = $parserTestFile; + } else { + self::debug( "skipped parser tests: $parserTestFile" ); + } + } + self::debug( 'parser tests files: ' + . implode( ' ', $filesToTest ) ); - foreach ( $wgParserTestFiles as $filename ) { - $testsName = basename( $filename, '.txt' ); + $suite = new PHPUnit_Framework_TestSuite; + foreach ( $filesToTest as $fileName ) { + $testsName = basename( $fileName, '.txt' ); + $escapedFileName = strtr( $fileName, array( "'" => "\\'", '\\' => '\\\\' ) ); /* This used to be ucfirst( basename( dirname( $filename ) ) ) * and then was ucfirst( basename( $filename, '.txt' ) * but that didn't work with names like foo.tests.txt */ - $className = str_replace( '.', '_', ucfirst( $testsName ) ); - - eval( "/** @group Database\n@group Parser\n*/ class $className extends NewParserTest { protected \$file = '" . strtr( $filename, array( "'" => "\\'", '\\' => '\\\\' ) ) . "'; } " ); + $parserTestClassName = str_replace( '.', '_', ucfirst( $testsName ) ); + $parserTestClassDefinition = <<<EOT +/** + * @group Database + * @group Parser + * @group ParserTests + * @group ParserTests_$parserTestClassName + */ +class $parserTestClassName extends NewParserTest { + protected \$file = '$escapedFileName'; +} +EOT; - $parserTester = new $className( $testsName ); - $suite->addTestSuite( new ReflectionClass ( $parserTester ) ); + eval( $parserTestClassDefinition ); + self::debug( "Adding test class $parserTestClassName" ); + $suite->addTestSuite( $parserTestClassName ); } return $suite; } + + /** + * Write $msg under log group 'tests-parser' + * @param string $msg Message to log + */ + protected static function debug( $msg ) { + return wfDebugLog( 'tests-parser', wfGetCaller() . ' ' . $msg ); + } } diff --git a/tests/phpunit/includes/parser/NewParserTest.php b/tests/phpunit/includes/parser/NewParserTest.php index bf6931a1..eac4de5c 100644 --- a/tests/phpunit/includes/parser/NewParserTest.php +++ b/tests/phpunit/includes/parser/NewParserTest.php @@ -6,6 +6,8 @@ * @group Database * @group Parser * @group Stub + * + * @todo covers tags */ class NewParserTest extends MediaWikiTestCase { static protected $articles = array(); // Array of test articles defined by the tests @@ -19,7 +21,6 @@ class NewParserTest extends MediaWikiTestCase { public $runParsoid = false; public $regex = ''; public $showProgress = true; - public $savedInitialGlobals = array(); public $savedWeirdGlobals = array(); public $savedGlobals = array(); public $hooks = array(); @@ -32,8 +33,13 @@ class NewParserTest extends MediaWikiTestCase { protected $file = false; + public static function setUpBeforeClass() { + // Inject ParserTest well-known interwikis + ParserTest::setupInterwikis(); + } + protected function setUp() { - global $wgNamespaceProtection, $wgNamespaceAliases; + global $wgNamespaceAliases, $wgContLang; global $wgHooks, $IP; parent::setUp(); @@ -52,11 +58,16 @@ class NewParserTest extends MediaWikiTestCase { $tmpGlobals['wgLanguageCode'] = 'en'; $tmpGlobals['wgContLang'] = Language::factory( 'en' ); + $tmpGlobals['wgSitename'] = 'MediaWiki'; + $tmpGlobals['wgServer'] = 'http://example.org'; $tmpGlobals['wgScript'] = '/index.php'; $tmpGlobals['wgScriptPath'] = '/'; $tmpGlobals['wgArticlePath'] = '/wiki/$1'; - $tmpGlobals['wgStyleSheetPath'] = '/skins'; + $tmpGlobals['wgActionPaths'] = array(); + $tmpGlobals['wgVariantArticlePath'] = false; + $tmpGlobals['wgExtensionAssetsPath'] = '/extensions'; $tmpGlobals['wgStylePath'] = '/skins'; + $tmpGlobals['wgEnableUploads'] = true; $tmpGlobals['wgThumbnailScriptPath'] = false; $tmpGlobals['wgLocalFileRepo'] = array( 'class' => 'LocalRepo', @@ -67,51 +78,81 @@ class NewParserTest extends MediaWikiTestCase { 'backend' => 'local-backend' ); $tmpGlobals['wgForeignFileRepos'] = array(); + $tmpGlobals['wgDefaultExternalStore'] = array(); $tmpGlobals['wgEnableParserCache'] = false; - $tmpGlobals['wgHooks'] = $wgHooks; + $tmpGlobals['wgCapitalLinks'] = true; + $tmpGlobals['wgNoFollowLinks'] = true; + $tmpGlobals['wgNoFollowDomainExceptions'] = array(); + $tmpGlobals['wgExternalLinkTarget'] = false; + $tmpGlobals['wgThumbnailScriptPath'] = false; + $tmpGlobals['wgUseImageResize'] = true; + $tmpGlobals['wgAllowExternalImages'] = true; + $tmpGlobals['wgRawHtml'] = false; + $tmpGlobals['wgUseTidy'] = false; + $tmpGlobals['wgAlwaysUseTidy'] = false; + $tmpGlobals['wgWellFormedXml'] = true; + $tmpGlobals['wgAllowMicrodataAttributes'] = true; + $tmpGlobals['wgExperimentalHtmlIds'] = false; + $tmpGlobals['wgAdaptiveMessageCache'] = true; + $tmpGlobals['wgUseDatabaseMessages'] = true; + $tmpGlobals['wgLocaltimezone'] = 'UTC'; $tmpGlobals['wgDeferredUpdateList'] = array(); - $tmpGlobals['wgMemc'] = wfGetMainCache(); - $tmpGlobals['messageMemc'] = wfGetMessageCacheStorage(); - $tmpGlobals['parserMemc'] = wfGetParserCacheStorage(); + $tmpGlobals['wgGroupPermissions'] = array( + '*' => array( + 'createaccount' => true, + 'read' => true, + 'edit' => true, + 'createpage' => true, + 'createtalk' => true, + ) ); + $tmpGlobals['wgNamespaceProtection'] = array( NS_MEDIAWIKI => 'editinterface' ); - // $tmpGlobals['wgContLang'] = new StubContLang; - $tmpGlobals['wgUser'] = new User; - $context = new RequestContext(); - $tmpGlobals['wgLang'] = $context->getLanguage(); - $tmpGlobals['wgOut'] = $context->getOutput(); - $tmpGlobals['wgParser'] = new StubObject( 'wgParser', $GLOBALS['wgParserConf']['class'], array( $GLOBALS['wgParserConf'] ) ); - $tmpGlobals['wgRequest'] = $context->getRequest(); + $tmpGlobals['wgParser'] = new StubObject( + 'wgParser', $GLOBALS['wgParserConf']['class'], + array( $GLOBALS['wgParserConf'] ) ); + + $tmpGlobals['wgFileExtensions'][] = 'svg'; + $tmpGlobals['wgSVGConverter'] = 'rsvg'; + $tmpGlobals['wgSVGConverters']['rsvg'] = + '$path/rsvg-convert -w $width -h $height $input -o $output'; if ( $GLOBALS['wgStyleDirectory'] === false ) { $tmpGlobals['wgStyleDirectory'] = "$IP/skins"; } + # Replace all media handlers with a mock. We do not need to generate + # actual thumbnails to do parser testing, we only care about receiving + # a ThumbnailImage properly initialized. + global $wgMediaHandlers; + foreach ( $wgMediaHandlers as $type => $handler ) { + $tmpGlobals['wgMediaHandlers'][$type] = 'MockBitmapHandler'; + } + // Vector images have to be handled slightly differently + $tmpGlobals['wgMediaHandlers']['image/svg+xml'] = 'MockSvgHandler'; - foreach ( $tmpGlobals as $var => $val ) { - if ( array_key_exists( $var, $GLOBALS ) ) { - $this->savedInitialGlobals[$var] = $GLOBALS[$var]; - } + $tmpHooks = $wgHooks; + $tmpHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; + $tmpHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; + $tmpGlobals['wgHooks'] = $tmpHooks; + # add a namespace shadowing a interwiki link, to test + # proper precedence when resolving links. (bug 51680) + $tmpGlobals['wgExtraNamespaces'] = array( 100 => 'MemoryAlpha' ); - $GLOBALS[$var] = $val; - } + $this->setMwGlobals( $tmpGlobals ); - $this->savedWeirdGlobals['mw_namespace_protection'] = $wgNamespaceProtection[NS_MEDIAWIKI]; $this->savedWeirdGlobals['image_alias'] = $wgNamespaceAliases['Image']; $this->savedWeirdGlobals['image_talk_alias'] = $wgNamespaceAliases['Image_talk']; - $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; + + MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache + $wgContLang->resetNamespaces(); # reset namespace cache } protected function tearDown() { - foreach ( $this->savedInitialGlobals as $var => $val ) { - $GLOBALS[$var] = $val; - } + global $wgNamespaceAliases, $wgContLang; - global $wgNamespaceProtection, $wgNamespaceAliases; - - $wgNamespaceProtection[NS_MEDIAWIKI] = $this->savedWeirdGlobals['mw_namespace_protection']; $wgNamespaceAliases['Image'] = $this->savedWeirdGlobals['image_alias']; $wgNamespaceAliases['Image_talk'] = $this->savedWeirdGlobals['image_talk_alias']; @@ -119,67 +160,34 @@ class NewParserTest extends MediaWikiTestCase { RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); + // Remove temporary pages from the link cache + LinkCache::singleton()->clear(); + + // Restore message cache (temporary pages and $wgUseDatabaseMessages) + MessageCache::destroyInstance(); + parent::tearDown(); + + MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache + $wgContLang->resetNamespaces(); # reset namespace cache + } + + public static function tearDownAfterClass() { + ParserTest::tearDownInterwikis(); + parent::tearDownAfterClass(); } function addDBData() { $this->tablesUsed[] = 'site_stats'; - $this->tablesUsed[] = 'interwiki'; # disabled for performance #$this->tablesUsed[] = 'image'; - # Hack: insert a few Wikipedia in-project interwiki prefixes, - # for testing inter-language links - $this->db->insert( 'interwiki', array( - array( 'iw_prefix' => 'wikipedia', - 'iw_url' => 'http://en.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 0 ), - array( 'iw_prefix' => 'meatball', - 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 0 ), - array( 'iw_prefix' => 'zh', - 'iw_url' => 'http://zh.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'es', - 'iw_url' => 'http://es.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'fr', - 'iw_url' => 'http://fr.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'ru', - 'iw_url' => 'http://ru.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - /** - * @todo Fixme! Why are we inserting duplicate data here? Shouldn't - * need this IGNORE or shouldn't need the insert at all. - */ - ), __METHOD__, array( 'IGNORE' ) - ); - # Update certain things in site_stats $this->db->insert( 'site_stats', array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ), __METHOD__ ); - # Reinitialise the LocalisationCache to match the database state - Language::getLocalisationCache()->unloadAll(); - - # Clear the message cache - MessageCache::singleton()->clear(); - $user = User::newFromId( 0 ); LinkCache::singleton()->clear(); # Avoids the odd failure at creating the nullRevision @@ -187,6 +195,10 @@ class NewParserTest extends MediaWikiTestCase { # We will upload the actual files later. Note that if anything causes LocalFile::load() # to be triggered before then, it will break via maybeUpgrade() setting the fileExists # member to false and storing it in cache. + # note that the size/width/height/bits/etc of the file + # are actually set by inspecting the file itself; the arguments + # to recordUpload2 have no effect. That said, we try to make things + # match up so it is less confusing to readers of the code & tests. $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) ); if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { $image->recordUpload2( @@ -194,19 +206,39 @@ class NewParserTest extends MediaWikiTestCase { 'Upload of some lame file', 'Some lame file', array( - 'size' => 12345, + 'size' => 7881, 'width' => 1941, 'height' => 220, - 'bits' => 24, + 'bits' => 8, 'media_type' => MEDIATYPE_BITMAP, 'mime' => 'image/jpeg', 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), + 'sha1' => wfBaseConvert( '1', 16, 36, 31 ), 'fileExists' => true ), $this->db->timestamp( '20010115123500' ), $user ); } + $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Thumb.png' ) ); + if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { + $image->recordUpload2( + '', // archive name + 'Upload of some lame thumbnail', + 'Some lame thumbnail', + array( + 'size' => 22589, + 'width' => 135, + 'height' => 135, + 'bits' => 8, + 'media_type' => MEDIATYPE_BITMAP, + 'mime' => 'image/png', + 'metadata' => serialize( array() ), + 'sha1' => wfBaseConvert( '2', 16, 36, 31 ), + 'fileExists' => true ), + $this->db->timestamp( '20130225203040' ), $user + ); + } + # This image will be blacklisted in [[MediaWiki:Bad image list]] $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) ); if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { @@ -222,11 +254,25 @@ class NewParserTest extends MediaWikiTestCase { 'media_type' => MEDIATYPE_BITMAP, 'mime' => 'image/jpeg', 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), + 'sha1' => wfBaseConvert( '3', 16, 36, 31 ), 'fileExists' => true ), $this->db->timestamp( '20010115123500' ), $user ); } + $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.svg' ) ); + if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { + $image->recordUpload2( '', 'Upload of some lame SVG', 'Some lame SVG', array( + 'size' => 12345, + 'width' => 200, + 'height' => 200, + 'bits' => 24, + 'media_type' => MEDIATYPE_DRAWING, + 'mime' => 'image/svg+xml', + 'metadata' => serialize( array() ), + 'sha1' => wfBaseConvert( '', 16, 36, 31 ), + 'fileExists' => true + ), $this->db->timestamp( '20010115123500' ), $user ); + } } //ParserTest setup/teardown functions @@ -265,7 +311,10 @@ class NewParserTest extends MediaWikiTestCase { $backend = self::$backendToUse; } } else { - $backend = new FSFileBackend( array( + # Replace with a mock. We do not care about generating real + # files on the filesystem, just need to expose the file + # informations. + $backend = new MockFileBackend( array( 'name' => 'local-backend', 'lockManager' => 'nullLockManager', 'containerPaths' => array( @@ -276,12 +325,6 @@ class NewParserTest extends MediaWikiTestCase { } $settings = array( - 'wgServer' => 'http://example.org', - 'wgScript' => '/index.php', - 'wgScriptPath' => '/', - 'wgArticlePath' => '/wiki/$1', - 'wgExtensionAssetsPath' => '/extensions', - 'wgActionPaths' => array(), 'wgLocalFileRepo' => array( 'class' => 'LocalRepo', 'name' => 'local', @@ -291,47 +334,16 @@ class NewParserTest extends MediaWikiTestCase { 'backend' => $backend ), 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ), - 'wgStylePath' => '/skins', - 'wgStyleSheetPath' => '/skins', - 'wgSitename' => 'MediaWiki', 'wgLanguageCode' => $lang, 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'unittest_' : 'ut_', - 'wgRawHtml' => isset( $opts['rawhtml'] ), - 'wgLang' => null, - 'wgContLang' => null, + 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ), 'wgNamespacesWithSubpages' => array( NS_MAIN => isset( $opts['subpage'] ) ), + 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ), 'wgMaxTocLevel' => $maxtoclevel, - 'wgCapitalLinks' => true, - 'wgNoFollowLinks' => true, - 'wgNoFollowDomainExceptions' => array(), - 'wgThumbnailScriptPath' => false, - 'wgUseImageResize' => true, - 'wgUseTeX' => isset( $opts['math'] ), + 'wgUseTeX' => isset( $opts['math'] ) || isset( $opts['texvc'] ), 'wgMathDirectory' => $uploadDir . '/math', - 'wgLocaltimezone' => 'UTC', - 'wgAllowExternalImages' => true, - 'wgUseTidy' => false, 'wgDefaultLanguageVariant' => $variant, - 'wgVariantArticlePath' => false, - 'wgGroupPermissions' => array( '*' => array( - 'createaccount' => true, - 'read' => true, - 'edit' => true, - 'createpage' => true, - 'createtalk' => true, - ) ), - 'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ), - 'wgDefaultExternalStore' => array(), - 'wgForeignFileRepos' => array(), 'wgLinkHolderBatchSize' => $linkHolderBatchSize, - 'wgExperimentalHtmlIds' => false, - 'wgExternalLinkTarget' => false, - 'wgAlwaysUseTidy' => false, - 'wgHtml5' => true, - 'wgWellFormedXml' => true, - 'wgAllowMicrodataAttributes' => true, - 'wgAdaptiveMessageCache' => true, - 'wgUseDatabaseMessages' => true, ); if ( $config ) { @@ -349,6 +361,15 @@ class NewParserTest extends MediaWikiTestCase { /** @since 1.20 */ wfRunHooks( 'ParserTestGlobals', array( &$settings ) ); + $langObj = Language::factory( $lang ); + $settings['wgContLang'] = $langObj; + $settings['wgLang'] = $langObj; + + $context = new RequestContext(); + $settings['wgOut'] = $context->getOutput(); + $settings['wgUser'] = $context->getUser(); + $settings['wgRequest'] = $context->getRequest(); + foreach ( $settings as $var => $val ) { if ( array_key_exists( $var, $GLOBALS ) ) { $this->savedGlobals[$var] = $GLOBALS[$var]; @@ -357,21 +378,9 @@ class NewParserTest extends MediaWikiTestCase { $GLOBALS[$var] = $val; } - $langObj = Language::factory( $lang ); - $GLOBALS['wgContLang'] = $langObj; - $context = new RequestContext(); - $GLOBALS['wgLang'] = $context->getLanguage(); - - $GLOBALS['wgMemc'] = new EmptyBagOStuff; - $GLOBALS['wgOut'] = $context->getOutput(); - $GLOBALS['wgUser'] = $context->getUser(); - - global $wgHooks; - - $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; - $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; - MagicWord::clearCache(); + + # The entries saved into RepoGroup cache with previous globals will be wrong. RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); @@ -381,9 +390,6 @@ class NewParserTest extends MediaWikiTestCase { # Publish the articles after we have the final language set $this->publishTestArticles(); - # The entries saved into RepoGroup cache with previous globals will be wrong. - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); MessageCache::destroyInstance(); return $context; @@ -408,6 +414,7 @@ class NewParserTest extends MediaWikiTestCase { // wfDebug( "Creating upload directory $dir\n" ); if ( file_exists( $dir ) ) { wfDebug( "Already exists!\n" ); + return $dir; } @@ -429,10 +436,27 @@ class NewParserTest extends MediaWikiTestCase { $backend->store( array( 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/3/3a/Foobar.jpg" ) ); + $backend->prepare( array( 'dir' => "$base/local-public/e/ea" ) ); + $backend->store( array( + 'src' => "$IP/skins/monobook/wiki.png", 'dst' => "$base/local-public/e/ea/Thumb.png" + ) ); $backend->prepare( array( 'dir' => "$base/local-public/0/09" ) ); $backend->store( array( 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/0/09/Bad.jpg" ) ); + + // No helpful SVG file to copy, so make one ourselves + $tmpDir = wfTempDir(); + $tempFsFile = new TempFSFile( "$tmpDir/Foobar.svg" ); + $tempFsFile->autocollect(); // destroy file when $tempFsFile leaves scope + file_put_contents( "$tmpDir/Foobar.svg", + '<?xml version="1.0" encoding="utf-8"?>' . + '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><text>Foo</text></svg>' ); + + $backend->prepare( array( 'dir' => "$base/local-public/f/ff" ) ); + $backend->quickStore( array( + 'src' => "$tmpDir/Foobar.svg", 'dst' => "$base/local-public/f/ff/Foobar.svg" + ) ); } /** @@ -445,9 +469,6 @@ class NewParserTest extends MediaWikiTestCase { foreach ( $this->savedGlobals as $var => $val ) { $GLOBALS[$var] = $val; } - - RepoGroup::destroySingleton(); - LinkCache::singleton()->clear(); } /** @@ -458,6 +479,12 @@ class NewParserTest extends MediaWikiTestCase { return; } + $backend = RepoGroup::singleton()->getLocalRepo()->getBackend(); + if ( $backend instanceof MockFileBackend ) { + # In memory backend, so dont bother cleaning them up. + return; + } + $base = $this->getBaseDir(); // delete the files first, then the dirs. self::deleteFiles( @@ -478,8 +505,17 @@ class NewParserTest extends MediaWikiTestCase { "$base/local-thumb/3/3a/Foobar.jpg/70px-Foobar.jpg", "$base/local-thumb/3/3a/Foobar.jpg/960px-Foobar.jpg", + "$base/local-public/e/ea/Thumb.png", + "$base/local-public/0/09/Bad.jpg", - "$base/local-thumb/0/09/Bad.jpg", + + "$base/local-public/f/ff/Foobar.svg", + "$base/local-thumb/f/ff/Foobar.svg/180px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/270px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/360px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/langde-180px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/langde-270px-Foobar.svg.jpg", + "$base/local-thumb/f/ff/Foobar.svg/langde-360px-Foobar.svg.jpg", "$base/local-public/math/f/a/5/fa50b8b616463173474302ca3e63586b.png", ) @@ -514,6 +550,7 @@ class NewParserTest extends MediaWikiTestCase { global $wgParserTestFiles; $this->file = $wgParserTestFiles[0]; } + return new TestFileIterator( $this->file, $this ); } @@ -537,7 +574,7 @@ class NewParserTest extends MediaWikiTestCase { if ( !$this->isWikitextNS( NS_MAIN ) ) { // parser tests frequently assume that the main namespace contains wikitext. - // @todo: When setting up pages, force the content model. Only skip if + // @todo When setting up pages, force the content model. Only skip if // $wgtContentModelUseDB is false. $this->markTestSkipped( "Main namespace does not support wikitext," . "skipping parser test: $desc" ); @@ -563,6 +600,20 @@ class NewParserTest extends MediaWikiTestCase { $title = Title::newFromText( $titleText ); + # Parser test requiring math. Make sure texvc is executable + # or just skip such tests. + if ( isset( $opts['math'] ) || isset( $opts['texvc'] ) ) { + global $wgTexvc; + + if ( !isset( $wgTexvc ) ) { + $this->markTestSkipped( "SKIPPED: \$wgTexvc is not set" ); + } elseif ( !is_executable( $wgTexvc ) ) { + $this->markTestSkipped( "SKIPPED: texvc binary does not exist" + . " or is not executable.\n" + . "Current configuration is:\n\$wgTexvc = '$wgTexvc'" ); + } + } + if ( isset( $opts['pst'] ) ) { $out = $parser->preSaveTransform( $input, $title, $user, $options ); } elseif ( isset( $opts['msg'] ) ) { @@ -577,9 +628,10 @@ class NewParserTest extends MediaWikiTestCase { } elseif ( isset( $opts['comment'] ) ) { $out = Linker::formatComment( $input, $title, $local ); } elseif ( isset( $opts['preload'] ) ) { - $out = $parser->getpreloadText( $input, $title, $options ); + $out = $parser->getPreloadText( $input, $title, $options ); } else { $output = $parser->parse( $input, $title, $options, true, true, 1337 ); + $output->setTOCEnabled( !isset( $opts['notoc'] ) ); $out = $output->getText(); if ( isset( $opts['showtitle'] ) ) { @@ -621,7 +673,7 @@ class NewParserTest extends MediaWikiTestCase { * * @group ParserFuzz */ - function testFuzzTests() { + public function testFuzzTests() { global $wgParserTestFiles; $files = $wgParserTestFiles; @@ -666,7 +718,9 @@ class NewParserTest extends MediaWikiTestCase { } catch ( Exception $exception ) { $input_dump = sprintf( "string(%d) \"%s\"\n", strlen( $input ), $input ); - $this->assertTrue( false, "Test $id, fuzz seed {$this->fuzzSeed}. \n\nInput: $input_dump\n\nError: {$exception->getMessage()}\n\nBacktrace: {$exception->getTraceAsString()}" ); + $this->assertTrue( false, "Test $id, fuzz seed {$this->fuzzSeed}. \n\n" . + "Input: $input_dump\n\nError: {$exception->getMessage()}\n\n" . + "Backtrace: {$exception->getTraceAsString()}" ); } $this->teardownGlobals(); @@ -688,7 +742,6 @@ class NewParserTest extends MediaWikiTestCase { } $id++; - } } @@ -882,6 +935,7 @@ class NewParserTest extends MediaWikiTestCase { } } } + return $opts; } @@ -893,6 +947,7 @@ class NewParserTest extends MediaWikiTestCase { if ( substr( $opt, 0, 2 ) == '[[' ) { return substr( $opt, 2, -2 ); } + return $opt; } diff --git a/tests/phpunit/includes/parser/ParserMethodsTest.php b/tests/phpunit/includes/parser/ParserMethodsTest.php index 50fe0e4d..e5c5cb21 100644 --- a/tests/phpunit/includes/parser/ParserMethodsTest.php +++ b/tests/phpunit/includes/parser/ParserMethodsTest.php @@ -15,6 +15,7 @@ class ParserMethodsTest extends MediaWikiLangTestCase { /** * @dataProvider providePreSaveTransform + * @covers Parser::preSaveTransform */ public function testPreSaveTransform( $text, $expected ) { global $wgParser; @@ -28,6 +29,9 @@ class ParserMethodsTest extends MediaWikiLangTestCase { $this->assertEquals( $expected, $text ); } + /** + * @covers Parser::callParserFunction + */ public function testCallParserFunction() { global $wgParser; @@ -45,5 +49,47 @@ class ParserMethodsTest extends MediaWikiLangTestCase { ), $ret, 'callParserFunction works for {{#tag:pre|foo|style=margin-left: 1.6em}}' ); } - // TODO: Add tests for cleanSig() / cleanSigInSig(), getSection(), replaceSection(), getPreloadText() + /** + * @covers Parser::parse + * @covers ParserOutput::getSections + */ + public function testGetSections() { + global $wgParser; + + $title = Title::newFromText( str_replace( '::', '__', __METHOD__ ) ); + $out = $wgParser->parse( "==foo==\n<h2>bar</h2>\n==baz==\n", $title, new ParserOptions() ); + $this->assertSame( array( + array( + 'toclevel' => 1, + 'level' => '2', + 'line' => 'foo', + 'number' => '1', + 'index' => '1', + 'fromtitle' => $title->getPrefixedDBkey(), + 'byteoffset' => 0, + 'anchor' => 'foo', + ), + array( + 'toclevel' => 1, + 'level' => '2', + 'line' => 'bar', + 'number' => '2', + 'index' => '', + 'fromtitle' => false, + 'byteoffset' => null, + 'anchor' => 'bar', + ), + array( + 'toclevel' => 1, + 'level' => '2', + 'line' => 'baz', + 'number' => '3', + 'index' => '2', + 'fromtitle' => $title->getPrefixedDBkey(), + 'byteoffset' => 21, + 'anchor' => 'baz', + ), + ), $out->getSections(), 'getSections() with proper value when <h2> is used' ); + } + //@Todo Add tests for cleanSig() / cleanSigInSig(), getSection(), replaceSection(), getPreloadText() } diff --git a/tests/phpunit/includes/parser/ParserOutputTest.php b/tests/phpunit/includes/parser/ParserOutputTest.php index 68f77ab5..c73666da 100644 --- a/tests/phpunit/includes/parser/ParserOutputTest.php +++ b/tests/phpunit/includes/parser/ParserOutputTest.php @@ -2,7 +2,7 @@ class ParserOutputTest extends MediaWikiTestCase { - function dataIsLinkInternal() { + public static function provideIsLinkInternal() { return array( // Different domains array( false, 'http://example.org', 'http://mediawiki.org' ), @@ -29,13 +29,17 @@ class ParserOutputTest extends MediaWikiTestCase { /** * Test to make sure ParserOutput::isLinkInternal behaves properly - * @dataProvider dataIsLinkInternal + * @dataProvider provideIsLinkInternal + * @covers ParserOutput::isLinkInternal */ - function testIsLinkInternal( $shouldMatch, $server, $url ) { - + public function testIsLinkInternal( $shouldMatch, $server, $url ) { $this->assertEquals( $shouldMatch, ParserOutput::isLinkInternal( $server, $url ) ); } + /** + * @covers ParserOutput::setExtensionData + * @covers ParserOutput::getExtensionData + */ public function testExtensionData() { $po = new ParserOutput(); diff --git a/tests/phpunit/includes/parser/ParserPreloadTest.php b/tests/phpunit/includes/parser/ParserPreloadTest.php index e16b407e..d12fee36 100644 --- a/tests/phpunit/includes/parser/ParserPreloadTest.php +++ b/tests/phpunit/includes/parser/ParserPreloadTest.php @@ -4,8 +4,17 @@ * @author Antoine Musso */ class ParserPreloadTest extends MediaWikiTestCase { + /** + * @var Parser + */ private $testParser; + /** + * @var ParserOptions + */ private $testParserOptions; + /** + * @var Title + */ private $title; protected function setUp() { @@ -31,14 +40,14 @@ class ParserPreloadTest extends MediaWikiTestCase { /** * @covers Parser::getPreloadText */ - function testPreloadSimpleText() { + public function testPreloadSimpleText() { $this->assertPreloaded( 'simple', 'simple' ); } /** * @covers Parser::getPreloadText */ - function testPreloadedPreIsUnstripped() { + public function testPreloadedPreIsUnstripped() { $this->assertPreloaded( '<pre>monospaced</pre>', '<pre>monospaced</pre>', @@ -49,7 +58,7 @@ class ParserPreloadTest extends MediaWikiTestCase { /** * @covers Parser::getPreloadText */ - function testPreloadedNowikiIsUnstripped() { + public function testPreloadedNowikiIsUnstripped() { $this->assertPreloaded( '<nowiki>[[Dummy title]]</nowiki>', '<nowiki>[[Dummy title]]</nowiki>', @@ -57,7 +66,7 @@ class ParserPreloadTest extends MediaWikiTestCase { ); } - function assertPreloaded( $expected, $text, $msg = '' ) { + protected function assertPreloaded( $expected, $text, $msg = '' ) { $this->assertEquals( $expected, $this->testParser->getPreloadText( @@ -68,5 +77,4 @@ class ParserPreloadTest extends MediaWikiTestCase { $msg ); } - } diff --git a/tests/phpunit/includes/parser/PreprocessorTest.php b/tests/phpunit/includes/parser/PreprocessorTest.php index c51a1dc5..8aee937c 100644 --- a/tests/phpunit/includes/parser/PreprocessorTest.php +++ b/tests/phpunit/includes/parser/PreprocessorTest.php @@ -1,9 +1,16 @@ <?php class PreprocessorTest extends MediaWikiTestCase { - var $mTitle = 'Page title'; - var $mPPNodeCount = 0; - var $mOptions; + protected $mTitle = 'Page title'; + protected $mPPNodeCount = 0; + /** + * @var ParserOptions + */ + protected $mOptions; + /** + * @var Preprocessor + */ + protected $mPreprocessor; protected function setUp() { global $wgParserConf, $wgContLang; @@ -18,7 +25,7 @@ class PreprocessorTest extends MediaWikiTestCase { return array( 'gallery', 'display map' /* Used by Maps, see r80025 CR */, '/foo' ); } - function provideCases() { + public static function provideCases() { return array( array( "Foo", "<root>Foo</root>" ), array( "<!-- Foo -->", "<root><comment><!-- Foo --></comment></root>" ), @@ -115,7 +122,7 @@ class PreprocessorTest extends MediaWikiTestCase { * @param string $wikiText * @return string */ - function preprocessToXml( $wikiText ) { + protected function preprocessToXml( $wikiText ) { if ( method_exists( $this->mPreprocessor, 'preprocessToXml' ) ) { return $this->normalizeXml( $this->mPreprocessor->preprocessToXml( $wikiText ) ); } @@ -134,21 +141,22 @@ class PreprocessorTest extends MediaWikiTestCase { * @param string $xml * @return string */ - function normalizeXml( $xml ) { + protected function normalizeXml( $xml ) { return preg_replace( '!<([a-z]+)/>!', '<$1></$1>', str_replace( ' />', '/>', $xml ) ); } /** * @dataProvider provideCases + * @covers Preprocessor_DOM::preprocessToXml */ - function testPreprocessorOutput( $wikiText, $expectedXml ) { + public function testPreprocessorOutput( $wikiText, $expectedXml ) { $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) ); } /** * These are more complex test cases taken out of wiki articles. */ - function provideFiles() { + public static function provideFiles() { return array( array( "QuoteQuran" ), # http://en.wikipedia.org/w/index.php?title=Template:QuoteQuran/sandbox&oldid=237348988 GFDL + CC-BY-SA by Striver array( "Factorial" ), # http://en.wikipedia.org/w/index.php?title=Template:Factorial&oldid=98548758 GFDL + CC-BY-SA by Polonium @@ -160,8 +168,9 @@ class PreprocessorTest extends MediaWikiTestCase { /** * @dataProvider provideFiles + * @covers Preprocessor_DOM::preprocessToXml */ - function testPreprocessorOutputFiles( $filename ) { + public function testPreprocessorOutputFiles( $filename ) { $folder = __DIR__ . "/../../../parser/preprocess"; $wikiText = file_get_contents( "$folder/$filename.txt" ); $output = $this->preprocessToXml( $wikiText ); @@ -180,7 +189,7 @@ class PreprocessorTest extends MediaWikiTestCase { /** * Tests from Bug 28642 · https://bugzilla.wikimedia.org/28642 */ - function provideHeadings() { + public static function provideHeadings() { return array( /* These should become headings: */ array( "== h ==<!--c1-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment></h></root>" ), array( "== h == <!--c1-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment></h></root>" ), @@ -209,11 +218,11 @@ class PreprocessorTest extends MediaWikiTestCase { array( "== h == <!--c1--> <!--c2--><!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment><comment><!--c3--></comment> </h></root>" ), array( "== h == <!--c1--><!--c2--> <!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment><comment><!--c2--></comment> <comment><!--c3--></comment> </h></root>" ), array( "== h == <!--c1--> <!--c2--> <!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment> <comment><!--c3--></comment> </h></root>" ), + array( "== h ==<!--c1--> <!--c2-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment></h></root>" ), + array( "== h == <!--c1--> <!--c2-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment></h></root>" ), + array( "== h ==<!--c1--> <!--c2--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment> </h></root>" ), /* These are not working: */ - array( "== h ==<!--c1--> <!--c2-->", "<root>== h ==<comment><!--c1--></comment> <comment><!--c2--></comment></root>" ), - array( "== h == <!--c1--> <!--c2-->", "<root>== h == <comment><!--c1--></comment> <comment><!--c2--></comment></root>" ), - array( "== h ==<!--c1--> <!--c2--> ", "<root>== h ==<comment><!--c1--></comment> <comment><!--c2--></comment> </root>" ), array( "== h == x <!--c1--><!--c2--><!--c3--> ", "<root>== h == x <comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment> </root>" ), array( "== h ==<!--c1--> x <!--c2--><!--c3--> ", "<root>== h ==<comment><!--c1--></comment> x <comment><!--c2--></comment><comment><!--c3--></comment> </root>" ), array( "== h ==<!--c1--><!--c2--><!--c3--> x ", "<root>== h ==<comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment> x </root>" ), @@ -222,8 +231,9 @@ class PreprocessorTest extends MediaWikiTestCase { /** * @dataProvider provideHeadings + * @covers Preprocessor_DOM::preprocessToXml */ - function testHeadings( $wikiText, $expectedXml ) { + public function testHeadings( $wikiText, $expectedXml ) { $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) ); } } diff --git a/tests/phpunit/includes/parser/TagHooksTest.php b/tests/phpunit/includes/parser/TagHooksTest.php index ed600790..61cbe45d 100644 --- a/tests/phpunit/includes/parser/TagHooksTest.php +++ b/tests/phpunit/includes/parser/TagHooksTest.php @@ -21,7 +21,7 @@ class TagHookTest extends MediaWikiTestCase { /** * @dataProvider provideValidNames */ - function testTagHooks( $tag ) { + public function testTagHooks( $tag ) { global $wgParserConf, $wgContLang; $parser = new Parser( $wgParserConf ); @@ -36,7 +36,7 @@ class TagHookTest extends MediaWikiTestCase { * @dataProvider provideBadNames * @expectedException MWException */ - function testBadTagHooks( $tag ) { + public function testBadTagHooks( $tag ) { global $wgParserConf, $wgContLang; $parser = new Parser( $wgParserConf ); @@ -48,7 +48,7 @@ class TagHookTest extends MediaWikiTestCase { /** * @dataProvider provideValidNames */ - function testFunctionTagHooks( $tag ) { + public function testFunctionTagHooks( $tag ) { global $wgParserConf, $wgContLang; $parser = new Parser( $wgParserConf ); @@ -63,7 +63,7 @@ class TagHookTest extends MediaWikiTestCase { * @dataProvider provideBadNames * @expectedException MWException */ - function testBadFunctionTagHooks( $tag ) { + public function testBadFunctionTagHooks( $tag ) { global $wgParserConf, $wgContLang; $parser = new Parser( $wgParserConf ); diff --git a/tests/phpunit/includes/parser/TidyTest.php b/tests/phpunit/includes/parser/TidyTest.php new file mode 100644 index 00000000..57a88b9d --- /dev/null +++ b/tests/phpunit/includes/parser/TidyTest.php @@ -0,0 +1,44 @@ +<?php + +/** + * @group Parser + */ +class TidyTest extends MediaWikiTestCase { + public function setUp() { + parent::setUp(); + $check = MWTidy::tidy( '' ); + if ( strpos( $check, '<!--' ) !== false ) { + $this->markTestSkipped( 'Tidy not found' ); + } + } + + /** + * @dataProvider provideTestWrapping + */ + public function testTidyWrapping( $expected, $text, $msg = '' ) { + $text = MWTidy::tidy( $text ); + // We don't care about where Tidy wants to stick is <p>s + $text = trim( preg_replace( '#</?p>#', '', $text ) ); + // Windows, we love you! + $text = str_replace( "\r", '', $text ); + $this->assertEquals( $expected, $text, $msg ); + } + + public function provideTestWrapping() { + return array( + array( + '<mw:editsection page="foo" section="bar">foo</mw:editsection>', + '<mw:editsection page="foo" section="bar">foo</mw:editsection>', + '<mw:editsection> should survive tidy' + ), + array( + '<editsection page="foo" section="bar">foo</editsection>', + '<editsection page="foo" section="bar">foo</editsection>', + '<editsection> should survive tidy' + ), + array( '<mw:toc>foo</mw:toc>', '<mw:toc>foo</mw:toc>', '<mw:toc> should survive tidy' ), + array( "<link foo=\"bar\" />\nfoo", '<link foo="bar"/>foo', '<link> should survive tidy' ), + array( "<meta foo=\"bar\" />\nfoo", '<meta foo="bar"/>foo', '<meta> should survive tidy' ), + ); + } +}
\ No newline at end of file diff --git a/tests/phpunit/includes/search/SearchEngineTest.php b/tests/phpunit/includes/search/SearchEngineTest.php index 6abca6d4..87067038 100644 --- a/tests/phpunit/includes/search/SearchEngineTest.php +++ b/tests/phpunit/includes/search/SearchEngineTest.php @@ -45,7 +45,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { } if ( !$this->isWikitextNS( NS_MAIN ) ) { - //@todo: cover the case of non-wikitext content in the main namespace + // @todo cover the case of non-wikitext content in the main namespace return; } @@ -87,6 +87,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { # sort them numerically so we will compare simply that we received # the expected matches. sort( $matches ); + return $matches; } @@ -114,7 +115,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { return true; } - function testFullWidth() { + public function testFullWidth() { $this->assertEquals( array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), $this->fetchIds( $this->search->searchText( 'AZ' ) ), @@ -133,14 +134,14 @@ class SearchEngineTest extends MediaWikiLangTestCase { "Search for normalized from Full-width Lower" ); } - function testTextSearch() { + public function testTextSearch() { $this->assertEquals( array( 'Smithee' ), $this->fetchIds( $this->search->searchText( 'smithee' ) ), "Plain search failed" ); } - function testTextPowerSearch() { + public function testTextPowerSearch() { $this->search->setNamespaces( array( 0, 1, 4 ) ); $this->assertEquals( array( @@ -151,7 +152,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { "Power search failed" ); } - function testTitleSearch() { + public function testTitleSearch() { $this->assertEquals( array( 'Alan Smithee', @@ -161,7 +162,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { "Title search failed" ); } - function testTextTitlePowerSearch() { + public function testTextTitlePowerSearch() { $this->search->setNamespaces( array( 0, 1, 4 ) ); $this->assertEquals( array( @@ -172,5 +173,4 @@ class SearchEngineTest extends MediaWikiLangTestCase { $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), "Title power search failed" ); } - } diff --git a/tests/phpunit/includes/search/SearchUpdateTest.php b/tests/phpunit/includes/search/SearchUpdateTest.php index 7d867bc4..2f4fd501 100644 --- a/tests/phpunit/includes/search/SearchUpdateTest.php +++ b/tests/phpunit/includes/search/SearchUpdateTest.php @@ -17,6 +17,7 @@ class MockSearch extends SearchEngine { /** * @group Search + * @group Database */ class SearchUpdateTest extends MediaWikiTestCase { @@ -25,19 +26,11 @@ class SearchUpdateTest extends MediaWikiTestCase { $this->setMwGlobals( 'wgSearchType', 'MockSearch' ); } - function update( $text, $title = 'Test', $id = 1 ) { - $u = new SearchUpdate( $id, $title, $text ); - $u->doUpdate(); - return array( MockSearch::$title, MockSearch::$text ); - } - function updateText( $text ) { - list( , $resultText ) = $this->update( $text ); - $resultText = trim( $resultText ); // abstract from some implementation details - return $resultText; + return trim( SearchUpdate::updateText( $text ) ); } - function testUpdateText() { + public function testUpdateText() { $this->assertEquals( 'test', $this->updateText( '<div>TeSt</div>' ), @@ -69,7 +62,7 @@ EOT ); } - function testBug32712() { + public function testBug32712() { $text = "text „http://example.com“ text"; $result = $this->updateText( $text ); $processed = preg_replace( '/Q/u', 'Q', $result ); diff --git a/tests/phpunit/includes/site/MediaWikiSiteTest.php b/tests/phpunit/includes/site/MediaWikiSiteTest.php index 0cecdeea..c5d52d33 100644 --- a/tests/phpunit/includes/site/MediaWikiSiteTest.php +++ b/tests/phpunit/includes/site/MediaWikiSiteTest.php @@ -54,6 +54,7 @@ class MediaWikiSiteTest extends SiteTest { /** * @dataProvider fileUrlProvider + * @covers MediaWikiSite::getFileUrl */ public function testGetFileUrl( $url, $filePath, $pathArgument, $expected ) { $site = new MediaWikiSite(); @@ -62,7 +63,7 @@ class MediaWikiSiteTest extends SiteTest { $this->assertEquals( $expected, $site->getFileUrl( $pathArgument ) ); } - public function provideGetPageUrl() { + public static function provideGetPageUrl() { return array( // path, page, expected substring array( 'http://acme.test/wiki/$1', 'Berlin', '/wiki/Berlin' ), @@ -77,6 +78,7 @@ class MediaWikiSiteTest extends SiteTest { /** * @dataProvider provideGetPageUrl + * @covers MediaWikiSite::getPageUrl */ public function testGetPageUrl( $path, $page, $expected ) { $site = new MediaWikiSite(); @@ -85,5 +87,4 @@ class MediaWikiSiteTest extends SiteTest { $this->assertContains( $path, $site->getPageUrl() ); $this->assertContains( $expected, $site->getPageUrl( $page ) ); } - } diff --git a/tests/phpunit/includes/site/SiteListTest.php b/tests/phpunit/includes/site/SiteListTest.php index c3298397..8af2fc1b 100644 --- a/tests/phpunit/includes/site/SiteListTest.php +++ b/tests/phpunit/includes/site/SiteListTest.php @@ -68,6 +68,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::isEmpty */ public function testIsEmpty( SiteList $sites ) { $this->assertEquals( count( $sites ) === 0, $sites->isEmpty() ); @@ -76,6 +77,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::getSite */ public function testGetSiteByGlobalId( SiteList $sites ) { if ( $sites->isEmpty() ) { @@ -93,6 +95,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::getSiteByInternalId */ public function testGetSiteByInternalId( $sites ) { /** @@ -110,6 +113,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::hasSite */ public function testHasGlobalId( $sites ) { $this->assertFalse( $sites->hasSite( 'non-existing-global-id' ) ); @@ -128,6 +132,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::hasInternalId */ public function testHasInternallId( $sites ) { /** @@ -145,6 +150,7 @@ class SiteListTest extends MediaWikiTestCase { /** * @dataProvider siteListProvider * @param SiteList $sites + * @covers SiteList::getGlobalIdentifiers */ public function testGetGlobalIdentifiers( SiteList $sites ) { $identifiers = $sites->getGlobalIdentifiers(); @@ -169,6 +175,8 @@ class SiteListTest extends MediaWikiTestCase { * @since 1.21 * * @param SiteList $list + * @covers SiteList::getSerializationData + * @covers SiteList::unserialize */ public function testSerialization( SiteList $list ) { $serialization = serialize( $list ); @@ -186,5 +194,4 @@ class SiteListTest extends MediaWikiTestCase { $this->assertTrue( $copy->hasInternalId( $site->getInternalId() ) ); } } - } diff --git a/tests/phpunit/includes/site/SiteSQLStoreTest.php b/tests/phpunit/includes/site/SiteSQLStoreTest.php index cf4ce945..6002c1a1 100644 --- a/tests/phpunit/includes/site/SiteSQLStoreTest.php +++ b/tests/phpunit/includes/site/SiteSQLStoreTest.php @@ -32,6 +32,9 @@ */ class SiteSQLStoreTest extends MediaWikiTestCase { + /** + * @covers SiteSQLStore::getSites + */ public function testGetSites() { $expectedSites = TestSites::getSites(); TestSites::insertIntoDb(); @@ -56,6 +59,9 @@ class SiteSQLStoreTest extends MediaWikiTestCase { } } + /** + * @covers SiteSQLStore::saveSites + */ public function testSaveSites() { $store = SiteSQLStore::newInstance(); @@ -86,6 +92,9 @@ class SiteSQLStoreTest extends MediaWikiTestCase { $this->assertTrue( $site->getInternalId() >= 0 ); } + /** + * @covers SiteSQLStore::reset + */ public function testReset() { $store1 = SiteSQLStore::newInstance(); $store2 = SiteSQLStore::newInstance(); @@ -109,6 +118,9 @@ class SiteSQLStoreTest extends MediaWikiTestCase { $this->assertNull( $site ); } + /** + * @covers SiteSQLStore::clear + */ public function testClear() { $store = SiteSQLStore::newInstance(); $this->assertTrue( $store->clear() ); @@ -119,5 +131,4 @@ class SiteSQLStoreTest extends MediaWikiTestCase { $sites = $store->getSites(); $this->assertEquals( 0, $sites->count() ); } - } diff --git a/tests/phpunit/includes/site/SiteTest.php b/tests/phpunit/includes/site/SiteTest.php index d20e2a52..29c1ff33 100644 --- a/tests/phpunit/includes/site/SiteTest.php +++ b/tests/phpunit/includes/site/SiteTest.php @@ -38,6 +38,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getInterwikiIds */ public function testGetInterwikiIds( Site $site ) { $this->assertInternalType( 'array', $site->getInterwikiIds() ); @@ -46,6 +47,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getNavigationIds */ public function testGetNavigationIds( Site $site ) { $this->assertInternalType( 'array', $site->getNavigationIds() ); @@ -54,6 +56,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::addNavigationId */ public function testAddNavigationId( Site $site ) { $site->addNavigationId( 'foobar' ); @@ -63,6 +66,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::addInterwikiId */ public function testAddInterwikiId( Site $site ) { $site->addInterwikiId( 'foobar' ); @@ -72,6 +76,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getLanguageCode */ public function testGetLanguageCode( Site $site ) { $this->assertTypeOrValue( 'string', $site->getLanguageCode(), null ); @@ -80,6 +85,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::setLanguageCode */ public function testSetLanguageCode( Site $site ) { $site->setLanguageCode( 'en' ); @@ -89,6 +95,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::normalizePageName */ public function testNormalizePageName( Site $site ) { $this->assertInternalType( 'string', $site->normalizePageName( 'Foobar' ) ); @@ -97,6 +104,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getGlobalId */ public function testGetGlobalId( Site $site ) { $this->assertTypeOrValue( 'string', $site->getGlobalId(), null ); @@ -105,6 +113,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::setGlobalId */ public function testSetGlobalId( Site $site ) { $site->setGlobalId( 'foobar' ); @@ -114,6 +123,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getType */ public function testGetType( Site $site ) { $this->assertInternalType( 'string', $site->getType() ); @@ -122,6 +132,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getPath */ public function testGetPath( Site $site ) { $this->assertTypeOrValue( 'string', $site->getPath( 'page_path' ), null ); @@ -132,6 +143,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::getAllPaths */ public function testGetAllPaths( Site $site ) { $this->assertInternalType( 'array', $site->getAllPaths() ); @@ -140,6 +152,8 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::setPath + * @covers Site::removePath */ public function testSetAndRemovePath( Site $site ) { $count = count( $site->getAllPaths() ); @@ -162,6 +176,9 @@ class SiteTest extends MediaWikiTestCase { $this->assertNull( $site->getPath( 'spam' ) ); } + /** + * @covers Site::setLinkPath + */ public function testSetLinkPath() { $site = new Site(); $path = "TestPath/$1"; @@ -170,6 +187,9 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( $path, $site->getLinkPath() ); } + /** + * @covers Site::getLinkPathType + */ public function testGetLinkPathType() { $site = new Site(); @@ -182,6 +202,9 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( $path, $site->getLinkPath() ); } + /** + * @covers Site::setPath + */ public function testSetPath() { $site = new Site(); @@ -191,6 +214,10 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( $path, $site->getPath( 'foo' ) ); } + /** + * @covers Site::setPath + * @covers Site::getProtocol + */ public function testProtocolRelativePath() { $site = new Site(); @@ -201,7 +228,7 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( '', $site->getProtocol() ); } - public function provideGetPageUrl() { + public static function provideGetPageUrl() { //NOTE: the assumption that the URL is built by replacing $1 // with the urlencoded version of $page // is true for Site but not guaranteed for subclasses. @@ -228,6 +255,7 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider provideGetPageUrl + * @covers Site::getPageUrl */ public function testGetPageUrl( $path, $page, $expected ) { $site = new Site(); @@ -252,6 +280,8 @@ class SiteTest extends MediaWikiTestCase { /** * @dataProvider instanceProvider * @param Site $site + * @covers Site::serialize + * @covers Site::unserialize */ public function testSerialization( Site $site ) { $this->assertInstanceOf( 'Serializable', $site ); @@ -263,5 +293,4 @@ class SiteTest extends MediaWikiTestCase { $this->assertEquals( $serialization, serialize( $newInstance ) ); } - } diff --git a/tests/phpunit/includes/site/TestSites.php b/tests/phpunit/includes/site/TestSites.php index a5656a73..f224b7d7 100644 --- a/tests/phpunit/includes/site/TestSites.php +++ b/tests/phpunit/includes/site/TestSites.php @@ -97,5 +97,4 @@ class TestSites { $sitesTable->clear(); $sitesTable->saveSites( TestSites::getSites() ); } - } diff --git a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php b/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php index 3b82e07d..a806b4ac 100644 --- a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php +++ b/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php @@ -51,7 +51,7 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase { * Test SQL for each of our QueryPages objects * @group Database */ - function testQuerypageSqlQuery() { + public function testQuerypageSqlQuery() { global $wgDBtype; foreach ( $this->queryPages as $page ) { diff --git a/tests/phpunit/includes/specials/SpecialPreferencesTest.php b/tests/phpunit/includes/specials/SpecialPreferencesTest.php new file mode 100644 index 00000000..6c637c65 --- /dev/null +++ b/tests/phpunit/includes/specials/SpecialPreferencesTest.php @@ -0,0 +1,60 @@ +<?php +/** + * Test class for SpecialPreferences class. + * + * Copyright © 2013, Antoine Musso + * Copyright © 2013, Wikimedia Foundation Inc. + * + */ + +class SpecialPreferencesTest extends MediaWikiTestCase { + + /** + * Make sure a nickname which is longer than $wgMaxSigChars + * is not throwing a fatal error. + * + * Test specifications by Alexandre "ialex" Emsenhuber. + */ + public function testBug41337() { + + // Set a low limit + $this->setMwGlobals( 'wgMaxSigChars', 2 ); + + $user = $this->getMock( 'User' ); + $user->expects( $this->any() ) + ->method( 'isAnon' ) + ->will( $this->returnValue( false ) ); + + # Yeah foreach requires an array, not NULL =( + $user->expects( $this->any() ) + ->method( 'getEffectiveGroups' ) + ->will( $this->returnValue( array() ) ); + + # The mocked user has a long nickname + $user->expects( $this->any() ) + ->method( 'getOption' ) + ->will( $this->returnValueMap( array( + array( 'nickname', null, false, 'superlongnickname' ), + ) + ) ); + + # Validate the mock (FIXME should probably be removed) + $this->assertFalse( $user->isAnon() ); + $this->assertEquals( array(), + $user->getEffectiveGroups() ); + $this->assertEquals( 'superlongnickname', + $user->getOption( 'nickname' ) ); + + # Forge a request to call the special page + $context = new RequestContext(); + $context->setRequest( new FauxRequest() ); + $context->setUser( $user ); + $context->setTitle( Title::newFromText( 'Test' ) ); + + # Do the call, should not spurt a fatal error. + $special = new SpecialPreferences(); + $special->setContext( $context ); + $special->execute( array() ); + } + +} diff --git a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php b/tests/phpunit/includes/specials/SpecialRecentchangesTest.php index add830b0..436eb2e2 100644 --- a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php +++ b/tests/phpunit/includes/specials/SpecialRecentchangesTest.php @@ -42,7 +42,6 @@ class SpecialRecentchangesTest extends MediaWikiTestCase { /** return false if condition begin with 'rc_timestamp ' */ private static function filterOutRcTimestampCondition( $var ) { return ( false === strpos( $var, 'rc_timestamp ' ) ); - } public function testRcNsFilter() { @@ -123,5 +122,4 @@ class SpecialRecentchangesTest extends MediaWikiTestCase { array( NS_TALK, NS_MAIN ), ); } - } diff --git a/tests/phpunit/includes/specials/SpecialSearchTest.php b/tests/phpunit/includes/specials/SpecialSearchTest.php index f5ef0fb7..17e883fd 100644 --- a/tests/phpunit/includes/specials/SpecialSearchTest.php +++ b/tests/phpunit/includes/specials/SpecialSearchTest.php @@ -18,7 +18,7 @@ class SpecialSearchTest extends MediaWikiTestCase { * @param $expectedProfile An expected search profile name * @param $expectedNs Array Expected namespaces */ - function testProfileAndNamespaceLoading( + public function testProfileAndNamespaceLoading( $requested, $userOptions, $expectedProfile, $expectedNS, $message = 'Profile name and namespaces mismatches!' ) { @@ -53,10 +53,9 @@ class SpecialSearchTest extends MediaWikiTestCase { ) , $message ); - } - function provideSearchOptionsTests() { + public static function provideSearchOptionsTests() { $defaultNS = SearchEngine::defaultNamespaces(); $EMPTY_REQUEST = array(); $NO_USER_PREF = null; @@ -105,6 +104,7 @@ class SpecialSearchTest extends MediaWikiTestCase { foreach ( $opt as $name => $value ) { $u->setOption( $name, $value ); } + return $u; } @@ -112,7 +112,7 @@ class SpecialSearchTest extends MediaWikiTestCase { * Verify we do not expand search term in <title> on search result page * https://gerrit.wikimedia.org/r/4841 */ - function testSearchTermIsNotExpanded() { + public function testSearchTermIsNotExpanded() { # Initialize [[Special::Search]] $search = new SpecialSearch(); @@ -135,6 +135,5 @@ class SpecialSearchTest extends MediaWikiTestCase { $pageTitle, "Search term '{$term}' should not be expanded in Special:Search <title>" ); - } } diff --git a/tests/phpunit/includes/upload/UploadTest.php b/tests/phpunit/includes/upload/UploadBaseTest.php index b809d320..982b46b2 100644 --- a/tests/phpunit/includes/upload/UploadTest.php +++ b/tests/phpunit/includes/upload/UploadBaseTest.php @@ -1,10 +1,12 @@ <?php + /** * @group Upload */ -class UploadTest extends MediaWikiTestCase { - protected $upload; +class UploadBaseTest extends MediaWikiTestCase { + /** @var UploadTestHandler */ + protected $upload; protected function setUp() { global $wgHooks; @@ -30,6 +32,7 @@ class UploadTest extends MediaWikiTestCase { * of UploadBase::getTitle() and then the actual returned title * * @dataProvider provideTestTitleValidation + * @covers UploadBase::getTitle */ public function testTitleValidation( $srcFilename, $dstFilename, $code, $msg ) { /* Check the result code */ @@ -82,6 +85,7 @@ class UploadTest extends MediaWikiTestCase { /** * Test the upload verification functions + * @covers UploadBase::verifyUpload */ public function testVerifyUpload() { /* Setup with zero file size */ @@ -108,7 +112,6 @@ class UploadTest extends MediaWikiTestCase { * * This method should be abstracted so we can test different settings. */ - public function testMaxUploadSize() { global $wgMaxUploadSize; $savedGlobal = $wgMaxUploadSize; // save global @@ -130,15 +133,15 @@ class UploadTest extends MediaWikiTestCase { } class UploadTestHandler extends UploadBase { - public function initializeFromRequest( &$request ) {} + public function initializeFromRequest( &$request ) { + } public function testTitleValidation( $name ) { $this->mTitle = false; $this->mDesiredDestName = $name; $this->mTitleError = UploadBase::OK; $this->getTitle(); + return $this->mTitleError; } - - } diff --git a/tests/phpunit/includes/upload/UploadFromUrlTest.php b/tests/phpunit/includes/upload/UploadFromUrlTest.php index 4d2d8ce3..a75fba69 100644 --- a/tests/phpunit/includes/upload/UploadFromUrlTest.php +++ b/tests/phpunit/includes/upload/UploadFromUrlTest.php @@ -6,14 +6,14 @@ * @group Database */ class UploadFromUrlTest extends ApiTestCase { - protected function setUp() { - global $wgEnableUploads, $wgAllowCopyUploads, $wgAllowAsyncCopyUploads; parent::setUp(); - $wgEnableUploads = true; - $wgAllowCopyUploads = true; - $wgAllowAsyncCopyUploads = true; + $this->setMwGlobals( array( + 'wgEnableUploads' => true, + 'wgAllowCopyUploads' => true, + 'wgAllowAsyncCopyUploads' => true, + ) ); wfSetupSession(); if ( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ) { @@ -30,6 +30,7 @@ class UploadFromUrlTest extends ApiTestCase { $module->execute(); wfSetupSession( $sessionId ); + return array( $module->getResultData(), $req ); } @@ -174,7 +175,6 @@ class UploadFromUrlTest extends ApiTestCase { $this->user->addGroup( 'users' ); - $data = $this->doAsyncUpload( $token ); $this->assertEquals( $data[0]['upload']['result'], 'Warning' ); @@ -235,7 +235,7 @@ class UploadFromUrlTest extends ApiTestCase { $this->assertFalse( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk does not exist' ); - $data = $this->doApiRequest( array( + $this->doApiRequest( array( 'action' => 'upload', 'filename' => 'UploadFromUrlTest.png', 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', @@ -259,7 +259,7 @@ class UploadFromUrlTest extends ApiTestCase { $exception = false; try { - $data = $this->doApiRequest( array( + $this->doApiRequest( array( 'action' => 'upload', 'filename' => 'UploadFromUrlTest.png', 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', @@ -277,7 +277,6 @@ class UploadFromUrlTest extends ApiTestCase { $this->assertFalse( $job ); return; - /* // Broken until using leavemessage with ignorewarnings is supported $job->run(); @@ -330,7 +329,6 @@ class UploadFromUrlTest extends ApiTestCase { return $data; } - /** * */ diff --git a/tests/phpunit/includes/upload/UploadStashTest.php b/tests/phpunit/includes/upload/UploadStashTest.php index 8fcaa214..7a0fea48 100644 --- a/tests/phpunit/includes/upload/UploadStashTest.php +++ b/tests/phpunit/includes/upload/UploadStashTest.php @@ -44,8 +44,7 @@ class UploadStashTest extends MediaWikiTestCase { } public function testBug29408() { - global $wgUser; - $wgUser = self::$users['uploader']->user; + $this->setMwGlobals( 'wgUser', self::$users['uploader']->user ); $repo = RepoGroup::singleton()->getLocalRepo(); $stash = new UploadStash( $repo ); diff --git a/tests/phpunit/install-phpunit.sh b/tests/phpunit/install-phpunit.sh index 36012748..1f602935 100644 --- a/tests/phpunit/install-phpunit.sh +++ b/tests/phpunit/install-phpunit.sh @@ -8,7 +8,7 @@ has_binary () { } if [ `id -u` -ne 0 ]; then - echo '*** ERROR' Must be root to run + echo '*** ERROR: Must be root to run' exit 1 fi diff --git a/tests/phpunit/languages/LanguageAmTest.php b/tests/phpunit/languages/LanguageAmTest.php index 9723e1e3..a644f5e0 100644 --- a/tests/phpunit/languages/LanguageAmTest.php +++ b/tests/phpunit/languages/LanguageAmTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageAm.php */ class LanguageAmTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageArTest.php b/tests/phpunit/languages/LanguageArTest.php index 523ee7f6..7b48f236 100644 --- a/tests/phpunit/languages/LanguageArTest.php +++ b/tests/phpunit/languages/LanguageArTest.php @@ -6,8 +6,11 @@ /** Tests for MediaWiki languages/LanguageAr.php */ class LanguageArTest extends LanguageClassesTestCase { - - function testFormatNum() { + /** + * @covers Language::formatNum + * @todo split into a test and a dataprovider + */ + public function testFormatNum() { $this->assertEquals( '١٬٢٣٤٬٥٦٧', $this->getLang()->formatNum( '1234567' ) ); $this->assertEquals( '-١٢٫٨٩', $this->getLang()->formatNum( -12.89 ) ); } @@ -15,12 +18,13 @@ class LanguageArTest extends LanguageClassesTestCase { /** * Mostly to test the raw ascii feature. * @dataProvider providerSprintfDate + * @covers Language::sprintfDate */ - function testSprintfDate( $format, $date, $expected ) { + public function testSprintfDate( $format, $date, $expected ) { $this->assertEquals( $expected, $this->getLang()->sprintfDate( $format, $date ) ); } - function providerSprintfDate() { + public static function providerSprintfDate() { return array( array( 'xg "vs" g', @@ -45,13 +49,24 @@ class LanguageArTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'zero', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageBeTest.php b/tests/phpunit/languages/LanguageBeTest.php index 0144941b..7bd586af 100644 --- a/tests/phpunit/languages/LanguageBeTest.php +++ b/tests/phpunit/languages/LanguageBeTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageBe.php */ class LanguageBeTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), diff --git a/tests/phpunit/languages/LanguageBe_taraskTest.php b/tests/phpunit/languages/LanguageBe_taraskTest.php index 5b246d8e..d5822f4a 100644 --- a/tests/phpunit/languages/LanguageBe_taraskTest.php +++ b/tests/phpunit/languages/LanguageBe_taraskTest.php @@ -1,20 +1,22 @@ <?php class LanguageBe_taraskTest extends LanguageClassesTestCase { - /** * Make sure the language code we are given is indeed * be-tarask. This is to ensure LanguageClassesTestCase * does not give us the wrong language. */ - function testBeTaraskTestsUsesBeTaraskCode() { + public function testBeTaraskTestsUsesBeTaraskCode() { $this->assertEquals( 'be-tarask', $this->getLang()->getCode() ); } - /** see bug 23156 & r64981 */ - function testSearchRightSingleQuotationMarkAsApostroph() { + /** + * @see bug 23156 & r64981 + * @covers Language::commafy + */ + public function testSearchRightSingleQuotationMarkAsApostroph() { $this->assertEquals( "'", $this->getLang()->normalizeForSearch( '’' ), @@ -22,24 +24,41 @@ class LanguageBe_taraskTest extends LanguageClassesTestCase { ); } - /** see bug 23156 & r64981 */ - function testCommafy() { + /** + * @see bug 23156 & r64981 + * @covers Language::commafy + */ + public function testCommafy() { $this->assertEquals( '1,234,567', $this->getLang()->commafy( '1234567' ) ); $this->assertEquals( '12,345', $this->getLang()->commafy( '12345' ) ); } - /** see bug 23156 & r64981 */ - function testDoesNotCommafyFourDigitsNumber() { + /** + * @see bug 23156 & r64981 + * @covers Language::commafy + */ + public function testDoesNotCommafyFourDigitsNumber() { $this->assertEquals( '1234', $this->getLang()->commafy( '1234' ) ); } - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), @@ -55,19 +74,21 @@ class LanguageBe_taraskTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), + array( 'other', 11 ), + array( 'other', 91 ), + array( 'other', 121 ), ); } - } diff --git a/tests/phpunit/languages/LanguageBhoTest.php b/tests/phpunit/languages/LanguageBhoTest.php index c364917d..187bfbbc 100644 --- a/tests/phpunit/languages/LanguageBhoTest.php +++ b/tests/phpunit/languages/LanguageBhoTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageBho.php */ class LanguageBhoTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageBhoTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageBsTest.php b/tests/phpunit/languages/LanguageBsTest.php index 76d00704..fb965b89 100644 --- a/tests/phpunit/languages/LanguageBsTest.php +++ b/tests/phpunit/languages/LanguageBsTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageBs.php */ class LanguageBsTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'many', 0 ), array( 'one', 1 ), @@ -29,5 +39,4 @@ class LanguageBsTest extends LanguageClassesTestCase { array( 'many', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageClassesTestCase.php b/tests/phpunit/languages/LanguageClassesTestCase.php index 6659dad1..632e037f 100644 --- a/tests/phpunit/languages/LanguageClassesTestCase.php +++ b/tests/phpunit/languages/LanguageClassesTestCase.php @@ -3,16 +3,7 @@ * Helping class to run tests using a clean language instance. * * This is intended for the MediaWiki language class tests under - * tests/phpunit/languages. You simply need to extends this test - * and set it up with a language code using setUpBeforeClass: - * - * @par Setting up a language: - * @code - * class LanguageFooTest extends LanguageClassesTestCase { - * public static function setUpBeforeClass() { - * self::setLang( 'Foo' ); - * } - * @endcode + * tests/phpunit/languages. * * Before each tests, a new language object is build which you * can retrieve in your test using the $this->getLang() method: @@ -28,19 +19,6 @@ * @endcode */ abstract class LanguageClassesTestCase extends MediaWikiTestCase { - - /** - * Regex used to find out the language code out of the class name - * used by setUpBeforeClass - */ - private static $reExtractLangFromClass = '/Language(.*)Test/'; - - /** - * Hold the language code we are going to use. This is extracted - * directly from the extending class. - */ - private static $LanguageClassCode; - /** * Internal language object * @@ -57,9 +35,19 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase { */ private $languageObject; - public static function setUpBeforeClass() { - $found = preg_match( self::$reExtractLangFromClass, - get_called_class(), $m ); + /** + * @return Language + */ + protected function getLang() { + return $this->languageObject; + } + + /** + * Create a new language object before each test. + */ + protected function setUp() { + parent::setUp(); + $found = preg_match( '/Language(.+)Test/', get_called_class(), $m ); if ( $found ) { # Normalize language code since classes uses underscores $m[1] = str_replace( '_', '-', $m[1] ); @@ -71,21 +59,8 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase { . "out of " . get_called_class() . " failling back to 'en'\n" ); } - // TODO: validate $m[1] which should be a valid language code - self::$LanguageClassCode = $m[1]; - } - - protected function getLang() { - return $this->languageObject; - } - - /** - * Create a new language object before each test. - */ - protected function setUp() { - parent::setUp(); - $this->languageObject = Language::factory( - self::$LanguageClassCode ); + // @todo validate $m[1] which should be a valid language code + $this->languageObject = Language::factory( $m[1] ); } /** @@ -96,5 +71,4 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase { unset( $this->languageObject ); parent::tearDown(); } - } diff --git a/tests/phpunit/languages/LanguageCsTest.php b/tests/phpunit/languages/LanguageCsTest.php index 884a129e..da9e6b88 100644 --- a/tests/phpunit/languages/LanguageCsTest.php +++ b/tests/phpunit/languages/LanguageCsTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/Languagecs.php */ class LanguageCsTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -28,5 +38,4 @@ class LanguageCsTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageCuTest.php b/tests/phpunit/languages/LanguageCuTest.php index e2394b35..07193172 100644 --- a/tests/phpunit/languages/LanguageCuTest.php +++ b/tests/phpunit/languages/LanguageCuTest.php @@ -7,27 +7,36 @@ /** Tests for MediaWiki languages/LanguageCu.php */ class LanguageCuTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), - array( 'few', 2 ), - array( 'many', 3 ), - array( 'many', 4 ), + array( 'two', 2 ), + array( 'few', 3 ), + array( 'few', 4 ), array( 'other', 5 ), array( 'one', 11 ), array( 'other', 20 ), - array( 'few', 22 ), - array( 'many', 223 ), + array( 'two', 22 ), + array( 'few', 223 ), array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageCyTest.php b/tests/phpunit/languages/LanguageCyTest.php index 2a7f4a92..eaf663a8 100644 --- a/tests/phpunit/languages/LanguageCyTest.php +++ b/tests/phpunit/languages/LanguageCyTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageCy.php */ class LanguageCyTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'zero', 0 ), array( 'one', 1 ), @@ -30,5 +40,4 @@ class LanguageCyTest extends LanguageClassesTestCase { array( 'other', 200.00 ), ); } - } diff --git a/tests/phpunit/languages/LanguageDsbTest.php b/tests/phpunit/languages/LanguageDsbTest.php index 285ce648..94c11bcc 100644 --- a/tests/phpunit/languages/LanguageDsbTest.php +++ b/tests/phpunit/languages/LanguageDsbTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageDsb.php */ class LanguageDsbTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -28,5 +38,4 @@ class LanguageDsbTest extends LanguageClassesTestCase { array( 'other', 555 ), ); } - } diff --git a/tests/phpunit/languages/LanguageFrTest.php b/tests/phpunit/languages/LanguageFrTest.php index faf0de58..46b65011 100644 --- a/tests/phpunit/languages/LanguageFrTest.php +++ b/tests/phpunit/languages/LanguageFrTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageFr.php */ class LanguageFrTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageFrTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageGaTest.php b/tests/phpunit/languages/LanguageGaTest.php index 2dbb088b..c009f56b 100644 --- a/tests/phpunit/languages/LanguageGaTest.php +++ b/tests/phpunit/languages/LanguageGaTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageGa.php */ class LanguageGaTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageGaTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageGdTest.php b/tests/phpunit/languages/LanguageGdTest.php index 5de1e9d2..0b2612b2 100644 --- a/tests/phpunit/languages/LanguageGdTest.php +++ b/tests/phpunit/languages/LanguageGdTest.php @@ -7,15 +7,17 @@ /** Tests for MediaWiki languages/classes/LanguageGd.php */ class LanguageGdTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providerPlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { - return array ( + public static function providerPlural() { + return array( array( 'other', 0 ), array( 'one', 1 ), array( 'two', 2 ), @@ -27,22 +29,25 @@ class LanguageGdTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPluralExplicit */ - function testExplicitPlural( $result, $value ) { + /** + * @dataProvider providerPluralExplicit + * @covers Language::convertPlural + */ + public function testExplicitPlural( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other', '11=Form11', '12=Form12' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralExplicit() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'Form11', 11 ), - array( 'Form12', 12 ), - array( 'few', 3 ), - array( 'few', 19 ), - array( 'other', 200 ), + public static function providerPluralExplicit() { + return array( + array( 'other', 0 ), + array( 'one', 1 ), + array( 'two', 2 ), + array( 'Form11', 11 ), + array( 'Form12', 12 ), + array( 'few', 3 ), + array( 'few', 19 ), + array( 'other', 200 ), ); } } diff --git a/tests/phpunit/languages/LanguageGvTest.php b/tests/phpunit/languages/LanguageGvTest.php index 4126e071..a0def628 100644 --- a/tests/phpunit/languages/LanguageGvTest.php +++ b/tests/phpunit/languages/LanguageGvTest.php @@ -7,15 +7,27 @@ /** Tests for MediaWiki languages/classes/LanguageGv.php */ class LanguageGvTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { // This is not compatible with CLDR plural rules http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#gv + // What does this mean? Is there a hard-coded override for gv somewhere? -Ryan Kaldari 2013-01-28 $forms = array( 'Form 1', 'Form 2', 'Form 3', 'Form 4' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->markTestSkipped( "This test won't work since convertPlural for gv doesn't seem to actually follow our plural rules." ); + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'Form 4', 0 ), array( 'Form 2', 1 ), @@ -28,5 +40,4 @@ class LanguageGvTest extends LanguageClassesTestCase { array( 'Form 4', 50 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHeTest.php b/tests/phpunit/languages/LanguageHeTest.php index 6de88e59..8edc6ddf 100644 --- a/tests/phpunit/languages/LanguageHeTest.php +++ b/tests/phpunit/languages/LanguageHeTest.php @@ -7,70 +7,125 @@ /** Tests for MediaWiki languages/classes/LanguageHe.php */ class LanguageHeTest extends LanguageClassesTestCase { + /** + * The most common usage for the plural forms is two forms, + * for singular and plural. In this case, the second form + * is technically dual, but in practice it's used as plural. + * In some cases, usually with expressions of time, three forms + * are needed - singular, dual and plural. + * CLDR also specifies a fourth form for multiples of 10, + * which is very rare. It also has a mistake, because + * the number 10 itself is supposed to be just plural, + * so currently it's overridden in MediaWiki. + */ - /** @dataProvider providerPluralDual */ - function testPluralDual( $result, $value ) { + // @todo the below test*PluralForms test methods can be refactored + // to use a single test method and data provider.. + + /** + * @dataProvider provideTwoPluralForms + * @covers Language::convertPlural + */ + public function testTwoPluralForms( $result, $value ) { + $forms = array( 'one', 'other' ); + $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + } + + /** + * @dataProvider provideThreePluralForms + * @covers Language::convertPlural + */ + public function testThreePluralForms( $result, $value ) { $forms = array( 'one', 'two', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralDual() { + /** + * @dataProvider provideFourPluralForms + * @covers Language::convertPlural + */ + public function testFourPluralForms( $result, $value ) { + $forms = array( 'one', 'two', 'many', 'other' ); + $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + } + + /** + * @dataProvider provideFourPluralForms + * @covers Language::convertPlural + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function provideTwoPluralForms() { return array( - array( 'other', 0 ), // Zero -> plural + array( 'other', 0 ), // Zero - plural array( 'one', 1 ), // Singular - array( 'two', 2 ), // Dual - array( 'other', 3 ), // Plural + array( 'other', 2 ), // No third form provided, use it as plural + array( 'other', 3 ), // Plural - other + array( 'other', 10 ), // No fourth form provided, use it as plural + array( 'other', 20 ), // No fourth form provided, use it as plural ); } - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + public static function provideThreePluralForms() { + return array( + array( 'other', 0 ), // Zero - plural + array( 'one', 1 ), // Singular + array( 'two', 2 ), // Dual + array( 'other', 3 ), // Plural - other + array( 'other', 10 ), // No fourth form provided, use it as plural + array( 'other', 20 ), // No fourth form provided, use it as plural + ); } - function providerPlural() { + public static function provideFourPluralForms() { return array( - array( 'other', 0 ), // Zero -> plural + array( 'other', 0 ), // Zero - plural array( 'one', 1 ), // Singular - array( 'other', 2 ), // Plural, no dual provided - array( 'other', 3 ), // Plural + array( 'two', 2 ), // Dual + array( 'other', 3 ), // Plural - other + array( 'other', 10 ), // 10 is supposed to be plural (other), not "many" + array( 'many', 20 ), // Fourth form provided - rare, but supported by CLDR ); } - /** @dataProvider providerGrammar */ - function testGrammar( $result, $word, $case ) { + /** + * @dataProvider provideGrammar + * @covers Language::convertGrammar + */ + public function testGrammar( $result, $word, $case ) { $this->assertEquals( $result, $this->getLang()->convertGrammar( $word, $case ) ); } // The comments in the beginning of the line help avoid RTL problems // with text editors. - function providerGrammar() { + public static function provideGrammar() { return array( array( - /* result */ 'וויקיפדיה', - /* word */ 'ויקיפדיה', - /* case */ 'תחילית', + /* result */'וויקיפדיה', + /* word */'ויקיפדיה', + /* case */'תחילית', ), array( - /* result */ 'וולפגנג', - /* word */ 'וולפגנג', - /* case */ 'prefixed', + /* result */'וולפגנג', + /* word */'וולפגנג', + /* case */'prefixed', ), array( - /* result */ 'קובץ', - /* word */ 'הקובץ', - /* case */ 'תחילית', + /* result */'קובץ', + /* word */'הקובץ', + /* case */'תחילית', ), array( - /* result */ '־Wikipedia', - /* word */ 'Wikipedia', - /* case */ 'תחילית', + /* result */'־Wikipedia', + /* word */'Wikipedia', + /* case */'תחילית', ), array( - /* result */ '־1995', - /* word */ '1995', - /* case */ 'תחילית', + /* result */'־1995', + /* word */'1995', + /* case */'תחילית', ), ); } diff --git a/tests/phpunit/languages/LanguageHiTest.php b/tests/phpunit/languages/LanguageHiTest.php index 86d6af58..f6d2c9e9 100644 --- a/tests/phpunit/languages/LanguageHiTest.php +++ b/tests/phpunit/languages/LanguageHiTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageHi.php */ class LanguageHiTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageHiTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHrTest.php b/tests/phpunit/languages/LanguageHrTest.php index 9dce4ea7..6ce4aff9 100644 --- a/tests/phpunit/languages/LanguageHrTest.php +++ b/tests/phpunit/languages/LanguageHrTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageHr.php */ class LanguageHrTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'many', 0 ), array( 'one', 1 ), @@ -29,5 +39,4 @@ class LanguageHrTest extends LanguageClassesTestCase { array( 'many', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHsbTest.php b/tests/phpunit/languages/LanguageHsbTest.php index bec7d819..f95a43bf 100644 --- a/tests/phpunit/languages/LanguageHsbTest.php +++ b/tests/phpunit/languages/LanguageHsbTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageHsb.php */ class LanguageHsbTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -28,5 +38,4 @@ class LanguageHsbTest extends LanguageClassesTestCase { array( 'other', 555 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHuTest.php b/tests/phpunit/languages/LanguageHuTest.php index 23d8e0ce..ee9197d7 100644 --- a/tests/phpunit/languages/LanguageHuTest.php +++ b/tests/phpunit/languages/LanguageHuTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/LanguageHu.php */ class LanguageHuTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageHuTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageHyTest.php b/tests/phpunit/languages/LanguageHyTest.php index 7088d37b..896522b0 100644 --- a/tests/phpunit/languages/LanguageHyTest.php +++ b/tests/phpunit/languages/LanguageHyTest.php @@ -7,14 +7,25 @@ /** Tests for MediaWiki languages/LanguageHy.php */ class LanguageHyTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + // This fails for 0, but I'm not sure why. Some voodoo going on here. + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -22,5 +33,4 @@ class LanguageHyTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageKshTest.php b/tests/phpunit/languages/LanguageKshTest.php index 9b4a53ad..568a3780 100644 --- a/tests/phpunit/languages/LanguageKshTest.php +++ b/tests/phpunit/languages/LanguageKshTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageKsh.php */ class LanguageKshTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other', 'zero' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'zero', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageKshTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageLnTest.php b/tests/phpunit/languages/LanguageLnTest.php index 669d8b0a..10b3234f 100644 --- a/tests/phpunit/languages/LanguageLnTest.php +++ b/tests/phpunit/languages/LanguageLnTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageLn.php */ class LanguageLnTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -22,5 +32,4 @@ class LanguageLnTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageLtTest.php b/tests/phpunit/languages/LanguageLtTest.php index 9d6428b8..30642f62 100644 --- a/tests/phpunit/languages/LanguageLtTest.php +++ b/tests/phpunit/languages/LanguageLtTest.php @@ -7,20 +7,24 @@ /** Tests for MediaWiki languages/LanguageLt.php */ class LanguageLtTest extends LanguageClassesTestCase { - - /** @dataProvider provideOneFewOtherCases */ - function testOneFewOtherPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - /** @dataProvider provideOneFewCases */ - function testOneFewPlural( $result, $value ) { - $forms = array( 'one', 'few' ); - $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); } - function provideOneFewOtherCases() { + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -36,10 +40,24 @@ class LanguageLtTest extends LanguageClassesTestCase { ); } - function provideOneFewCases() { + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testOneFewPlural( $result, $value ) { + $forms = array( 'one', 'other' ); + // This fails for 21, but not sure why. + $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); + } + + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'few', 15 ), + array( 'other', 2 ), + array( 'other', 15 ), + array( 'other', 20 ), + array( 'one', 21 ), + array( 'other', 22 ), ); } } diff --git a/tests/phpunit/languages/LanguageLvTest.php b/tests/phpunit/languages/LanguageLvTest.php index bd0c759b..c4d8a6f0 100644 --- a/tests/phpunit/languages/LanguageLvTest.php +++ b/tests/phpunit/languages/LanguageLvTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageLv.php */ class LanguageLvTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'zero', 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'zero', 0 ), array( 'one', 1 ), @@ -27,5 +37,4 @@ class LanguageLvTest extends LanguageClassesTestCase { array( 'other', 200 ), ); } - } diff --git a/tests/phpunit/languages/LanguageMgTest.php b/tests/phpunit/languages/LanguageMgTest.php index c1e516bc..65e8fd7b 100644 --- a/tests/phpunit/languages/LanguageMgTest.php +++ b/tests/phpunit/languages/LanguageMgTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageMg.php */ class LanguageMgTest extends LanguageClassesTestCase { - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), @@ -23,5 +33,4 @@ class LanguageMgTest extends LanguageClassesTestCase { array( 'other', 123.3434 ), ); } - } diff --git a/tests/phpunit/languages/LanguageMkTest.php b/tests/phpunit/languages/LanguageMkTest.php index 5c241ba7..7d47b375 100644 --- a/tests/phpunit/languages/LanguageMkTest.php +++ b/tests/phpunit/languages/LanguageMkTest.php @@ -7,27 +7,34 @@ /** Tests for MediaWiki languages/classes/LanguageMk.php */ class LanguageMkTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } - function providerPlural() { + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), array( 'other', 11 ), array( 'one', 21 ), - array( 'other', 411 ), + array( 'one', 411 ), array( 'other', 12.345 ), array( 'other', 20 ), array( 'one', 31 ), array( 'other', 200 ), ); } - - } diff --git a/tests/phpunit/languages/LanguageMlTest.php b/tests/phpunit/languages/LanguageMlTest.php index 396114d9..4fa45ce3 100644 --- a/tests/phpunit/languages/LanguageMlTest.php +++ b/tests/phpunit/languages/LanguageMlTest.php @@ -8,13 +8,16 @@ /** Tests for MediaWiki languages/LanguageMl.php */ class LanguageMlTest extends LanguageClassesTestCase { - /** see bug 29495 */ - /** @dataProvider providerFormatNum */ - function testFormatNum( $result, $value ) { + /** + * @dataProvider providerFormatNum + * @see bug 29495 + * @covers Language::formatNum + */ + public function testFormatNum( $result, $value ) { $this->assertEquals( $result, $this->getLang()->formatNum( $value ) ); } - function providerFormatNum() { + public static function providerFormatNum() { return array( array( '12,34,567', '1234567' ), array( '12,345', '12345' ), diff --git a/tests/phpunit/languages/LanguageMoTest.php b/tests/phpunit/languages/LanguageMoTest.php index f7da1cd6..e0e54ca8 100644 --- a/tests/phpunit/languages/LanguageMoTest.php +++ b/tests/phpunit/languages/LanguageMoTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageMo.php */ class LanguageMoTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'few', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageMtTest.php b/tests/phpunit/languages/LanguageMtTest.php index f2b881e7..96d2bc92 100644 --- a/tests/phpunit/languages/LanguageMtTest.php +++ b/tests/phpunit/languages/LanguageMtTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageMt.php */ class LanguageMtTest extends LanguageClassesTestCase { - - /** @dataProvider providerPluralAllForms */ - function testPluralAllForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralAllForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'few', 0 ), array( 'one', 1 ), @@ -35,30 +45,33 @@ class LanguageMtTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralTwoForms() { + public static function providePluralTwoForms() { return array( - array( 'many', 0 ), + array( 'other', 0 ), array( 'one', 1 ), - array( 'many', 2 ), - array( 'many', 10 ), - array( 'many', 11 ), - array( 'many', 19 ), - array( 'many', 20 ), - array( 'many', 99 ), - array( 'many', 100 ), - array( 'many', 101 ), - array( 'many', 102 ), - array( 'many', 110 ), - array( 'many', 111 ), - array( 'many', 119 ), - array( 'many', 120 ), - array( 'many', 201 ), + array( 'other', 2 ), + array( 'other', 10 ), + array( 'other', 11 ), + array( 'other', 19 ), + array( 'other', 20 ), + array( 'other', 99 ), + array( 'other', 100 ), + array( 'other', 101 ), + array( 'other', 102 ), + array( 'other', 110 ), + array( 'other', 111 ), + array( 'other', 119 ), + array( 'other', 120 ), + array( 'other', 201 ), ); } } diff --git a/tests/phpunit/languages/LanguageNlTest.php b/tests/phpunit/languages/LanguageNlTest.php index f783f2c0..26bd691a 100644 --- a/tests/phpunit/languages/LanguageNlTest.php +++ b/tests/phpunit/languages/LanguageNlTest.php @@ -8,7 +8,11 @@ /** Tests for MediaWiki languages/LanguageNl.php */ class LanguageNlTest extends LanguageClassesTestCase { - function testFormatNum() { + /** + * @covers Language::formatNum + * @todo split into a test and a dataprovider + */ + public function testFormatNum() { $this->assertEquals( '1.234.567', $this->getLang()->formatNum( '1234567' ) ); $this->assertEquals( '12.345', $this->getLang()->formatNum( '12345' ) ); $this->assertEquals( '1', $this->getLang()->formatNum( '1' ) ); diff --git a/tests/phpunit/languages/LanguageNsoTest.php b/tests/phpunit/languages/LanguageNsoTest.php index 9d80d138..18efd736 100644 --- a/tests/phpunit/languages/LanguageNsoTest.php +++ b/tests/phpunit/languages/LanguageNsoTest.php @@ -7,18 +7,28 @@ /** Tests for MediaWiki languages/classes/LanguageNso.php */ class LanguageNsoTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'other', 2 ), ); } } diff --git a/tests/phpunit/languages/LanguagePlTest.php b/tests/phpunit/languages/LanguagePlTest.php index 1e36097b..d180037b 100644 --- a/tests/phpunit/languages/LanguagePlTest.php +++ b/tests/phpunit/languages/LanguagePlTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguagePl.php */ class LanguagePlTest extends LanguageClassesTestCase { - - /** @dataProvider providerPluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'many', 0 ), array( 'one', 1 ), @@ -35,30 +45,33 @@ class LanguagePlTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + public static function providePluralTwoForms() { return array( - array( 'many', 0 ), + array( 'other', 0 ), array( 'one', 1 ), - array( 'many', 2 ), - array( 'many', 3 ), - array( 'many', 4 ), - array( 'many', 5 ), - array( 'many', 9 ), - array( 'many', 10 ), - array( 'many', 11 ), - array( 'many', 21 ), - array( 'many', 22 ), - array( 'many', 23 ), - array( 'many', 24 ), - array( 'many', 25 ), - array( 'many', 200 ), - array( 'many', 201 ), + array( 'other', 2 ), + array( 'other', 3 ), + array( 'other', 4 ), + array( 'other', 5 ), + array( 'other', 9 ), + array( 'other', 10 ), + array( 'other', 11 ), + array( 'other', 21 ), + array( 'other', 22 ), + array( 'other', 23 ), + array( 'other', 24 ), + array( 'other', 25 ), + array( 'other', 200 ), + array( 'other', 201 ), ); } } diff --git a/tests/phpunit/languages/LanguageRoTest.php b/tests/phpunit/languages/LanguageRoTest.php index 916ea45d..ae7816bc 100644 --- a/tests/phpunit/languages/LanguageRoTest.php +++ b/tests/phpunit/languages/LanguageRoTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageRo.php */ class LanguageRoTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'few', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageRuTest.php b/tests/phpunit/languages/LanguageRuTest.php index 0792f75b..e938be79 100644 --- a/tests/phpunit/languages/LanguageRuTest.php +++ b/tests/phpunit/languages/LanguageRuTest.php @@ -8,14 +8,24 @@ /** Tests for MediaWiki languages/classes/LanguageRu.php */ class LanguageRuTest extends LanguageClassesTestCase { - - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), @@ -31,27 +41,33 @@ class LanguageRuTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), + array( 'other', 11 ), + array( 'other', 91 ), + array( 'other', 121 ), ); } - /** @dataProvider providerGrammar */ - function testGrammar( $result, $word, $case ) { + /** + * @dataProvider providerGrammar + * @covers Language::convertGrammar + */ + public function testGrammar( $result, $word, $case ) { $this->assertEquals( $result, $this->getLang()->convertGrammar( $word, $case ) ); } - function providerGrammar() { + public static function providerGrammar() { return array( array( 'Википедии', diff --git a/tests/phpunit/languages/LanguageSeTest.php b/tests/phpunit/languages/LanguageSeTest.php index c7dd8020..533aa2bc 100644 --- a/tests/phpunit/languages/LanguageSeTest.php +++ b/tests/phpunit/languages/LanguageSeTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageSe.php */ class LanguageSeTest extends LanguageClassesTestCase { - - /** @dataProvider providerPluralThreeForms */ - function testPluralThreeForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralThreeForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -23,13 +33,16 @@ class LanguageSeTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + public static function providePluralTwoForms() { return array( array( 'other', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageSgsTest.php b/tests/phpunit/languages/LanguageSgsTest.php index 95e63462..bf6a14b1 100644 --- a/tests/phpunit/languages/LanguageSgsTest.php +++ b/tests/phpunit/languages/LanguageSgsTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageSgs.php */ class LanguageSgsTest extends LanguageClassesTestCase { - - /** @dataProvider providePluralAllForms */ - function testPluralAllForms( $result, $value ) { + /** + * @dataProvider providePluralAllForms + * @covers Language::convertPlural + */ + public function testPluralAllForms( $result, $value ) { $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralAllForms() { + /** + * @dataProvider providePluralAllForms + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePluralAllForms() { return array( array( 'few', 0 ), array( 'one', 1 ), @@ -32,13 +42,16 @@ class LanguageSgsTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'other', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageShTest.php b/tests/phpunit/languages/LanguageShTest.php index 282fd2f2..6d2e25a6 100644 --- a/tests/phpunit/languages/LanguageShTest.php +++ b/tests/phpunit/languages/LanguageShTest.php @@ -7,18 +7,36 @@ /** Tests for MediaWiki languages/classes/LanguageSh.php */ class LanguageShTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'many', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'few', 2 ), + array( 'few', 4 ), + array( 'many', 5 ), + array( 'many', 10 ), + array( 'many', 11 ), + array( 'many', 12 ), + array( 'one', 101 ), + array( 'few', 102 ), + array( 'many', 111 ), ); } } diff --git a/tests/phpunit/languages/LanguageSkTest.php b/tests/phpunit/languages/LanguageSkTest.php index 89cbbf01..cb8a13b8 100644 --- a/tests/phpunit/languages/LanguageSkTest.php +++ b/tests/phpunit/languages/LanguageSkTest.php @@ -8,14 +8,24 @@ /** Tests for MediaWiki languages/classes/LanguageSk.php */ class LanguageSkTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageSlTest.php b/tests/phpunit/languages/LanguageSlTest.php index 075e6af3..9783dd80 100644 --- a/tests/phpunit/languages/LanguageSlTest.php +++ b/tests/phpunit/languages/LanguageSlTest.php @@ -8,16 +8,26 @@ /** Tests for MediaWiki languages/classes/LanguageSl.php */ class LanguageSlTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', 'other', 'zero' ); + /** + * @dataProvider providerPlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'two', 'few', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providerPlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providerPlural() { return array( - array( 'zero', 0 ), + array( 'other', 0 ), array( 'one', 1 ), array( 'two', 2 ), array( 'few', 3 ), diff --git a/tests/phpunit/languages/LanguageSmaTest.php b/tests/phpunit/languages/LanguageSmaTest.php index 6d655219..95cb333c 100644 --- a/tests/phpunit/languages/LanguageSmaTest.php +++ b/tests/phpunit/languages/LanguageSmaTest.php @@ -7,14 +7,24 @@ /** Tests for MediaWiki languages/classes/LanguageSma.php */ class LanguageSmaTest extends LanguageClassesTestCase { - - /** @dataProvider providerPluralThreeForms */ - function testPluralThreeForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'two', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPluralThreeForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'other', 0 ), array( 'one', 1 ), @@ -23,13 +33,16 @@ class LanguageSmaTest extends LanguageClassesTestCase { ); } - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + public static function providePluralTwoForms() { return array( array( 'other', 0 ), array( 'one', 1 ), diff --git a/tests/phpunit/languages/LanguageSrTest.php b/tests/phpunit/languages/LanguageSrTest.php index 5611030b..ab4d4aba 100644 --- a/tests/phpunit/languages/LanguageSrTest.php +++ b/tests/phpunit/languages/LanguageSrTest.php @@ -10,16 +10,18 @@ * @author Antoine Musso <hashar at free dot fr> * @copyright Copyright © 2011, Antoine Musso <hashar at free dot fr> * @file + * + * @todo methods in test class should be tidied: + * - Should be split into separate test methods and data providers + * - Tests for LanguageConverter and Language should probably be separate.. */ -require_once dirname( __DIR__ ) . '/bootstrap.php'; - /** Tests for MediaWiki languages/LanguageSr.php */ class LanguageSrTest extends LanguageClassesTestCase { - - ##### TESTS ####################################################### - - function testEasyConversions() { + /** + * @covers LanguageConverter::convertTo + */ + public function testEasyConversions() { $this->assertCyrillic( 'шђчћжШЂЧЋЖ', 'Cyrillic guessing characters' @@ -30,7 +32,10 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - function testMixedConversions() { + /** + * @covers LanguageConverter::convertTo + */ + public function testMixedConversions() { $this->assertCyrillic( 'шђчћжШЂЧЋЖ - šđčćž', 'Mostly cyrillic characters' @@ -41,7 +46,10 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - function testSameAmountOfLatinAndCyrillicGetConverted() { + /** + * @covers LanguageConverter::convertTo + */ + public function testSameAmountOfLatinAndCyrillicGetConverted() { $this->assertConverted( '4 latin: šđčć | 4 cyrillic: шђчћ', 'sr-ec' @@ -54,8 +62,9 @@ class LanguageSrTest extends LanguageClassesTestCase { /** * @author Nikola Smolenski + * @covers LanguageConverter::convertTo */ - function testConversionToCyrillic() { + public function testConversionToCyrillic() { //A simple convertion of Latin to Cyrillic $this->assertEquals( 'абвг', $this->convertToCyrillic( 'abvg' ) @@ -94,7 +103,10 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - function testConversionToLatin() { + /** + * @covers LanguageConverter::convertTo + */ + public function testConversionToLatin() { //A simple convertion of Latin to Latin $this->assertEquals( 'abcd', $this->convertToLatin( 'abcd' ) @@ -113,13 +125,24 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), @@ -135,18 +158,21 @@ class LanguageSrTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), + array( 'other', 11 ), + array( 'other', 91 ), + array( 'other', 121 ), ); } @@ -157,7 +183,7 @@ class LanguageSrTest extends LanguageClassesTestCase { * @param $variant string Language variant 'sr-ec' or 'sr-el' * @param $msg string Optional message */ - function assertUnConverted( $text, $variant, $msg = '' ) { + protected function assertUnConverted( $text, $variant, $msg = '' ) { $this->assertEquals( $text, $this->convertTo( $text, $variant ), @@ -171,7 +197,7 @@ class LanguageSrTest extends LanguageClassesTestCase { * @param $variant string Language variant 'sr-ec' or 'sr-el' * @param $msg string Optional message */ - function assertConverted( $text, $variant, $msg = '' ) { + protected function assertConverted( $text, $variant, $msg = '' ) { $this->assertNotEquals( $text, $this->convertTo( $text, $variant ), @@ -184,7 +210,7 @@ class LanguageSrTest extends LanguageClassesTestCase { * using the cyrillic variant and converted to Latin when using * the Latin variant. */ - function assertCyrillic( $text, $msg = '' ) { + protected function assertCyrillic( $text, $msg = '' ) { $this->assertUnConverted( $text, 'sr-ec', $msg ); $this->assertConverted( $text, 'sr-el', $msg ); } @@ -194,26 +220,26 @@ class LanguageSrTest extends LanguageClassesTestCase { * using the Latin variant and converted to Cyrillic when using * the Cyrillic variant. */ - function assertLatin( $text, $msg = '' ) { + protected function assertLatin( $text, $msg = '' ) { $this->assertUnConverted( $text, 'sr-el', $msg ); $this->assertConverted( $text, 'sr-ec', $msg ); } /** Wrapper for converter::convertTo() method*/ - function convertTo( $text, $variant ) { + protected function convertTo( $text, $variant ) { return $this->getLang() ->mConverter ->convertTo( - $text, $variant - ); + $text, $variant + ); } - function convertToCyrillic( $text ) { + protected function convertToCyrillic( $text ) { return $this->convertTo( $text, 'sr-ec' ); } - function convertToLatin( $text ) { + protected function convertToLatin( $text ) { return $this->convertTo( $text, 'sr-el' ); } } diff --git a/tests/phpunit/languages/LanguageTest.php b/tests/phpunit/languages/LanguageTest.php index 76471445..78929e23 100644 --- a/tests/phpunit/languages/LanguageTest.php +++ b/tests/phpunit/languages/LanguageTest.php @@ -1,8 +1,11 @@ <?php class LanguageTest extends LanguageClassesTestCase { - - function testLanguageConvertDoubleWidthToSingleWidth() { + /** + * @covers Language::convertDoubleWidth + * @covers Language::normalizeForSearch + */ + public function testLanguageConvertDoubleWidthToSingleWidth() { $this->assertEquals( "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", $this->getLang()->normalizeForSearch( @@ -13,13 +16,14 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * @dataProvider provideFormattableTimes + * @dataProvider provideFormattableTimes# + * @covers Language::formatTimePeriod */ - function testFormatTimePeriod( $seconds, $format, $expected, $desc ) { + public function testFormatTimePeriod( $seconds, $format, $expected, $desc ) { $this->assertEquals( $expected, $this->getLang()->formatTimePeriod( $seconds, $format ), $desc ); } - function provideFormattableTimes() { + public static function provideFormattableTimes() { return array( array( 9.45, @@ -202,10 +206,12 @@ class LanguageTest extends LanguageClassesTestCase { 'formatTimePeriod() rounding, recursion, (>48h)' ), ); - } - function testTruncate() { + /** + * @covers Language::truncate + */ + public function testTruncate() { $this->assertEquals( "XXX", $this->getLang()->truncate( "1234567890", 0, 'XXX' ), @@ -238,9 +244,10 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * @dataProvider provideHTMLTruncateData() + * @dataProvider provideHTMLTruncateData + * @covers Language::truncateHTML */ - function testTruncateHtml( $len, $ellipsis, $input, $expected ) { + public function testTruncateHtml( $len, $ellipsis, $input, $expected ) { // Actual HTML... $this->assertEquals( $expected, @@ -249,9 +256,9 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * Array format is ($len, $ellipsis, $input, $expected) + * @return array format is ($len, $ellipsis, $input, $expected) */ - function provideHTMLTruncateData() { + public static function provideHTMLTruncateData() { return array( array( 0, 'XXX', "1234567890", "XXX" ), array( 8, 'XXX', "1234567890", "12345XXX" ), @@ -310,8 +317,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * Test Language::isWellFormedLanguageTag() * @dataProvider provideWellFormedLanguageTags + * @covers Language::isWellFormedLanguageTag */ - function testWellFormedLanguageTag( $code, $message = '' ) { + public function testWellFormedLanguageTag( $code, $message = '' ) { $this->assertTrue( Language::isWellFormedLanguageTag( $code ), "validating code $code $message" @@ -324,7 +332,7 @@ class LanguageTest extends LanguageClassesTestCase { * and distributed as free software, under the GNU General Public Licence. * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html */ - function provideWellFormedLanguageTags() { + public static function provideWellFormedLanguageTags() { return array( array( 'fr', 'two-letter code' ), array( 'fr-latn', 'two-letter code with lower case script code' ), @@ -361,8 +369,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * Negative test for Language::isWellFormedLanguageTag() * @dataProvider provideMalformedLanguageTags + * @covers Language::isWellFormedLanguageTag */ - function testMalformedLanguageTag( $code, $message = '' ) { + public function testMalformedLanguageTag( $code, $message = '' ) { $this->assertFalse( Language::isWellFormedLanguageTag( $code ), "validating that code $code is a malformed language tag - $message" @@ -375,7 +384,7 @@ class LanguageTest extends LanguageClassesTestCase { * and distributed as free software, under the GNU General Public Licence. * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html */ - function provideMalformedLanguageTags() { + public static function provideMalformedLanguageTags() { return array( array( 'f', 'language too short' ), array( 'f-Latn', 'language too short with script' ), @@ -411,8 +420,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * Negative test for Language::isWellFormedLanguageTag() + * @covers Language::isWellFormedLanguageTag */ - function testLenientLanguageTag() { + public function testLenientLanguageTag() { $this->assertTrue( Language::isWellFormedLanguageTag( 'pa_guru', true ), 'pa_guru is a well-formed language tag in lenient mode' @@ -422,22 +432,26 @@ class LanguageTest extends LanguageClassesTestCase { /** * Test Language::isValidBuiltInCode() * @dataProvider provideLanguageCodes + * @covers Language::isValidBuiltInCode */ - function testBuiltInCodeValidation( $code, $message = '' ) { + public function testBuiltInCodeValidation( $code, $message = '' ) { $this->assertTrue( (bool)Language::isValidBuiltInCode( $code ), "validating code $code $message" ); } - function testBuiltInCodeValidationRejectUnderscore() { + /** + * @covers Language::isValidBuiltInCode + */ + public function testBuiltInCodeValidationRejectUnderscore() { $this->assertFalse( (bool)Language::isValidBuiltInCode( 'be_tarask' ), "reject underscore in language code" ); } - function provideLanguageCodes() { + public static function provideLanguageCodes() { return array( array( 'fr', 'Two letters, minor case' ), array( 'EN', 'Two letters, upper case' ), @@ -452,15 +466,16 @@ class LanguageTest extends LanguageClassesTestCase { /** * Test Language::isKnownLanguageTag() * @dataProvider provideKnownLanguageTags + * @covers Language::isKnownLanguageTag */ - function testKnownLanguageTag( $code, $message = '' ) { + public function testKnownLanguageTag( $code, $message = '' ) { $this->assertTrue( (bool)Language::isKnownLanguageTag( $code ), "validating code $code - $message" ); } - function provideKnownLanguageTags() { + public static function provideKnownLanguageTags() { return array( array( 'fr', 'simple code' ), array( 'bat-smg', 'an MW legacy tag' ), @@ -469,9 +484,9 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * Test Language::isKnownLanguageTag() + * @covers Language::isKnownLanguageTag */ - function testKnownCldrLanguageTag() { + public function testKnownCldrLanguageTag() { if ( !class_exists( 'LanguageNames' ) ) { $this->markTestSkipped( 'The LanguageNames class is not available. The cldr extension is probably not installed.' ); } @@ -485,24 +500,54 @@ class LanguageTest extends LanguageClassesTestCase { /** * Negative tests for Language::isKnownLanguageTag() * @dataProvider provideUnKnownLanguageTags + * @covers Language::isKnownLanguageTag */ - function testUnknownLanguageTag( $code, $message = '' ) { + public function testUnknownLanguageTag( $code, $message = '' ) { $this->assertFalse( (bool)Language::isKnownLanguageTag( $code ), "checking that code $code is invalid - $message" ); } - function provideUnknownLanguageTags() { + public static function provideUnknownLanguageTags() { return array( array( 'mw', 'non-existent two-letter code' ), + array( 'foo"<bar', 'very invalid language code' ), ); } /** + * Test too short timestamp + * @expectedException MWException + * @covers Language::sprintfDate + */ + public function testSprintfDateTooShortTimestamp() { + $this->getLang()->sprintfDate( 'xiY', '1234567890123' ); + } + + /** + * Test too long timestamp + * @expectedException MWException + * @covers Language::sprintfDate + */ + public function testSprintfDateTooLongTimestamp() { + $this->getLang()->sprintfDate( 'xiY', '123456789012345' ); + } + + /** + * Test too short timestamp + * @expectedException MWException + * @covers Language::sprintfDate + */ + public function testSprintfDateNotAllDigitTimestamp() { + $this->getLang()->sprintfDate( 'xiY', '-1234567890123' ); + } + + /** * @dataProvider provideSprintfDateSamples + * @covers Language::sprintfDate */ - function testSprintfDate( $format, $ts, $expected, $msg ) { + public function testSprintfDate( $format, $ts, $expected, $msg ) { $this->assertEquals( $expected, $this->getLang()->sprintfDate( $format, $ts ), @@ -511,10 +556,11 @@ class LanguageTest extends LanguageClassesTestCase { } /** - * bug 33454. sprintfDate should always use UTC. + * sprintfDate should always use UTC when no zone is given. * @dataProvider provideSprintfDateSamples + * @covers Language::sprintfDate */ - function testSprintfDateTZ( $format, $ts, $expected, $msg ) { + public function testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg ) { $oldTZ = date_default_timezone_get(); $res = date_default_timezone_set( 'Asia/Seoul' ); if ( !$res ) { @@ -530,42 +576,66 @@ class LanguageTest extends LanguageClassesTestCase { date_default_timezone_set( $oldTZ ); } - function provideSprintfDateSamples() { + /** + * sprintfDate should use passed timezone + * @dataProvider provideSprintfDateSamples + * @covers Language::sprintfDate + */ + public function testSprintfDateTZ( $format, $ts, $ignore, $expected, $msg ) { + $tz = new DateTimeZone( 'Asia/Seoul' ); + if ( !$tz ) { + $this->markTestSkipped( "Error getting Timezone" ); + } + + $this->assertEquals( + $expected, + $this->getLang()->sprintfDate( $format, $ts, $tz ), + "sprintfDate('$format', '$ts', 'Asia/Seoul'): $msg" + ); + } + + public static function provideSprintfDateSamples() { return array( array( 'xiY', '20111212000000', '1390', // note because we're testing English locale we get Latin-standard digits + '1390', 'Iranian calendar full year' ), array( 'xiy', '20111212000000', '90', + '90', 'Iranian calendar short year' ), array( 'o', '20120101235000', '2011', + '2011', 'ISO 8601 (week) year' ), array( 'W', '20120101235000', '52', + '52', 'Week number' ), array( 'W', '20120102235000', '1', + '1', 'Week number' ), array( 'o-\\WW-N', '20091231235000', '2009-W53-4', + '2009-W53-4', 'leap week' ), // What follows is mostly copied from http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time @@ -573,252 +643,336 @@ class LanguageTest extends LanguageClassesTestCase { 'Y', '20120102090705', '2012', + '2012', 'Full year' ), array( 'y', '20120102090705', '12', + '12', '2 digit year' ), array( 'L', '20120102090705', '1', + '1', 'Leap year' ), array( 'n', '20120102090705', '1', + '1', 'Month index, not zero pad' ), array( 'N', '20120102090705', '01', + '01', 'Month index. Zero pad' ), array( 'M', '20120102090705', 'Jan', + 'Jan', 'Month abbrev' ), array( 'F', '20120102090705', 'January', + 'January', 'Full month' ), array( 'xg', '20120102090705', 'January', + 'January', 'Genitive month name (same in EN)' ), array( 'j', '20120102090705', '2', + '2', 'Day of month (not zero pad)' ), array( 'd', '20120102090705', '02', + '02', 'Day of month (zero-pad)' ), array( 'z', '20120102090705', '1', + '1', 'Day of year (zero-indexed)' ), array( 'D', '20120102090705', 'Mon', + 'Mon', 'Day of week (abbrev)' ), array( 'l', '20120102090705', 'Monday', + 'Monday', 'Full day of week' ), array( 'N', '20120101090705', '7', + '7', 'Day of week (Mon=1, Sun=7)' ), array( 'w', '20120101090705', '0', + '0', 'Day of week (Sun=0, Sat=6)' ), array( 'N', '20120102090705', '1', + '1', 'Day of week' ), array( 'a', '20120102090705', 'am', + 'am', 'am vs pm' ), array( 'A', '20120102120000', 'PM', + 'PM', 'AM vs PM' ), array( 'a', '20120102000000', 'am', + 'am', 'AM vs PM' ), array( 'g', '20120102090705', '9', + '9', '12 hour, not Zero' ), array( 'h', '20120102090705', '09', + '09', '12 hour, zero padded' ), array( 'G', '20120102090705', '9', + '9', '24 hour, not zero' ), array( 'H', '20120102090705', '09', + '09', '24 hour, zero' ), array( 'H', '20120102110705', '11', + '11', '24 hour, zero' ), array( 'i', '20120102090705', '07', + '07', 'Minutes' ), array( 's', '20120102090705', '05', + '05', 'seconds' ), array( 'U', '20120102090705', '1325495225', + '1325462825', 'unix time' ), array( 't', '20120102090705', '31', + '31', 'Days in current month' ), array( 'c', '20120102090705', '2012-01-02T09:07:05+00:00', + '2012-01-02T09:07:05+09:00', 'ISO 8601 timestamp' ), array( 'r', '20120102090705', 'Mon, 02 Jan 2012 09:07:05 +0000', + 'Mon, 02 Jan 2012 09:07:05 +0900', 'RFC 5322' ), array( + 'e', + '20120102090705', + 'UTC', + 'Asia/Seoul', + 'Timezone identifier' + ), + array( + 'I', + '19880602090705', + '0', + '1', + 'DST indicator' + ), + array( + 'O', + '20120102090705', + '+0000', + '+0900', + 'Timezone offset' + ), + array( + 'P', + '20120102090705', + '+00:00', + '+09:00', + 'Timezone offset with colon' + ), + array( + 'T', + '20120102090705', + 'UTC', + 'KST', + 'Timezone abbreviation' + ), + array( + 'Z', + '20120102090705', + '0', + '32400', + 'Timezone offset in seconds' + ), + array( 'xmj xmF xmn xmY', '20120102090705', '7 Safar 2 1433', + '7 Safar 2 1433', 'Islamic' ), array( 'xij xiF xin xiY', '20120102090705', '12 Dey 10 1390', + '12 Dey 10 1390', 'Iranian' ), array( 'xjj xjF xjn xjY', '20120102090705', '7 Tevet 4 5772', + '7 Tevet 4 5772', 'Hebrew' ), array( 'xjt', '20120102090705', '29', + '29', 'Hebrew number of days in month' ), array( 'xjx', '20120102090705', 'Tevet', + 'Tevet', 'Hebrew genitive month name (No difference in EN)' ), array( 'xkY', '20120102090705', '2555', + '2555', 'Thai year' ), array( 'xoY', '20120102090705', '101', + '101', 'Minguo' ), array( 'xtY', '20120102090705', '平成24', + '平成24', 'nengo' ), array( 'xrxkYY', '20120102090705', 'MMDLV2012', + 'MMDLV2012', 'Roman numerals' ), array( 'xhxjYY', '20120102090705', 'ה\'תשע"ב2012', + 'ה\'תשע"ב2012', 'Hebrew numberals' ), array( 'xnY', '20120102090705', '2012', + '2012', 'Raw numerals (doesn\'t mean much in EN)' ), array( '[[Y "(yea"\\r)]] \\"xx\\"', '20120102090705', '[[2012 (year)]] "x"', + '[[2012 (year)]] "x"', 'Various escaping' ), @@ -827,8 +981,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideFormatSizes + * @covers Language::formatSize */ - function testFormatSize( $size, $expected, $msg ) { + public function testFormatSize( $size, $expected, $msg ) { $this->assertEquals( $expected, $this->getLang()->formatSize( $size ), @@ -836,7 +991,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideFormatSizes() { + public static function provideFormatSizes() { return array( array( 0, @@ -889,8 +1044,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideFormatBitrate + * @covers Language::formatBitrate */ - function testFormatBitrate( $bps, $expected, $msg ) { + public function testFormatBitrate( $bps, $expected, $msg ) { $this->assertEquals( $expected, $this->getLang()->formatBitrate( $bps ), @@ -898,7 +1054,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideFormatBitrate() { + public static function provideFormatBitrate() { return array( array( 0, @@ -961,8 +1117,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideFormatDuration + * @covers Language::formatDuration */ - function testFormatDuration( $duration, $expected, $intervals = array() ) { + public function testFormatDuration( $duration, $expected, $intervals = array() ) { $this->assertEquals( $expected, $this->getLang()->formatDuration( $duration, $intervals ), @@ -970,7 +1127,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideFormatDuration() { + public static function provideFormatDuration() { return array( array( 0, @@ -1097,8 +1254,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideCheckTitleEncodingData + * @covers Language::checkTitleEncoding */ - function testCheckTitleEncoding( $s ) { + public function testCheckTitleEncoding( $s ) { $this->assertEquals( $s, $this->getLang()->checkTitleEncoding( $s ), @@ -1106,7 +1264,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideCheckTitleEncodingData() { + public static function provideCheckTitleEncodingData() { return array( array( "" ), array( "United States of America" ), // 7bit ASCII @@ -1161,8 +1319,9 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideRomanNumeralsData + * @covers Language::romanNumeral */ - function testRomanNumerals( $num, $numerals ) { + public function testRomanNumerals( $num, $numerals ) { $this->assertEquals( $numerals, Language::romanNumeral( $num ), @@ -1170,7 +1329,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideRomanNumeralsData() { + public static function provideRomanNumeralsData() { return array( array( 1, 'I' ), array( 2, 'II' ), @@ -1219,13 +1378,14 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider providePluralData + * @covers Language::convertPlural */ - function testConvertPlural( $expected, $number, $forms ) { + public function testConvertPlural( $expected, $number, $forms ) { $chosen = $this->getLang()->convertPlural( $number, $forms ); $this->assertEquals( $expected, $chosen ); } - function providePluralData() { + public static function providePluralData() { // Params are: [expected text, number given, [the plural forms]] return array( array( 'plural', 0, array( @@ -1255,6 +1415,9 @@ class LanguageTest extends LanguageClassesTestCase { array( 'other', 2, array( 'kissa=kala', '1=2=3', 'other', ) ), + array( '', 2, array( + '0=explicit zero', '1=explicit one', + ) ), ); } @@ -1262,7 +1425,7 @@ class LanguageTest extends LanguageClassesTestCase { * @covers Language::translateBlockExpiry() * @dataProvider provideTranslateBlockExpiry */ - function testTranslateBlockExpiry( $expectedData, $str, $desc ) { + public function testTranslateBlockExpiry( $expectedData, $str, $desc ) { $lang = $this->getLang(); if ( is_array( $expectedData ) ) { list( $func, $arg ) = $expectedData; @@ -1273,7 +1436,7 @@ class LanguageTest extends LanguageClassesTestCase { $this->assertEquals( $expected, $lang->translateBlockExpiry( $str ), $desc ); } - function provideTranslateBlockExpiry() { + public static function provideTranslateBlockExpiry() { return array( array( '2 hours', '2 hours', 'simple data from ipboptions' ), array( 'indefinite', 'infinite', 'infinite from ipboptions' ), @@ -1294,7 +1457,7 @@ class LanguageTest extends LanguageClassesTestCase { * @covers Language::commafy() * @dataProvider provideCommafyData */ - function testCommafy( $number, $numbersWithCommas ) { + public function testCommafy( $number, $numbersWithCommas ) { $this->assertEquals( $numbersWithCommas, $this->getLang()->commafy( $number ), @@ -1302,7 +1465,7 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function provideCommafyData() { + public static function provideCommafyData() { return array( array( 1, '1' ), array( 10, '10' ), @@ -1321,7 +1484,10 @@ class LanguageTest extends LanguageClassesTestCase { ); } - function testListToText() { + /** + * @covers Language::listToText + */ + public function testListToText() { $lang = $this->getLang(); $and = $lang->getMessageFromDB( 'and' ); $s = $lang->getMessageFromDB( 'word-separator' ); @@ -1336,12 +1502,13 @@ class LanguageTest extends LanguageClassesTestCase { /** * @dataProvider provideIsSupportedLanguage + * @covers Language::isSupportedLanguage */ - function testIsSupportedLanguage( $code, $expected, $comment ) { + public function testIsSupportedLanguage( $code, $expected, $comment ) { $this->assertEquals( $expected, Language::isSupportedLanguage( $code ), $comment ); } - static function provideIsSupportedLanguage() { + public static function provideIsSupportedLanguage() { return array( array( 'en', true, 'is supported language' ), array( 'fi', true, 'is supported language' ), @@ -1349,4 +1516,52 @@ class LanguageTest extends LanguageClassesTestCase { array( 'FI', false, 'is not supported language, input should be in lower case' ), ); } + + /** + * @dataProvider provideGetParentLanguage + * @covers Language::getParentLanguage + */ + public function testGetParentLanguage( $code, $expected, $comment ) { + $lang = Language::factory( $code ); + if ( is_null( $expected ) ) { + $this->assertNull( $lang->getParentLanguage(), $comment ); + } else { + $this->assertEquals( $expected, $lang->getParentLanguage()->getCode(), $comment ); + } + } + + public static function provideGetParentLanguage() { + return array( + array( 'zh-cn', 'zh', 'zh is the parent language of zh-cn' ), + array( 'zh', 'zh', 'zh is defined as the parent language of zh, because zh converter can convert zh-cn to zh' ), + array( 'zh-invalid', null, 'do not be fooled by arbitrarily composed language codes' ), + array( 'en-gb', null, 'en does not have converter' ), + array( 'en', null, 'en does not have converter. Although FakeConverter handles en -> en conversion but it is useless' ), + ); + } + + /** + * @dataProvider provideGetNamespaceAliases + * @covers Language::getNamespaceAliases + */ + public function testGetNamespaceAliases( $languageCode, $subset ) { + $language = Language::factory( $languageCode ); + $aliases = $language->getNamespaceAliases(); + foreach ( $subset as $alias => $nsId ) { + $this->assertEquals( $nsId, $aliases[$alias] ); + } + } + + public static function provideGetNamespaceAliases() { + // TODO: Add tests for NS_PROJECT_TALK and GenderNamespaces + return array( + array( + 'zh', + array( + '文件' => NS_FILE, + '檔案' => NS_FILE, + ), + ), + ); + } } diff --git a/tests/phpunit/languages/LanguageTiTest.php b/tests/phpunit/languages/LanguageTiTest.php index 8af0eee2..e225af97 100644 --- a/tests/phpunit/languages/LanguageTiTest.php +++ b/tests/phpunit/languages/LanguageTiTest.php @@ -7,18 +7,28 @@ /** Tests for MediaWiki languages/classes/LanguageTi.php */ class LanguageTiTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'other', 2 ), ); } } diff --git a/tests/phpunit/languages/LanguageTlTest.php b/tests/phpunit/languages/LanguageTlTest.php index abd8581a..7ac51c69 100644 --- a/tests/phpunit/languages/LanguageTlTest.php +++ b/tests/phpunit/languages/LanguageTlTest.php @@ -7,18 +7,28 @@ /** Tests for MediaWiki languages/classes/LanguageTl.php */ class LanguageTlTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'other', 2 ), ); } } diff --git a/tests/phpunit/languages/LanguageTrTest.php b/tests/phpunit/languages/LanguageTrTest.php index e93d49d9..8fc2795c 100644 --- a/tests/phpunit/languages/LanguageTrTest.php +++ b/tests/phpunit/languages/LanguageTrTest.php @@ -17,7 +17,7 @@ class LanguageTrTest extends LanguageClassesTestCase { * @see http://en.wikipedia.org/wiki/Dotted_and_dotless_I * @dataProvider provideDottedAndDotlessI */ - function testDottedAndDotlessI( $func, $input, $inputCase, $expected ) { + public function testDottedAndDotlessI( $func, $input, $inputCase, $expected ) { if ( $func == 'ucfirst' ) { $res = $this->getLang()->ucfirst( $input ); } elseif ( $func == 'lcfirst' ) { @@ -31,7 +31,7 @@ class LanguageTrTest extends LanguageClassesTestCase { $this->assertEquals( $expected, $res, $msg ); } - function provideDottedAndDotlessI() { + public static function provideDottedAndDotlessI() { return array( # function, input, input case, expected # Case changed: @@ -56,5 +56,4 @@ class LanguageTrTest extends LanguageClassesTestCase { ); } - } diff --git a/tests/phpunit/languages/LanguageUkTest.php b/tests/phpunit/languages/LanguageUkTest.php index 9bbfaf66..0783fcf6 100644 --- a/tests/phpunit/languages/LanguageUkTest.php +++ b/tests/phpunit/languages/LanguageUkTest.php @@ -8,14 +8,24 @@ /** Tests for MediaWiki languages/classes/LanguageUk.php */ class LanguageUkTest extends LanguageClassesTestCase { - - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { $forms = array( 'one', 'few', 'many', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralFourForms() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 1 ), array( 'many', 11 ), @@ -31,18 +41,21 @@ class LanguageUkTest extends LanguageClassesTestCase { ); } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); + /** + * @dataProvider providePluralTwoForms + * @covers Language::convertPlural + */ + public function testPluralTwoForms( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providePluralTwoForms() { + public static function providePluralTwoForms() { return array( array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), + array( 'other', 11 ), + array( 'other', 91 ), + array( 'other', 121 ), ); } } diff --git a/tests/phpunit/languages/LanguageUzTest.php b/tests/phpunit/languages/LanguageUzTest.php index 495c0be6..13f57c16 100644 --- a/tests/phpunit/languages/LanguageUzTest.php +++ b/tests/phpunit/languages/LanguageUzTest.php @@ -10,17 +10,20 @@ * @copyright Copyright © 2012, Robin Pepermans * @copyright Copyright © 2011, Antoine Musso <hashar at free dot fr> * @file + * + * @todo methods in test class should be tidied: + * - Should be split into separate test methods and data providers + * - Tests for LanguageConverter and Language should probably be separate.. */ -require_once dirname( __DIR__ ) . '/bootstrap.php'; - /** Tests for MediaWiki languages/LanguageUz.php */ class LanguageUzTest extends LanguageClassesTestCase { /** * @author Nikola Smolenski + * @covers LanguageConverter::convertTo */ - function testConversionToCyrillic() { + public function testConversionToCyrillic() { // A convertion of Latin to Cyrillic $this->assertEquals( 'абвгғ', $this->convertToCyrillic( 'abvggʻ' ) @@ -39,7 +42,10 @@ class LanguageUzTest extends LanguageClassesTestCase { ); } - function testConversionToLatin() { + /** + * @covers LanguageConverter::convertTo + */ + public function testConversionToLatin() { // A simple convertion of Latin to Latin $this->assertEquals( 'abdef', $this->convertToLatin( 'abdef' ) @@ -57,7 +63,7 @@ class LanguageUzTest extends LanguageClassesTestCase { * @param $variant string Language variant 'uz-cyrl' or 'uz-latn' * @param $msg string Optional message */ - function assertUnConverted( $text, $variant, $msg = '' ) { + protected function assertUnConverted( $text, $variant, $msg = '' ) { $this->assertEquals( $text, $this->convertTo( $text, $variant ), @@ -71,7 +77,7 @@ class LanguageUzTest extends LanguageClassesTestCase { * @param $variant string Language variant 'uz-cyrl' or 'uz-latn' * @param $msg string Optional message */ - function assertConverted( $text, $variant, $msg = '' ) { + protected function assertConverted( $text, $variant, $msg = '' ) { $this->assertNotEquals( $text, $this->convertTo( $text, $variant ), @@ -84,7 +90,7 @@ class LanguageUzTest extends LanguageClassesTestCase { * using the cyrillic variant and converted to Latin when using * the Latin variant. */ - function assertCyrillic( $text, $msg = '' ) { + protected function assertCyrillic( $text, $msg = '' ) { $this->assertUnConverted( $text, 'uz-cyrl', $msg ); $this->assertConverted( $text, 'uz-latn', $msg ); } @@ -94,22 +100,22 @@ class LanguageUzTest extends LanguageClassesTestCase { * using the Latin variant and converted to Cyrillic when using * the Cyrillic variant. */ - function assertLatin( $text, $msg = '' ) { + protected function assertLatin( $text, $msg = '' ) { $this->assertUnConverted( $text, 'uz-latn', $msg ); $this->assertConverted( $text, 'uz-cyrl', $msg ); } /** Wrapper for converter::convertTo() method*/ - function convertTo( $text, $variant ) { + protected function convertTo( $text, $variant ) { return $this->getLang()->mConverter->convertTo( $text, $variant ); } - function convertToCyrillic( $text ) { + protected function convertToCyrillic( $text ) { return $this->convertTo( $text, 'uz-cyrl' ); } - function convertToLatin( $text ) { + protected function convertToLatin( $text ) { return $this->convertTo( $text, 'uz-latn' ); } } diff --git a/tests/phpunit/languages/LanguageWaTest.php b/tests/phpunit/languages/LanguageWaTest.php index 28329fa3..d05196c0 100644 --- a/tests/phpunit/languages/LanguageWaTest.php +++ b/tests/phpunit/languages/LanguageWaTest.php @@ -7,18 +7,28 @@ /** Tests for MediaWiki languages/classes/LanguageWa.php */ class LanguageWaTest extends LanguageClassesTestCase { - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); + /** + * @dataProvider providePlural + * @covers Language::convertPlural + */ + public function testPlural( $result, $value ) { + $forms = array( 'one', 'other' ); $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) ); } - function providerPlural() { + /** + * @dataProvider providePlural + * @covers Language::getPluralRuleType + */ + public function testGetPluralRuleType( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->getPluralRuleType( $value ) ); + } + + public static function providePlural() { return array( array( 'one', 0 ), array( 'one', 1 ), - array( 'many', 2 ), + array( 'other', 2 ), ); } } diff --git a/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php b/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php index 73d5dcc0..3bf74146 100644 --- a/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php +++ b/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php @@ -89,7 +89,7 @@ class CLDRPluralRuleEvaluatorTest extends MediaWikiTestCase { array( 'n', 'just n' ), array( 'n is in 5', 'is in' ), ); + return $tests; } - } diff --git a/tests/phpunit/maintenance/DumpTestCase.php b/tests/phpunit/maintenance/DumpTestCase.php index 40d24fc5..83d8c71d 100644 --- a/tests/phpunit/maintenance/DumpTestCase.php +++ b/tests/phpunit/maintenance/DumpTestCase.php @@ -60,11 +60,14 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { if ( $gzipped_contents === false ) { $this->fail( "Could not get contents of $fname" ); } - // We resort to use gzinflate instead of gzdecode, as gzdecode - // need not be available - $contents = gzinflate( substr( $gzipped_contents, 10, -8 ) ); - $this->assertEquals( strlen( $contents ), - file_put_contents( $fname, $contents ), "# bytes written" ); + + $contents = gzdecode( $gzipped_contents ); + + $this->assertEquals( + strlen( $contents ), + file_put_contents( $fname, $contents ), + '# bytes written' + ); } /** @@ -73,8 +76,6 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { * Clears $wgUser, and reports errors from addDBData to PHPUnit */ protected function setUp() { - global $wgUser; - parent::setUp(); // Check if any Exception is stored for rethrowing from addDBData @@ -83,7 +84,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { throw $this->exceptionFromAddDBData; } - $wgUser = new User(); + $this->setMwGlobals( 'wgUser', new User() ); } /** @@ -116,7 +117,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { * @param $name string: name of the closing element to look for * (e.g.: "mediawiki" when looking for </mediawiki>) * - * @return bool: true iff the end node could be found. false otherwise. + * @return bool: true if the end node could be found. false otherwise. */ protected function skipToNodeEnd( $name ) { while ( $this->xml->read() ) { @@ -126,6 +127,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { return true; } } + return false; } @@ -147,6 +149,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { return true; } } + return false; } @@ -273,7 +276,6 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { $this->assertTextNode( "title", $name ); $this->assertTextNode( "ns", $ns ); $this->assertTextNode( "id", $id ); - } /** @@ -301,8 +303,8 @@ abstract class DumpTestCase extends MediaWikiLangTestCase { * @param $parentid int|false: (optional) id of the parent revision */ protected function assertRevision( $id, $summary, $text_id, $text_bytes, $text_sha1, $text = false, $parentid = false, - $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT ) { - + $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT + ) { $this->assertNodeStart( "revision" ); $this->skipWhitespace(); diff --git a/tests/phpunit/maintenance/MaintenanceTest.php b/tests/phpunit/maintenance/MaintenanceTest.php index 741f8b7f..318ce0da 100644 --- a/tests/phpunit/maintenance/MaintenanceTest.php +++ b/tests/phpunit/maintenance/MaintenanceTest.php @@ -43,7 +43,7 @@ class MaintenanceFixup extends Maintenance { private $testCase; /** - * shutdownSimulated === true iff simulateShutdown has done it's work + * shutdownSimulated === true if simulateShutdown has done it's work * * @var bool */ @@ -128,7 +128,6 @@ class MaintenanceFixup extends Maintenance { public function execute() { $this->testCase->fail( __METHOD__ . " called unexpectedly" ); } - } class MaintenanceTest extends MediaWikiTestCase { @@ -186,7 +185,6 @@ class MaintenanceTest extends MediaWikiTestCase { // test.*Intermittent.* tests), the objective of these tests is not to describe // consistent behavior, but rather currently existing behavior. - function testOutputEmpty() { $this->m->output( "" ); $this->assertOutputPrePostShutdown( "", false ); @@ -815,6 +813,4 @@ class MaintenanceTest extends MediaWikiTestCase { $m2->simulateShutdown(); $this->assertOutputPrePostShutdown( "foobar\n\n", false ); } - - } diff --git a/tests/phpunit/maintenance/backupPrefetchTest.php b/tests/phpunit/maintenance/backupPrefetchTest.php index cc00e6e5..bc2d7375 100644 --- a/tests/phpunit/maintenance/backupPrefetchTest.php +++ b/tests/phpunit/maintenance/backupPrefetchTest.php @@ -36,7 +36,6 @@ class BaseDumpTest extends MediaWikiTestCase { private function assertPrefetchEquals( $expected, $page, $revision ) { $this->assertEquals( $expected, $this->dump->prefetch( $page, $revision ), "Prefetch of page $page revision $revision" ); - } function testSequential() { @@ -181,7 +180,6 @@ class BaseDumpTest extends MediaWikiTestCase { </siteinfo> '; - // An array holding the pages that are available for prefetch $available_pages = array(); @@ -274,5 +272,4 @@ class BaseDumpTest extends MediaWikiTestCase { return $fname; } - } diff --git a/tests/phpunit/maintenance/backupTextPassTest.php b/tests/phpunit/maintenance/backupTextPassTest.php index 09623445..653a1145 100644 --- a/tests/phpunit/maintenance/backupTextPassTest.php +++ b/tests/phpunit/maintenance/backupTextPassTest.php @@ -63,7 +63,7 @@ class TextPassDumperTest extends DumpTestCase { // Page from non-default namespace if ( $ns === NS_TALK ) { - //@todo: work around this. + // @todo work around this. throw new MWException( "The default wikitext namespace is the talk namespace. " . " We can't currently deal with that." ); } @@ -80,7 +80,6 @@ class TextPassDumperTest extends DumpTestCase { // DumpTestCase $this->exceptionFromAddDBData = $e; } - } protected function setUp() { @@ -94,7 +93,6 @@ class TextPassDumperTest extends DumpTestCase { array( $this->pageId2, $this->pageId3, $this->pageId4 ), array( $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ), "Page ids increasing without holes" ); - } function testPlain() { @@ -214,7 +212,6 @@ class TextPassDumperTest extends DumpTestCase { $this->assertPageEnd(); $this->assertDumpEnd(); - } /** @@ -239,7 +236,6 @@ class TextPassDumperTest extends DumpTestCase { $minDuration = 2; // We want the dump to take at least this many seconds $checkpointAfter = 0.5; // Generate checkpoint after this many seconds - // Until a dump takes at least $minDuration seconds, perform a dump and check // duration. If the dump did not take long enough increase the iteration // count, to generate a bigger stub file next time. @@ -579,6 +575,7 @@ class TextPassDumperTest extends DumpTestCase { $content .= $tail; $this->assertEquals( strlen( $content ), file_put_contents( $fname, $content ), "Length of prepared stub" ); + return $fname; } } diff --git a/tests/phpunit/maintenance/backup_LogTest.php b/tests/phpunit/maintenance/backup_LogTest.php index 5cf172e6..98d81653 100644 --- a/tests/phpunit/maintenance/backup_LogTest.php +++ b/tests/phpunit/maintenance/backup_LogTest.php @@ -39,6 +39,7 @@ class BackupDumperLoggerTest extends DumpTestCase { if ( $parameters !== null ) { $logEntry->setParameters( $parameters ); } + return $logEntry->insert(); } @@ -75,14 +76,12 @@ class BackupDumperLoggerTest extends DumpTestCase { $user2, NS_MAIN, "PageA", "SomeOtherComment", array( 'key1' => 1, 3 => 'value3' ) ); $this->assertGreaterThan( 0, $this->logId3 ); - } catch ( Exception $e ) { // We'd love to pass $e directly. However, ... see // documentation of exceptionFromAddDBData in // DumpTestCase $this->exceptionFromAddDBData = $e; } - } @@ -226,5 +225,4 @@ class BackupDumperLoggerTest extends DumpTestCase { // the following statement to catch good output $this->expectOutputString( '' ); } - } diff --git a/tests/phpunit/maintenance/backup_PageTest.php b/tests/phpunit/maintenance/backup_PageTest.php index 07c76705..99bd2700 100644 --- a/tests/phpunit/maintenance/backup_PageTest.php +++ b/tests/phpunit/maintenance/backup_PageTest.php @@ -34,7 +34,7 @@ class BackupDumperPageTest extends DumpTestCase { $this->talk_namespace = NS_TALK; if ( $this->namespace === $this->talk_namespace ) { - //@todo: work around this. + // @todo work around this. throw new MWException( "The default wikitext namespace is the talk namespace. " . " We can't currently deal with that." ); } @@ -79,7 +79,6 @@ class BackupDumperPageTest extends DumpTestCase { // DumpTestCase $this->exceptionFromAddDBData = $e; } - } protected function setUp() { @@ -93,7 +92,6 @@ class BackupDumperPageTest extends DumpTestCase { array( $this->pageId2, $this->pageId3, $this->pageId4 ), array( $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ), "Page ids increasing without holes" ); - } function testFullTextPlain() { @@ -403,6 +401,4 @@ class BackupDumperPageTest extends DumpTestCase { $this->expectETAOutput(); } - - } diff --git a/tests/phpunit/maintenance/fetchTextTest.php b/tests/phpunit/maintenance/fetchTextTest.php index 4d1d45d6..e8df199e 100644 --- a/tests/phpunit/maintenance/fetchTextTest.php +++ b/tests/phpunit/maintenance/fetchTextTest.php @@ -63,7 +63,6 @@ class SemiMockedFetchText extends FetchText { return fopen( 'data://text/plain,' . $this->mockStdinText, 'r' ); } - } /** @@ -236,5 +235,4 @@ class FetchTextTest extends MediaWikiTestCase { $this->textId3 . "\n23\nFetchTextTestPage2Text2" ) ) ); } - } diff --git a/tests/phpunit/maintenance/getSlaveServerTest.php b/tests/phpunit/maintenance/getSlaveServerTest.php index 699571b7..2c848862 100644 --- a/tests/phpunit/maintenance/getSlaveServerTest.php +++ b/tests/phpunit/maintenance/getSlaveServerTest.php @@ -64,6 +64,4 @@ class GetSlaveServerTest extends MediaWikiTestCase { $this->expectOutputRegex( "/^[[:space:]]*\[wgDBprefix\][[:space:]]*=> " . $wgDBprefix . "$/m" ); } - - } diff --git a/tests/phpunit/mocks/filebackend/MockFSFile.php b/tests/phpunit/mocks/filebackend/MockFSFile.php new file mode 100644 index 00000000..e0463281 --- /dev/null +++ b/tests/phpunit/mocks/filebackend/MockFSFile.php @@ -0,0 +1,69 @@ +<?php +/** + * Mock of a filesystem file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup FileBackend + */ + +/** + * Class representing an in memory fake file. + * This is intended for unit testing / developement when you do not want + * to hit the filesystem. + * + * It reimplements abstract methods with some hardcoded values. Might + * not be suitable for all tests but is good enough for the parser tests. + * + * @ingroup FileBackend + */ +class MockFSFile extends FSFile { + protected $sha1Base36 = null; // File Sha1Base36 + + public function exists() { + return true; + } + + /** + * August 22 – The theft of the Mona Lisa is discovered in the Louvre." + * @bug 20281 + */ + public function getSize() { + return 1911; + } + + public function getTimestamp() { + return wfTimestamp( TS_MW ); + } + + public function getMimeType() { + return 'text/mock'; + } + + public function getProps( $ext = true ) { + return array( + 'fileExists' => $this->exists(), + 'size' => $this->getSize(), + 'file-mime' => $this->getMimeType(), + 'sha1' => $this->getSha1Base36(), + ); + } + + public function getSha1Base36( $recache = false ) { + return '1234567890123456789012345678901'; + } +} diff --git a/tests/phpunit/mocks/filebackend/MockFileBackend.php b/tests/phpunit/mocks/filebackend/MockFileBackend.php new file mode 100644 index 00000000..49aefbd1 --- /dev/null +++ b/tests/phpunit/mocks/filebackend/MockFileBackend.php @@ -0,0 +1,122 @@ +<?php +/** + * Simulation (mock) of a backend storage. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup FileBackend + * @author Antoine Musso <hashar@free.fr> + */ + +/** + * Class simulating a backend store. + * + * @ingroup FileBackend + * @since 1.22 + */ +class MockFileBackend extends FileBackendStore { + + protected $mocked = array(); + + /** Poor man debugging */ + protected function debug( $msg = '' ) { + wfDebug( wfGetCaller() . "$msg\n" ); + } + + public function isPathUsableInternal( $storagePath ) { + return true; + } + + protected function doCreateInternal( array $params ) { + if ( isset( $params['content'] ) ) { + $content = $params['content']; + } else { + $content = 'Default mocked file content'; + } + $this->debug( serialize( $params ) ); + $dst = $params['dst']; + $this->mocked[$dst] = $content; + return Status::newGood(); + } + + protected function doStoreInternal( array $params ) { + $this->debug( serialize( $params ) ); + return $this->doCreateInternal( $params ); + } + + protected function doCopyInternal( array $params ) { + $this->debug( serialize( $params ) ); + $src = $params['src']; + $dst = $params['dst']; + $this->mocked[$dst] = $this->mocked[$src]; + return Status::newGood(); + } + + protected function doDeleteInternal( array $params ) { + $this->debug( serialize( $params ) ); + $src = $params['src']; + unset( $this->mocked[$src] ); + return Status::newGood(); + } + + protected function doGetFileStat( array $params ) { + $src = $params['src']; + if ( array_key_exists( $src, $this->mocked ) ) { + $this->debug( "('$src') found" ); + return array( + 'mtime' => wfTimestamp( TS_MW ), + 'size' => strlen( $this->mocked[$src] ), + # No sha1, stat does not need it. + ); + } else { + $this->debug( "('$src') not found" ); + return false; + } + } + + protected function doGetLocalCopyMulti( array $params ) { + $tmpFiles = array(); // (path => MockFSFile) + + $this->debug( '(' . serialize( $params ) . ')' ); + foreach ( $params['srcs'] as $src ) { + $tmpFiles[$src] = new MockFSFile( + wfTempDir() . '/' . wfRandomString( 32 ) + ); + } + return $tmpFiles; + } + + protected function doDirectoryExists( $container, $dir, array $params ) { + $this->debug(); + return true; + } + + public function getDirectoryListInternal( $container, $dir, array $params ) { + $this->debug(); + return array(); + } + + public function getFileListInternal( $container, $dir, array $params ) { + $this->debug(); + return array(); + } + + protected function directoriesAreVirtual() { + $this->debug(); + return true; + } +} diff --git a/tests/phpunit/mocks/media/MockBitmapHandler.php b/tests/phpunit/mocks/media/MockBitmapHandler.php new file mode 100644 index 00000000..742b41e4 --- /dev/null +++ b/tests/phpunit/mocks/media/MockBitmapHandler.php @@ -0,0 +1,92 @@ +<?php +/** + * Fake handler for images. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup Media + */ + +class MockBitmapHandler extends BitmapHandler { + function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) { + return MockImageHandler::doFakeTransform( $this, $image, $dstPath, $dstUrl, $params, $flags ); + } + function doClientImage( $image, $scalerParams ) { + return $this->getClientScalingThumbnailImage( $image, $scalerParams ); + } +} +class MockSvgHandler extends SvgHandler { + function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) { + return MockImageHandler::doFakeTransform( $this, $image, $dstPath, $dstUrl, $params, $flags ); + } +} +/** + * Mock handler for images. + * + * This is really intended for unit testing. + * + * @ingroup Media + */ +class MockImageHandler { + + /** + * Override BitmapHandler::doTransform() making sure we do not generate + * a thumbnail at all. That is merely returning a ThumbnailImage that + * will be consumed by the unit test. There is no need to create a real + * thumbnail on the filesystem. + */ + static function doFakeTransform( $that, $image, $dstPath, $dstUrl, $params, $flags = 0 ) { + # Example of what we receive: + # $image: LocalFile + # $dstPath: /tmp/transform_7d0a7a2f1a09-1.jpg + # $dstUrl : http://example.com/images/thumb/0/09/Bad.jpg/320px-Bad.jpg + # $params: width: 320, descriptionUrl http://trunk.dev/wiki/File:Bad.jpg + + $that->normaliseParams( $image, $params ); + + $scalerParams = array( + # The size to which the image will be resized + 'physicalWidth' => $params['physicalWidth'], + 'physicalHeight' => $params['physicalHeight'], + 'physicalDimensions' => "{$params['physicalWidth']}x{$params['physicalHeight']}", + # The size of the image on the page + 'clientWidth' => $params['width'], + 'clientHeight' => $params['height'], + # Comment as will be added to the EXIF of the thumbnail + 'comment' => isset( $params['descriptionUrl'] ) ? + "File source: {$params['descriptionUrl']}" : '', + # Properties of the original image + 'srcWidth' => $image->getWidth(), + 'srcHeight' => $image->getHeight(), + 'mimeType' => $image->getMimeType(), + 'dstPath' => $dstPath, + 'dstUrl' => $dstUrl, + ); + + # In some cases, we do not bother generating a thumbnail. + if ( !$image->mustRender() && + $scalerParams['physicalWidth'] == $scalerParams['srcWidth'] + && $scalerParams['physicalHeight'] == $scalerParams['srcHeight'] + ) { + wfDebug( __METHOD__ . ": returning unscaled image\n" ); + // getClientScalingThumbnailImage is protected + return $that->doClientImage( $image, $scalerParams ); + } + + return new ThumbnailImage( $image, $dstUrl, false, $params ); + } +} diff --git a/tests/phpunit/phpunit.php b/tests/phpunit/phpunit.php index 2ec07440..1d65e521 100644 --- a/tests/phpunit/phpunit.php +++ b/tests/phpunit/phpunit.php @@ -12,7 +12,7 @@ define( 'MW_PHPUNIT_TEST', true ); // Start up MediaWiki in command-line mode -require_once( dirname( dirname( __DIR__ ) ) . "/maintenance/Maintenance.php" ); +require_once dirname( dirname( __DIR__ ) ) . "/maintenance/Maintenance.php"; class PHPUnitMaintClass extends Maintenance { @@ -33,6 +33,9 @@ class PHPUnitMaintClass extends Maintenance { global $wgLocaltimezone, $wgLocalisationCacheConf; global $wgDevelopmentWarnings; + // Inject test autoloader + require_once __DIR__ . '/../TestsAutoLoader.php'; + // wfWarn should cause tests to fail $wgDevelopmentWarnings = true; @@ -50,8 +53,11 @@ class PHPUnitMaintClass extends Maintenance { // Bug 44192 Do not attempt to send a real e-mail Hooks::clear( 'AlternateUserMailer' ); - Hooks::register( 'AlternateUserMailer', - function() { return false; } + Hooks::register( + 'AlternateUserMailer', + function () { + return false; + } ); } @@ -86,7 +92,6 @@ class PHPUnitMaintClass extends Maintenance { unset( $_SERVER['argv'][$key] ); // the option unset( $_SERVER['argv'][$key + 1] ); // its value $_SERVER['argv'] = array_values( $_SERVER['argv'] ); - } } @@ -96,16 +101,19 @@ class PHPUnitMaintClass extends Maintenance { } $maintClass = 'PHPUnitMaintClass'; -require( RUN_MAINTENANCE_IF_MAIN ); +require RUN_MAINTENANCE_IF_MAIN; -require_once( 'PHPUnit/Runner/Version.php' ); +if ( !class_exists( 'PHPUnit_Runner_Version' ) ) { + require_once 'PHPUnit/Runner/Version.php'; +} if ( PHPUnit_Runner_Version::id() !== '@package_version@' && version_compare( PHPUnit_Runner_Version::id(), '3.6.7', '<' ) ) { die( 'PHPUnit 3.6.7 or later required, you have ' . PHPUnit_Runner_Version::id() . ".\n" ); } -require_once( 'PHPUnit/Autoload.php' ); -require_once( "$IP/tests/TestsAutoLoader.php" ); +if ( !class_exists( 'PHPUnit_TextUI_Command' ) ) { + require_once 'PHPUnit/Autoload.php'; +} MediaWikiPHPUnitCommand::main(); diff --git a/tests/phpunit/skins/SideBarTest.php b/tests/phpunit/skins/SideBarTest.php index 3902b686..a385320f 100644 --- a/tests/phpunit/skins/SideBarTest.php +++ b/tests/phpunit/skins/SideBarTest.php @@ -5,7 +5,10 @@ */ class SideBarTest extends MediaWikiLangTestCase { - /** A skin template, reinitialized before each test */ + /** + * A skin template, reinitialized before each test + * @var SkinTemplate + */ private $skin; /** Local cache for sidebar messages */ private $messages; @@ -36,16 +39,12 @@ class SideBarTest extends MediaWikiLangTestCase { $this->skin->getContext()->setLanguage( Language::factory( 'en' ) ); } - protected function tearDown() { - parent::tearDown(); - $this->skin = null; - } - /** * Internal helper to test the sidebar * @param $expected * @param $text * @param $message (Default: '') + * @todo this assert method to should be converted to a test using a dataprovider.. */ private function assertSideBar( $expected, $text, $message = '' ) { $bar = array(); @@ -53,7 +52,10 @@ class SideBarTest extends MediaWikiLangTestCase { $this->assertEquals( $expected, $bar, $message ); } - function testSidebarWithOnlyTwoTitles() { + /** + * @covers SkinTemplate::addToSidebarPlain + */ + public function testSidebarWithOnlyTwoTitles() { $this->assertSideBar( array( 'Title1' => array(), @@ -65,7 +67,10 @@ class SideBarTest extends MediaWikiLangTestCase { ); } - function testExpandMessages() { + /** + * @covers SkinTemplate::addToSidebarPlain + */ + public function testExpandMessages() { $this->assertSidebar( array( 'Title' => array( array( @@ -81,7 +86,10 @@ class SideBarTest extends MediaWikiLangTestCase { ); } - function testExternalUrlsRequireADescription() { + /** + * @covers SkinTemplate::addToSidebarPlain + */ + public function testExternalUrlsRequireADescription() { $this->assertSidebar( array( 'Title' => array( # ** http://www.mediawiki.org/| Home @@ -100,14 +108,14 @@ class SideBarTest extends MediaWikiLangTestCase { ** http://valid.no.desc.org/ ' ); - } /** * bug 33321 - Make sure there's a | after transforming. * @group Database + * @covers SkinTemplate::addToSidebarPlain */ - function testTrickyPipe() { + public function testTrickyPipe() { $this->assertSidebar( array( 'Title' => array( # The first 2 are skipped @@ -116,13 +124,13 @@ class SideBarTest extends MediaWikiLangTestCase { # ** Baz|Fred array( 'text' => 'Fred', - 'href' => Title::newFromText( 'Baz' )->getLocalUrl(), + 'href' => Title::newFromText( 'Baz' )->getLocalURL(), 'id' => 'n-Fred', 'active' => null, ), array( 'text' => 'title-to-display', - 'href' => Title::newFromText( 'page-to-go-to' )->getLocalUrl(), + 'href' => Title::newFromText( 'page-to-go-to' )->getLocalURL(), 'id' => 'n-title-to-display', 'active' => null, ), @@ -151,11 +159,12 @@ class SideBarTest extends MediaWikiLangTestCase { /** * Simple test to verify our helper assertAttribs() is functional - * Please note this assume MediaWiki default settings: - * $wgNoFollowLinks = true - * $wgExternalLinkTarget = false */ - function testTestAttributesAssertionHelper() { + public function testTestAttributesAssertionHelper() { + $this->setMwGlobals( array( + 'wgNoFollowLinks' => true, + 'wgExternalLinkTarget' => false, + ) ); $attribs = $this->getAttribs(); $this->assertArrayHasKey( 'rel', $attribs ); @@ -167,39 +176,31 @@ class SideBarTest extends MediaWikiLangTestCase { /** * Test $wgNoFollowLinks in sidebar */ - function testRespectWgnofollowlinks() { - global $wgNoFollowLinks; - $saved = $wgNoFollowLinks; - $wgNoFollowLinks = false; + public function testRespectWgnofollowlinks() { + $this->setMwGlobals( 'wgNoFollowLinks', false ); $attribs = $this->getAttribs(); $this->assertArrayNotHasKey( 'rel', $attribs, 'External URL in sidebar do not have rel=nofollow when $wgNoFollowLinks = false' ); - - // Restore global - $wgNoFollowLinks = $saved; } /** * Test $wgExternaLinkTarget in sidebar + * @dataProvider dataRespectExternallinktarget */ - function testRespectExternallinktarget() { - global $wgExternalLinkTarget; - $saved = $wgExternalLinkTarget; + public function testRespectExternallinktarget( $externalLinkTarget ) { + $this->setMwGlobals( 'wgExternalLinkTarget', $externalLinkTarget ); - $wgExternalLinkTarget = '_blank'; $attribs = $this->getAttribs(); $this->assertArrayHasKey( 'target', $attribs ); - $this->assertEquals( $attribs['target'], '_blank' ); - - $wgExternalLinkTarget = '_self'; - $attribs = $this->getAttribs(); - $this->assertArrayHasKey( 'target', $attribs ); - $this->assertEquals( $attribs['target'], '_self' ); - - // Restore global - $wgExternalLinkTarget = $saved; + $this->assertEquals( $attribs['target'], $externalLinkTarget ); } + public static function dataRespectExternallinktarget() { + return array( + array( '_blank' ), + array( '_self' ), + ); + } } diff --git a/tests/phpunit/AutoLoaderTest.php b/tests/phpunit/structure/AutoLoaderTest.php index c8f38685..205ea360 100644 --- a/tests/phpunit/AutoLoaderTest.php +++ b/tests/phpunit/structure/AutoLoaderTest.php @@ -1,6 +1,12 @@ <?php class AutoLoaderTest extends MediaWikiTestCase { + /** + * Assert that there were no classes loaded that are not registered with the AutoLoader. + * + * For example foo.php having class Foo and class Bar but only registering Foo. + * This is important because we should not be relying on Foo being used before Bar. + */ public function testAutoLoadConfig() { $results = self::checkAutoLoadConf(); @@ -12,7 +18,6 @@ class AutoLoaderTest extends MediaWikiTestCase { protected static function checkAutoLoadConf() { global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP; - static $supportsParsekit; $supportsParsekit = function_exists( 'parsekit_compile_file' ); // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php diff --git a/tests/phpunit/resources/ResourcesTest.php b/tests/phpunit/structure/ResourcesTest.php index 71b8c676..fe823fa4 100644 --- a/tests/phpunit/resources/ResourcesTest.php +++ b/tests/phpunit/structure/ResourcesTest.php @@ -3,10 +3,15 @@ * Sanity checks for making sure registered resources are sane. * * @file - * @author Niklas Laxström, 2012 - * @author Antoine Musso, 2012 - * @author Santhosh Thottingal, 2012 - * @author Timo Tijhof, 2012 + * @author Antoine Musso + * @author Niklas Laxström + * @author Santhosh Thottingal + * @author Timo Tijhof + * @copyright © 2012, Antoine Musso + * @copyright © 2012, Niklas Laxström + * @copyright © 2012, Santhosh Thottingal + * @copyright © 2012, Timo Tijhof + * * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later */ class ResourcesTest extends MediaWikiTestCase { @@ -91,7 +96,7 @@ class ResourcesTest extends MediaWikiTestCase { $property = $reflectedModule->getProperty( $propName ); $property->setAccessible( true ); $lists = $property->getValue( $module ); - foreach ( $lists as $group => $list ) { + foreach ( $lists as $list ) { foreach ( $list as $key => $value ) { // We need the same filter as for 'lists', // due to 'skinStyles'. @@ -116,7 +121,6 @@ class ResourcesTest extends MediaWikiTestCase { $file, ); } - } // Restore settings @@ -124,5 +128,4 @@ class ResourcesTest extends MediaWikiTestCase { return $cases; } - } diff --git a/tests/phpunit/StructureTest.php b/tests/phpunit/structure/StructureTest.php index a9420981..df00d4df 100644 --- a/tests/phpunit/StructureTest.php +++ b/tests/phpunit/structure/StructureTest.php @@ -14,7 +14,7 @@ class StructureTest extends MediaWikiTestCase { if ( wfIsWindows() ) { $this->markTestSkipped( 'This test does not work on Windows' ); } - $rootPath = escapeshellarg( __DIR__ ); + $rootPath = escapeshellarg( __DIR__ . '/..' ); $testClassRegex = implode( '|', array( 'ApiFormatTestBase', 'ApiTestCase', @@ -58,6 +58,6 @@ class StructureTest extends MediaWikiTestCase { * Filter to remove testUnitTestFileNamesEndWithTest false positives. */ public function filterSuites( $filename ) { - return strpos( $filename, __DIR__ . '/suites/' ) !== 0; + return strpos( $filename, __DIR__ . '/../suites/' ) !== 0; } } diff --git a/tests/phpunit/suite.xml b/tests/phpunit/suite.xml index 8f7e977f..7a9122fa 100644 --- a/tests/phpunit/suite.xml +++ b/tests/phpunit/suite.xml @@ -2,17 +2,18 @@ <!-- colors don't work on Windows! --> <phpunit bootstrap="./bootstrap.php" - colors="true" - backupGlobals="false" - convertErrorsToExceptions="true" - convertNoticesToExceptions="true" - convertWarningsToExceptions="true" - stopOnFailure="false" - timeoutForSmallTests="10" - timeoutForMediumTests="30" - timeoutForLargeTests="60" - strict="true" - verbose="true"> + colors="true" + backupGlobals="false" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + forceCoversAnnotation="true" + stopOnFailure="false" + timeoutForSmallTests="10" + timeoutForMediumTests="30" + timeoutForLargeTests="60" + strict="true" + verbose="true"> <testsuites> <testsuite name="includes"> <directory>includes</directory> @@ -29,14 +30,14 @@ <directory>maintenance</directory> </testsuite> <testsuite name="structure"> - <file>AutoLoaderTest.php</file> - <file>StructureTest.php</file> + <directory>structure</directory> </testsuite> <testsuite name="uploadfromurl"> <file>suites/UploadFromUrlTestSuite.php</file> </testsuite> <testsuite name="extensions"> <file>suites/ExtensionsTestSuite.php</file> + <file>suites/ExtensionsParserTestSuite.php</file> </testsuite> </testsuites> <groups> diff --git a/tests/phpunit/suites/ExtensionsParserTestSuite.php b/tests/phpunit/suites/ExtensionsParserTestSuite.php new file mode 100644 index 00000000..3d68b241 --- /dev/null +++ b/tests/phpunit/suites/ExtensionsParserTestSuite.php @@ -0,0 +1,8 @@ +<?php +class ExtensionsParserTestSuite extends PHPUnit_Framework_TestSuite { + + public static function suite() { + return MediaWikiParserTest::suite( MediaWikiParserTest::NO_CORE ); + } + +} diff --git a/tests/phpunit/suites/UploadFromUrlTestSuite.php b/tests/phpunit/suites/UploadFromUrlTestSuite.php index 28d38ab4..7eb599e3 100644 --- a/tests/phpunit/suites/UploadFromUrlTestSuite.php +++ b/tests/phpunit/suites/UploadFromUrlTestSuite.php @@ -1,6 +1,6 @@ <?php -require_once( dirname( __DIR__ ) . '/includes/upload/UploadFromUrlTest.php' ); +require_once dirname( __DIR__ ) . '/includes/upload/UploadFromUrlTest.php'; class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { public $savedGlobals = array(); @@ -16,16 +16,16 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { } protected function setUp() { - global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, - $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, - $wgNamespaceAliases, $wgNamespaceProtection, $parserMemc; + global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgUser, + $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, + $wgEnableParserCache, $wgNamespaceAliases, $wgNamespaceProtection, + $parserMemc; $tmpGlobals = array(); $tmpGlobals['wgScript'] = '/index.php'; $tmpGlobals['wgScriptPath'] = '/'; $tmpGlobals['wgArticlePath'] = '/wiki/$1'; - $tmpGlobals['wgStyleSheetPath'] = '/skins'; $tmpGlobals['wgStylePath'] = '/skins'; $tmpGlobals['wgThumbnailScriptPath'] = false; $tmpGlobals['wgLocalFileRepo'] = array( @@ -56,7 +56,6 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - $wgEnableParserCache = false; DeferredUpdates::clearPendingUpdates(); $wgMemc = wfGetMainCache(); @@ -184,6 +183,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { if ( file_exists( $dir ) ) { wfDebug( "Already exists!\n" ); + return $dir; } @@ -201,6 +201,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { // the UploadFromUrlTest class class_exists( 'UploadFromUrlTest' ); $suite = new UploadFromUrlTestSuite( 'UploadFromUrlTest' ); + return $suite; } } |