From 4ac9fa081a7c045f6a9f1cfc529d82423f485b2e Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sun, 8 Dec 2013 09:55:49 +0100 Subject: Update to MediaWiki 1.22.0 --- tests/phpunit/includes/ArticleTablesTest.php | 7 +- tests/phpunit/includes/ArticleTest.php | 12 +- tests/phpunit/includes/BlockTest.php | 143 ++++- tests/phpunit/includes/CdbTest.php | 2 +- tests/phpunit/includes/CollationTest.php | 8 +- tests/phpunit/includes/DiffHistoryBlobTest.php | 9 +- tests/phpunit/includes/EditPageTest.php | 93 ++- tests/phpunit/includes/ExternalStoreTest.php | 2 +- tests/phpunit/includes/ExtraParserTest.php | 27 +- tests/phpunit/includes/FallbackTest.php | 73 +++ tests/phpunit/includes/FauxRequestTest.php | 15 + tests/phpunit/includes/FauxResponseTest.php | 9 +- .../includes/FormOptionsInitializationTest.php | 1 - .../includes/GlobalFunctions/GlobalTest.php | 201 +++---- .../includes/GlobalFunctions/GlobalWithDBTest.php | 6 +- .../includes/GlobalFunctions/wfAssembleUrlTest.php | 7 +- .../includes/GlobalFunctions/wfBCP47Test.php | 20 +- .../includes/GlobalFunctions/wfBaseConvertTest.php | 3 +- .../includes/GlobalFunctions/wfBaseNameTest.php | 6 +- .../includes/GlobalFunctions/wfExpandUrlTest.php | 20 +- .../includes/GlobalFunctions/wfGetCallerTest.php | 15 +- .../includes/GlobalFunctions/wfParseUrlTest.php | 9 +- .../GlobalFunctions/wfRemoveDotSegmentsTest.php | 6 +- .../GlobalFunctions/wfShorthandToIntegerTest.php | 8 +- .../includes/GlobalFunctions/wfTimestampTest.php | 19 +- .../includes/GlobalFunctions/wfUrlencodeTest.php | 11 +- tests/phpunit/includes/HTMLCheckMatrixTest.php | 102 ++++ tests/phpunit/includes/HashRingTest.php | 53 ++ tests/phpunit/includes/HooksTest.php | 171 +++--- tests/phpunit/includes/HtmlFormatterTest.php | 81 +++ tests/phpunit/includes/HtmlTest.php | 65 ++- tests/phpunit/includes/HttpTest.php | 11 +- tests/phpunit/includes/IPTest.php | 78 ++- tests/phpunit/includes/JsonTest.php | 27 - tests/phpunit/includes/LanguageConverterTest.php | 35 +- tests/phpunit/includes/LicensesTest.php | 2 +- tests/phpunit/includes/LinkerTest.php | 4 +- tests/phpunit/includes/LinksUpdateTest.php | 23 +- tests/phpunit/includes/LocalFileTest.php | 22 +- tests/phpunit/includes/MWExceptionHandlerTest.php | 73 +++ tests/phpunit/includes/MWFunctionTest.php | 47 +- tests/phpunit/includes/MWNamespaceTest.php | 21 +- tests/phpunit/includes/MessageTest.php | 78 ++- tests/phpunit/includes/OutputPageTest.php | 73 +-- tests/phpunit/includes/PathRouterTest.php | 36 +- tests/phpunit/includes/PreferencesTest.php | 23 +- tests/phpunit/includes/Providers.php | 44 -- tests/phpunit/includes/RecentChangeTest.php | 34 +- tests/phpunit/includes/RequestContextTest.php | 8 +- tests/phpunit/includes/ResourceLoaderTest.php | 62 +- tests/phpunit/includes/RevisionStorageTest.php | 16 +- .../RevisionStorageTest_ContentHandlerUseDB.php | 20 +- tests/phpunit/includes/RevisionTest.php | 78 ++- tests/phpunit/includes/SampleTest.php | 4 +- tests/phpunit/includes/SanitizerTest.php | 114 +++- .../includes/SanitizerValidateEmailTest.php | 35 +- .../phpunit/includes/SeleniumConfigurationTest.php | 222 -------- tests/phpunit/includes/SiteConfigurationTest.php | 39 +- tests/phpunit/includes/StringUtilsTest.php | 166 +++--- tests/phpunit/includes/TemplateCategoriesTest.php | 24 +- tests/phpunit/includes/TestUser.php | 7 +- tests/phpunit/includes/TimeAdjustTest.php | 40 +- tests/phpunit/includes/TimestampTest.php | 264 ++++++++- tests/phpunit/includes/TitleMethodsTest.php | 20 +- tests/phpunit/includes/TitlePermissionTest.php | 142 ++++- tests/phpunit/includes/TitleTest.php | 194 ++++++- tests/phpunit/includes/UIDGeneratorTest.php | 22 + tests/phpunit/includes/UserMailerTest.php | 14 + tests/phpunit/includes/UserTest.php | 20 + tests/phpunit/includes/WebRequestTest.php | 114 +++- tests/phpunit/includes/WikiPageTest.php | 68 ++- .../includes/WikiPageTest_ContentHandlerUseDB.php | 25 +- tests/phpunit/includes/XmlJsTest.php | 25 +- tests/phpunit/includes/XmlSelectTest.php | 39 +- tests/phpunit/includes/XmlTest.php | 132 +++-- tests/phpunit/includes/XmlTypeCheckTest.php | 30 + tests/phpunit/includes/ZipDirectoryReaderTest.php | 27 +- .../includes/api/ApiAccountCreationTest.php | 56 +- tests/phpunit/includes/api/ApiBlockTest.php | 21 +- tests/phpunit/includes/api/ApiEditPageTest.php | 107 +++- tests/phpunit/includes/api/ApiOptionsTest.php | 38 +- tests/phpunit/includes/api/ApiParseTest.php | 5 +- tests/phpunit/includes/api/ApiPurgeTest.php | 3 +- tests/phpunit/includes/api/ApiTest.php | 47 +- tests/phpunit/includes/api/ApiTestCase.php | 40 +- tests/phpunit/includes/api/ApiTestCaseUpload.php | 4 +- tests/phpunit/includes/api/ApiUploadTest.php | 42 +- tests/phpunit/includes/api/ApiWatchTest.php | 55 +- .../phpunit/includes/api/RandomImageGenerator.php | 13 +- .../includes/api/format/ApiFormatPhpTest.php | 4 +- .../phpunit/includes/api/generateRandomImages.php | 6 +- .../includes/api/query/ApiQueryBasicTest.php | 77 ++- .../includes/api/query/ApiQueryContinue2Test.php | 14 +- .../includes/api/query/ApiQueryContinueTest.php | 198 +++---- .../api/query/ApiQueryContinueTestBase.php | 62 +- .../includes/api/query/ApiQueryRevisionsTest.php | 2 +- tests/phpunit/includes/api/query/ApiQueryTest.php | 7 +- .../includes/api/query/ApiQueryTestBase.php | 15 +- tests/phpunit/includes/cache/GenderCacheTest.php | 9 +- tests/phpunit/includes/cache/MessageCacheTest.php | 128 +++++ .../phpunit/includes/cache/ProcessCacheLRUTest.php | 24 +- .../includes/content/ContentHandlerTest.php | 99 ++-- tests/phpunit/includes/content/CssContentTest.php | 8 +- .../includes/content/JavaScriptContentTest.php | 20 +- tests/phpunit/includes/content/TextContentTest.php | 43 +- .../content/WikitextContentHandlerTest.php | 44 +- .../includes/content/WikitextContentTest.php | 24 +- .../phpunit/includes/db/DatabaseMysqlBaseTest.php | 209 +++++++ tests/phpunit/includes/db/DatabaseSQLTest.php | 633 ++++++++++++++++++++- tests/phpunit/includes/db/DatabaseSqliteTest.php | 46 +- tests/phpunit/includes/db/DatabaseTest.php | 62 +- tests/phpunit/includes/db/DatabaseTestHelper.php | 166 ++++++ tests/phpunit/includes/db/ORMRowTest.php | 1 + tests/phpunit/includes/db/ORMTableTest.php | 2 +- tests/phpunit/includes/db/TestORMRowTest.php | 52 +- tests/phpunit/includes/debug/MWDebugTest.php | 8 +- .../includes/filebackend/FileBackendTest.php | 251 +++++--- tests/phpunit/includes/filerepo/FileRepoTest.php | 25 +- tests/phpunit/includes/filerepo/StoreBatchTest.php | 13 +- .../includes/installer/InstallDocFormatterTest.php | 7 +- .../includes/installer/OracleInstallerTest.php | 48 ++ tests/phpunit/includes/jobqueue/JobQueueTest.php | 129 +++-- tests/phpunit/includes/json/FormatJsonTest.php | 161 ++++++ tests/phpunit/includes/json/ServicesJsonTest.php | 93 --- tests/phpunit/includes/libs/CSSJanusTest.php | 72 ++- tests/phpunit/includes/libs/CSSMinTest.php | 12 +- .../includes/libs/GenericArrayObjectTest.php | 3 +- tests/phpunit/includes/libs/IEUrlExtensionTest.php | 30 +- .../includes/libs/JavaScriptMinifierTest.php | 8 +- .../includes/media/BitmapMetadataHandlerTest.php | 29 +- tests/phpunit/includes/media/BitmapScalingTest.php | 47 +- tests/phpunit/includes/media/ExifBitmapTest.php | 53 +- tests/phpunit/includes/media/ExifRotationTest.php | 49 +- tests/phpunit/includes/media/ExifTest.php | 12 +- tests/phpunit/includes/media/FakeDimensionFile.php | 28 + .../phpunit/includes/media/FormatMetadataTest.php | 11 +- .../includes/media/GIFMetadataExtractorTest.php | 1 + tests/phpunit/includes/media/GIFTest.php | 16 + tests/phpunit/includes/media/IPTCTest.php | 31 +- .../includes/media/JpegMetadataExtractorTest.php | 5 +- tests/phpunit/includes/media/JpegTest.php | 10 +- tests/phpunit/includes/media/MediaHandlerTest.php | 7 +- .../includes/media/PNGMetadataExtractorTest.php | 32 +- tests/phpunit/includes/media/PNGTest.php | 16 + .../includes/media/SVGMetadataExtractorTest.php | 9 +- tests/phpunit/includes/media/TiffTest.php | 20 +- tests/phpunit/includes/media/XMPTest.php | 17 +- tests/phpunit/includes/media/XMPValidateTest.php | 5 +- tests/phpunit/includes/normal/CleanUpTest.php | 32 +- .../phpunit/includes/objectcache/BagOStuffTest.php | 13 +- .../phpunit/includes/parser/MagicVariableTest.php | 107 ++-- .../includes/parser/MediaWikiParserTest.php | 108 +++- tests/phpunit/includes/parser/NewParserTest.php | 347 ++++++----- .../phpunit/includes/parser/ParserMethodsTest.php | 48 +- tests/phpunit/includes/parser/ParserOutputTest.php | 12 +- .../phpunit/includes/parser/ParserPreloadTest.php | 18 +- tests/phpunit/includes/parser/PreprocessorTest.php | 38 +- tests/phpunit/includes/parser/TagHooksTest.php | 8 +- tests/phpunit/includes/parser/TidyTest.php | 44 ++ tests/phpunit/includes/search/SearchEngineTest.php | 14 +- tests/phpunit/includes/search/SearchUpdateTest.php | 15 +- tests/phpunit/includes/site/MediaWikiSiteTest.php | 5 +- tests/phpunit/includes/site/SiteListTest.php | 9 +- tests/phpunit/includes/site/SiteSQLStoreTest.php | 13 +- tests/phpunit/includes/site/SiteTest.php | 33 +- tests/phpunit/includes/site/TestSites.php | 1 - .../includes/specials/QueryAllSpecialPagesTest.php | 2 +- .../includes/specials/SpecialPreferencesTest.php | 60 ++ .../includes/specials/SpecialRecentchangesTest.php | 2 - .../includes/specials/SpecialSearchTest.php | 9 +- tests/phpunit/includes/upload/UploadBaseTest.php | 147 +++++ .../phpunit/includes/upload/UploadFromUrlTest.php | 18 +- tests/phpunit/includes/upload/UploadStashTest.php | 3 +- tests/phpunit/includes/upload/UploadTest.php | 144 ----- 174 files changed, 6154 insertions(+), 2546 deletions(-) create mode 100644 tests/phpunit/includes/FallbackTest.php create mode 100644 tests/phpunit/includes/FauxRequestTest.php create mode 100644 tests/phpunit/includes/HTMLCheckMatrixTest.php create mode 100644 tests/phpunit/includes/HashRingTest.php create mode 100644 tests/phpunit/includes/HtmlFormatterTest.php delete mode 100644 tests/phpunit/includes/JsonTest.php create mode 100644 tests/phpunit/includes/MWExceptionHandlerTest.php delete mode 100644 tests/phpunit/includes/Providers.php delete mode 100644 tests/phpunit/includes/SeleniumConfigurationTest.php create mode 100644 tests/phpunit/includes/UserMailerTest.php create mode 100644 tests/phpunit/includes/XmlTypeCheckTest.php create mode 100644 tests/phpunit/includes/cache/MessageCacheTest.php create mode 100644 tests/phpunit/includes/db/DatabaseMysqlBaseTest.php create mode 100644 tests/phpunit/includes/db/DatabaseTestHelper.php create mode 100644 tests/phpunit/includes/installer/OracleInstallerTest.php create mode 100644 tests/phpunit/includes/json/FormatJsonTest.php delete mode 100644 tests/phpunit/includes/json/ServicesJsonTest.php create mode 100644 tests/phpunit/includes/media/FakeDimensionFile.php create mode 100644 tests/phpunit/includes/parser/TidyTest.php create mode 100644 tests/phpunit/includes/specials/SpecialPreferencesTest.php create mode 100644 tests/phpunit/includes/upload/UploadBaseTest.php delete mode 100644 tests/phpunit/includes/upload/UploadTest.php (limited to 'tests/phpunit/includes') 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( "

Test\nContent of Template:Foo\nContent of Template:Bar\n

", $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}} censored information ", $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 @@ +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 @@ +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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ + 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 @@ + 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 @@ +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( + 'Blah', + '', + $removeImages, + ), + // basic tag removal + array( + '
foo
foo
foo
bar +foobar
test
+baz', + + '
test
+baz', + $removeTags, + ), + // don't flatten tags that start like chosen ones + array( + '
foo bar
', + 'foo bar', + $flattenSomeStuff, + ), + // total flattening + array( + '
bar2
', + 'bar2', + $flattenEverything, + ), + // UTF-8 preservation and security + array( + '<Тест!> &<&&&&', + '<Тест!> &<&&&&', + ), + // https://bugzilla.wikimedia.org/show_bug.cgi?id=53086 + array( + 'Foo[1] Bar', + 'Foo[1] Bar', + ), + ); + } +} 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( '', 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( '', @@ -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( '' . "\n" . '' . "\n" . @@ -376,7 +386,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testCanDisableANamespaces() { + public function testCanDisableANamespaces() { $this->assertEquals( '', 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 @@ 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 @@ -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 @@ +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 @@ 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,58 +38,38 @@ class OutputPageTest extends MediaWikiTestCase { $fauxRequest = new FauxRequest( $queryData, false ); $this->setMWGlobals( array( 'wgRequest' => $fauxRequest, - 'wgHandheldForIPhone' => $args['handheldForIPhone'] ) ); $actualReturn = OutputPage::transformCssMedia( $args['media'] ); $this->assertSame( $args['expectedReturn'], $actualReturn, $args['message'] ); } - /** - * 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 @@ 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 @@ -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; } @@ -47,8 +83,23 @@ class ResourceLoaderTest extends MediaWikiTestCase { $this->assertEquals( $module, $resourceLoader->getModule( $name ) ); } + /** + * @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 @@ 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( - '
Hello world
', - Sanitizer::removeHTMLtags( '
Hello world
' ), - 'Self-closing closing div' + function dataRemoveHTMLtags() { + return array( + // former testSelfClosingTag + array( + '
Hello world
', + '
Hello world
', + '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( + 'Shift+F3', + 'Shift+F3', + 'Nested .' + ), + // http://www.whatwg.org/html/text-level-semantics.html#the-sub-and-sup-elements + array( + 'xi, yi', + 'xi, yi', + 'Nested .' + ), + // http://www.whatwg.org/html/text-level-semantics.html#the-dfn-element + array( + 'GDO', + 'GDO', + ' inside ', + ), ); } + /** + * @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( , , [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( , , ) */ 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 @@ 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 @@ - '*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 @@ 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,32 +34,22 @@ 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 @@ 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 @@ 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 @@ +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 @@ 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,9 +144,21 @@ 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( @@ -138,6 +166,7 @@ class WebRequestTest extends MediaWikiTestCase { '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 @@ 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", "

hello world

" ), - // @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*(

)!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 @@ 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 @@ 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( '', $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( '', $this->select->getHTML() ); } + /** + * @covers XmlSelect::addOption + */ public function testAddOptionWithDefault() { $this->select->addOption( 'foo', true ); $this->assertEquals( '', $this->select->getHTML() ); } + /** + * @covers XmlSelect::addOption + */ public function testAddOptionWithFalse() { $this->select->addOption( 'foo', false ); $this->assertEquals( '', $this->select->getHTML() ); } + /** + * @covers XmlSelect::addOption + */ public function testAddOptionWithValueZero() { $this->select->addOption( 'foo', 0 ); $this->assertEquals( '', $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 { '', $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 @@ 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( '', Xml::element( 'element', null, null ), @@ -56,7 +65,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testElementEmpty() { + /** + * @covers Xml::element + */ + public function testElementEmpty() { $this->assertEquals( '', Xml::element( 'element', null, '' ), @@ -64,7 +76,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testElementInputCanHaveAValueOfZero() { + /** + * @covers Xml::input + */ + public function testElementInputCanHaveAValueOfZero() { $this->assertEquals( '', Xml::input( 'name', false, 0 ), @@ -72,7 +87,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testElementEscaping() { + /** + * @covers Xml::element + */ + public function testElementEscaping() { $this->assertEquals( 'hello <there> you & you', Xml::element( 'element', null, 'hello 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( '="<>">', 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( '', Xml::openElement( 'element', array( 'k' => 'v' ) ), @@ -102,10 +129,16 @@ class XmlTest extends MediaWikiTestCase { ); } - function testCloseElement() { + /** + * @covers Xml::closeElement + */ + public function testCloseElement() { $this->assertEquals( '', 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( '', Xml::textarea( 'name', '' ), @@ -197,7 +230,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testTextareaAttribs() { + /** + * @covers Xml::textarea + */ + public function testTextareaAttribs() { $this->assertEquals( '', Xml::textarea( 'name', '', 20, 10 ), @@ -205,10 +241,10 @@ class XmlTest extends MediaWikiTestCase { ); } - # - # input and label - # - function testLabelCreation() { + /** + * @covers Xml::label + */ + public function testLabelCreation() { $this->assertEquals( '', Xml::label( 'name', 'id' ), @@ -216,7 +252,10 @@ class XmlTest extends MediaWikiTestCase { ); } - function testLabelAttributeCanOnlyBeClassOrTitle() { + /** + * @covers Xml::label + */ + public function testLabelAttributeCanOnlyBeClassOrTitle() { $this->assertEquals( '', 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 @@ +"; + const MAL_FORMED_XML = ""; + + /** + * @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 @@ 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 @@ -299,6 +320,32 @@ class ApiQueryBasicTest extends ApiQueryTestBase { self::$categorymembers ) ); } + /** + * 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 */ 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 @@ +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(); @@ -60,8 +69,40 @@ 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 @@ +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 @@ +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 @@ 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 @@ 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 ', '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 @@ +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 @@ + 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 @@ -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,10 +139,15 @@ 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; }' ), @@ -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. @@ -376,6 +417,11 @@ class CSSJanusTest extends MediaWikiTestCase { '/* @noflip */ div { float: left; } .foo { float: left; }', '/* @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; }', @@ -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 @@ 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 @@ +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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ "\\'", '\\' => '\\\\' ) ); /* 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 = <<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", + '' . + 'Foo' ); + + $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

bar

\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

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( '
monospaced
', '
monospaced
', @@ -49,7 +58,7 @@ class ParserPreloadTest extends MediaWikiTestCase { /** * @covers Parser::getPreloadText */ - function testPreloadedNowikiIsUnstripped() { + public function testPreloadedNowikiIsUnstripped() { $this->assertPreloaded( '[[Dummy title]]', '[[Dummy title]]', @@ -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 @@ Foo" ), array( "", "<!-- Foo -->" ), @@ -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>', 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 ==", "== h ==<!--c1-->" ), array( "== h == ", "== h == <!--c1-->" ), @@ -209,11 +218,11 @@ class PreprocessorTest extends MediaWikiTestCase { array( "== h == ", "== h == <!--c1--> <!--c2--><!--c3--> " ), array( "== h == ", "== h == <!--c1--><!--c2--> <!--c3--> " ), array( "== h == ", "== h == <!--c1--> <!--c2--> <!--c3--> " ), + array( "== h == ", "== h ==<!--c1--> <!--c2-->" ), + array( "== h == ", "== h == <!--c1--> <!--c2-->" ), + array( "== h == ", "== h ==<!--c1--> <!--c2--> " ), /* These are not working: */ - array( "== h == ", "== h ==<!--c1--> <!--c2-->" ), - array( "== h == ", "== h == <!--c1--> <!--c2-->" ), - array( "== h == ", "== h ==<!--c1--> <!--c2--> " ), array( "== h == x ", "== h == x <!--c1--><!--c2--><!--c3--> " ), array( "== h == x ", "== h ==<!--c1--> x <!--c2--><!--c3--> " ), array( "== h == x ", "== h ==<!--c1--><!--c2--><!--c3--> x " ), @@ -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 @@ +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

s + $text = trim( preg_replace( '##', '', $text ) ); + // Windows, we love you! + $text = str_replace( "\r", '', $text ); + $this->assertEquals( $expected, $text, $msg ); + } + + public function provideTestWrapping() { + return array( + array( + 'foo', + 'foo', + ' should survive tidy' + ), + array( + 'foo', + 'foo', + ' should survive tidy' + ), + array( 'foo', 'foo', ' should survive tidy' ), + array( "\nfoo", 'foo', ' should survive tidy' ), + array( "\nfoo", 'foo', ' 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( '

TeSt
' ), @@ -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 @@ +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 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/UploadBaseTest.php b/tests/phpunit/includes/upload/UploadBaseTest.php new file mode 100644 index 00000000..982b46b2 --- /dev/null +++ b/tests/phpunit/includes/upload/UploadBaseTest.php @@ -0,0 +1,147 @@ +<?php + +/** + * @group Upload + */ +class UploadBaseTest extends MediaWikiTestCase { + + /** @var UploadTestHandler */ + protected $upload; + + protected function setUp() { + global $wgHooks; + parent::setUp(); + + $this->upload = new UploadTestHandler; + $this->hooks = $wgHooks; + $wgHooks['InterwikiLoadPrefix'][] = function ( $prefix, &$data ) { + return false; + }; + } + + protected function tearDown() { + global $wgHooks; + $wgHooks = $this->hooks; + + parent::tearDown(); + } + + + /** + * First checks the return code + * 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 */ + $this->assertEquals( $code, + $this->upload->testTitleValidation( $srcFilename ), + "$msg code" ); + + /* If we expect a valid title, check the title itself. */ + if ( $code == UploadBase::OK ) { + $this->assertEquals( $dstFilename, + $this->upload->getTitle()->getText(), + "$msg text" ); + } + } + + /** + * Test various forms of valid and invalid titles that can be supplied. + */ + public static function provideTestTitleValidation() { + return array( + /* Test a valid title */ + array( 'ValidTitle.jpg', 'ValidTitle.jpg', UploadBase::OK, + 'upload valid title' ), + /* A title with a slash */ + array( 'A/B.jpg', 'B.jpg', UploadBase::OK, + 'upload title with slash' ), + /* A title with illegal char */ + array( 'A:B.jpg', 'A-B.jpg', UploadBase::OK, + 'upload title with colon' ), + /* Stripping leading File: prefix */ + array( 'File:C.jpg', 'C.jpg', UploadBase::OK, + 'upload title with File prefix' ), + /* Test illegal suggested title (r94601) */ + array( '%281%29.JPG', null, UploadBase::ILLEGAL_FILENAME, + 'illegal title for upload' ), + /* A title without extension */ + array( 'A', null, UploadBase::FILETYPE_MISSING, + 'upload title without extension' ), + /* A title with no basename */ + array( '.jpg', null, UploadBase::MIN_LENGTH_PARTNAME, + 'upload title without basename' ), + /* A title that is longer than 255 bytes */ + array( str_repeat( 'a', 255 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, + 'upload title longer than 255 bytes' ), + /* A title that is longer than 240 bytes */ + array( str_repeat( 'a', 240 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, + 'upload title longer than 240 bytes' ), + ); + } + + /** + * Test the upload verification functions + * @covers UploadBase::verifyUpload + */ + public function testVerifyUpload() { + /* Setup with zero file size */ + $this->upload->initializePathInfo( '', '', 0 ); + $result = $this->upload->verifyUpload(); + $this->assertEquals( UploadBase::EMPTY_FILE, + $result['status'], + 'upload empty file' ); + } + + // Helper used to create an empty file of size $size. + private function createFileOfSize( $size ) { + $filename = tempnam( wfTempDir(), "mwuploadtest" ); + + $fh = fopen( $filename, 'w' ); + ftruncate( $fh, $size ); + fclose( $fh ); + + return $filename; + } + + /** + * test uploading a 100 bytes file with $wgMaxUploadSize = 100 + * + * This method should be abstracted so we can test different settings. + */ + public function testMaxUploadSize() { + global $wgMaxUploadSize; + $savedGlobal = $wgMaxUploadSize; // save global + global $wgFileExtensions; + $wgFileExtensions[] = 'txt'; + + $wgMaxUploadSize = 100; + + $filename = $this->createFileOfSize( $wgMaxUploadSize ); + $this->upload->initializePathInfo( basename( $filename ) . '.txt', $filename, 100 ); + $result = $this->upload->verifyUpload(); + unlink( $filename ); + + $this->assertEquals( + array( 'status' => UploadBase::OK ), $result ); + + $wgMaxUploadSize = $savedGlobal; // restore global + } +} + +class UploadTestHandler extends UploadBase { + 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/includes/upload/UploadTest.php b/tests/phpunit/includes/upload/UploadTest.php deleted file mode 100644 index b809d320..00000000 --- a/tests/phpunit/includes/upload/UploadTest.php +++ /dev/null @@ -1,144 +0,0 @@ -<?php -/** - * @group Upload - */ -class UploadTest extends MediaWikiTestCase { - protected $upload; - - - protected function setUp() { - global $wgHooks; - parent::setUp(); - - $this->upload = new UploadTestHandler; - $this->hooks = $wgHooks; - $wgHooks['InterwikiLoadPrefix'][] = function ( $prefix, &$data ) { - return false; - }; - } - - protected function tearDown() { - global $wgHooks; - $wgHooks = $this->hooks; - - parent::tearDown(); - } - - - /** - * First checks the return code - * of UploadBase::getTitle() and then the actual returned title - * - * @dataProvider provideTestTitleValidation - */ - public function testTitleValidation( $srcFilename, $dstFilename, $code, $msg ) { - /* Check the result code */ - $this->assertEquals( $code, - $this->upload->testTitleValidation( $srcFilename ), - "$msg code" ); - - /* If we expect a valid title, check the title itself. */ - if ( $code == UploadBase::OK ) { - $this->assertEquals( $dstFilename, - $this->upload->getTitle()->getText(), - "$msg text" ); - } - } - - /** - * Test various forms of valid and invalid titles that can be supplied. - */ - public static function provideTestTitleValidation() { - return array( - /* Test a valid title */ - array( 'ValidTitle.jpg', 'ValidTitle.jpg', UploadBase::OK, - 'upload valid title' ), - /* A title with a slash */ - array( 'A/B.jpg', 'B.jpg', UploadBase::OK, - 'upload title with slash' ), - /* A title with illegal char */ - array( 'A:B.jpg', 'A-B.jpg', UploadBase::OK, - 'upload title with colon' ), - /* Stripping leading File: prefix */ - array( 'File:C.jpg', 'C.jpg', UploadBase::OK, - 'upload title with File prefix' ), - /* Test illegal suggested title (r94601) */ - array( '%281%29.JPG', null, UploadBase::ILLEGAL_FILENAME, - 'illegal title for upload' ), - /* A title without extension */ - array( 'A', null, UploadBase::FILETYPE_MISSING, - 'upload title without extension' ), - /* A title with no basename */ - array( '.jpg', null, UploadBase::MIN_LENGTH_PARTNAME, - 'upload title without basename' ), - /* A title that is longer than 255 bytes */ - array( str_repeat( 'a', 255 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, - 'upload title longer than 255 bytes' ), - /* A title that is longer than 240 bytes */ - array( str_repeat( 'a', 240 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, - 'upload title longer than 240 bytes' ), - ); - } - - /** - * Test the upload verification functions - */ - public function testVerifyUpload() { - /* Setup with zero file size */ - $this->upload->initializePathInfo( '', '', 0 ); - $result = $this->upload->verifyUpload(); - $this->assertEquals( UploadBase::EMPTY_FILE, - $result['status'], - 'upload empty file' ); - } - - // Helper used to create an empty file of size $size. - private function createFileOfSize( $size ) { - $filename = tempnam( wfTempDir(), "mwuploadtest" ); - - $fh = fopen( $filename, 'w' ); - ftruncate( $fh, $size ); - fclose( $fh ); - - return $filename; - } - - /** - * test uploading a 100 bytes file with $wgMaxUploadSize = 100 - * - * This method should be abstracted so we can test different settings. - */ - - public function testMaxUploadSize() { - global $wgMaxUploadSize; - $savedGlobal = $wgMaxUploadSize; // save global - global $wgFileExtensions; - $wgFileExtensions[] = 'txt'; - - $wgMaxUploadSize = 100; - - $filename = $this->createFileOfSize( $wgMaxUploadSize ); - $this->upload->initializePathInfo( basename( $filename ) . '.txt', $filename, 100 ); - $result = $this->upload->verifyUpload(); - unlink( $filename ); - - $this->assertEquals( - array( 'status' => UploadBase::OK ), $result ); - - $wgMaxUploadSize = $savedGlobal; // restore global - } -} - -class UploadTestHandler extends UploadBase { - public function initializeFromRequest( &$request ) {} - - public function testTitleValidation( $name ) { - $this->mTitle = false; - $this->mDesiredDestName = $name; - $this->mTitleError = UploadBase::OK; - $this->getTitle(); - return $this->mTitleError; - } - - -} -- cgit v1.2.2