diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2014-04-25 06:26:49 +0200 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2014-04-25 06:26:49 +0200 |
commit | 2e44b49a2db3026050b136de9b00f749dd3ff939 (patch) | |
tree | ef048f4db79a93c25cfc86319264aa7ae2a4ae0b /tests/phpunit/includes | |
parent | 9441dde8bfb95277df073717ed7817dced40f948 (diff) |
Update to MediaWiki 1.22.6
Diffstat (limited to 'tests/phpunit/includes')
177 files changed, 0 insertions, 35617 deletions
diff --git a/tests/phpunit/includes/ArticleTablesTest.php b/tests/phpunit/includes/ArticleTablesTest.php deleted file mode 100644 index 469d1d19..00000000 --- a/tests/phpunit/includes/ArticleTablesTest.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -/** - * @group Database - */ -class ArticleTablesTest extends MediaWikiLangTestCase { - - public function testbug14404() { - global $wgContLang, $wgLanguageCode, $wgLang; - - $title = Title::newFromText( 'Bug 14404' ); - $page = WikiPage::factory( $title ); - $user = new User(); - $user->mRights = array( 'createpage', 'edit', 'purge' ); - $wgLanguageCode = 'es'; - $wgContLang = Language::factory( 'es' ); - - $wgLang = Language::factory( 'fr' ); - $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', 0, false, $user ); - $templates1 = $title->getTemplateLinksFrom(); - - $wgLang = Language::factory( 'de' ); - $page = WikiPage::factory( $title ); // In order to force the rerendering of the same wikitext - - // We need an edit, a purge is not enough to regenerate the tables - $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 deleted file mode 100644 index b4d6dca6..00000000 --- a/tests/phpunit/includes/ArticleTest.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php - -class ArticleTest extends MediaWikiTestCase { - - /** - * @var Title - */ - private $title; - /** - * @var Article - */ - private $article; - - /** creates a title object and its article object */ - protected function setUp() { - parent::setUp(); - $this->title = Title::makeTitle( NS_MAIN, 'SomePage' ); - $this->article = new Article( $this->title ); - } - - /** cleanup title object and its article object */ - protected function tearDown() { - parent::tearDown(); - $this->title = null; - $this->article = null; - } - - public function testImplementsGetMagic() { - $this->assertEquals( false, $this->article->mLatest, "Article __get magic" ); - } - - /** - * @depends testImplementsGetMagic - */ - public function testImplementsSetMagic() { - $this->article->mLatest = 2; - $this->assertEquals( 2, $this->article->mLatest, "Article __set magic" ); - } - - /** - * @depends testImplementsSetMagic - */ - public function testImplementsCallMagic() { - $this->article->mLatest = 33; - $this->article->mDataLoaded = true; - $this->assertEquals( 33, $this->article->getLatest(), "Article __call magic" ); - } - - public function testGetOrSetOnNewProperty() { - $this->article->ext_someNewProperty = 12; - $this->assertEquals( 12, $this->article->ext_someNewProperty, - "Article get/set magic on new field" ); - - $this->article->ext_someNewProperty = -8; - $this->assertEquals( -8, $this->article->ext_someNewProperty, - "Article get/set magic on update to new field" ); - } - - /** - * Checks for the existence of the backwards compatibility static functions (forwarders to WikiPage class) - */ - public function testStaticFunctions() { - $this->hideDeprecated( 'Article::getAutosummary' ); - $this->hideDeprecated( 'WikiPage::getAutosummary' ); - $this->hideDeprecated( 'CategoryPage::getAutosummary' ); // Inherited from Article - - $this->assertEquals( WikiPage::selectFields(), Article::selectFields(), - "Article static functions" ); - $this->assertEquals( true, is_callable( "Article::onArticleCreate" ), - "Article static functions" ); - $this->assertEquals( true, is_callable( "Article::onArticleDelete" ), - "Article static functions" ); - $this->assertEquals( true, is_callable( "ImagePage::onArticleEdit" ), - "Article static functions" ); - $this->assertTrue( is_string( CategoryPage::getAutosummary( '', '', 0 ) ), - "Article static functions" ); - } - - public function testWikiPageFactory() { - $title = Title::makeTitle( NS_FILE, 'Someimage.png' ); - $page = WikiPage::factory( $title ); - $this->assertEquals( 'WikiFilePage', get_class( $page ) ); - - $title = Title::makeTitle( NS_CATEGORY, 'SomeCategory' ); - $page = WikiPage::factory( $title ); - $this->assertEquals( 'WikiCategoryPage', get_class( $page ) ); - - $title = Title::makeTitle( NS_MAIN, 'SomePage' ); - $page = WikiPage::factory( $title ); - $this->assertEquals( 'WikiPage', get_class( $page ) ); - } -} diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php deleted file mode 100644 index 21de0985..00000000 --- a/tests/phpunit/includes/BlockTest.php +++ /dev/null @@ -1,354 +0,0 @@ -<?php - -/** - * @group Database - * @group Blocking - */ -class BlockTest extends MediaWikiLangTestCase { - - private $block, $madeAt; - - /* variable used to save up the blockID we insert in this test suite */ - private $blockId; - - protected function setUp() { - parent::setUp(); - $this->setMwGlobals( array( - 'wgLanguageCode' => 'en', - 'wgContLang' => Language::factory( 'en' ) - ) ); - } - - function addDBData() { - - $user = User::newFromName( 'UTBlockee' ); - if ( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTBlockeePassword' ); - - $user->saveSettings(); - } - - // Delete the last round's block if it's still there - $oldBlock = Block::newFromTarget( 'UTBlockee' ); - if ( $oldBlock ) { - // An old block will prevent our new one from saving. - $oldBlock->delete(); - } - - $this->block = new Block( 'UTBlockee', $user->getID(), 0, - 'Parce que', 0, false, time() + 100500 - ); - $this->madeAt = wfTimestamp( TS_MW ); - - $this->block->insert(); - // save up ID for use in assertion. Since ID is an autoincrement, - // its value might change depending on the order the tests are run. - // ApiBlockTest insert its own blocks! - $newBlockId = $this->block->getId(); - if ( $newBlockId ) { - $this->blockId = $newBlockId; - } 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->select( 'ipblocks', '*' ); - print "Got " . $v->numRows() . " rows. Full dump follow:\n"; - foreach ( $v as $row ) { - print_r( $row ); - } - } - - 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 - */ - 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()" ); - } - - /** - * This is the method previously used to load block info in CheckUser etc - * passing an empty value (empty string, null, etc) as the ip parameter bypasses IP lookup checks. - * - * This stopped working with r84475 and friends: regression being fixed for bug 29116. - * - * @dataProvider provideBug29116Data - */ - public function testBug29116LoadWithEmptyIp( $vagueTarget ) { - $this->hideDeprecated( 'Block::load' ); - - $uid = User::idFromName( 'UTBlockee' ); - $this->assertTrue( ( $uid > 0 ), 'Must be able to look up the target user during tests' ); - - $block = new Block(); - $ok = $block->load( $vagueTarget, $uid ); - $this->assertTrue( $ok, "Block->load() with empty IP and user ID '$uid' should return a block" ); - - $this->assertTrue( $this->block->equals( $block ), "Block->load() returns the same block as the one that was made when given empty ip param " . var_export( $vagueTarget, true ) ); - } - - /** - * CheckUser since being changed to use Block::newFromTarget started failing - * because the new function didn't accept empty strings like Block::load() - * had. Regression bug 29116. - * - * @dataProvider provideBug29116Data - */ - 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 ) ); - } - - public static function provideBug29116Data() { - return array( - array( null ), - array( '' ), - array( false ) - ); - } - - public function testBlockedUserCanNotCreateAccount() { - $username = 'BlockedUserToCreateAccountWith'; - $u = User::newFromName( $username ); - $u->setPassword( 'NotRandomPass' ); - $u->addToDatabase(); - unset( $u ); - - // Sanity check - $this->assertNull( - Block::newFromTarget( $username ), - "$username should not be blocked" - ); - - // Reload user - $u = User::newFromName( $username ); - $this->assertFalse( - $u->isBlockedFromCreateAccount(), - "Our sandbox user should be able to create account before being blocked" - ); - - // Foreign perspective (blockee not on current wiki)... - $block = new Block( - /* $address */ $username, - /* $user */ 14146, - /* $by */ 0, - /* $reason */ 'crosswiki block...', - /* $timestamp */ wfTimestampNow(), - /* $auto */ false, - /* $expiry */ $this->db->getInfinity(), - /* anonOnly */ false, - /* $createAccount */ true, - /* $enableAutoblock */ true, - /* $hideName (ipb_deleted) */ true, - /* $blockEmail */ true, - /* $allowUsertalk */ false, - /* $byName */ 'MetaWikiUser' - ); - $block->insert(); - - // Reload block from DB - $userBlock = Block::newFromTarget( $username ); - $this->assertTrue( - (bool)$block->prevents( 'createaccount' ), - "Block object in DB should prevents 'createaccount'" - ); - - $this->assertInstanceOf( - 'Block', - $userBlock, - "'$username' block block object should be existent" - ); - - // Reload user - $u = User::newFromName( $username ); - $this->assertTrue( - (bool)$u->isBlockedFromCreateAccount(), - "Our sandbox user '$username' should NOT be able to create account" - ); - } - - public function testCrappyCrossWikiBlocks() { - // Delete the last round's block if it's still there - $oldBlock = Block::newFromTarget( 'UserOnForeignWiki' ); - if ( $oldBlock ) { - // An old block will prevent our new one from saving. - $oldBlock->delete(); - } - - // Foreign perspective (blockee not on current wiki)... - $block = new Block( - /* $address */ 'UserOnForeignWiki', - /* $user */ 14146, - /* $by */ 0, - /* $reason */ 'crosswiki block...', - /* $timestamp */ wfTimestampNow(), - /* $auto */ false, - /* $expiry */ $this->db->getInfinity(), - /* anonOnly */ false, - /* $createAccount */ true, - /* $enableAutoblock */ true, - /* $hideName (ipb_deleted) */ true, - /* $blockEmail */ true, - /* $allowUsertalk */ false, - /* $byName */ 'MetaWikiUser' - ); - - $res = $block->insert( $this->db ); - $this->assertTrue( (bool)$res['id'], 'Block succeeded' ); - - // Local perspective (blockee on current wiki)... - $user = User::newFromName( 'UserOnForeignWiki' ); - $user->addToDatabase(); - // Set user ID to match the test value - $this->db->update( 'user', array( 'user_id' => 14146 ), array( 'user_id' => $user->getId() ) ); - $user = null; // clear - - $block = Block::newFromID( $res['id'] ); - $this->assertEquals( 'UserOnForeignWiki', $block->getTarget()->getName(), 'Correct blockee name' ); - $this->assertEquals( '14146', $block->getTarget()->getId(), 'Correct blockee id' ); - $this->assertEquals( 'MetaWikiUser', $block->getBlocker(), 'Correct blocker name' ); - $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 deleted file mode 100644 index e3d9da7c..00000000 --- a/tests/phpunit/includes/CdbTest.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php - -/** - * Test the CDB reader/writer - */ -class CdbTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - if ( !CdbReader::haveExtension() ) { - $this->markTestSkipped( 'Native CDB support is not available' ); - } - } - - /** - * @group medium - */ - public function testCdb() { - $dir = wfTempDir(); - if ( !is_writable( $dir ) ) { - $this->markTestSkipped( "Temp dir isn't writable" ); - } - - $phpcdbfile = $this->getNewTempFile(); - $dbacdbfile = $this->getNewTempFile(); - - $w1 = new CdbWriter_PHP( $phpcdbfile ); - $w2 = new CdbWriter_DBA( $dbacdbfile ); - - $data = array(); - for ( $i = 0; $i < 1000; $i++ ) { - $key = $this->randomString(); - $value = $this->randomString(); - $w1->set( $key, $value ); - $w2->set( $key, $value ); - - if ( !isset( $data[$key] ) ) { - $data[$key] = $value; - } - } - - $w1->close(); - $w2->close(); - - $this->assertEquals( - md5_file( $phpcdbfile ), - md5_file( $dbacdbfile ), - 'same hash' - ); - - $r1 = new CdbReader_PHP( $phpcdbfile ); - $r2 = new CdbReader_DBA( $dbacdbfile ); - - foreach ( $data as $key => $value ) { - if ( $key === '' ) { - // Known bug - continue; - } - $v1 = $r1->get( $key ); - $v2 = $r2->get( $key ); - - $v1 = $v1 === false ? '(not found)' : $v1; - $v2 = $v2 === false ? '(not found)' : $v2; - - # cdbAssert( 'Mismatch', $key, $v1, $v2 ); - $this->cdbAssert( "PHP error", $key, $v1, $value ); - $this->cdbAssert( "DBA error", $key, $v2, $value ); - } - } - - private function randomString() { - $len = mt_rand( 0, 10 ); - $s = ''; - for ( $j = 0; $j < $len; $j++ ) { - $s .= chr( mt_rand( 0, 255 ) ); - } - - return $s; - } - - private function cdbAssert( $msg, $key, $v1, $v2 ) { - $this->assertEquals( - $v2, - $v1, - $msg . ', k=' . bin2hex( $key ) - ); - } -} diff --git a/tests/phpunit/includes/CollationTest.php b/tests/phpunit/includes/CollationTest.php deleted file mode 100644 index 43bb3941..00000000 --- a/tests/phpunit/includes/CollationTest.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -class CollationTest extends MediaWikiLangTestCase { - protected function setUp() { - parent::setUp(); - if ( !extension_loaded( 'intl' ) ) { - $this->markTestSkipped( 'These tests require intl extension' ); - } - } - - /** - * Test to make sure, that if you - * have "X" and "XY", the binary - * sortkey also has "X" being a - * prefix of "XY". Our collation - * code makes this assumption. - * - * @param $lang String Language code for collator - * @param $base String Base string - * @param $extended String String containing base as a prefix. - * - * @dataProvider prefixDataProvider - */ - public function testIsPrefix( $lang, $base, $extended ) { - $cp = Collator::create( $lang ); - $cp->setStrength( Collator::PRIMARY ); - $baseBin = $cp->getSortKey( $base ); - // Remove sortkey terminator - $baseBin = rtrim( $baseBin, "\0" ); - $extendedBin = $cp->getSortKey( $extended ); - $this->assertStringStartsWith( $baseBin, $extendedBin, "$base is not a prefix of $extended" ); - } - - function prefixDataProvider() { - return array( - array( 'en', 'A', 'AA' ), - array( 'en', 'A', 'AAA' ), - array( 'en', 'Д', 'ДЂ' ), - array( 'en', 'Д', 'ДA' ), - // 'Ʒ' should expand to 'Z ' (note space). - array( 'fi', 'Z', 'Ʒ' ), - // 'Þ' should expand to 'th' - array( 'sv', 't', 'Þ' ), - // Javanese is a limited use alphabet, so should have 3 bytes - // per character, so do some tests with it. - array( 'en', 'ꦲ', 'ꦲꦤ' ), - array( 'en', 'ꦲ', 'ꦲД' ), - array( 'en', 'A', 'Aꦲ' ), - ); - } - - /** - * Opposite of testIsPrefix - * - * @dataProvider notPrefixDataProvider - */ - public function testNotIsPrefix( $lang, $base, $extended ) { - $cp = Collator::create( $lang ); - $cp->setStrength( Collator::PRIMARY ); - $baseBin = $cp->getSortKey( $base ); - // Remove sortkey terminator - $baseBin = rtrim( $baseBin, "\0" ); - $extendedBin = $cp->getSortKey( $extended ); - $this->assertStringStartsNotWith( $baseBin, $extendedBin, "$base is a prefix of $extended" ); - } - - function notPrefixDataProvider() { - return array( - array( 'en', 'A', 'B' ), - array( 'en', 'AC', 'ABC' ), - array( 'en', 'Z', 'Ʒ' ), - array( 'en', 'A', 'ꦲ' ), - ); - } - - /** - * Test correct first letter is fetched. - * - * @param $collation String Collation name (aka uca-en) - * @param $string String String to get first letter of - * @param $firstLetter String Expected first letter. - * - * @dataProvider firstLetterProvider - */ - public function testGetFirstLetter( $collation, $string, $firstLetter ) { - $col = Collation::factory( $collation ); - $this->assertEquals( $firstLetter, $col->getFirstLetter( $string ) ); - } - - function firstLetterProvider() { - return array( - array( 'uppercase', 'Abc', 'A' ), - array( 'uppercase', 'abc', 'A' ), - array( 'identity', 'abc', 'a' ), - array( 'uca-en', 'abc', 'A' ), - array( 'uca-en', ' ', ' ' ), - array( 'uca-en', 'Êveryone', 'E' ), - array( 'uca-vi', 'Êveryone', 'Ê' ), - // Make sure thorn is not a first letter. - array( 'uca-sv', 'The', 'T' ), - array( 'uca-sv', 'Å', 'Å' ), - array( 'uca-hu', 'dzsdo', 'Dzs' ), - array( 'uca-hu', 'dzdso', 'Dz' ), - array( 'uca-hu', 'CSD', 'Cs' ), - array( 'uca-root', 'CSD', 'C' ), - array( 'uca-fi', 'Ǥ', 'G' ), - array( 'uca-fi', 'Ŧ', 'T' ), - array( 'uca-fi', 'Ʒ', 'Z' ), - array( 'uca-fi', 'Ŋ', 'N' ), - ); - } -} diff --git a/tests/phpunit/includes/DiffHistoryBlobTest.php b/tests/phpunit/includes/DiffHistoryBlobTest.php deleted file mode 100644 index a4d5b91a..00000000 --- a/tests/phpunit/includes/DiffHistoryBlobTest.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -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' ) ) { - $this->markTestSkipped( 'The hash extension is not available' ); - - return; - } - parent::setUp(); - } - - /** - * Test for DiffHistoryBlob::xdiffAdler32() - * @dataProvider provideXdiffAdler32 - */ - public function testXdiffAdler32( $input ) { - $xdiffHash = substr( xdiff_string_rabdiff( $input, '' ), 0, 4 ); - $dhb = new DiffHistoryBlob; - $myHash = $dhb->xdiffAdler32( $input ); - $this->assertSame( bin2hex( $xdiffHash ), bin2hex( $myHash ), - "Hash of " . addcslashes( $input, "\0..\37!@\@\177..\377" ) ); - } - - public static function provideXdiffAdler32() { - return array( - array( '', 'Empty string' ), - array( "\0", 'Null' ), - array( "\0\0\0", "Several nulls" ), - array( "Hello", "An ASCII string" ), - array( str_repeat( "x", 6000 ), "A string larger than xdiff's NMAX (5552)" ) - ); - } -} diff --git a/tests/phpunit/includes/EditPageTest.php b/tests/phpunit/includes/EditPageTest.php deleted file mode 100644 index 87272a4c..00000000 --- a/tests/phpunit/includes/EditPageTest.php +++ /dev/null @@ -1,491 +0,0 @@ -<?php - -/** - * @group Editing - * - * @group Database - * ^--- tell jenkins this test needs the database - * - * @group medium - * ^--- tell phpunit that these test cases may take longer than 2 seconds. - */ -class EditPageTest extends MediaWikiLangTestCase { - - /** - * @dataProvider provideExtractSectionTitle - */ - public function testExtractSectionTitle( $section, $title ) { - $extracted = EditPage::extractSectionTitle( $section ); - $this->assertEquals( $title, $extracted ); - } - - public static function provideExtractSectionTitle() { - return array( - array( - "== Test ==\n\nJust a test section.", - "Test" - ), - array( - "An initial section, no header.", - false - ), - array( - "An initial section with a fake heder (bug 32617)\n\n== Test == ??\nwtf", - false - ), - array( - "== Section ==\nfollowed by a fake == Non-section == ??\nnoooo", - "Section" - ), - array( - "== Section== \t\r\n followed by whitespace (bug 35051)", - 'Section', - ), - ); - } - - protected function forceRevisionDate( WikiPage $page, $timestamp ) { - $dbw = wfGetDB( DB_MASTER ); - - $dbw->update( 'revision', - array( 'rev_timestamp' => $dbw->timestamp( $timestamp ) ), - array( 'rev_id' => $page->getLatest() ) ); - - $page->clear(); - } - - /** - * User input text is passed to rtrim() by edit page. This is a simple - * wrapper around assertEquals() which calls rrtrim() to normalize the - * expected and actual texts. - */ - function assertEditedTextEquals( $expected, $actual, $msg = '' ) { - return $this->assertEquals( rtrim( $expected ), rtrim( $actual ), $msg ); - } - - /** - * Performs an edit and checks the result. - * - * @param String|Title $title The title of the page to edit - * @param String|null $baseText Some text to create the page with before attempting the edit. - * @param User|String|null $user The user to perform the edit as. - * @param array $edit An array of request parameters used to define the edit to perform. - * Some well known fields are: - * * wpTextbox1: the text to submit - * * wpSummary: the edit summary - * * wpEditToken: the edit token (will be inserted if not provided) - * * wpEdittime: timestamp of the edit's base revision (will be inserted if not provided) - * * wpStarttime: timestamp when the edit started (will be inserted if not provided) - * * wpSectionTitle: the section to edit - * * wpMinorEdit: mark as minor edit - * * wpWatchthis: whether to watch the page - * @param int|null $expectedCode The expected result code (EditPage::AS_XXX constants). - * Set to null to skip the check. Defaults to EditPage::AS_OK. - * @param String|null $expectedText The text expected to be on the page after the edit. - * Set to null to skip the check. - * @param String|null $message An optional message to show along with any error message. - * - * @return WikiPage The page that was just edited, useful for getting the edit's rev_id, etc. - */ - protected function assertEdit( $title, $baseText, $user = null, array $edit, - $expectedCode = EditPage::AS_OK, $expectedText = null, $message = null - ) { - if ( is_string( $title ) ) { - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( $title, $ns ); - } - - if ( is_string( $user ) ) { - $user = User::newFromName( $user ); - - if ( $user->getId() === 0 ) { - $user->addToDatabase(); - } - } - - $page = WikiPage::factory( $title ); - - if ( $baseText !== null ) { - $content = ContentHandler::makeContent( $baseText, $title ); - $page->doEditContent( $content, "base text for test" ); - $this->forceRevisionDate( $page, '20120101000000' ); - - //sanity check - $page->clear(); - $currentText = ContentHandler::getContentText( $page->getContent() ); - - # EditPage rtrim() the user input, so we alter our expected text - # to reflect that. - $this->assertEditedTextEquals( $baseText, $currentText ); - } - - if ( $user == null ) { - $user = $GLOBALS['wgUser']; - } else { - $this->setMwGlobals( 'wgUser', $user ); - } - - if ( !isset( $edit['wpEditToken'] ) ) { - $edit['wpEditToken'] = $user->getEditToken(); - } - - if ( !isset( $edit['wpEdittime'] ) ) { - $edit['wpEdittime'] = $page->exists() ? $page->getTimestamp() : ''; - } - - if ( !isset( $edit['wpStarttime'] ) ) { - $edit['wpStarttime'] = wfTimestampNow(); - } - - $req = new FauxRequest( $edit, true ); // session ?? - - $ep = new EditPage( new Article( $title ) ); - $ep->setContextTitle( $title ); - $ep->importFormData( $req ); - - $bot = isset( $edit['bot'] ) ? (bool)$edit['bot'] : false; - - // this is where the edit happens! - // Note: don't want to use EditPage::AttemptSave, because it messes with $wgOut - // and throws exceptions like PermissionsError - $status = $ep->internalAttemptSave( $result, $bot ); - - if ( $expectedCode !== null ) { - // check edit code - $this->assertEquals( $expectedCode, $status->value, - "Expected result code mismatch. $message" ); - } - - $page = WikiPage::factory( $title ); - - if ( $expectedText !== null ) { - // check resulting page text - $content = $page->getContent(); - $text = ContentHandler::getContentText( $content ); - - # EditPage rtrim() the user input, so we alter our expected text - # to reflect that. - $this->assertEditedTextEquals( $expectedText, $text, - "Expected article text mismatch. $message" ); - } - - return $page; - } - - public function testCreatePage() { - $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( - '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() { - $text = "one"; - $edit = array( - 'wpTextbox1' => $text, - 'wpSummary' => 'first update', - ); - - $page = $this->assertEdit( 'EditPageTest_testUpdatePage', "zero", null, $edit, - EditPage::AS_SUCCESS_UPDATE, $text, - "expected successfull update with given text" ); - - $this->forceRevisionDate( $page, '20120101000000' ); - - $text = "two"; - $edit = array( - 'wpTextbox1' => $text, - 'wpSummary' => 'second update', - ); - - $this->assertEdit( 'EditPageTest_testUpdatePage', null, null, $edit, - EditPage::AS_SUCCESS_UPDATE, $text, - "expected successfull update with given text" ); - } - - public static function provideSectionEdit() { - $text = 'Intro - -== one == -first section. - -== two == -second section. -'; - - $sectionOne = '== one == -hello -'; - - $newSection = '== new section == - -hello -'; - - $textWithNewSectionOne = preg_replace( - '/== one ==.*== two ==/ms', - "$sectionOne\n== two ==", $text - ); - - $textWithNewSectionAdded = "$text\n$newSection"; - - return array( - array( #0 - $text, - '', - 'hello', - 'replace all', - 'hello' - ), - - array( #1 - $text, - '1', - $sectionOne, - 'replace first section', - $textWithNewSectionOne, - ), - - array( #2 - $text, - 'new', - 'hello', - 'new section', - $textWithNewSectionAdded, - ), - ); - } - - /** - * @dataProvider provideSectionEdit - */ - public function testSectionEdit( $base, $section, $text, $summary, $expected ) { - $edit = array( - 'wpTextbox1' => $text, - 'wpSummary' => $summary, - 'wpSection' => $section, - ); - - $this->assertEdit( 'EditPageTest_testSectionEdit', $base, null, $edit, - EditPage::AS_SUCCESS_UPDATE, $expected, - "expected successfull update of section" ); - } - - public static function provideAutoMerge() { - $tests = array(); - - $tests[] = array( #0: plain conflict - "Elmo", # base edit user - "one\n\ntwo\n\nthree\n", - array( #adam's edit - 'wpStarttime' => 1, - 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n", - ), - array( #berta's edit - 'wpStarttime' => 2, - 'wpTextbox1' => "(one)\n\ntwo\n\nthree\n", - ), - EditPage::AS_CONFLICT_DETECTED, # expected code - "ONE\n\ntwo\n\nthree\n", # expected text - 'expected edit conflict', # message - ); - - $tests[] = array( #1: successful merge - "Elmo", # base edit user - "one\n\ntwo\n\nthree\n", - array( #adam's edit - 'wpStarttime' => 1, - 'wpTextbox1' => "ONE\n\ntwo\n\nthree\n", - ), - array( #berta's edit - 'wpStarttime' => 2, - 'wpTextbox1' => "one\n\ntwo\n\nTHREE\n", - ), - EditPage::AS_SUCCESS_UPDATE, # expected code - "ONE\n\ntwo\n\nTHREE\n", # expected text - 'expected automatic merge', # message - ); - - $text = "Intro\n\n"; - $text .= "== first section ==\n\n"; - $text .= "one\n\ntwo\n\nthree\n\n"; - $text .= "== second section ==\n\n"; - $text .= "four\n\nfive\n\nsix\n\n"; - - // extract the first section. - $section = preg_replace( '/.*(== first section ==.*)== second section ==.*/sm', '$1', $text ); - - // generate expected text after merge - $expected = str_replace( 'one', 'ONE', str_replace( 'three', 'THREE', $text ) ); - - $tests[] = array( #2: merge in section - "Elmo", # base edit user - $text, - array( #adam's edit - 'wpStarttime' => 1, - 'wpTextbox1' => str_replace( 'one', 'ONE', $section ), - 'wpSection' => '1' - ), - array( #berta's edit - 'wpStarttime' => 2, - 'wpTextbox1' => str_replace( 'three', 'THREE', $section ), - 'wpSection' => '1' - ), - EditPage::AS_SUCCESS_UPDATE, # expected code - $expected, # expected text - 'expected automatic section merge', # message - ); - - // see whether it makes a difference who did the base edit - $testsWithAdam = array_map( function ( $test ) { - $test[0] = 'Adam'; // change base edit user - return $test; - }, $tests ); - - $testsWithBerta = array_map( function ( $test ) { - $test[0] = 'Berta'; // change base edit user - return $test; - }, $tests ); - - return array_merge( $tests, $testsWithAdam, $testsWithBerta ); - } - - /** - * @dataProvider provideAutoMerge - */ - public function testAutoMerge( $baseUser, $text, $adamsEdit, $bertasEdit, - $expectedCode, $expectedText, $message = null - ) { - $this->checkHasDiff3(); - - //create page - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( 'EditPageTest_testAutoMerge', $ns ); - $page = WikiPage::factory( $title ); - - if ( $page->exists() ) { - $page->doDeleteArticle( "clean slate for testing" ); - } - - $baseEdit = array( - 'wpTextbox1' => $text, - ); - - $page = $this->assertEdit( 'EditPageTest_testAutoMerge', null, - $baseUser, $baseEdit, null, null, __METHOD__ ); - - $this->forceRevisionDate( $page, '20120101000000' ); - - $edittime = $page->getTimestamp(); - - // start timestamps for conflict detection - if ( !isset( $adamsEdit['wpStarttime'] ) ) { - $adamsEdit['wpStarttime'] = 1; - } - - if ( !isset( $bertasEdit['wpStarttime'] ) ) { - $bertasEdit['wpStarttime'] = 2; - } - - $starttime = wfTimestampNow(); - $adamsTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$adamsEdit['wpStarttime'] ); - $bertasTime = wfTimestamp( TS_MW, (int)wfTimestamp( TS_UNIX, $starttime ) + (int)$bertasEdit['wpStarttime'] ); - - $adamsEdit['wpStarttime'] = $adamsTime; - $bertasEdit['wpStarttime'] = $bertasTime; - - $adamsEdit['wpSummary'] = 'Adam\'s edit'; - $bertasEdit['wpSummary'] = 'Bertas\'s edit'; - - $adamsEdit['wpEdittime'] = $edittime; - $bertasEdit['wpEdittime'] = $edittime; - - // first edit - $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Adam', $adamsEdit, - EditPage::AS_SUCCESS_UPDATE, null, "expected successfull update" ); - - // second edit - $this->assertEdit( 'EditPageTest_testAutoMerge', null, 'Berta', $bertasEdit, - $expectedCode, $expectedText, $message ); - } -} diff --git a/tests/phpunit/includes/ExternalStoreTest.php b/tests/phpunit/includes/ExternalStoreTest.php deleted file mode 100644 index fcffcbc2..00000000 --- a/tests/phpunit/includes/ExternalStoreTest.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * External Store tests - */ - -class ExternalStoreTest extends MediaWikiTestCase { - - public function testExternalFetchFromURL() { - $this->setMwGlobals( 'wgExternalStores', false ); - - $this->assertFalse( - ExternalStore::fetchFromURL( 'FOO://cluster1/200' ), - 'Deny if wgExternalStores is not set to a non-empty array' - ); - - $this->setMwGlobals( 'wgExternalStores', array( 'FOO' ) ); - - $this->assertEquals( - ExternalStore::fetchFromURL( 'FOO://cluster1/200' ), - 'Hello', - 'Allow FOO://cluster1/200' - ); - $this->assertEquals( - ExternalStore::fetchFromURL( 'FOO://cluster1/300/0' ), - 'Hello', - 'Allow FOO://cluster1/300/0' - ); - # Assertions for r68900 - $this->assertFalse( - ExternalStore::fetchFromURL( 'ftp.example.org' ), - 'Deny domain ftp.example.org' - ); - $this->assertFalse( - ExternalStore::fetchFromURL( '/example.txt' ), - 'Deny path /example.txt' - ); - $this->assertFalse( - ExternalStore::fetchFromURL( 'http://' ), - 'Deny protocol http://' - ); - } -} - -class ExternalStoreFOO { - - protected $data = array( - 'cluster1' => array( - '200' => 'Hello', - '300' => array( - 'Hello', 'World', - ), - ), - ); - - /** - * Fetch data from given URL - * @param $url String: an url of the form FOO://cluster/id or FOO://cluster/id/itemid. - * @return mixed - */ - function fetchFromURL( $url ) { - // Based on ExternalStoreDB - $path = explode( '/', $url ); - $cluster = $path[2]; - $id = $path[3]; - if ( isset( $path[4] ) ) { - $itemID = $path[4]; - } else { - $itemID = false; - } - - if ( !isset( $this->data[$cluster][$id] ) ) { - return null; - } - - if ( $itemID !== false && is_array( $this->data[$cluster][$id] ) && isset( $this->data[$cluster][$id][$itemID] ) ) { - return $this->data[$cluster][$id][$itemID]; - } - - return $this->data[$cluster][$id]; - } -} diff --git a/tests/phpunit/includes/ExtraParserTest.php b/tests/phpunit/includes/ExtraParserTest.php deleted file mode 100644 index 6c67beb1..00000000 --- a/tests/phpunit/includes/ExtraParserTest.php +++ /dev/null @@ -1,157 +0,0 @@ -<?php - -/** - * Parser-related tests that don't suit for parserTests.txt - */ -class ExtraParserTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $contLang = Language::factory( 'en' ); - $this->setMwGlobals( array( - 'wgShowDBErrorBacktrace' => true, - 'wgLanguageCode' => 'en', - 'wgContLang' => $contLang, - 'wgLang' => Language::factory( 'en' ), - 'wgMemc' => new EmptyBagOStuff, - 'wgAlwaysUseTidy' => false, - 'wgCleanSignatures' => true, - ) ); - - $this->options = ParserOptions::newFromUserAndLang( new User, $contLang ); - $this->options->setTemplateCallback( array( __CLASS__, 'statelessFetchTemplate' ) ); - $this->parser = new Parser; - - MagicWord::clearCache(); - } - - // Bug 8689 - Long numeric lines kill the parser - public function testBug8689() { - global $wgUser; - $longLine = '1.' . str_repeat( '1234567890', 100000 ) . "\n"; - - $t = Title::newFromText( 'Unit test' ); - $options = ParserOptions::newFromUser( $wgUser ); - $this->assertEquals( "<p>$longLine</p>", - $this->parser->parse( $longLine, $t, $options )->getText() ); - } - - /* Test the parser entry points */ - public function testParse() { - $title = Title::newFromText( __FUNCTION__ ); - $parserOutput = $this->parser->parse( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options ); - $this->assertEquals( "<p>Test\nContent of <i>Template:Foo</i>\nContent of <i>Template:Bar</i>\n</p>", $parserOutput->getText() ); - } - - public function testPreSaveTransform() { - global $wgUser; - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->preSaveTransform( "Test\r\n{{subst:Foo}}\n{{Bar}}", $title, $wgUser, $this->options ); - - $this->assertEquals( "Test\nContent of ''Template:Foo''\n{{Bar}}", $outputText ); - } - - public function testPreprocess() { - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->preprocess( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options ); - - $this->assertEquals( "Test\nContent of ''Template:Foo''\nContent of ''Template:Bar''", $outputText ); - } - - /** - * cleanSig() makes all templates substs and removes tildes - */ - public function testCleanSig() { - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); - - $this->assertEquals( "{{SUBST:Foo}} ", $outputText ); - } - - /** - * cleanSig() should do nothing if disabled - */ - public function testCleanSigDisabled() { - $this->setMwGlobals( 'wgCleanSignatures', false ); - - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); - - $this->assertEquals( "{{Foo}} ~~~~", $outputText ); - } - - /** - * cleanSigInSig() just removes tildes - * @dataProvider provideStringsForCleanSigInSig - */ - public function testCleanSigInSig( $in, $out ) { - $this->assertEquals( Parser::cleanSigInSig( $in ), $out ); - } - - public static function provideStringsForCleanSigInSig() { - return array( - array( "{{Foo}} ~~~~", "{{Foo}} " ), - array( "~~~", "" ), - array( "~~~~~", "" ), - ); - } - - 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 ); - - $this->assertEquals( "=== Heading 2 ===\nSection 2", $outputText2 ); - $this->assertEquals( "== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2", $outputText1 ); - } - - 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 ); - } - - /** - * Templates and comments are not affected, but noinclude/onlyinclude is. - */ - public function testGetPreloadText() { - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->getPreloadText( "{{Foo}}<noinclude> censored</noinclude> information <!-- is very secret -->", $title, $this->options ); - - $this->assertEquals( "{{Foo}} information <!-- is very secret -->", $outputText ); - } - - static function statelessFetchTemplate( $title, $parser = false ) { - $text = "Content of ''" . $title->getFullText() . "''"; - $deps = array(); - - return array( - 'text' => $text, - 'finalTitle' => $title, - 'deps' => $deps ); - } - - /** - * @group Database - */ - public function testTrackingCategory() { - $title = Title::newFromText( __FUNCTION__ ); - $catName = wfMessage( 'broken-file-category' )->inContentLanguage()->text(); - $cat = Title::makeTitleSafe( NS_CATEGORY, $catName ); - $expected = array( $cat->getDBkey() ); - $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options ); - $result = $parserOutput->getCategoryLinks(); - $this->assertEquals( $expected, $result ); - } - - /** - * @group Database - */ - public function testTrackingCategorySpecial() { - // Special pages shouldn't have tracking cats. - $title = SpecialPage::getTitleFor( 'Contributions' ); - $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options ); - $result = $parserOutput->getCategoryLinks(); - $this->assertEmpty( $result ); - } -} diff --git a/tests/phpunit/includes/FallbackTest.php b/tests/phpunit/includes/FallbackTest.php deleted file mode 100644 index f408f471..00000000 --- a/tests/phpunit/includes/FallbackTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php - -/** - * @covers Fallback - */ -class FallbackTest extends MediaWikiTestCase { - - public function testFallbackMbstringFunctions() { - - if ( !extension_loaded( 'mbstring' ) ) { - $this->markTestSkipped( "The mb_string functions must be installed to test the fallback functions" ); - } - - $sampleUTF = "Östergötland_coat_of_arms.png"; - - //mb_substr - $substr_params = array( - array( 0, 0 ), - array( 5, -4 ), - array( 33 ), - array( 100, -5 ), - array( -8, 10 ), - array( 1, 1 ), - array( 2, -1 ) - ); - - foreach ( $substr_params as $param_set ) { - $old_param_set = $param_set; - array_unshift( $param_set, $sampleUTF ); - - $this->assertEquals( - call_user_func_array( 'mb_substr', $param_set ), - call_user_func_array( 'Fallback::mb_substr', $param_set ), - 'Fallback mb_substr with params ' . implode( ', ', $old_param_set ) - ); - } - - //mb_strlen - $this->assertEquals( - mb_strlen( $sampleUTF ), - Fallback::mb_strlen( $sampleUTF ), - 'Fallback mb_strlen' - ); - - //mb_str(r?)pos - $strpos_params = array( - //array( 'ter' ), - //array( 'Ö' ), - //array( 'Ö', 3 ), - //array( 'oat_', 100 ), - //array( 'c', -10 ), - //Broken for now - ); - - foreach ( $strpos_params as $param_set ) { - $old_param_set = $param_set; - array_unshift( $param_set, $sampleUTF ); - - $this->assertEquals( - call_user_func_array( 'mb_strpos', $param_set ), - call_user_func_array( 'Fallback::mb_strpos', $param_set ), - 'Fallback mb_strpos with params ' . implode( ', ', $old_param_set ) - ); - - $this->assertEquals( - call_user_func_array( 'mb_strrpos', $param_set ), - call_user_func_array( 'Fallback::mb_strrpos', $param_set ), - 'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set ) - ); - } - } - -}
\ No newline at end of file diff --git a/tests/phpunit/includes/FauxRequestTest.php b/tests/phpunit/includes/FauxRequestTest.php deleted file mode 100644 index 9f3aa11d..00000000 --- a/tests/phpunit/includes/FauxRequestTest.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php - -class FauxRequestTest extends MediaWikiTestCase { - - public function testGetSetHeader() { - $value = 'test/test'; - - $request = new FauxRequest(); - $request->setHeader( 'Content-Type', $value ); - - $this->assertEquals( $request->getHeader( 'Content-Type' ), $value ); - $this->assertEquals( $request->getHeader( 'CONTENT-TYPE' ), $value ); - $this->assertEquals( $request->getHeader( 'content-type' ), $value ); - } -} diff --git a/tests/phpunit/includes/FauxResponseTest.php b/tests/phpunit/includes/FauxResponseTest.php deleted file mode 100644 index f9ba1b3b..00000000 --- a/tests/phpunit/includes/FauxResponseTest.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Tests for the FauxResponse class - * - * Copyright @ 2011 Alexandre Emsenhuber - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -class FauxResponseTest extends MediaWikiTestCase { - var $response; - - protected function setUp() { - parent::setUp(); - $this->response = new FauxResponse; - } - - 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' ); - } - - public function testHeader() { - $this->assertEquals( null, $this->response->getheader( 'Location' ), 'Non-existing header' ); - - $this->response->header( 'Location: http://localhost/' ); - $this->assertEquals( 'http://localhost/', $this->response->getheader( 'Location' ), 'Set header' ); - - $this->response->header( 'Location: http://127.0.0.1/' ); - $this->assertEquals( 'http://127.0.0.1/', $this->response->getheader( 'Location' ), 'Same header' ); - - $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' ); - } - - public function testResponseCode() { - $this->response->header( 'HTTP/1.1 200' ); - $this->assertEquals( 200, $this->response->getStatusCode(), 'Header with no message' ); - - $this->response->header( 'HTTP/1.x 201' ); - $this->assertEquals( 201, $this->response->getStatusCode(), 'Header with no message and protocol 1.x' ); - - $this->response->header( 'HTTP/1.1 202 OK' ); - $this->assertEquals( 202, $this->response->getStatusCode(), 'Normal header' ); - - $this->response->header( 'HTTP/1.x 203 OK' ); - $this->assertEquals( 203, $this->response->getStatusCode(), 'Normal header with no message and protocol 1.x' ); - - $this->response->header( 'HTTP/1.x 204 OK', false, 205 ); - $this->assertEquals( 205, $this->response->getStatusCode(), 'Third parameter overrides the HTTP/... header' ); - - $this->response->header( 'Location: http://localhost/', false, 206 ); - $this->assertEquals( 206, $this->response->getStatusCode(), 'Third parameter with another header' ); - } -} diff --git a/tests/phpunit/includes/FormOptionsInitializationTest.php b/tests/phpunit/includes/FormOptionsInitializationTest.php deleted file mode 100644 index fb2304dc..00000000 --- a/tests/phpunit/includes/FormOptionsInitializationTest.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php -/** - * This file host two test case classes for the MediaWiki FormOptions class: - * - FormOptionsInitializationTest : tests initialization of the class. - * - FormOptionsTest : tests methods an on instance - * - * The split let us take advantage of setting up a fixture for the methods - * tests. - */ - -/** - * Dummy class to makes FormOptions::$options public. - * Used by FormOptionsInitializationTest which need to verify the $options - * array is correctly set through the FormOptions::add() function. - */ -class FormOptionsExposed extends FormOptions { - public function getOptions() { - return $this->options; - } -} - -/** - * Test class for FormOptions initialization - * Ensure the FormOptions::add() does what we want it to do. - * - * Generated by PHPUnit on 2011-02-28 at 20:46:27. - * - * Copyright © 2011, Antoine Musso - * - * @author Antoine Musso - */ -class FormOptionsInitializationTest extends MediaWikiTestCase { - /** - * @var FormOptions - */ - protected $object; - - - /** - * A new fresh and empty FormOptions object to test initialization - * with. - */ - protected function setUp() { - parent::setUp(); - $this->object = new FormOptionsExposed(); - } - - public function testAddStringOption() { - $this->object->add( 'foo', 'string value' ); - $this->assertEquals( - array( - 'foo' => array( - 'default' => 'string value', - 'consumed' => false, - 'type' => FormOptions::STRING, - 'value' => null, - ) - ), - $this->object->getOptions() - ); - } - - public function testAddIntegers() { - $this->object->add( 'one', 1 ); - $this->object->add( 'negone', -1 ); - $this->assertEquals( - array( - 'negone' => array( - 'default' => -1, - 'value' => null, - 'consumed' => false, - 'type' => FormOptions::INT, - ), - 'one' => array( - 'default' => 1, - 'value' => null, - 'consumed' => false, - 'type' => FormOptions::INT, - ) - ), - $this->object->getOptions() - ); - } -} diff --git a/tests/phpunit/includes/FormOptionsTest.php b/tests/phpunit/includes/FormOptionsTest.php deleted file mode 100644 index 0a13cfec..00000000 --- a/tests/phpunit/includes/FormOptionsTest.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php -/** - * This file host two test case classes for the MediaWiki FormOptions class: - * - FormOptionsInitializationTest : tests initialization of the class. - * - FormOptionsTest : tests methods an on instance - * - * The split let us take advantage of setting up a fixture for the methods - * tests. - */ - -/** - * Test class for FormOptions methods. - * Generated by PHPUnit on 2011-02-28 at 20:46:27. - * - * Copyright © 2011, Antoine Musso - * - * @author Antoine Musso - */ -class FormOptionsTest extends MediaWikiTestCase { - /** - * @var FormOptions - */ - protected $object; - - /** - * Instanciates a FormOptions object to play with. - * FormOptions::add() is tested by the class FormOptionsInitializationTest - * so we assume the function is well tested already an use it to create - * the fixture. - */ - protected function setUp() { - parent::setUp(); - $this->object = new FormOptions; - $this->object->add( 'string1', 'string one' ); - $this->object->add( 'string2', 'string two' ); - $this->object->add( 'integer', 0 ); - $this->object->add( 'intnull', 0, FormOptions::INTNULL ); - } - - /** Helpers for testGuessType() */ - /* @{ */ - private function assertGuessBoolean( $data ) { - $this->guess( FormOptions::BOOL, $data ); - } - private function assertGuessInt( $data ) { - $this->guess( FormOptions::INT, $data ); - } - private function assertGuessString( $data ) { - $this->guess( FormOptions::STRING, $data ); - } - - /** Generic helper */ - private function guess( $expected, $data ) { - $this->assertEquals( - $expected, - FormOptions::guessType( $data ) - ); - } - /* @} */ - - /** - * Reuse helpers above assertGuessBoolean assertGuessInt assertGuessString - */ - public function testGuessTypeDetection() { - $this->assertGuessBoolean( true ); - $this->assertGuessBoolean( false ); - - $this->assertGuessInt( 0 ); - $this->assertGuessInt( -5 ); - $this->assertGuessInt( 5 ); - $this->assertGuessInt( 0x0F ); - - $this->assertGuessString( 'true' ); - $this->assertGuessString( 'false' ); - $this->assertGuessString( '5' ); - $this->assertGuessString( '0' ); - } - - /** - * @expectedException MWException - */ - public function testGuessTypeOnArrayThrowException() { - $this->object->guessType( array( 'foo' ) ); - } - /** - * @expectedException MWException - */ - public function testGuessTypeOnNullThrowException() { - $this->object->guessType( null ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php deleted file mode 100644 index 6154df1d..00000000 --- a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php +++ /dev/null @@ -1,652 +0,0 @@ -<?php - -class GlobalTest extends MediaWikiTestCase { - protected function setUp() { - parent::setUp(); - - $readOnlyFile = tempnam( wfTempDir(), "mwtest_readonly" ); - unlink( $readOnlyFile ); - - $this->setMwGlobals( array( - 'wgReadOnlyFile' => $readOnlyFile, - 'wgUrlProtocols' => array( - 'http://', - 'https://', - 'mailto:', - '//', - 'file://', # Non-default - ), - ) ); - } - - protected function tearDown() { - global $wgReadOnlyFile; - - if ( file_exists( $wgReadOnlyFile ) ) { - unlink( $wgReadOnlyFile ); - } - - parent::tearDown(); - } - - /** - * @dataProvider provideForWfArrayDiff2 - * @covers ::wfArrayDiff2 - */ - public function testWfArrayDiff2( $a, $b, $expected ) { - $this->assertEquals( - wfArrayDiff2( $a, $b ), $expected - ); - } - - // @todo Provide more tests - public static function provideForWfArrayDiff2() { - // $a $b $expected - return array( - array( - array( 'a', 'b' ), - array( 'a', 'b' ), - array(), - ), - array( - array( array( 'a' ), array( 'a', 'b', 'c' ) ), - array( array( 'a' ), array( 'a', 'b' ) ), - array( 1 => array( 'a', 'b', 'c' ) ), - ), - ); - } - - /** - * @covers ::wfRandom - */ - public function testRandom() { - # This could hypothetically fail, but it shouldn't ;) - $this->assertFalse( - wfRandom() == wfRandom() ); - } - - /** - * @covers ::wfUrlencode - */ - public function testUrlencode() { - $this->assertEquals( - "%E7%89%B9%E5%88%A5:Contributions/Foobar", - wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) ); - } - - /** - * @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" ) ); - } - - /** - * @covers ::wfReadOnly - */ - public function testReadOnlyEmpty() { - global $wgReadOnly; - $wgReadOnly = null; - - $this->assertFalse( wfReadOnly() ); - $this->assertFalse( wfReadOnly() ); - } - - /** - * @covers ::wfReadOnly - */ - public function testReadOnlySet() { - global $wgReadOnly, $wgReadOnlyFile; - - $f = fopen( $wgReadOnlyFile, "wt" ); - fwrite( $f, 'Message' ); - fclose( $f ); - $wgReadOnly = null; # Check on $wgReadOnlyFile - - $this->assertTrue( wfReadOnly() ); - $this->assertTrue( wfReadOnly() ); # Check cached - - unlink( $wgReadOnlyFile ); - $wgReadOnly = null; # Clean cache - - $this->assertFalse( wfReadOnly() ); - $this->assertFalse( wfReadOnly() ); - } - - public static function provideArrayToCGI() { - return array( - array( array(), '' ), // empty - array( array( 'foo' => 'bar' ), 'foo=bar' ), // string test - array( array( 'foo' => '' ), 'foo=' ), // empty string test - array( array( 'foo' => 1 ), 'foo=1' ), // number test - array( array( 'foo' => true ), 'foo=1' ), // true test - array( array( 'foo' => false ), '' ), // false test - array( array( 'foo' => null ), '' ), // null test - array( array( 'foo' => 'A&B=5+6@!"\'' ), 'foo=A%26B%3D5%2B6%40%21%22%27' ), // urlencoding test - array( array( 'foo' => 'bar', 'baz' => 'is', 'asdf' => 'qwerty' ), 'foo=bar&baz=is&asdf=qwerty' ), // multi-item test - array( array( 'foo' => array( 'bar' => 'baz' ) ), 'foo%5Bbar%5D=baz' ), - array( array( 'foo' => array( 'bar' => 'baz', 'qwerty' => 'asdf' ) ), 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf' ), - array( array( 'foo' => array( 'bar', 'baz' ) ), 'foo%5B0%5D=bar&foo%5B1%5D=baz' ), - array( array( 'foo' => array( 'bar' => array( 'bar' => 'baz' ) ) ), 'foo%5Bbar%5D%5Bbar%5D=baz' ), - ); - } - - /** - * @dataProvider provideArrayToCGI - * @covers ::wfArrayToCgi - */ - public function testArrayToCGI( $array, $result ) { - $this->assertEquals( $result, wfArrayToCgi( $array ) ); - } - - - /** - * @covers ::testWfArrayDiff2 - */ - public function testArrayToCGI2() { - $this->assertEquals( - "baz=bar&foo=bar", - wfArrayToCgi( - array( 'baz' => 'bar' ), - array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) ); - } - - public static function provideCgiToArray() { - return array( - array( '', array() ), // empty - array( 'foo=bar', array( 'foo' => 'bar' ) ), // string - array( 'foo=', array( 'foo' => '' ) ), // empty string - array( 'foo', array( 'foo' => '' ) ), // missing = - array( 'foo=bar&qwerty=asdf', array( 'foo' => 'bar', 'qwerty' => 'asdf' ) ), // multiple value - array( 'foo=A%26B%3D5%2B6%40%21%22%27', array( 'foo' => 'A&B=5+6@!"\'' ) ), // urldecoding test - array( 'foo%5Bbar%5D=baz', array( 'foo' => array( 'bar' => 'baz' ) ) ), - array( 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf', array( 'foo' => array( 'bar' => 'baz', 'qwerty' => 'asdf' ) ) ), - array( 'foo%5B0%5D=bar&foo%5B1%5D=baz', array( 'foo' => array( 0 => 'bar', 1 => 'baz' ) ) ), - array( 'foo%5Bbar%5D%5Bbar%5D=baz', array( 'foo' => array( 'bar' => array( 'bar' => 'baz' ) ) ) ), - ); - } - - /** - * @dataProvider provideCgiToArray - * @covers ::wfCgiToArray - */ - public function testCgiToArray( $cgi, $result ) { - $this->assertEquals( $result, wfCgiToArray( $cgi ) ); - } - - public static function provideCgiRoundTrip() { - return array( - array( '' ), - array( 'foo=bar' ), - array( 'foo=' ), - array( 'foo=bar&baz=biz' ), - array( 'foo=A%26B%3D5%2B6%40%21%22%27' ), - array( 'foo%5Bbar%5D=baz' ), - array( 'foo%5B0%5D=bar&foo%5B1%5D=baz' ), - array( 'foo%5Bbar%5D%5Bbar%5D=baz' ), - ); - } - - /** - * @dataProvider provideCgiRoundTrip - * @covers ::wfArrayToCgi - */ - public function testCgiRoundTrip( $cgi ) { - $this->assertEquals( $cgi, wfArrayToCgi( wfCgiToArray( $cgi ) ) ); - } - - /** - * @covers ::mimeTypeMatch - */ - public function testMimeTypeMatch() { - $this->assertEquals( - 'text/html', - mimeTypeMatch( 'text/html', - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.3 ) ) ); - $this->assertEquals( - 'text/*', - mimeTypeMatch( 'text/html', - array( 'image/*' => 1.0, - 'text/*' => 0.5 ) ) ); - $this->assertEquals( - '*/*', - mimeTypeMatch( 'text/html', - array( '*/*' => 1.0 ) ) ); - $this->assertNull( - mimeTypeMatch( 'text/html', - array( 'image/png' => 1.0, - 'image/svg+xml' => 0.5 ) ) ); - } - - /** - * @covers ::wfNegotiateType - */ - public function testNegotiateType() { - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.5, - 'text/*' => 0.2 ), - array( 'text/html' => 1.0 ) ) ); - $this->assertEquals( - 'application/xhtml+xml', - wfNegotiateType( - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.5, - 'text/*' => 0.2 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'text/html' => 1.0, - 'text/plain' => 0.5, - 'text/*' => 0.5, - 'application/xhtml+xml' => 0.2 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'text/*' => 1.0, - 'image/*' => 0.7, - '*/*' => 0.3 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertNull( - wfNegotiateType( - array( 'text/*' => 1.0 ), - array( 'application/xhtml+xml' => 1.0 ) ) ); - } - - /** - * @covers ::wfDebug - * @covers ::wfDebugMem - */ - public function testDebugFunctionTest() { - - global $wgDebugLogFile, $wgDebugTimestamps; - - $old_log_file = $wgDebugLogFile; - $wgDebugLogFile = tempnam( wfTempDir(), 'mw-' ); - # @todo FIXME: $wgDebugTimestamps should be tested - $old_wgDebugTimestamps = $wgDebugTimestamps; - $wgDebugTimestamps = false; - - wfDebug( "This is a normal string" ); - $this->assertEquals( "This is a normal string", file_get_contents( $wgDebugLogFile ) ); - unlink( $wgDebugLogFile ); - - wfDebug( "This is nöt an ASCII string" ); - $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 ); - - wfDebugMem(); - $this->assertGreaterThan( 5000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) ); - unlink( $wgDebugLogFile ); - - wfDebugMem( true ); - $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) ); - unlink( $wgDebugLogFile ); - - $wgDebugLogFile = $old_log_file; - $wgDebugTimestamps = $old_wgDebugTimestamps; - } - - /** - * @covers ::wfClientAcceptsGzip - */ - public function testClientAcceptsGzipTest() { - - $settings = array( - 'gzip' => true, - 'bzip' => false, - '*' => false, - 'compress, gzip' => true, - 'gzip;q=1.0' => true, - 'foozip' => false, - 'foo*zip' => false, - 'gzip;q=abcde' => true, //is this REALLY valid? - 'gzip;q=12345678.9' => true, - ' gzip' => true, - ); - - if ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) { - $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING']; - } - - foreach ( $settings as $encoding => $expect ) { - $_SERVER['HTTP_ACCEPT_ENCODING'] = $encoding; - - $this->assertEquals( $expect, wfClientAcceptsGzip( true ), - "'$encoding' => " . wfBoolToStr( $expect ) ); - } - - if ( isset( $old_server_setting ) ) { - $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting; - } - } - - /** - * @covers ::swap - */ - public function testSwapVarsTest() { - $var1 = 1; - $var2 = 2; - - $this->assertEquals( $var1, 1, 'var1 is set originally' ); - $this->assertEquals( $var2, 2, 'var1 is set originally' ); - - swap( $var1, $var2 ); - - $this->assertEquals( $var1, 2, 'var1 is swapped' ); - $this->assertEquals( $var2, 1, 'var2 is swapped' ); - } - - /** - * @covers ::wfPercent - */ - public function testWfPercentTest() { - - $pcts = array( - array( 6 / 7, '0.86%', 2, false ), - array( 3 / 3, '1%' ), - array( 22 / 7, '3.14286%', 5 ), - array( 3 / 6, '0.5%' ), - array( 1 / 3, '0%', 0 ), - array( 10 / 3, '0%', -1 ), - array( 3 / 4 / 5, '0.1%', 1 ), - array( 6 / 7 * 8, '6.8571428571%', 10 ), - ); - - foreach ( $pcts as $pct ) { - if ( !isset( $pct[2] ) ) { - $pct[2] = 2; - } - if ( !isset( $pct[3] ) ) { - $pct[3] = true; - } - - $this->assertEquals( wfPercent( $pct[0], $pct[2], $pct[3] ), $pct[1], $pct[1] ); - } - } - - /** - * test @see wfShorthandToInteger() - * @dataProvider provideShorthand - * @covers ::wfShorthandToInteger - */ - public function testWfShorthandToInteger( $shorthand, $expected ) { - $this->assertEquals( $expected, - wfShorthandToInteger( $shorthand ) - ); - } - - /** array( shorthand, expected integer ) */ - public static function provideShorthand() { - return array( - # Null, empty ... - array( '', -1 ), - array( ' ', -1 ), - array( null, -1 ), - - # Failures returns 0 :( - array( 'ABCDEFG', 0 ), - array( 'Ak', 0 ), - - # Int, strings with spaces - array( 1, 1 ), - array( ' 1 ', 1 ), - array( 1023, 1023 ), - array( ' 1023 ', 1023 ), - - # kilo, Mega, Giga - array( '1k', 1024 ), - array( '1K', 1024 ), - array( '1m', 1024 * 1024 ), - array( '1M', 1024 * 1024 ), - array( '1g', 1024 * 1024 * 1024 ), - array( '1G', 1024 * 1024 * 1024 ), - - # Negatives - array( -1, -1 ), - array( -500, -500 ), - array( '-500', -500 ), - array( '-1k', -1024 ), - - # Zeroes - array( '0', 0 ), - array( '0k', 0 ), - array( '0M', 0 ), - array( '0G', 0 ), - array( '-0', 0 ), - array( '-0k', 0 ), - array( '-0M', 0 ), - array( '-0G', 0 ), - ); - } - - /** - * @param String $old: Text as it was in the database - * @param String $mine: Text submitted while user was editing - * @param String $yours: Text submitted by the user - * @param Boolean $expectedMergeResult Whether the merge should be a success - * @param String $expectedText: Text after merge has been completed - * - * @dataProvider provideMerge() - * @group medium - * @covers ::wfMerge - */ - public function testMerge( $old, $mine, $yours, $expectedMergeResult, $expectedText ) { - $this->checkHasDiff3(); - - $mergedText = null; - $isMerged = wfMerge( $old, $mine, $yours, $mergedText ); - - $msg = 'Merge should be a '; - $msg .= $expectedMergeResult ? 'success' : 'failure'; - $this->assertEquals( $expectedMergeResult, $isMerged, $msg ); - - if ( $isMerged ) { - // Verify the merged text - $this->assertEquals( $expectedText, $mergedText, - 'is merged text as expected?' ); - } - } - - public static function provideMerge() { - $EXPECT_MERGE_SUCCESS = true; - $EXPECT_MERGE_FAILURE = false; - - return array( - // #0: clean merge - array( - // old: - "one one one\n" . // trimmed - "\n" . - "two two two", - - // mine: - "one one one ONE ONE\n" . - "\n" . - "two two two\n", // with tailing whitespace - - // yours: - "one one one\n" . - "\n" . - "two two TWO TWO", // trimmed - - // ok: - $EXPECT_MERGE_SUCCESS, - - // result: - "one one one ONE ONE\n" . - "\n" . - "two two TWO TWO\n", // note: will always end in a newline - ), - - // #1: conflict, fail - array( - // old: - "one one one", // trimmed - - // mine: - "one one one ONE ONE\n" . - "\n" . - "bla bla\n" . - "\n", // with tailing whitespace - - // yours: - "one one one\n" . - "\n" . - "two two", // trimmed - - $EXPECT_MERGE_FAILURE, - - // result: - null, - ), - ); - } - - /** - * @dataProvider provideMakeUrlIndexes() - * @covers ::wfMakeUrlIndexes - */ - public function testMakeUrlIndexes( $url, $expected ) { - $index = wfMakeUrlIndexes( $url ); - $this->assertEquals( $expected, $index, "wfMakeUrlIndexes(\"$url\")" ); - } - - public static function provideMakeUrlIndexes() { - return array( - array( - // just a regular :) - 'https://bugzilla.wikimedia.org/show_bug.cgi?id=28627', - array( 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627' ) - ), - array( - // mailtos are handled special - // is this really right though? that final . probably belongs earlier? - 'mailto:wiki@wikimedia.org', - array( 'mailto:org.wikimedia@wiki.' ) - ), - - // file URL cases per bug 28627... - array( - // three slashes: local filesystem path Unix-style - 'file:///whatever/you/like.txt', - array( 'file://./whatever/you/like.txt' ) - ), - array( - // three slashes: local filesystem path Windows-style - 'file:///c:/whatever/you/like.txt', - array( 'file://./c:/whatever/you/like.txt' ) - ), - array( - // two slashes: UNC filesystem path Windows-style - 'file://intranet/whatever/you/like.txt', - array( 'file://intranet./whatever/you/like.txt' ) - ), - // Multiple-slash cases that can sorta work on Mozilla - // if you hack it just right are kinda pathological, - // and unreliable cross-platform or on IE which means they're - // unlikely to appear on intranets. - // - // Those will survive the algorithm but with results that - // are less consistent. - - // protocol-relative URL cases per bug 29854... - array( - '//bugzilla.wikimedia.org/show_bug.cgi?id=28627', - array( - 'http://org.wikimedia.bugzilla./show_bug.cgi?id=28627', - 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627' - ) - ), - ); - } - - /** - * @dataProvider provideWfMatchesDomainList - * @covers ::wfMatchesDomainList - */ - public function testWfMatchesDomainList( $url, $domains, $expected, $description ) { - $actual = wfMatchesDomainList( $url, $domains ); - $this->assertEquals( $expected, $actual, $description ); - } - - public static function provideWfMatchesDomainList() { - $a = array(); - $protocols = array( 'HTTP' => 'http:', 'HTTPS' => 'https:', 'protocol-relative' => '' ); - foreach ( $protocols as $pDesc => $p ) { - $a = array_merge( $a, array( - array( "$p//www.example.com", array(), false, "No matches for empty domains array, $pDesc URL" ), - array( "$p//www.example.com", array( 'www.example.com' ), true, "Exact match in domains array, $pDesc URL" ), - array( "$p//www.example.com", array( 'example.com' ), true, "Match without subdomain in domains array, $pDesc URL" ), - 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" ), - 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 - */ - public function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) { - if ( wfIsWindows() ) { - // Approximation that's good enough for our purposes just now - $expected = str_replace( "'", '"', $expected ); - } - $actual = wfShellMaintenanceCmd( $script, $parameters, $options ); - $this->assertEquals( $expected, $actual, $description ); - } - - public static function provideWfShellMaintenanceCmdList() { - global $wgPhpCli; - - return array( - array( 'eval.php', array( '--help', '--test' ), array(), - "'$wgPhpCli' 'eval.php' '--help' '--test'", - "Called eval.php --help --test" ), - array( 'eval.php', array( '--help', '--test space' ), array( 'php' => 'php5' ), - "'php5' 'eval.php' '--help' '--test space'", - "Called eval.php --help --test with php option" ), - array( 'eval.php', array( '--help', '--test', 'X' ), array( 'wrapper' => 'MWScript.php' ), - "'$wgPhpCli' 'MWScript.php' 'eval.php' '--help' '--test' 'X'", - "Called eval.php --help --test with wrapper option" ), - array( 'eval.php', array( '--help', '--test', 'y' ), array( 'php' => 'php5', 'wrapper' => 'MWScript.php' ), - "'php5' 'MWScript.php' 'eval.php' '--help' '--test' 'y'", - "Called eval.php --help --test with wrapper and php option" ), - ); - } - /* @TODO many more! */ -} diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php deleted file mode 100644 index cf891e7b..00000000 --- a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php - -/** - * @group Database - */ -class GlobalWithDBTest extends MediaWikiTestCase { - /** - * @dataProvider provideWfIsBadImageList - * @covers ::wfIsBadImage - */ - public function testWfIsBadImage( $name, $title, $blacklist, $expected, $desc ) { - $this->assertEquals( $expected, wfIsBadImage( $name, $title, $blacklist ), $desc ); - } - - public static function provideWfIsBadImageList() { - $blacklist = '* [[File:Bad.jpg]] except [[Nasty page]]'; - - return array( - array( 'Bad.jpg', false, $blacklist, true, - 'Called on a bad image' ), - array( 'Bad.jpg', Title::makeTitle( NS_MAIN, 'A page' ), $blacklist, true, - 'Called on a bad image' ), - array( 'NotBad.jpg', false, $blacklist, false, - 'Called on a non-bad image' ), - array( 'Bad.jpg', Title::makeTitle( NS_MAIN, 'Nasty page' ), $blacklist, false, - 'Called on a bad image but is on a whitelisted page' ), - array( 'File:Bad.jpg', false, $blacklist, false, - 'Called on a bad image with File:' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/README b/tests/phpunit/includes/GlobalFunctions/README deleted file mode 100644 index 0042bdac..00000000 --- a/tests/phpunit/includes/GlobalFunctions/README +++ /dev/null @@ -1,2 +0,0 @@ -This directory hold tests for includes/GlobalFunctions.php file -which is a pile of functions. diff --git a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php deleted file mode 100644 index 9bb74873..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** - * @covers ::wfAssembleUrl - */ -class WfAssembleUrlTest extends MediaWikiTestCase { - /** - * @dataProvider provideURLParts - */ - public function testWfAssembleUrl( $parts, $output ) { - $partsDump = print_r( $parts, true ); - $this->assertEquals( - $output, - wfAssembleUrl( $parts ), - "Testing $partsDump assembles to $output" - ); - } - - /** - * Provider of URL parts for testing wfAssembleUrl() - * - * @return array - */ - public static function provideURLParts() { - $schemes = array( - '' => array(), - '//' => array( - 'delimiter' => '//', - ), - 'http://' => array( - 'scheme' => 'http', - 'delimiter' => '://', - ), - ); - - $hosts = array( - '' => array(), - 'example.com' => array( - 'host' => 'example.com', - ), - 'example.com:123' => array( - 'host' => 'example.com', - 'port' => 123, - ), - 'id@example.com' => array( - 'user' => 'id', - 'host' => 'example.com', - ), - 'id@example.com:123' => array( - 'user' => 'id', - 'host' => 'example.com', - 'port' => 123, - ), - 'id:key@example.com' => array( - 'user' => 'id', - 'pass' => 'key', - 'host' => 'example.com', - ), - 'id:key@example.com:123' => array( - 'user' => 'id', - 'pass' => 'key', - 'host' => 'example.com', - 'port' => 123, - ), - ); - - $cases = array(); - foreach ( $schemes as $scheme => $schemeParts ) { - foreach ( $hosts as $host => $hostParts ) { - foreach ( array( '', '/path' ) as $path ) { - foreach ( array( '', 'query' ) as $query ) { - foreach ( array( '', 'fragment' ) as $fragment ) { - $parts = array_merge( - $schemeParts, - $hostParts - ); - $url = $scheme . - $host . - $path; - - if ( $path ) { - $parts['path'] = $path; - } - if ( $query ) { - $parts['query'] = $query; - $url .= '?' . $query; - } - if ( $fragment ) { - $parts['fragment'] = $fragment; - $url .= '#' . $fragment; - } - - $cases[] = array( - $parts, - $url, - ); - } - } - } - } - } - - $complexURL = 'http://id:key@example.org:321' . - '/over/there?name=ferret&foo=bar#nose'; - $cases[] = array( - wfParseUrl( $complexURL ), - $complexURL, - ); - - return $cases; - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php b/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php deleted file mode 100644 index a01c0d49..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php -/** - * @covers ::wfBCP47 - */ -class WfBCP47Test extends MediaWikiTestCase { - /** - * test @see wfBCP47(). - * Please note the BCP explicitly state that language codes are case - * insensitive, there are some exceptions to the rule :) - * This test is used to verify our formatting against all lower and - * all upper cases language code. - * - * @see http://tools.ietf.org/html/bcp47 - * @dataProvider provideLanguageCodes() - */ - public function testBCP47( $code, $expected ) { - $code = strtolower( $code ); - $this->assertEquals( $expected, wfBCP47( $code ), - "Applying BCP47 standard to lower case '$code'" - ); - - $code = strtoupper( $code ); - $this->assertEquals( $expected, wfBCP47( $code ), - "Applying BCP47 standard to upper case '$code'" - ); - } - - /** - * Array format is ($code, $expected) - */ - public static function provideLanguageCodes() { - return array( - // Extracted from BCP47 (list not exhaustive) - # 2.1.1 - array( 'en-ca-x-ca', 'en-CA-x-ca' ), - array( 'sgn-be-fr', 'sgn-BE-FR' ), - array( 'az-latn-x-latn', 'az-Latn-x-latn' ), - # 2.2 - array( 'sr-Latn-RS', 'sr-Latn-RS' ), - array( 'az-arab-ir', 'az-Arab-IR' ), - - # 2.2.5 - array( 'sl-nedis', 'sl-nedis' ), - array( 'de-ch-1996', 'de-CH-1996' ), - - # 2.2.6 - array( - 'en-latn-gb-boont-r-extended-sequence-x-private', - 'en-Latn-GB-boont-r-extended-sequence-x-private' - ), - - // Examples from BCP47 Appendix A - # Simple language subtag: - array( 'DE', 'de' ), - array( 'fR', 'fr' ), - array( 'ja', 'ja' ), - - # Language subtag plus script subtag: - array( 'zh-hans', 'zh-Hans' ), - array( 'sr-cyrl', 'sr-Cyrl' ), - array( 'sr-latn', 'sr-Latn' ), - - # Extended language subtags and their primary language subtag - # counterparts: - array( 'zh-cmn-hans-cn', 'zh-cmn-Hans-CN' ), - array( 'cmn-hans-cn', 'cmn-Hans-CN' ), - array( 'zh-yue-hk', 'zh-yue-HK' ), - array( 'yue-hk', 'yue-HK' ), - - # Language-Script-Region: - array( 'zh-hans-cn', 'zh-Hans-CN' ), - array( 'sr-latn-RS', 'sr-Latn-RS' ), - - # Language-Variant: - array( 'sl-rozaj', 'sl-rozaj' ), - array( 'sl-rozaj-biske', 'sl-rozaj-biske' ), - array( 'sl-nedis', 'sl-nedis' ), - - # Language-Region-Variant: - array( 'de-ch-1901', 'de-CH-1901' ), - array( 'sl-it-nedis', 'sl-IT-nedis' ), - - # Language-Script-Region-Variant: - array( 'hy-latn-it-arevela', 'hy-Latn-IT-arevela' ), - - # Language-Region: - array( 'de-de', 'de-DE' ), - array( 'en-us', 'en-US' ), - array( 'es-419', 'es-419' ), - - # Private use subtags: - array( 'de-ch-x-phonebk', 'de-CH-x-phonebk' ), - array( 'az-arab-x-aze-derbend', 'az-Arab-x-aze-derbend' ), - /** - * Previous test does not reflect the BCP which states: - * az-Arab-x-AZE-derbend - * AZE being private, it should be lower case, hence the test above - * should probably be: - #array( 'az-arab-x-aze-derbend', 'az-Arab-x-AZE-derbend' ), - */ - - # Private use registry values: - array( 'x-whatever', 'x-whatever' ), - array( 'qaa-qaaa-qm-x-southern', 'qaa-Qaaa-QM-x-southern' ), - array( 'de-qaaa', 'de-Qaaa' ), - array( 'sr-latn-qm', 'sr-Latn-QM' ), - array( 'sr-qaaa-rs', 'sr-Qaaa-RS' ), - - # Tags that use extensions - array( 'en-us-u-islamcal', 'en-US-u-islamcal' ), - array( 'zh-cn-a-myext-x-private', 'zh-CN-a-myext-x-private' ), - array( 'en-a-myext-b-another', 'en-a-myext-b-another' ), - - # Invalid: - // de-419-DE - // a-DE - // ar-a-aaa-b-bbb-a-ccc - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php deleted file mode 100644 index 7da804e6..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php +++ /dev/null @@ -1,182 +0,0 @@ -<?php -/** - * @covers ::wfBaseConvert - */ -class WfBaseConvertTest extends MediaWikiTestCase { - public static function provideSingleDigitConversions() { - return array( - // 2 3 5 8 10 16 36 - array( '0', '0', '0', '0', '0', '0', '0' ), - array( '1', '1', '1', '1', '1', '1', '1' ), - array( '10', '2', '2', '2', '2', '2', '2' ), - array( '11', '10', '3', '3', '3', '3', '3' ), - array( '100', '11', '4', '4', '4', '4', '4' ), - array( '101', '12', '10', '5', '5', '5', '5' ), - array( '110', '20', '11', '6', '6', '6', '6' ), - array( '111', '21', '12', '7', '7', '7', '7' ), - array( '1000', '22', '13', '10', '8', '8', '8' ), - array( '1001', '100', '14', '11', '9', '9', '9' ), - array( '1010', '101', '20', '12', '10', 'a', 'a' ), - array( '1011', '102', '21', '13', '11', 'b', 'b' ), - array( '1100', '110', '22', '14', '12', 'c', 'c' ), - array( '1101', '111', '23', '15', '13', 'd', 'd' ), - array( '1110', '112', '24', '16', '14', 'e', 'e' ), - array( '1111', '120', '30', '17', '15', 'f', 'f' ), - array( '10000', '121', '31', '20', '16', '10', 'g' ), - array( '10001', '122', '32', '21', '17', '11', 'h' ), - array( '10010', '200', '33', '22', '18', '12', 'i' ), - array( '10011', '201', '34', '23', '19', '13', 'j' ), - array( '10100', '202', '40', '24', '20', '14', 'k' ), - array( '10101', '210', '41', '25', '21', '15', 'l' ), - array( '10110', '211', '42', '26', '22', '16', 'm' ), - array( '10111', '212', '43', '27', '23', '17', 'n' ), - array( '11000', '220', '44', '30', '24', '18', 'o' ), - array( '11001', '221', '100', '31', '25', '19', 'p' ), - array( '11010', '222', '101', '32', '26', '1a', 'q' ), - array( '11011', '1000', '102', '33', '27', '1b', 'r' ), - array( '11100', '1001', '103', '34', '28', '1c', 's' ), - array( '11101', '1002', '104', '35', '29', '1d', 't' ), - array( '11110', '1010', '110', '36', '30', '1e', 'u' ), - array( '11111', '1011', '111', '37', '31', '1f', 'v' ), - array( '100000', '1012', '112', '40', '32', '20', 'w' ), - array( '100001', '1020', '113', '41', '33', '21', 'x' ), - array( '100010', '1021', '114', '42', '34', '22', 'y' ), - array( '100011', '1022', '120', '43', '35', '23', 'z' ) - ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase2( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base2, wfBaseConvert( $base3, '3', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base5, '5', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base8, '8', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base10, '10', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base16, '16', '2' ) ); - $this->assertSame( $base2, wfBaseConvert( $base36, '36', '2' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase3( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base3, wfBaseConvert( $base2, '2', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base5, '5', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base8, '8', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base10, '10', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base16, '16', '3' ) ); - $this->assertSame( $base3, wfBaseConvert( $base36, '36', '3' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase5( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base5, wfBaseConvert( $base2, '2', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base3, '3', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base8, '8', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base10, '10', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base16, '16', '5' ) ); - $this->assertSame( $base5, wfBaseConvert( $base36, '36', '5' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase8( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base8, wfBaseConvert( $base2, '2', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base3, '3', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base5, '5', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base10, '10', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base16, '16', '8' ) ); - $this->assertSame( $base8, wfBaseConvert( $base36, '36', '8' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase10( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base10, wfBaseConvert( $base2, '2', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base3, '3', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base5, '5', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base8, '8', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base16, '16', '10' ) ); - $this->assertSame( $base10, wfBaseConvert( $base36, '36', '10' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase16( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base16, wfBaseConvert( $base2, '2', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base3, '3', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base5, '5', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base8, '8', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base10, '10', '16' ) ); - $this->assertSame( $base16, wfBaseConvert( $base36, '36', '16' ) ); - } - - /** - * @dataProvider provideSingleDigitConversions - */ - public function testDigitToBase36( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) { - $this->assertSame( $base36, wfBaseConvert( $base2, '2', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base3, '3', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base5, '5', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base8, '8', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base10, '10', '36' ) ); - $this->assertSame( $base36, wfBaseConvert( $base16, '16', '36' ) ); - } - - public function testLargeNumber() { - $this->assertSame( '1100110001111010000000101110100', wfBaseConvert( 'sd89ys', 36, 2 ) ); - $this->assertSame( '11102112120221201101', wfBaseConvert( 'sd89ys', 36, 3 ) ); - $this->assertSame( '12003102232400', wfBaseConvert( 'sd89ys', 36, 5 ) ); - $this->assertSame( '14617200564', wfBaseConvert( 'sd89ys', 36, 8 ) ); - $this->assertSame( '1715274100', wfBaseConvert( 'sd89ys', 36, 10 ) ); - $this->assertSame( '663d0174', wfBaseConvert( 'sd89ys', 36, 16 ) ); - } - - public static function provideNumbers() { - $x = array(); - $chars = '0123456789abcdefghijklmnopqrstuvwxyz'; - for ( $i = 0; $i < 50; $i++ ) { - $base = mt_rand( 2, 36 ); - $len = mt_rand( 10, 100 ); - - $str = ''; - for ( $j = 0; $j < $len; $j++ ) { - $str .= $chars[mt_rand( 0, $base - 1 )]; - } - - $x[] = array( $base, $str ); - } - - return $x; - } - - /** - * @dataProvider provideNumbers - */ - public function testIdentity( $base, $number ) { - $this->assertSame( $number, wfBaseConvert( $number, $base, $base, strlen( $number ) ) ); - } - - public function testInvalid() { - $this->assertFalse( wfBaseConvert( '101', 1, 15 ) ); - $this->assertFalse( wfBaseConvert( '101', 15, 1 ) ); - $this->assertFalse( wfBaseConvert( '101', 37, 15 ) ); - $this->assertFalse( wfBaseConvert( '101', 15, 37 ) ); - $this->assertFalse( wfBaseConvert( 'abcde', 10, 11 ) ); - $this->assertFalse( wfBaseConvert( '12930', 2, 10 ) ); - $this->assertFalse( wfBaseConvert( '101', 'abc', 15 ) ); - $this->assertFalse( wfBaseConvert( '101', 15, 'abc' ) ); - } - - public function testPadding() { - $number = "10101010101"; - $this->assertSame( strlen( $number ) + 5, strlen( wfBaseConvert( $number, 2, 2, strlen( $number ) + 5 ) ) ); - $this->assertSame( strlen( $number ), strlen( wfBaseConvert( $number, 2, 2, strlen( $number ) - 5 ) ) ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php deleted file mode 100644 index 8c548040..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php -/** - * @covers ::wfBaseName - */ -class WfBaseNameTest extends MediaWikiTestCase { - /** - * @dataProvider providePaths - */ - public function testBaseName( $fullpath, $basename ) { - $this->assertEquals( $basename, wfBaseName( $fullpath ), - "wfBaseName('$fullpath') => '$basename'" ); - } - - public static function providePaths() { - return array( - array( '', '' ), - array( '/', '' ), - array( '\\', '' ), - array( '//', '' ), - array( '\\\\', '' ), - array( 'a', 'a' ), - array( 'aaaa', 'aaaa' ), - array( '/a', 'a' ), - array( '\\a', 'a' ), - array( '/aaaa', 'aaaa' ), - array( '\\aaaa', 'aaaa' ), - array( '/aaaa/', 'aaaa' ), - array( '\\aaaa\\', 'aaaa' ), - array( '\\aaaa\\', 'aaaa' ), - array( '/mnt/upload3/wikipedia/en/thumb/8/8b/Zork_Grand_Inquisitor_box_cover.jpg/93px-Zork_Grand_Inquisitor_box_cover.jpg', - '93px-Zork_Grand_Inquisitor_box_cover.jpg' ), - array( 'C:\\Progra~1\\Wikime~1\\Wikipe~1\\VIEWER.EXE', 'VIEWER.EXE' ), - array( 'Östergötland_coat_of_arms.png', 'Östergötland_coat_of_arms.png' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php deleted file mode 100644 index 41230a1e..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** - * @covers ::wfExpandUrl - */ -class WfExpandUrlTest extends MediaWikiTestCase { - /** - * @dataProvider provideExpandableUrls - */ - public function testWfExpandUrl( $fullUrl, $shortUrl, $defaultProto, $server, $canServer, $httpsMode, $message ) { - // Fake $wgServer and $wgCanonicalServer - $this->setMwGlobals( array( - 'wgServer' => $server, - 'wgCanonicalServer' => $canServer, - ) ); - - // Fake $_SERVER['HTTPS'] if needed - if ( $httpsMode ) { - $_SERVER['HTTPS'] = 'on'; - } else { - unset( $_SERVER['HTTPS'] ); - } - - $this->assertEquals( $fullUrl, wfExpandUrl( $shortUrl, $defaultProto ), $message ); - } - - /** - * Provider of URL examples for testing wfExpandUrl() - * - * @return array - */ - public static function provideExpandableUrls() { - $modes = array( 'http', 'https' ); - $servers = array( - 'http' => 'http://example.com', - 'https' => 'https://example.com', - 'protocol-relative' => '//example.com' - ); - $defaultProtos = array( - 'http' => PROTO_HTTP, - 'https' => PROTO_HTTPS, - 'protocol-relative' => PROTO_RELATIVE, - 'current' => PROTO_CURRENT, - 'canonical' => PROTO_CANONICAL - ); - - $retval = array(); - foreach ( $modes as $mode ) { - $httpsMode = $mode == 'https'; - foreach ( $servers as $serverDesc => $server ) { - foreach ( $modes as $canServerMode ) { - $canServer = "$canServerMode://example2.com"; - foreach ( $defaultProtos as $protoDesc => $defaultProto ) { - $retval[] = array( - 'http://example.com', 'http://example.com', - $defaultProto, $server, $canServer, $httpsMode, - "Testing fully qualified http URLs (no need to expand) ' . - '(defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - $retval[] = array( - 'https://example.com', 'https://example.com', - $defaultProto, $server, $canServer, $httpsMode, - "Testing fully qualified https URLs (no need to expand) ' . - '(defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - # Would be nice to support this, see fixme on wfExpandUrl() - $retval[] = array( - "wiki/FooBar", 'wiki/FooBar', - $defaultProto, $server, $canServer, $httpsMode, - "Test non-expandable relative URLs ' . - '(defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - - // Determine expected protocol - if ( $protoDesc == 'protocol-relative' ) { - $p = ''; - } elseif ( $protoDesc == 'current' ) { - $p = "$mode:"; - } elseif ( $protoDesc == 'canonical' ) { - $p = "$canServerMode:"; - } else { - $p = $protoDesc . ':'; - } - // Determine expected server name - if ( $protoDesc == 'canonical' ) { - $srv = $canServer; - } elseif ( $serverDesc == 'protocol-relative' ) { - $srv = $p . $server; - } else { - $srv = $server; - } - - $retval[] = array( - "$p//wikipedia.org", '//wikipedia.org', - $defaultProto, $server, $canServer, $httpsMode, - "Test protocol-relative URL ' . - '(defaultProto: $protoDesc, wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - $retval[] = array( - "$srv/wiki/FooBar", '/wiki/FooBar', - $defaultProto, $server, $canServer, $httpsMode, - "Testing expanding URL beginning with / ' . - '(defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" - ); - } - } - } - } - - return $retval; - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php deleted file mode 100644 index 62296245..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -/** - * @covers ::wfGetCaller - */ -class WfGetCallerTest extends MediaWikiTestCase { - - public function testZero() { - $this->assertEquals( __METHOD__, wfGetCaller( 1 ) ); - } - - function callerOne() { - return wfGetCaller(); - } - - public function testOne() { - $this->assertEquals( 'WfGetCallerTest::testOne', self::callerOne() ); - } - - function intermediateFunction( $level = 2, $n = 0 ) { - if ( $n > 0 ) { - return self::intermediateFunction( $level, $n - 1 ); - } - - return wfGetCaller( $level ); - } - - public function testTwo() { - $this->assertEquals( 'WfGetCallerTest::testTwo', self::intermediateFunction() ); - } - - 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++ ) { - $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 deleted file mode 100644 index 5032dc11..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php -/** - * Copyright © 2013 Alexandre Emsenhuber - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -/** - * @covers ::wfParseUrl - */ -class WfParseUrlTest extends MediaWikiTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( 'wgUrlProtocols', array( - '//', 'http://', 'file://', 'mailto:', - ) ); - } - - /** - * @dataProvider provideURLs - */ - public function testWfParseUrl( $url, $parts ) { - $partsDump = var_export( $parts, true ); - $this->assertEquals( - $parts, - wfParseUrl( $url ), - "Testing $url parses to $partsDump" - ); - } - - /** - * Provider of URLs for testing wfParseUrl() - * - * @return array - */ - public static function provideURLs() { - return array( - array( - '//example.org', - array( - 'scheme' => '', - 'delimiter' => '//', - 'host' => 'example.org', - ) - ), - array( - 'http://example.org', - array( - 'scheme' => 'http', - 'delimiter' => '://', - 'host' => 'example.org', - ) - ), - array( - 'http://id:key@example.org:123/path?foo=bar#baz', - array( - 'scheme' => 'http', - 'delimiter' => '://', - 'user' => 'id', - 'pass' => 'key', - 'host' => 'example.org', - 'port' => 123, - 'path' => '/path', - 'query' => 'foo=bar', - 'fragment' => 'baz', - ) - ), - array( - 'file://example.org/etc/php.ini', - array( - 'scheme' => 'file', - 'delimiter' => '://', - 'host' => 'example.org', - 'path' => '/etc/php.ini', - ) - ), - array( - 'file:///etc/php.ini', - array( - 'scheme' => 'file', - 'delimiter' => '://', - 'host' => '', - 'path' => '/etc/php.ini', - ) - ), - array( - 'file:///c:/', - array( - 'scheme' => 'file', - 'delimiter' => '://', - 'host' => '', - 'path' => '/c:/', - ) - ), - array( - 'mailto:id@example.org', - array( - 'scheme' => 'mailto', - 'delimiter' => ':', - 'host' => 'id@example.org', - 'path' => '', - ) - ), - array( - 'mailto:id@example.org?subject=Foo', - array( - 'scheme' => 'mailto', - 'delimiter' => ':', - 'host' => 'id@example.org', - 'path' => '', - 'query' => 'subject=Foo', - ) - ), - array( - 'mailto:?subject=Foo', - array( - 'scheme' => 'mailto', - 'delimiter' => ':', - 'host' => '', - 'path' => '', - 'query' => 'subject=Foo', - ) - ), - array( - 'invalid://test/', - false - ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php b/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php deleted file mode 100644 index 238a2c9c..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php -/** - *@covers ::wfRemoveDotSegments - */ -class WfRemoveDotSegmentsTest extends MediaWikiTestCase { - /** - * @dataProvider providePaths - */ - public function testWfRemoveDotSegments( $inputPath, $outputPath ) { - $this->assertEquals( - $outputPath, - wfRemoveDotSegments( $inputPath ), - "Testing $inputPath expands to $outputPath" - ); - } - - /** - * Provider of URL paths for testing wfRemoveDotSegments() - * - * @return array - */ - public static function providePaths() { - return array( - array( '/a/b/c/./../../g', '/a/g' ), - array( 'mid/content=5/../6', 'mid/6' ), - array( '/a//../b', '/a/b' ), - array( '/.../a', '/.../a' ), - array( '.../a', '.../a' ), - array( '', '' ), - array( '/', '/' ), - array( '//', '//' ), - array( '.', '' ), - array( '..', '' ), - array( '...', '...' ), - array( '/.', '/' ), - array( '/..', '/' ), - array( './', '' ), - array( '../', '' ), - array( './a', 'a' ), - array( '../a', 'a' ), - array( '../../a', 'a' ), - array( '.././a', 'a' ), - array( './../a', 'a' ), - array( '././a', 'a' ), - array( '../../', '' ), - array( '.././', '' ), - array( './../', '' ), - array( '././', '' ), - array( '../..', '' ), - array( '../.', '' ), - array( './..', '' ), - array( './.', '' ), - array( '/../../a', '/a' ), - array( '/.././a', '/a' ), - array( '/./../a', '/a' ), - array( '/././a', '/a' ), - array( '/../../', '/' ), - array( '/.././', '/' ), - array( '/./../', '/' ), - array( '/././', '/' ), - array( '/../..', '/' ), - array( '/../.', '/' ), - array( '/./..', '/' ), - array( '/./.', '/' ), - array( 'b/../../a', '/a' ), - array( 'b/.././a', '/a' ), - array( 'b/./../a', '/a' ), - array( 'b/././a', 'b/a' ), - array( 'b/../../', '/' ), - array( 'b/.././', '/' ), - array( 'b/./../', '/' ), - array( 'b/././', 'b/' ), - array( 'b/../..', '/' ), - array( 'b/../.', '/' ), - array( 'b/./..', '/' ), - array( 'b/./.', 'b/' ), - array( '/b/../../a', '/a' ), - array( '/b/.././a', '/a' ), - array( '/b/./../a', '/a' ), - array( '/b/././a', '/b/a' ), - array( '/b/../../', '/' ), - array( '/b/.././', '/' ), - array( '/b/./../', '/' ), - array( '/b/././', '/b/' ), - array( '/b/../..', '/' ), - array( '/b/../.', '/' ), - array( '/b/./..', '/' ), - array( '/b/./.', '/b/' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php b/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php deleted file mode 100644 index aadec87f..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -/** - * @covers ::wfShorthandToInteger - */ -class WfShorthandToIntegerTest extends MediaWikiTestCase { - /** - * @dataProvider provideABunchOfShorthands - */ - public function testWfShorthandToInteger( $input, $output, $description ) { - $this->assertEquals( - wfShorthandToInteger( $input ), - $output, - $description - ); - } - - public static function provideABunchOfShorthands() { - return array( - array( '', -1, 'Empty string' ), - array( ' ', -1, 'String of spaces' ), - array( '1G', 1024 * 1024 * 1024, 'One gig uppercased' ), - array( '1g', 1024 * 1024 * 1024, 'One gig lowercased' ), - array( '1M', 1024 * 1024, 'One meg uppercased' ), - array( '1m', 1024 * 1024, 'One meg lowercased' ), - array( '1K', 1024, 'One kb uppercased' ), - array( '1k', 1024, 'One kb lowercased' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php deleted file mode 100644 index 5998f186..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php -/* - * @covers ::wfTimestamp - */ -class WfTimestampTest extends MediaWikiTestCase { - /** - * @dataProvider provideNormalTimestamps - */ - public function testNormalTimestamps( $input, $format, $output, $desc ) { - $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); - } - - 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' ), - array( -30281104, TS_MW, '19690115123456', 'Negative TS_UNIX to TS_MW' ), - array( $t, TS_UNIX, 979562096, 'TS_UNIX to TS_UNIX' ), - array( $t, TS_DB, '2001-01-15 12:34:56', 'TS_UNIX to TS_DB' ), - - array( $t, TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_ISO_8601_BASIC to TS_DB' ), - - // TS_MW - array( '20010115123456', TS_MW, '20010115123456', 'TS_MW to TS_MW' ), - array( '20010115123456', TS_UNIX, 979562096, 'TS_MW to TS_UNIX' ), - array( '20010115123456', TS_DB, '2001-01-15 12:34:56', 'TS_MW to TS_DB' ), - array( '20010115123456', TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_MW to TS_ISO_8601_BASIC' ), - - // TS_DB - array( '2001-01-15 12:34:56', TS_MW, '20010115123456', 'TS_DB to TS_MW' ), - array( '2001-01-15 12:34:56', TS_UNIX, 979562096, 'TS_DB to TS_UNIX' ), - array( '2001-01-15 12:34:56', TS_DB, '2001-01-15 12:34:56', 'TS_DB to TS_DB' ), - array( '2001-01-15 12:34:56', TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_DB to TS_ISO_8601_BASIC' ), - - # rfc2822 section 3.3 - array( '20010115123456', TS_RFC2822, 'Mon, 15 Jan 2001 12:34:56 GMT', 'TS_MW to TS_RFC2822' ), - array( 'Mon, 15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 to TS_MW' ), - array( ' Mon, 15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 with leading space to TS_MW' ), - array( '15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 without optional day-of-week to TS_MW' ), - - # FWS = ([*WSP CRLF] 1*WSP) / obs-FWS ; Folding white space - # obs-FWS = 1*WSP *(CRLF 1*WSP) ; Section 4.2 - array( 'Mon, 15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 to TS_MW' ), - - # WSP = SP / HTAB ; rfc2234 - array( "Mon, 15 Jan\x092001 12:34:56 GMT", TS_MW, '20010115123456', 'TS_RFC2822 with HTAB to TS_MW' ), - array( "Mon, 15 Jan\x09 \x09 2001 12:34:56 GMT", TS_MW, '20010115123456', 'TS_RFC2822 with HTAB and SP to TS_MW' ), - array( 'Sun, 6 Nov 94 08:49:37 GMT', TS_MW, '19941106084937', 'TS_RFC2822 with obsolete year to TS_MW' ), - ); - } - - /** - * This test checks wfTimestamp() with values outside. - * It needs PHP 64 bits or PHP > 5.1. - * See r74778 and bug 25451 - * @dataProvider provideOldTimestamps - */ - public function testOldTimestamps( $input, $format, $output, $desc ) { - $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); - } - - 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' ), - array( '19011213204552', TS_UNIX, '-2147483648', 'Earliest 32 bit unix time' ), - array( '20380119031407', TS_UNIX, '2147483647', 'Latest 32 bit unix time' ), - array( '19011213204552', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:52 GMT', 'Earliest 32 bit time' ), - array( '19011213204551', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:51 GMT', 'Earliest 32 bit time - 1' ), - array( '20380119031408', TS_RFC2822, 'Tue, 19 Jan 2038 03:14:08 GMT', 'Latest 32 bit time + 1' ), - array( '19011212000000', TS_MW, '19011212000000', 'Convert to itself r74778#c10645' ), - array( '19011213204551', TS_UNIX, '-2147483649', 'Earliest 32 bit unix time - 1' ), - array( '20380119031408', TS_UNIX, '2147483648', 'Latest 32 bit unix time + 1' ), - array( '-2147483649', TS_MW, '19011213204551', '1901 negative unix time to MediaWiki' ), - array( '-5331871504', TS_MW, '18010115123456', '1801 negative unix time to MediaWiki' ), - array( '0117-08-09 12:34:56', TS_RFC2822, 'Tue, 09 Aug 0117 12:34:56 GMT', 'Death of Roman Emperor [[Trajan]]' ), - - /* @todo FIXME: 00 to 101 years are taken as being in [1970-2069] */ - array( '-58979923200', TS_RFC2822, 'Sun, 01 Jan 0101 00:00:00 GMT', '1/1/101' ), - array( '-62135596800', TS_RFC2822, 'Mon, 01 Jan 0001 00:00:00 GMT', 'Year 1' ), - - /* It is not clear if we should generate a year 0 or not - * We are completely off RFC2822 requirement of year being - * 1900 or later. - */ - array( '-62142076800', TS_RFC2822, 'Wed, 18 Oct 0000 00:00:00 GMT', 'ISO 8601:2004 [[year 0]], also called [[1 BC]]' ), - ); - } - - /** - * The Resource Loader uses wfTimestamp() to convert timestamps - * from If-Modified-Since header. Thus it must be able to parse all - * rfc2616 date formats - * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 - * @dataProvider provideHttpDates - */ - public function testHttpDate( $input, $output, $desc ) { - $this->assertEquals( $output, wfTimestamp( TS_MW, $input ), $desc ); - } - - 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' ), - array( 'Sun Nov 6 08:49:37 1994', '19941106084937', "ANSI C's asctime() format" ), - // See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html and r77171 - array( 'Mon, 22 Nov 2010 14:12:42 GMT; length=52626', '20101122141242', 'Netscape extension to HTTP/1.0' ), - ); - } - - /** - * 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 - */ - public function testTimestampParameter() { - $now = wfTimestamp( TS_UNIX ); - // 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 ); - $this->assertNotEquals( false, $zero ); - $this->assertLessThan( 5, $zero - $now ); - - $empty = wfTimestamp( TS_UNIX, '' ); - $this->assertNotEquals( false, $empty ); - $this->assertLessThan( 5, $empty - $now ); - - $null = wfTimestamp( TS_UNIX, null ); - $this->assertNotEquals( false, $null ); - $this->assertLessThan( 5, $null - $now ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php deleted file mode 100644 index ce6c82c5..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php -/** - * The function only need a string parameter and might react to IIS7.0 - * @covers ::wfUrlencode - */ -class WfUrlencodeTest extends MediaWikiTestCase { - #### TESTS ############################################################## - - /** - * @dataProvider provideURLS - */ - public function testEncodingUrlWith( $input, $expected ) { - $this->verifyEncodingFor( 'Apache', $input, $expected ); - } - - /** - * @dataProvider provideURLS - */ - public function testEncodingUrlWithMicrosoftIis7( $input, $expected ) { - $this->verifyEncodingFor( 'Microsoft-IIS/7', $input, $expected ); - } - - #### HELPERS ############################################################# - - /** - * Internal helper that actually run the test. - * Called by the public methods testEncodingUrlWith...() - * - */ - private function verifyEncodingFor( $server, $input, $expectations ) { - $expected = $this->extractExpect( $server, $expectations ); - - // save up global - $old = isset( $_SERVER['SERVER_SOFTWARE'] ) - ? $_SERVER['SERVER_SOFTWARE'] - : null; - $_SERVER['SERVER_SOFTWARE'] = $server; - wfUrlencode( null ); - - // do the requested test - $this->assertEquals( - $expected, - wfUrlencode( $input ), - "Encoding '$input' for server '$server' should be '$expected'" - ); - - // restore global - if ( $old === null ) { - unset( $_SERVER['SERVER_SOFTWARE'] ); - } else { - $_SERVER['SERVER_SOFTWARE'] = $old; - } - wfUrlencode( null ); - } - - /** - * Interprets the provider array. Return expected value depending - * the HTTP server name. - */ - private function extractExpect( $server, $expectations ) { - if ( is_string( $expectations ) ) { - return $expectations; - } elseif ( is_array( $expectations ) ) { - if ( !array_key_exists( $server, $expectations ) ) { - throw new MWException( __METHOD__ . " expectation does not have any value for server name $server. Check the provider array.\n" ); - } else { - return $expectations[$server]; - } - } else { - throw new MWException( __METHOD__ . " given invalid expectation for '$server'. Should be a string or an array( <http server name> => <string> ).\n" ); - } - } - - #### PROVIDERS ########################################################### - - /** - * Format is either: - * array( 'input', 'expected' ); - * Or: - * array( 'input', - * array( 'Apache', 'expected' ), - * array( 'Microsoft-IIS/7', 'expected' ), - * ), - * If you want to add other HTTP server name, you will have to add a new - * testing method much like the testEncodingUrlWith() method above. - */ - public static function provideURLS() { - return array( - ### RFC 1738 chars - // + is not safe - array( '+', '%2B' ), - // & and = not safe in queries - array( '&', '%26' ), - array( '=', '%3D' ), - - array( ':', array( - 'Apache' => ':', - 'Microsoft-IIS/7' => '%3A', - ) ), - - // remaining chars do not need encoding - array( - ';@$-_.!*', - ';@$-_.!*', - ), - - ### Other tests - // slash remain unchanged. %2F seems to break things - array( '/', '/' ), - - // Other 'funnies' chars - array( '[]', '%5B%5D' ), - array( '<>', '%3C%3E' ), - - // Apostrophe is encoded - array( '\'', '%27' ), - ); - } -} diff --git a/tests/phpunit/includes/HTMLCheckMatrixTest.php b/tests/phpunit/includes/HTMLCheckMatrixTest.php deleted file mode 100644 index 5bbafd37..00000000 --- a/tests/phpunit/includes/HTMLCheckMatrixTest.php +++ /dev/null @@ -1,102 +0,0 @@ -<?php - -/** - * Unit tests for the HTMLCheckMatrix form field - */ -class HtmlCheckMatrixTest extends MediaWikiTestCase { - static private $defaultOptions = array( - 'rows' => array( 'r1', 'r2' ), - 'columns' => array( 'c1', 'c2' ), - 'fieldname' => 'test', - ); - - public function testPlainInstantiation() { - try { - $form = new HTMLCheckMatrix( array() ); - } catch ( MWException $e ) { - $this->assertInstanceOf( 'HTMLFormFieldRequiredOptionsException', $e ); - return; - } - - $this->fail( 'Expected MWException indicating missing parameters but none was thrown.' ); - } - - public function testInstantiationWithMinimumRequiredParameters() { - $form = new HTMLCheckMatrix( self::$defaultOptions ); - $this->assertTrue( true ); // form instantiation must throw exception on failure - } - - public function testValidateCallsUserDefinedValidationCallback() { - $called = false; - $field = new HTMLCheckMatrix( self::$defaultOptions + array( - 'validation-callback' => function() use ( &$called ) { - $called = true; - return false; - }, - ) ); - $this->assertEquals( false, $this->validate( $field, array() ) ); - $this->assertTrue( $called ); - } - - public function testValidateRequiresArrayInput() { - $field = new HTMLCheckMatrix( self::$defaultOptions ); - $this->assertEquals( false, $this->validate( $field, null ) ); - $this->assertEquals( false, $this->validate( $field, true ) ); - $this->assertEquals( false, $this->validate( $field, 'abc' ) ); - $this->assertEquals( false, $this->validate( $field, new stdClass ) ); - $this->assertEquals( true, $this->validate( $field, array() ) ); - } - - public function testValidateAllowsOnlyKnownTags() { - $field = new HTMLCheckMatrix( self::$defaultOptions ); - $this->assertInternalType( 'string', $this->validate( $field, array( 'foo' ) ) ); - } - - public function testValidateAcceptsPartialTagList() { - $field = new HTMLCheckMatrix( self::$defaultOptions ); - $this->assertTrue( $this->validate( $field, array() ) ); - $this->assertTrue( $this->validate( $field, array( 'c1-r1' ) ) ); - $this->assertTrue( $this->validate( $field, array( 'c1-r1', 'c1-r2', 'c2-r1', 'c2-r2' ) ) ); - } - - /** - * This form object actually has no visibility into what happens later on, but essentially - * if the data submitted by the user passes validate the following is run: - * foreach ( $field->filterDataForSubmit( $data ) as $k => $v ) { - * $user->setOption( $k, $v ); - * } - */ - public function testValuesForcedOnRemainOn() { - $field = new HTMLCheckMatrix( self::$defaultOptions + array( - 'force-options-on' => array( 'c2-r1' ), - ) ); - $expected = array( - 'c1-r1' => false, - 'c1-r2' => false, - 'c2-r1' => true, - 'c2-r2' => false, - ); - $this->assertEquals( $expected, $field->filterDataForSubmit( array() ) ); - } - - public function testValuesForcedOffRemainOff() { - $field = new HTMLCheckMatrix( self::$defaultOptions + array( - 'force-options-off' => array( 'c1-r2', 'c2-r2' ), - ) ); - $expected = array( - 'c1-r1' => true, - 'c1-r2' => false, - 'c2-r1' => true, - 'c2-r2' => false, - ); - // array_keys on the result simulates submitting all fields checked - $this->assertEquals( $expected, $field->filterDataForSubmit( array_keys( $expected ) ) ); - } - - protected function validate( HTMLFormField $field, $submitted ) { - return $field->validate( - $submitted, - array( self::$defaultOptions['fieldname'] => $submitted ) - ); - } -} diff --git a/tests/phpunit/includes/HashRingTest.php b/tests/phpunit/includes/HashRingTest.php deleted file mode 100644 index 65f13696..00000000 --- a/tests/phpunit/includes/HashRingTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -/** - * @group HashRing - */ -class HashRingTest extends MediaWikiTestCase { - public function testHashRing() { - $ring = new HashRing( array( 's1' => 1, 's2' => 1, 's3' => 2, 's4' => 2, 's5' => 2, 's6' => 3 ) ); - - $locations = array(); - for ( $i = 0; $i < 20; $i++ ) { - $locations[ "hello$i"] = $ring->getLocation( "hello$i" ); - } - $expectedLocations = array( - "hello0" => "s5", - "hello1" => "s6", - "hello2" => "s2", - "hello3" => "s5", - "hello4" => "s6", - "hello5" => "s4", - "hello6" => "s5", - "hello7" => "s4", - "hello8" => "s5", - "hello9" => "s5", - "hello10" => "s3", - "hello11" => "s6", - "hello12" => "s1", - "hello13" => "s3", - "hello14" => "s3", - "hello15" => "s5", - "hello16" => "s4", - "hello17" => "s6", - "hello18" => "s6", - "hello19" => "s3" - ); - - $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' ); - - $locations = array(); - for ( $i = 0; $i < 5; $i++ ) { - $locations[ "hello$i"] = $ring->getLocations( "hello$i", 2 ); - } - - $expectedLocations = array( - "hello0" => array( "s5", "s6" ), - "hello1" => array( "s6", "s4" ), - "hello2" => array( "s2", "s1" ), - "hello3" => array( "s5", "s6" ), - "hello4" => array( "s6", "s4" ), - ); - $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' ); - } -} diff --git a/tests/phpunit/includes/HooksTest.php b/tests/phpunit/includes/HooksTest.php deleted file mode 100644 index 81dd4870..00000000 --- a/tests/phpunit/includes/HooksTest.php +++ /dev/null @@ -1,158 +0,0 @@ -<?php - -class HooksTest extends MediaWikiTestCase { - - function setUp() { - global $wgHooks; - parent::setUp(); - Hooks::clear( 'MediaWikiHooksTest001' ); - unset( $wgHooks['MediaWikiHooksTest001'] ); - } - - public static function provideHooks() { - $i = new NothingClass(); - - 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' ) - ); - } - - /** - * @dataProvider provideHooks - */ - public function testOldStyleHooks( $msg, array $hook, $expectedFoo, $expectedBar ) { - global $wgHooks; - $foo = $bar = 'original'; - - $wgHooks['MediaWikiHooksTest001'][] = $hook; - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertSame( $expectedFoo, $foo, $msg ); - $this->assertSame( $expectedBar, $bar, $msg ); - } - - /** - * @dataProvider provideHooks - */ - public function testNewStyleHooks( $msg, $hook, $expectedFoo, $expectedBar ) { - $foo = $bar = 'original'; - - Hooks::register( 'MediaWikiHooksTest001', $hook ); - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertSame( $expectedFoo, $foo, $msg ); - $this->assertSame( $expectedBar, $bar, $msg ); - } - - public function testNewStyleHookInteraction() { - global $wgHooks; - - $a = new NothingClass(); - $b = new NothingClass(); - - $wgHooks['MediaWikiHooksTest001'][] = $a; - $this->assertTrue( Hooks::isRegistered( 'MediaWikiHooksTest001' ), 'Hook registered via $wgHooks should be noticed by Hooks::isRegistered' ); - - Hooks::register( 'MediaWikiHooksTest001', $b ); - $this->assertEquals( 2, count( Hooks::getHandlers( 'MediaWikiHooksTest001' ) ), 'Hooks::getHandlers() should return hooks registered via wgHooks as well as Hooks::register' ); - - $foo = 'quux'; - $bar = 'qaax'; - - 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' ); - } - - /** - * @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 = 'changed-static'; - - return true; - } - - public function someNonStatic( &$foo, &$bar ) { - $this->calls++; - $foo = 'changed-nonstatic'; - $bar = 'changed-nonstatic'; - - return true; - } - - public function onMediaWikiHooksTest001( &$foo, &$bar ) { - $this->calls++; - $foo = 'changed-onevent'; - - return true; - } - - public function someNonStaticWithData( $data, &$foo, &$bar ) { - $this->calls++; - $foo = $data; - - return true; - } -} diff --git a/tests/phpunit/includes/HtmlFormatterTest.php b/tests/phpunit/includes/HtmlFormatterTest.php deleted file mode 100644 index a37df74f..00000000 --- a/tests/phpunit/includes/HtmlFormatterTest.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php - -/** - * @group HtmlFormatter - */ -class HtmlFormatterTest extends MediaWikiTestCase { - /** - * @dataProvider getHtmlData - */ - public function testTransform( $input, $expected, $callback = false ) { - $input = self::normalize( $input ); - $formatter = new HtmlFormatter( HtmlFormatter::wrapHTML( $input ) ); - if ( $callback ) { - $callback( $formatter ); - } - $formatter->filterContent(); - $html = $formatter->getText(); - $this->assertEquals( self::normalize( $expected ), self::normalize( $html ) ); - } - - private static function normalize( $s ) { - return str_replace( "\n", '', - str_replace( "\r", '', $s ) // "yay" to Windows! - ); - } - - public function getHtmlData() { - $removeImages = function( HtmlFormatter $f ) { - $f->setRemoveMedia(); - }; - $removeTags = function( HtmlFormatter $f ) { - $f->remove( array( 'table', '.foo', '#bar', 'div.baz' ) ); - }; - $flattenSomeStuff = function( HtmlFormatter $f ) { - $f->flatten( array( 's', 'div' ) ); - }; - $flattenEverything = function( HtmlFormatter $f ) { - $f->flattenAllTags(); - }; - return array( - // remove images if asked - array( - '<img src="/foo/bar.jpg" alt="Blah"/>', - '', - $removeImages, - ), - // basic tag removal - array( - '<table><tr><td>foo</td></tr></table><div class="foo">foo</div><div class="foo quux">foo</div><span id="bar">bar</span> -<strong class="foo" id="bar">foobar</strong><div class="notfoo">test</div><div class="baz"/> -<span class="baz">baz</span>', - - '<div class="notfoo">test</div> -<span class="baz">baz</span>', - $removeTags, - ), - // don't flatten tags that start like chosen ones - array( - '<div><s>foo</s> <span>bar</span></div>', - 'foo <span>bar</span>', - $flattenSomeStuff, - ), - // total flattening - array( - '<div style="foo">bar<sup>2</sup></div>', - 'bar2', - $flattenEverything, - ), - // UTF-8 preservation and security - array( - '<span title="" \' &"><Тест!></span> &<&&&&', - '<span title="" \' &"><Тест!></span> &<&&&&', - ), - // https://bugzilla.wikimedia.org/show_bug.cgi?id=53086 - array( - 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup> <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>', - 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup> <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>', - ), - ); - } -} diff --git a/tests/phpunit/includes/HtmlTest.php b/tests/phpunit/includes/HtmlTest.php deleted file mode 100644 index 1c62d032..00000000 --- a/tests/phpunit/includes/HtmlTest.php +++ /dev/null @@ -1,631 +0,0 @@ -<?php -/** tests for includes/Html.php */ - -class HtmlTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $langCode = 'en'; - $langObj = Language::factory( $langCode ); - - // Hardcode namespaces during test runs, - // so that html output based on existing namespaces - // can be properly evaluated. - $langObj->setNamespaces( array( - -2 => 'Media', - -1 => 'Special', - 0 => '', - 1 => 'Talk', - 2 => 'User', - 3 => 'User_talk', - 4 => 'MyWiki', - 5 => 'MyWiki_Talk', - 6 => 'File', - 7 => 'File_talk', - 8 => 'MediaWiki', - 9 => 'MediaWiki_talk', - 10 => 'Template', - 11 => 'Template_talk', - 14 => 'Category', - 15 => 'Category_talk', - 100 => 'Custom', - 101 => 'Custom_talk', - ) ); - - $this->setMwGlobals( array( - 'wgLanguageCode' => $langCode, - 'wgContLang' => $langObj, - 'wgLang' => $langObj, - 'wgWellFormedXml' => false, - ) ); - } - - public function testElementBasics() { - $this->assertEquals( - '<img>', - Html::element( 'img', null, '' ), - 'No close tag for short-tag elements' - ); - - $this->assertEquals( - '<element></element>', - Html::element( 'element', null, null ), - 'Close tag for empty element (null, null)' - ); - - $this->assertEquals( - '<element></element>', - Html::element( 'element', array(), '' ), - 'Close tag for empty element (array, string)' - ); - - $this->setMwGlobals( 'wgWellFormedXml', true ); - - $this->assertEquals( - '<img />', - Html::element( 'img', null, '' ), - 'Self-closing tag for short-tag elements (wgWellFormedXml = true)' - ); - } - - 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 ######## - $this->assertEmpty( - Html::expandAttributes( array( 'foo' => null ) ), - 'skip keys with null value' - ); - $this->assertEmpty( - Html::expandAttributes( array( 'foo' => false ) ), - 'skip keys with false value' - ); - $this->assertNotEmpty( - Html::expandAttributes( array( 'foo' => '' ) ), - 'keep keys with an empty string' - ); - } - - public function testExpandAttributesForBooleans() { - $this->assertEquals( - '', - Html::expandAttributes( array( 'selected' => false ) ), - 'Boolean attributes do not generates output when value is false' - ); - $this->assertEquals( - '', - Html::expandAttributes( array( 'selected' => null ) ), - 'Boolean attributes do not generates output when value is null' - ); - - $this->assertEquals( - ' selected', - Html::expandAttributes( array( 'selected' => true ) ), - 'Boolean attributes have no value when value is true' - ); - $this->assertEquals( - ' selected', - Html::expandAttributes( array( 'selected' ) ), - 'Boolean attributes have no value when value is true (passed as numerical array)' - ); - - $this->setMwGlobals( 'wgWellFormedXml', true ); - - $this->assertEquals( - ' selected=""', - Html::expandAttributes( array( 'selected' => true ) ), - 'Boolean attributes have empty string value when value is true (wgWellFormedXml)' - ); - } - - /** - * Test for Html::expandAttributes() - * Please note it output a string prefixed with a space! - */ - public function testExpandAttributesVariousExpansions() { - ### NOT EMPTY #### - $this->assertEquals( - ' empty_string=""', - Html::expandAttributes( array( 'empty_string' => '' ) ), - 'Empty string is always quoted' - ); - $this->assertEquals( - ' key=value', - Html::expandAttributes( array( 'key' => 'value' ) ), - 'Simple string value needs no quotes' - ); - $this->assertEquals( - ' one=1', - Html::expandAttributes( array( 'one' => 1 ) ), - 'Number 1 value needs no quotes' - ); - $this->assertEquals( - ' zero=0', - Html::expandAttributes( array( 'zero' => 0 ) ), - 'Number 0 value needs no quotes' - ); - - $this->setMwGlobals( 'wgWellFormedXml', true ); - - $this->assertEquals( - ' empty_string=""', - Html::expandAttributes( array( 'empty_string' => '' ) ), - 'Attribute values are always quoted (wgWellFormedXml): Empty string' - ); - $this->assertEquals( - ' key="value"', - Html::expandAttributes( array( 'key' => 'value' ) ), - 'Attribute values are always quoted (wgWellFormedXml): Simple string' - ); - $this->assertEquals( - ' one="1"', - Html::expandAttributes( array( 'one' => 1 ) ), - 'Attribute values are always quoted (wgWellFormedXml): Number 1' - ); - $this->assertEquals( - ' zero="0"', - Html::expandAttributes( array( 'zero' => 0 ) ), - 'Attribute values are always quoted (wgWellFormedXml): Number 0' - ); - } - - /** - * Html::expandAttributes has special features for HTML - * attributes that use space separated lists and also - * allows arrays to be used as values. - */ - public function testExpandAttributesListValueAttributes() { - ### STRING VALUES - $this->assertEquals( - ' class="redundant spaces here"', - Html::expandAttributes( array( 'class' => ' redundant spaces here ' ) ), - 'Normalization should strip redundant spaces' - ); - $this->assertEquals( - ' class="foo bar"', - Html::expandAttributes( array( 'class' => 'foo bar foo bar bar' ) ), - 'Normalization should remove duplicates in string-lists' - ); - ### "EMPTY" ARRAY VALUES - $this->assertEquals( - ' class=""', - Html::expandAttributes( array( 'class' => array() ) ), - 'Value with an empty array' - ); - $this->assertEquals( - ' class=""', - Html::expandAttributes( array( 'class' => array( null, '', ' ', ' ' ) ) ), - 'Array with null, empty string and spaces' - ); - ### NON-EMPTY ARRAY VALUES - $this->assertEquals( - ' class="foo bar"', - Html::expandAttributes( array( 'class' => array( - 'foo', - 'bar', - 'foo', - 'bar', - 'bar', - ) ) ), - 'Normalization should remove duplicates in the array' - ); - $this->assertEquals( - ' class="foo bar"', - Html::expandAttributes( array( 'class' => array( - 'foo bar', - 'bar foo', - 'foo', - 'bar bar', - ) ) ), - 'Normalization should remove duplicates in string-lists in the array' - ); - } - - /** - * Test feature added by r96188, let pass attributes values as - * a PHP array. Restricted to class,rel, accesskey. - */ - public function testExpandAttributesSpaceSeparatedAttributesWithBoolean() { - $this->assertEquals( - ' class="booltrue one"', - Html::expandAttributes( array( 'class' => array( - 'booltrue' => true, - 'one' => 1, - - # Method use isset() internally, make sure we do discard - # attributes values which have been assigned well known values - 'emptystring' => '', - 'boolfalse' => false, - 'zero' => 0, - 'null' => null, - ) ) ) - ); - } - - /** - * How do we handle duplicate keys in HTML attributes expansion? - * We could pass a "class" the values: 'GREEN' and array( 'GREEN' => false ) - * The later will take precedence. - * - * Feature added by r96188 - */ - public function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() { - $this->assertEquals( - ' class=""', - Html::expandAttributes( array( 'class' => array( - 'GREEN', - 'GREEN' => false, - 'GREEN', - ) ) ) - ); - } - - public function testNamespaceSelector() { - $this->assertEquals( - '<select id=namespace name=namespace>' . "\n" . - '<option value=0>(Main)</option>' . "\n" . - '<option value=1>Talk</option>' . "\n" . - '<option value=2>User</option>' . "\n" . - '<option value=3>User talk</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . - '</select>', - Html::namespaceSelector(), - 'Basic namespace selector without custom options' - ); - - $this->assertEquals( - '<label for=mw-test-namespace>Select a namespace:</label> ' . - '<select id=mw-test-namespace name=wpNamespace>' . "\n" . - '<option value=all>all</option>' . "\n" . - '<option value=0>(Main)</option>' . "\n" . - '<option value=1>Talk</option>' . "\n" . - '<option value=2 selected>User</option>' . "\n" . - '<option value=3>User talk</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . - '</select>', - Html::namespaceSelector( - array( 'selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:' ), - array( 'name' => 'wpNamespace', 'id' => 'mw-test-namespace' ) - ), - 'Basic namespace selector with custom values' - ); - - $this->assertEquals( - '<label for=namespace>Select a namespace:</label> ' . - '<select id=namespace name=namespace>' . "\n" . - '<option value=0>(Main)</option>' . "\n" . - '<option value=1>Talk</option>' . "\n" . - '<option value=2>User</option>' . "\n" . - '<option value=3>User talk</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . - '</select>', - Html::namespaceSelector( - array( 'label' => 'Select a namespace:' ) - ), - 'Basic namespace selector with a custom label but no id attribtue for the <select>' - ); - } - - public function testCanFilterOutNamespaces() { - $this->assertEquals( - '<select id=namespace name=namespace>' . "\n" . - '<option value=2>User</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '</select>', - Html::namespaceSelector( - array( 'exclude' => array( 0, 1, 3, 100, 101 ) ) - ), - 'Namespace selector namespace filtering.' - ); - } - - public function testCanDisableANamespaces() { - $this->assertEquals( - '<select id=namespace name=namespace>' . "\n" . - '<option disabled value=0>(Main)</option>' . "\n" . - '<option disabled value=1>Talk</option>' . "\n" . - '<option disabled value=2>User</option>' . "\n" . - '<option disabled value=3>User talk</option>' . "\n" . - '<option disabled value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . - '</select>', - Html::namespaceSelector( array( - 'disable' => array( 0, 1, 2, 3, 4 ) - ) ), - 'Namespace selector namespace disabling' - ); - } - - /** - * @dataProvider provideHtml5InputTypes - */ - public function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { - $this->assertEquals( - '<input type=' . $HTML5InputType . '>', - Html::element( 'input', array( 'type' => $HTML5InputType ) ), - 'In HTML5, HTML::element() should accept type="' . $HTML5InputType . '"' - ); - } - - /** - * List of input element types values introduced by HTML5 - * Full list at http://www.w3.org/TR/html-markup/input.html - */ - public static function provideHtml5InputTypes() { - $types = array( - 'datetime', - 'datetime-local', - 'date', - 'month', - 'time', - 'week', - 'number', - 'range', - 'email', - 'url', - 'search', - 'tel', - 'color', - ); - $cases = array(); - foreach ( $types as $type ) { - $cases[] = array( $type ); - } - - return $cases; - } - - /** - * Test out Html::element drops or enforces default value - * @covers Html::dropDefaults - * @dataProvider provideElementsWithAttributesHavingDefaultValues - */ - public function testDropDefaults( $expected, $element, $attribs, $message = '' ) { - $this->assertEquals( $expected, Html::element( $element, $attribs ), $message ); - } - - public static function provideElementsWithAttributesHavingDefaultValues() { - # Use cases in a concise format: - # <expected>, <element name>, <array of attributes> [, <message>] - # Will be mapped to Html::element() - $cases = array(); - - ### Generic cases, match $attribDefault static array - $cases[] = array( '<area>', - 'area', array( 'shape' => 'rect' ) - ); - - $cases[] = array( '<button type=submit></button>', - 'button', array( 'formaction' => 'GET' ) - ); - $cases[] = array( '<button type=submit></button>', - 'button', array( 'formenctype' => 'application/x-www-form-urlencoded' ) - ); - - $cases[] = array( '<canvas></canvas>', - 'canvas', array( 'height' => '150' ) - ); - $cases[] = array( '<canvas></canvas>', - 'canvas', array( 'width' => '300' ) - ); - # Also check with numeric values - $cases[] = array( '<canvas></canvas>', - 'canvas', array( 'height' => 150 ) - ); - $cases[] = array( '<canvas></canvas>', - 'canvas', array( 'width' => 300 ) - ); - - $cases[] = array( '<command>', - 'command', array( 'type' => 'command' ) - ); - - $cases[] = array( '<form></form>', - 'form', array( 'action' => 'GET' ) - ); - $cases[] = array( '<form></form>', - 'form', array( 'autocomplete' => 'on' ) - ); - $cases[] = array( '<form></form>', - 'form', array( 'enctype' => 'application/x-www-form-urlencoded' ) - ); - - $cases[] = array( '<input>', - 'input', array( 'formaction' => 'GET' ) - ); - $cases[] = array( '<input>', - 'input', array( 'type' => 'text' ) - ); - - $cases[] = array( '<keygen>', - 'keygen', array( 'keytype' => 'rsa' ) - ); - - $cases[] = array( '<link>', - 'link', array( 'media' => 'all' ) - ); - - $cases[] = array( '<menu></menu>', - 'menu', array( 'type' => 'list' ) - ); - - $cases[] = array( '<script></script>', - 'script', array( 'type' => 'text/javascript' ) - ); - - $cases[] = array( '<style></style>', - 'style', array( 'media' => 'all' ) - ); - $cases[] = array( '<style></style>', - 'style', array( 'type' => 'text/css' ) - ); - - $cases[] = array( '<textarea></textarea>', - 'textarea', array( 'wrap' => 'soft' ) - ); - - ### SPECIFIC CASES - - # <link type="text/css"> - $cases[] = array( '<link>', - 'link', array( 'type' => 'text/css' ) - ); - - # <input> specific handling - $cases[] = array( '<input type=checkbox>', - 'input', array( 'type' => 'checkbox', 'value' => 'on' ), - 'Default value "on" is stripped of checkboxes', - ); - $cases[] = array( '<input type=radio>', - 'input', array( 'type' => 'radio', 'value' => 'on' ), - 'Default value "on" is stripped of radio buttons', - ); - $cases[] = array( '<input type=submit value=Submit>', - 'input', array( 'type' => 'submit', 'value' => 'Submit' ), - 'Default value "Submit" is kept on submit buttons (for possible l10n issues)', - ); - $cases[] = array( '<input type=color>', - 'input', array( 'type' => 'color', 'value' => '' ), - ); - $cases[] = array( '<input type=range>', - 'input', array( 'type' => 'range', 'value' => '' ), - ); - - # <button> specific handling - # see remarks on http://msdn.microsoft.com/en-us/library/ie/ms535211%28v=vs.85%29.aspx - $cases[] = array( '<button type=submit></button>', - 'button', array( 'type' => 'submit' ), - 'According to standard the default type is "submit". Depending on compatibility mode IE might use "button", instead.', - ); - - # <select> specifc handling - $cases[] = array( '<select multiple></select>', - 'select', array( 'size' => '4', 'multiple' => true ), - ); - # .. with numeric value - $cases[] = array( '<select multiple></select>', - 'select', array( 'size' => 4, 'multiple' => true ), - ); - $cases[] = array( '<select></select>', - 'select', array( 'size' => '1', 'multiple' => false ), - ); - # .. with numeric value - $cases[] = array( '<select></select>', - 'select', array( 'size' => 1, 'multiple' => false ), - ); - - # Passing an array as value - $cases[] = array( '<a class="css-class-one css-class-two"></a>', - 'a', array( 'class' => array( 'css-class-one', 'css-class-two' ) ), - "dropDefaults accepts values given as an array" - ); - - # FIXME: doDropDefault should remove defaults given in an array - # Expected should be '<a></a>' - $cases[] = array( '<a class=""></a>', - 'a', array( 'class' => array( '', '' ) ), - "dropDefaults accepts values given as an array" - ); - - # Craft the Html elements - $ret = array(); - foreach ( $cases as $case ) { - $ret[] = array( - $case[0], - $case[1], $case[2], - isset( $case[3] ) ? $case[3] : '' - ); - } - - return $ret; - } - - public function testFormValidationBlacklist() { - $this->assertEmpty( - Html::expandAttributes( array( 'min' => 1, 'max' => 100, 'pattern' => 'abc', 'required' => true, 'step' => 2 ) ), - 'Blacklist form validation attributes.' - ); - $this->assertEquals( - ' step=any', - Html::expandAttributes( array( 'min' => 1, 'max' => 100, 'pattern' => 'abc', 'required' => true, 'step' => 'any' ) ), - 'Allow special case "step=any".' - ); - } -} diff --git a/tests/phpunit/includes/HttpTest.php b/tests/phpunit/includes/HttpTest.php deleted file mode 100644 index 11d8ed60..00000000 --- a/tests/phpunit/includes/HttpTest.php +++ /dev/null @@ -1,216 +0,0 @@ -<?php -/** - * @group Broken - */ -class HttpTest extends MediaWikiTestCase { - /** - * @dataProvider cookieDomains - * @covers Cookie::validateCookieDomain - */ - public function testValidateCookieDomain( $expected, $domain, $origin = null ) { - if ( $origin ) { - $ok = Cookie::validateCookieDomain( $domain, $origin ); - $msg = "$domain against origin $origin"; - } else { - $ok = Cookie::validateCookieDomain( $domain ); - $msg = "$domain"; - } - $this->assertEquals( $expected, $ok, $msg ); - } - - public static function cookieDomains() { - return array( - array( false, "org" ), - array( false, ".org" ), - array( true, "wikipedia.org" ), - array( true, ".wikipedia.org" ), - array( false, "co.uk" ), - array( false, ".co.uk" ), - array( false, "gov.uk" ), - array( false, ".gov.uk" ), - array( true, "supermarket.uk" ), - array( false, "uk" ), - array( false, ".uk" ), - array( false, "127.0.0." ), - array( false, "127." ), - array( false, "127.0.0.1." ), - array( true, "127.0.0.1" ), - array( false, "333.0.0.1" ), - array( true, "example.com" ), - array( false, "example.com." ), - array( true, ".example.com" ), - - array( true, ".example.com", "www.example.com" ), - array( false, "example.com", "www.example.com" ), - array( true, "127.0.0.1", "127.0.0.1" ), - array( false, "127.0.0.1", "localhost" ), - ); - } - - /** - * Test Http::isValidURI() - * @bug 27854 : Http::isValidURI is too lax - * @dataProvider provideURI - * @covers Http::isValidURI - */ - public function testIsValidUri( $expect, $URI, $message = '' ) { - $this->assertEquals( - $expect, - (bool)Http::isValidURI( $URI ), - $message - ); - } - - /** - * Feeds URI to test a long regular expression in Http::isValidURI - */ - public static function provideURI() { - /** Format: 'boolean expectation', 'URI to test', 'Optional message' */ - return array( - array( false, '¿non sens before!! http://a', 'Allow anything before URI' ), - - # (http|https) - only two schemes allowed - array( true, 'http://www.example.org/' ), - array( true, 'https://www.example.org/' ), - array( true, 'http://www.example.org', 'URI without directory' ), - array( true, 'http://a', 'Short name' ), - array( true, 'http://étoile', 'Allow UTF-8 in hostname' ), # 'étoile' is french for 'star' - array( false, '\\host\directory', 'CIFS share' ), - array( false, 'gopher://host/dir', 'Reject gopher scheme' ), - array( false, 'telnet://host', 'Reject telnet scheme' ), - - # :\/\/ - double slashes - array( false, 'http//example.org', 'Reject missing colon in protocol' ), - array( false, 'http:/example.org', 'Reject missing slash in protocol' ), - array( false, 'http:example.org', 'Must have two slashes' ), - # Following fail since hostname can be made of anything - array( false, 'http:///example.org', 'Must have exactly two slashes, not three' ), - - # (\w+:{0,1}\w*@)? - optional user:pass - array( true, 'http://user@host', 'Username provided' ), - array( true, 'http://user:@host', 'Username provided, no password' ), - array( true, 'http://user:pass@host', 'Username and password provided' ), - - # (\S+) - host part is made of anything not whitespaces - array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ), - array( false, 'http://exam:ple.org/', 'hostname can not use colons!' ), - - # (:[0-9]+)? - port number - array( true, 'http://example.org:80/' ), - array( true, 'https://example.org:80/' ), - array( true, 'http://example.org:443/' ), - array( true, 'https://example.org:443/' ), - - # Part after the hostname is / or / with something else - array( true, 'http://example/#' ), - array( true, 'http://example/!' ), - array( true, 'http://example/:' ), - array( true, 'http://example/.' ), - array( true, 'http://example/?' ), - array( true, 'http://example/+' ), - array( true, 'http://example/=' ), - array( true, 'http://example/&' ), - array( true, 'http://example/%' ), - array( true, 'http://example/@' ), - array( true, 'http://example/-' ), - array( true, 'http://example//' ), - array( true, 'http://example/&' ), - - # Fragment - array( true, 'http://exam#ple.org', ), # This one is valid, really! - array( true, 'http://example.org:80#anchor' ), - array( true, 'http://example.org/?id#anchor' ), - array( true, 'http://example.org/?#anchor' ), - - array( false, 'http://a ¿non !!sens after', 'Allow anything after URI' ), - ); - } - - /** - * Warning: - * - * These tests are for code that makes use of an artifact of how CURL - * handles header reporting on redirect pages, and will need to be - * rewritten when bug 29232 is taken care of (high-level handling of - * HTTP redirects). - */ - public function testRelativeRedirections() { - $h = MWHttpRequestTester::factory( 'http://oldsite/file.ext' ); - - # Forge a Location header - $h->setRespHeaders( 'location', array( - 'http://newsite/file.ext', - '/newfile.ext', - ) - ); - # Verify we correctly fix the Location - $this->assertEquals( - 'http://newsite/newfile.ext', - $h->getFinalUrl(), - "Relative file path Location: interpreted as full URL" - ); - - $h->setRespHeaders( 'location', array( - 'https://oldsite/file.ext' - ) - ); - $this->assertEquals( - 'https://oldsite/file.ext', - $h->getFinalUrl(), - "Location to the HTTPS version of the site" - ); - - $h->setRespHeaders( 'location', array( - '/anotherfile.ext', - 'http://anotherfile/hoster.ext', - 'https://anotherfile/hoster.ext' - ) - ); - $this->assertEquals( - 'https://anotherfile/hoster.ext', - $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!" ) - ); - } -} - -/** - * Class to let us overwrite MWHttpRequest respHeaders variable - */ -class MWHttpRequestTester extends MWHttpRequest { - - // function derived from the MWHttpRequest factory function but - // returns appropriate tester class here - public static function factory( $url, $options = null ) { - if ( !Http::$httpEngine ) { - Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php'; - } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) { - throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' . - 'Http::$httpEngine is set to "curl"' ); - } - - switch ( Http::$httpEngine ) { - case 'curl': - return new CurlHttpRequestTester( $url, $options ); - case 'php': - if ( !wfIniGetBool( 'allow_url_fopen' ) ) { - 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: - } - } -} - -class CurlHttpRequestTester extends CurlHttpRequest { - function setRespHeaders( $name, $value ) { - $this->respHeaders[$name] = $value; - } -} - -class PhpHttpRequestTester extends PhpHttpRequest { - function setRespHeaders( $name, $value ) { - $this->respHeaders[$name] = $value; - } -} diff --git a/tests/phpunit/includes/IPTest.php b/tests/phpunit/includes/IPTest.php deleted file mode 100644 index c074eea6..00000000 --- a/tests/phpunit/includes/IPTest.php +++ /dev/null @@ -1,595 +0,0 @@ -<?php -/** - * Tests for IP validity functions. - * - * Ported from /t/inc/IP.t by avar. - * - * @group IP - * @todo Test methods in this call should be split into a method and a - * dataprovider. - */ - -class IPTest extends MediaWikiTestCase { - /** - * not sure it should be tested with boolean false. hashar 20100924 - * @covers IP::isIPAddress - */ - public function testisIPAddress() { - $this->assertFalse( IP::isIPAddress( false ), 'Boolean false is not an IP' ); - $this->assertFalse( IP::isIPAddress( true ), 'Boolean true is not an IP' ); - $this->assertFalse( IP::isIPAddress( "" ), 'Empty string is not an IP' ); - $this->assertFalse( IP::isIPAddress( 'abc' ), 'Garbage IP string' ); - $this->assertFalse( IP::isIPAddress( ':' ), 'Single ":" is not an IP' ); - $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1' ), 'IPv6 with a double :: occurrence' ); - $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::' ), 'IPv6 with a double :: occurrence, last at end' ); - $this->assertFalse( IP::isIPAddress( '::2001:0DB8::5:1' ), 'IPv6 with a double :: occurrence, firt at beginning' ); - $this->assertFalse( IP::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' ); - $this->assertFalse( IP::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' ); - $this->assertFalse( IP::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' ); - $this->assertFalse( IP::isIPAddress( 'fc:100:300' ), 'IPv6 with only 3 words' ); - - $this->assertTrue( IP::isIPAddress( '::' ), 'RFC 4291 IPv6 Unspecified Address' ); - $this->assertTrue( IP::isIPAddress( '::1' ), 'RFC 4291 IPv6 Loopback Address' ); - $this->assertTrue( IP::isIPAddress( '74.24.52.13/20', 'IPv4 range' ) ); - $this->assertTrue( IP::isIPAddress( 'fc:100:a:d:1:e:ac:0/24' ), 'IPv6 range' ); - $this->assertTrue( IP::isIPAddress( 'fc::100:a:d:1:e:ac/96' ), 'IPv6 range with "::"' ); - - $validIPs = array( 'fc:100::', 'fc:100:a:d:1:e:ac::', 'fc::100', '::fc:100:a:d:1:e:ac', - '::fc', 'fc::100:a:d:1:e:ac', 'fc:100:a:d:1:e:ac:0', '124.24.52.13', '1.24.52.13' ); - foreach ( $validIPs as $ip ) { - $this->assertTrue( IP::isIPAddress( $ip ), "$ip is a valid IP address" ); - } - } - - /** - * @covers IP::isIPv6 - */ - public function testisIPv6() { - $this->assertFalse( IP::isIPv6( ':fc:100::' ), 'IPv6 starting with lone ":"' ); - $this->assertFalse( IP::isIPv6( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); - $this->assertFalse( IP::isIPv6( 'fc:300' ), 'IPv6 with only 2 words' ); - $this->assertFalse( IP::isIPv6( 'fc:100:300' ), 'IPv6 with only 3 words' ); - - $this->assertTrue( IP::isIPv6( 'fc:100::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac::' ) ); - - $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' ); - $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' ); - - $this->assertFalse( IP::isIPv6( ':::' ) ); - $this->assertFalse( IP::isIPv6( '::0:' ), 'IPv6 ending in a lone ":"' ); - - $this->assertTrue( IP::isIPv6( '::' ), 'IPv6 zero address' ); - $this->assertTrue( IP::isIPv6( '::0' ) ); - $this->assertTrue( IP::isIPv6( '::fc' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e:ac' ) ); - - $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); - $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); - - $this->assertFalse( IP::isIPv6( ':fc::100' ), 'IPv6 starting with lone ":"' ); - $this->assertFalse( IP::isIPv6( 'fc::100:' ), 'IPv6 ending with lone ":"' ); - $this->assertFalse( IP::isIPv6( 'fc:::100' ), 'IPv6 with ":::" in the middle' ); - - $this->assertTrue( IP::isIPv6( 'fc::100' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' ) ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); - $this->assertTrue( IP::isIPv6( '2001::df' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' ); - - $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); - $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); - - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac:0' ) ); - } - - /** - * @covers IP::isIPv4 - */ - public function testisIPv4() { - $this->assertFalse( IP::isIPv4( false ), 'Boolean false is not an IP' ); - $this->assertFalse( IP::isIPv4( true ), 'Boolean true is not an IP' ); - $this->assertFalse( IP::isIPv4( "" ), 'Empty string is not an IP' ); - $this->assertFalse( IP::isIPv4( 'abc' ) ); - $this->assertFalse( IP::isIPv4( ':' ) ); - $this->assertFalse( IP::isIPv4( '124.24.52' ), 'IPv4 not enough quads' ); - $this->assertFalse( IP::isIPv4( '24.324.52.13' ), 'IPv4 out of range' ); - $this->assertFalse( IP::isIPv4( '.24.52.13' ), 'IPv4 starts with period' ); - - $this->assertTrue( IP::isIPv4( '124.24.52.13' ) ); - $this->assertTrue( IP::isIPv4( '1.24.52.13' ) ); - $this->assertTrue( IP::isIPv4( '74.24.52.13/20', 'IPv4 range' ) ); - } - - /** - * @covers IP::isValid - */ - public function testValidIPs() { - foreach ( range( 0, 255 ) as $i ) { - $a = sprintf( "%03d", $i ); - $b = sprintf( "%02d", $i ); - $c = sprintf( "%01d", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f.$f.$f.$f"; - $this->assertTrue( IP::isValid( $ip ), "$ip is a valid IPv4 address" ); - } - } - foreach ( range( 0x0, 0xFFFF, 0xF ) as $i ) { - $a = sprintf( "%04x", $i ); - $b = sprintf( "%03x", $i ); - $c = sprintf( "%02x", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f:$f:$f:$f:$f:$f:$f:$f"; - $this->assertTrue( IP::isValid( $ip ), "$ip is a valid IPv6 address" ); - } - } - // test with some abbreviations - $this->assertFalse( IP::isValid( ':fc:100::' ), 'IPv6 starting with lone ":"' ); - $this->assertFalse( IP::isValid( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); - $this->assertFalse( IP::isValid( 'fc:300' ), 'IPv6 with only 2 words' ); - $this->assertFalse( IP::isValid( 'fc:100:300' ), 'IPv6 with only 3 words' ); - - $this->assertTrue( IP::isValid( 'fc:100::' ) ); - $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e::' ) ); - $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e:ac::' ) ); - - $this->assertTrue( IP::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); - $this->assertTrue( IP::isValid( '2001::df' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' ); - $this->assertTrue( IP::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); - - $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' ); - $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' ); - } - - /** - * @covers IP::isValid - */ - public function testInvalidIPs() { - // Out of range... - foreach ( range( 256, 999 ) as $i ) { - $a = sprintf( "%03d", $i ); - $b = sprintf( "%02d", $i ); - $c = sprintf( "%01d", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f.$f.$f.$f"; - $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv4 address" ); - } - } - foreach ( range( 'g', 'z' ) as $i ) { - $a = sprintf( "%04s", $i ); - $b = sprintf( "%03s", $i ); - $c = sprintf( "%02s", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f:$f:$f:$f:$f:$f:$f:$f"; - $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv6 address" ); - } - } - // Have CIDR - $ipCIDRs = array( - '212.35.31.121/32', - '212.35.31.121/18', - '212.35.31.121/24', - '::ff:d:321:5/96', - 'ff::d3:321:5/116', - 'c:ff:12:1:ea:d:321:5/120', - ); - foreach ( $ipCIDRs as $i ) { - $this->assertFalse( IP::isValid( $i ), - "$i is an invalid IP address because it is a block" ); - } - // Incomplete/garbage - $invalid = array( - 'www.xn--var-xla.net', - '216.17.184.G', - '216.17.184.1.', - '216.17.184', - '216.17.184.', - '256.17.184.1' - ); - foreach ( $invalid as $i ) { - $this->assertFalse( IP::isValid( $i ), "$i is an invalid IP address" ); - } - } - - /** - * @covers IP::isValidBlock - */ - public function testValidBlocks() { - $valid = array( - '116.17.184.5/32', - '0.17.184.5/30', - '16.17.184.1/24', - '30.242.52.14/1', - '10.232.52.13/8', - '30.242.52.14/0', - '::e:f:2001/96', - '::c:f:2001/128', - '::10:f:2001/70', - '::fe:f:2001/1', - '::6d:f:2001/8', - '::fe:f:2001/0', - ); - foreach ( $valid as $i ) { - $this->assertTrue( IP::isValidBlock( $i ), "$i is a valid IP block" ); - } - } - - /** - * @covers IP::isValidBlock - */ - public function testInvalidBlocks() { - $invalid = array( - '116.17.184.5/33', - '0.17.184.5/130', - '16.17.184.1/-1', - '10.232.52.13/*', - '7.232.52.13/ab', - '11.232.52.13/', - '::e:f:2001/129', - '::c:f:2001/228', - '::10:f:2001/-1', - '::6d:f:2001/*', - '::86:f:2001/ab', - '::23:f:2001/', - ); - foreach ( $invalid as $i ) { - $this->assertFalse( IP::isValidBlock( $i ), "$i is not a valid IP block" ); - } - } - - /** - * Improve IP::sanitizeIP() code coverage - * @todo Most probably incomplete - */ - public function testSanitizeIP() { - $this->assertNull( IP::sanitizeIP( '' ) ); - $this->assertNull( IP::sanitizeIP( ' ' ) ); - } - - /** - * @covers IP::toUnsigned - * @dataProvider provideToUnsigned - */ - 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' ) - ); - } - - /** - * @covers IP::isPublic - */ - public function testPrivateIPs() { - $private = array( 'fc00::3', 'fc00::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' ); - foreach ( $private as $p ) { - $this->assertFalse( IP::isPublic( $p ), "$p is not a public IP address" ); - } - $public = array( '2001:5c0:1000:a::133', 'fc::3', '00FC::' ); - foreach ( $public as $p ) { - $this->assertTrue( IP::isPublic( $p ), "$p is a public IP address" ); - } - } - - // Private wrapper used to test CIDR Parsing. - private function assertFalseCIDR( $CIDR, $msg = '' ) { - $ff = array( false, false ); - $this->assertEquals( $ff, IP::parseCIDR( $CIDR ), $msg ); - } - - // Private wrapper to test network shifting using only dot notation - private function assertNet( $expected, $CIDR ) { - $parse = IP::parseCIDR( $CIDR ); - $this->assertEquals( $expected, long2ip( $parse[0] ), "network shifting $CIDR" ); - } - - /** - * @covers IP::hexToQuad - */ - public function testHexToQuad() { - $this->assertEquals( '0.0.0.1', IP::hexToQuad( '00000001' ) ); - $this->assertEquals( '255.0.0.0', IP::hexToQuad( 'FF000000' ) ); - $this->assertEquals( '255.255.255.255', IP::hexToQuad( 'FFFFFFFF' ) ); - $this->assertEquals( '10.188.222.255', IP::hexToQuad( '0ABCDEFF' ) ); - // hex not left-padded... - $this->assertEquals( '0.0.0.0', IP::hexToQuad( '0' ) ); - $this->assertEquals( '0.0.0.1', IP::hexToQuad( '1' ) ); - $this->assertEquals( '0.0.0.255', IP::hexToQuad( 'FF' ) ); - $this->assertEquals( '0.0.255.0', IP::hexToQuad( 'FF00' ) ); - } - - /** - * @covers IP::hexToOctet - */ - public function testHexToOctet() { - $this->assertEquals( '0:0:0:0:0:0:0:1', - IP::hexToOctet( '00000000000000000000000000000001' ) ); - $this->assertEquals( '0:0:0:0:0:0:FF:3', - IP::hexToOctet( '00000000000000000000000000FF0003' ) ); - $this->assertEquals( '0:0:0:0:0:0:FF00:6', - IP::hexToOctet( '000000000000000000000000FF000006' ) ); - $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', - IP::hexToOctet( '000000000000000000000000FCCFFAFF' ) ); - $this->assertEquals( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', - IP::hexToOctet( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ) ); - // hex not left-padded... - $this->assertEquals( '0:0:0:0:0:0:0:0', IP::hexToOctet( '0' ) ); - $this->assertEquals( '0:0:0:0:0:0:0:1', IP::hexToOctet( '1' ) ); - $this->assertEquals( '0:0:0:0:0:0:0:FF', IP::hexToOctet( 'FF' ) ); - $this->assertEquals( '0:0:0:0:0:0:0:FFD0', IP::hexToOctet( 'FFD0' ) ); - $this->assertEquals( '0:0:0:0:0:0:FA00:0', IP::hexToOctet( 'FA000000' ) ); - $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP::hexToOctet( 'FCCFFAFF' ) ); - } - - /** - * IP::parseCIDR() returns an array containing a signed IP address - * representing the network mask and the bit mask. - * @covers IP::parseCIDR - */ - public function testCIDRParsing() { - $this->assertFalseCIDR( '192.0.2.0', "missing mask" ); - $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" ); - - // Verify if statement - $this->assertFalseCIDR( '256.0.0.0/32', "invalid net" ); - $this->assertFalseCIDR( '192.0.2.0/AA', "mask not numeric" ); - $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0" ); - $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32" ); - - // Check internal logic - # 0 mask always result in array(0,0) - $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '192.0.0.2/0' ) ); - $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '0.0.0.0/0' ) ); - $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '255.255.255.255/0' ) ); - - // @todo FIXME: Add more tests. - - # This part test network shifting - $this->assertNet( '192.0.0.0', '192.0.0.2/24' ); - $this->assertNet( '192.168.5.0', '192.168.5.13/24' ); - $this->assertNet( '10.0.0.160', '10.0.0.161/28' ); - $this->assertNet( '10.0.0.0', '10.0.0.3/28' ); - $this->assertNet( '10.0.0.0', '10.0.0.3/30' ); - $this->assertNet( '10.0.0.4', '10.0.0.4/30' ); - $this->assertNet( '172.17.32.0', '172.17.35.48/21' ); - $this->assertNet( '10.128.0.0', '10.135.0.0/9' ); - $this->assertNet( '134.0.0.0', '134.0.5.1/8' ); - } - - /** - * @covers IP::canonicalize - */ - public function testIPCanonicalizeOnValidIp() { - $this->assertEquals( '192.0.2.152', IP::canonicalize( '192.0.2.152' ), - 'Canonicalization of a valid IP returns it unchanged' ); - } - - /** - * @covers IP::canonicalize - */ - public function testIPCanonicalizeMappedAddress() { - $this->assertEquals( - '192.0.2.152', - IP::canonicalize( '::ffff:192.0.2.152' ) - ); - $this->assertEquals( - '192.0.2.152', - IP::canonicalize( '::192.0.2.152' ) - ); - } - - /** - * Issues there are most probably from IP::toHex() or IP::parseRange() - * @covers IP::isInRange - * @dataProvider provideIPsAndRanges - */ - public function testIPIsInRange( $expected, $addr, $range, $message = '' ) { - $this->assertEquals( - $expected, - IP::isInRange( $addr, $range ), - $message - ); - } - - /** Provider for testIPIsInRange() */ - public static function provideIPsAndRanges() { - # Format: (expected boolean, address, range, optional message) - return array( - # IPv4 - array( true, '192.0.2.0', '192.0.2.0/24', 'Network address' ), - array( true, '192.0.2.77', '192.0.2.0/24', 'Simple address' ), - array( true, '192.0.2.255', '192.0.2.0/24', 'Broadcast address' ), - - array( false, '0.0.0.0', '192.0.2.0/24' ), - array( false, '255.255.255', '192.0.2.0/24' ), - - # IPv6 - array( false, '::1', '2001:DB8::/32' ), - array( false, '::', '2001:DB8::/32' ), - array( false, 'FE80::1', '2001:DB8::/32' ), - - array( true, '2001:DB8::', '2001:DB8::/32' ), - array( true, '2001:0DB8::', '2001:DB8::/32' ), - array( true, '2001:DB8::1', '2001:DB8::/32' ), - array( true, '2001:0DB8::1', '2001:DB8::/32' ), - array( true, '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', - '2001:DB8::/32' ), - - array( false, '2001:0DB8:F::', '2001:DB8::/96' ), - ); - } - - /** - * Test for IP::splitHostAndPort(). - * @dataProvider provideSplitHostAndPort - */ - public function testSplitHostAndPort( $expected, $input, $description ) { - $this->assertEquals( $expected, IP::splitHostAndPort( $input ), $description ); - } - - /** - * Provider for IP::splitHostAndPort() - */ - public static function provideSplitHostAndPort() { - return array( - array( false, '[', 'Unclosed square bracket' ), - array( false, '[::', 'Unclosed square bracket 2' ), - array( array( '::', false ), '::', 'Bare IPv6 0' ), - array( array( '::1', false ), '::1', 'Bare IPv6 1' ), - array( array( '::', false ), '[::]', 'Bracketed IPv6 0' ), - array( array( '::1', false ), '[::1]', 'Bracketed IPv6 1' ), - array( array( '::1', 80 ), '[::1]:80', 'Bracketed IPv6 with port' ), - array( false, '::x', 'Double colon but no IPv6' ), - array( array( 'x', 80 ), 'x:80', 'Hostname and port' ), - array( false, 'x:x', 'Hostname and invalid port' ), - array( array( 'x', false ), 'x', 'Plain hostname' ) - ); - } - - /** - * Test for IP::combineHostAndPort() - * @dataProvider provideCombineHostAndPort - */ - public function testCombineHostAndPort( $expected, $input, $description ) { - list( $host, $port, $defaultPort ) = $input; - $this->assertEquals( - $expected, - IP::combineHostAndPort( $host, $port, $defaultPort ), - $description ); - } - - /** - * Provider for IP::combineHostAndPort() - */ - public static function provideCombineHostAndPort() { - return array( - array( '[::1]', array( '::1', 2, 2 ), 'IPv6 default port' ), - array( '[::1]:2', array( '::1', 2, 3 ), 'IPv6 non-default port' ), - array( 'x', array( 'x', 2, 2 ), 'Normal default port' ), - array( 'x:2', array( 'x', 2, 3 ), 'Normal non-default port' ), - ); - } - - /** - * Test for IP::sanitizeRange() - * @dataProvider provideIPCIDRs - */ - public function testSanitizeRange( $input, $expected, $description ) { - $this->assertEquals( $expected, IP::sanitizeRange( $input ), $description ); - } - - /** - * Provider for IP::testSanitizeRange() - */ - public static function provideIPCIDRs() { - return array( - array( '35.56.31.252/16', '35.56.0.0/16', 'IPv4 range' ), - array( '135.16.21.252/24', '135.16.21.0/24', 'IPv4 range' ), - array( '5.36.71.252/32', '5.36.71.252/32', 'IPv4 silly range' ), - array( '5.36.71.252', '5.36.71.252', 'IPv4 non-range' ), - array( '0:1:2:3:4:c5:f6:7/96', '0:1:2:3:4:C5:0:0/96', 'IPv6 range' ), - array( '0:1:2:3:4:5:6:7/120', '0:1:2:3:4:5:6:0/120', 'IPv6 range' ), - array( '0:e1:2:3:4:5:e6:7/128', '0:E1:2:3:4:5:E6:7/128', 'IPv6 silly range' ), - array( '0:c1:A2:3:4:5:c6:7', '0:C1:A2:3:4:5:C6:7', 'IPv6 non range' ), - ); - } - - /** - * Test for IP::prettifyIP() - * @dataProvider provideIPsToPrettify - */ - public function testPrettifyIP( $ip, $prettified ) { - $this->assertEquals( $prettified, IP::prettifyIP( $ip ), "Prettify of $ip" ); - } - - /** - * Provider for IP::testPrettifyIP() - */ - public static function provideIPsToPrettify() { - return array( - array( '0:0:0:0:0:0:0:0', '::' ), - array( '0:0:0::0:0:0', '::' ), - array( '0:0:0:1:0:0:0:0', '0:0:0:1::' ), - array( '0:0::f', '::f' ), - array( '0::0:0:0:33:fef:b', '::33:fef:b' ), - array( '3f:535:0:0:0:0:e:fbb', '3f:535::e:fbb' ), - array( '0:0:fef:0:0:0:e:fbb', '0:0:fef::e:fbb' ), - array( 'abbc:2004::0:0:0:0', 'abbc:2004::' ), - array( 'cebc:2004:f:0:0:0:0:0', 'cebc:2004:f::' ), - array( '0:0:0:0:0:0:0:0/16', '::/16' ), - array( '0:0:0::0:0:0/64', '::/64' ), - array( '0:0::f/52', '::f/52' ), - array( '::0:0:33:fef:b/52', '::33:fef:b/52' ), - array( '3f:535:0:0:0:0:e:fbb/48', '3f:535::e:fbb/48' ), - array( '0:0:fef:0:0:0:e:fbb/96', '0:0:fef::e:fbb/96' ), - array( 'abbc:2004:0:0::0:0/40', 'abbc:2004::/40' ), - array( 'aebc:2004:f:0:0:0:0:0/80', 'aebc:2004:f::/80' ), - ); - } -} diff --git a/tests/phpunit/includes/LanguageConverterTest.php b/tests/phpunit/includes/LanguageConverterTest.php deleted file mode 100644 index 7c2134b9..00000000 --- a/tests/phpunit/includes/LanguageConverterTest.php +++ /dev/null @@ -1,148 +0,0 @@ -<?php - -class LanguageConverterTest extends MediaWikiLangTestCase { - protected $lang = null; - protected $lc = null; - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgContLang' => Language::factory( 'tg' ), - 'wgLanguageCode' => 'tg', - 'wgDefaultLanguageVariant' => false, - 'wgMemc' => new EmptyBagOStuff, - 'wgRequest' => new FauxRequest( array() ), - 'wgUser' => new User, - ) ); - - $this->lang = new LanguageToTest(); - $this->lc = new TestConverter( - $this->lang, 'tg', - array( 'tg', 'tg-latn' ) - ); - } - - protected function tearDown() { - unset( $this->lc ); - unset( $this->lang ); - - parent::tearDown(); - } - - public function testGetPreferredVariantDefaults() { - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantHeaders() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg-latn' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantHeaderWeight() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg;q=1' ); - - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantHeaderWeight2() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg-latn;q=1' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantHeaderMulti() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'en, tg-latn;q=1' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantUserOption() { - global $wgUser; - - $wgUser = new User; - $wgUser->load(); // from 'defaults' - $wgUser->mId = 1; - $wgUser->mDataLoaded = true; - $wgUser->mOptionsLoaded = true; - $wgUser->setOption( 'variant', 'tg-latn' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - 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' ); - $wgRequest->setVal( 'variant', 'tg' ); - $wgUser = User::newFromId( "admin" ); - $wgUser->setId( 1 ); - $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' ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } - - - public function testGetPreferredVariantDefaultLanguageVariant() { - global $wgDefaultLanguageVariant; - - $wgDefaultLanguageVariant = 'tg-latn'; - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - public function testGetPreferredVariantDefaultLanguageVsUrlVariant() { - global $wgDefaultLanguageVariant, $wgRequest, $wgContLang; - - $wgContLang = Language::factory( 'tg-latn' ); - $wgDefaultLanguageVariant = 'tg'; - $wgRequest->setVal( 'variant', null ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } -} - -/** - * Test converter (from Tajiki to latin orthography) - */ -class TestConverter extends LanguageConverter { - private $table = array( - 'б' => 'b', - 'в' => 'v', - 'г' => 'g', - ); - - function loadDefaultTables() { - $this->mTables = array( - 'tg-latn' => new ReplacementArray( $this->table ), - 'tg' => new ReplacementArray() - ); - } -} - -class LanguageToTest extends Language { - function __construct() { - parent::__construct(); - $variants = array( 'tg', 'tg-latn' ); - $this->mConverter = new TestConverter( $this, 'tg', $variants ); - } -} diff --git a/tests/phpunit/includes/LicensesTest.php b/tests/phpunit/includes/LicensesTest.php deleted file mode 100644 index 478a2ffc..00000000 --- a/tests/phpunit/includes/LicensesTest.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -class LicensesTest extends MediaWikiTestCase { - - public function testLicenses() { - $str = " -* Free licenses: -** GFDL|Debian disagrees -"; - - $lc = new Licenses( array( - 'fieldname' => 'FooField', - 'type' => 'select', - 'section' => 'description', - 'id' => 'wpLicense', - 'label' => 'A label text', # Note can't test label-message because $wgOut is not defined - 'name' => 'AnotherName', - 'licenses' => $str, - ) ); - $this->assertThat( $lc, $this->isInstanceOf( 'Licenses' ) ); - } -} diff --git a/tests/phpunit/includes/LinkerTest.php b/tests/phpunit/includes/LinkerTest.php deleted file mode 100644 index b605f08f..00000000 --- a/tests/phpunit/includes/LinkerTest.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php - -class LinkerTest extends MediaWikiLangTestCase { - - /** - * @dataProvider provideCasesForUserLink - * @covers Linker::userLink - */ - public function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) { - $this->setMwGlobals( array( - 'wgArticlePath' => '/wiki/$1', - 'wgWellFormedXml' => true, - ) ); - - $this->assertEquals( $expected, - Linker::userLink( $userId, $userName, $altUserName, $msg ) - ); - } - - public static function provideCasesForUserLink() { - # Format: - # - expected - # - userid - # - username - # - optional altUserName - # - optional message - return array( - - ### ANONYMOUS USER ######################################## - array( - '<a href="/wiki/Special:Contributions/JohnDoe" title="Special:Contributions/JohnDoe" class="mw-userlink">JohnDoe</a>', - 0, 'JohnDoe', false, - ), - array( - '<a href="/wiki/Special:Contributions/::1" title="Special:Contributions/::1" class="mw-userlink">::1</a>', - 0, '::1', false, - 'Anonymous with pretty IPv6' - ), - array( - '<a href="/wiki/Special:Contributions/0:0:0:0:0:0:0:1" title="Special:Contributions/0:0:0:0:0:0:0:1" class="mw-userlink">::1</a>', - 0, '0:0:0:0:0:0:0:1', false, - 'Anonymous with almost pretty IPv6' - ), - array( - '<a href="/wiki/Special:Contributions/0000:0000:0000:0000:0000:0000:0000:0001" title="Special:Contributions/0000:0000:0000:0000:0000:0000:0000:0001" class="mw-userlink">::1</a>', - 0, '0000:0000:0000:0000:0000:0000:0000:0001', false, - 'Anonymous with full IPv6' - ), - array( - '<a href="/wiki/Special:Contributions/::1" title="Special:Contributions/::1" class="mw-userlink">AlternativeUsername</a>', - 0, '::1', 'AlternativeUsername', - 'Anonymous with pretty IPv6 and an alternative username' - ), - - # IPV4 - array( - '<a href="/wiki/Special:Contributions/127.0.0.1" title="Special:Contributions/127.0.0.1" class="mw-userlink">127.0.0.1</a>', - 0, '127.0.0.1', false, - 'Anonymous with IPv4' - ), - array( - '<a href="/wiki/Special:Contributions/127.0.0.1" title="Special:Contributions/127.0.0.1" class="mw-userlink">AlternativeUsername</a>', - 0, '127.0.0.1', 'AlternativeUsername', - 'Anonymous with IPv4 and an alternative username' - ), - - ### Regular user ########################################## - # TODO! - ); - } -} diff --git a/tests/phpunit/includes/LinksUpdateTest.php b/tests/phpunit/includes/LinksUpdateTest.php deleted file mode 100644 index 5ade250e..00000000 --- a/tests/phpunit/includes/LinksUpdateTest.php +++ /dev/null @@ -1,175 +0,0 @@ -<?php - -/** - * - * @group Database - * ^--- make sure temporary tables are used. - */ -class LinksUpdateTest extends MediaWikiTestCase { - - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - - $this->tablesUsed = array_merge( $this->tablesUsed, - array( - 'interwiki', - 'page_props', - 'pagelinks', - 'categorylinks', - 'langlinks', - 'externallinks', - 'imagelinks', - 'templatelinks', - 'iwlinks' - ) - ); - } - - protected function setUp() { - parent::setUp(); - $dbw = wfGetDB( DB_MASTER ); - $dbw->replace( - 'interwiki', - array( 'iw_prefix' ), - array( - 'iw_prefix' => 'linksupdatetest', - 'iw_url' => 'http://testing.com/wiki/$1', - 'iw_api' => 'http://testing.com/w/api.php', - 'iw_local' => 0, - 'iw_trans' => 0, - 'iw_wikiid' => 'linksupdatetest', - ) - ); - } - - protected function makeTitleAndParserOutput( $name, $id ) { - $t = Title::newFromText( $name ); - $t->mArticleID = $id; # XXX: this is fugly - - $po = new ParserOutput(); - $po->setTitleText( $t->getPrefixedText() ); - - return array( $t, $po ); - } - - public function testUpdate_pagelinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addLink( Title::newFromText( "Foo" ) ); - $po->addLink( Title::newFromText( "Special:Foo" ) ); // special namespace should be ignored - $po->addLink( Title::newFromText( "linksupdatetest:Foo" ) ); // interwiki link should be ignored - $po->addLink( Title::newFromText( "#Foo" ) ); // hash link should be ignored - - $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" ) ); - - $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() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addExternalLink( "http://testing.com/wiki/Foo" ); - - $this->assertLinksUpdate( $t, $po, 'externallinks', 'el_to, el_index', 'el_from = 111', array( - array( 'http://testing.com/wiki/Foo', 'http://com.testing./wiki/Foo' ), - ) ); - } - - public function testUpdate_categorylinks() { - $this->setMwGlobals( 'wgCategoryCollation', 'uppercase' ); - - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addCategory( "Foo", "FOO" ); - - $this->assertLinksUpdate( $t, $po, 'categorylinks', 'cl_to, cl_sortkey', 'cl_from = 111', array( - array( 'Foo', "FOO\nTESTING" ), - ) ); - } - - public function testUpdate_iwlinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $target = Title::makeTitleSafe( NS_MAIN, "Foo", '', 'linksupdatetest' ); - $po->addInterwikiLink( $target ); - - $this->assertLinksUpdate( $t, $po, 'iwlinks', 'iwl_prefix, iwl_title', 'iwl_from = 111', array( - array( 'linksupdatetest', 'Foo' ), - ) ); - } - - public function testUpdate_templatelinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addTemplate( Title::newFromText( "Template:Foo" ), 23, 42 ); - - $this->assertLinksUpdate( $t, $po, 'templatelinks', 'tl_namespace, tl_title', 'tl_from = 111', array( - array( NS_TEMPLATE, 'Foo' ), - ) ); - } - - public function testUpdate_imagelinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addImage( "Foo.png" ); - - $this->assertLinksUpdate( $t, $po, 'imagelinks', 'il_to', 'il_from = 111', array( - array( 'Foo.png' ), - ) ); - } - - public function testUpdate_langlinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addLanguageLink( Title::newFromText( "en:Foo" )->getFullText() ); - - $this->assertLinksUpdate( $t, $po, 'langlinks', 'll_lang, ll_title', 'll_from = 111', array( - array( 'En', 'Foo' ), - ) ); - } - - public function testUpdate_page_props() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->setProperty( "foo", "bar" ); - - $this->assertLinksUpdate( $t, $po, 'page_props', 'pp_propname, pp_value', 'pp_page = 111', array( - array( 'foo', 'bar' ), - ) ); - } - - // @todo test recursive, too! - - protected function assertLinksUpdate( Title $title, ParserOutput $parserOutput, $table, $fields, $condition, array $expectedRows ) { - $update = new LinksUpdate( $title, $parserOutput ); - - //NOTE: make sure LinksUpdate does not generate warnings when called inside a transaction. - $update->beginTransaction(); - $update->doUpdate(); - $update->commitTransaction(); - - $this->assertSelect( $table, $fields, $condition, $expectedRows ); - return $update; - } -} diff --git a/tests/phpunit/includes/LocalFileTest.php b/tests/phpunit/includes/LocalFileTest.php deleted file mode 100644 index 2501c783..00000000 --- a/tests/phpunit/includes/LocalFileTest.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php - -/** - * These tests should work regardless of $wgCapitalLinks - * @group Database - */ - -class LocalFileTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( 'wgCapitalLinks', true ); - - $info = array( - 'name' => 'test', - 'directory' => '/testdir', - 'url' => '/testurl', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => new FSFileBackend( array( - 'name' => 'local-backend', - 'lockManager' => 'fsLockManager', - 'containerPaths' => array( - 'cont1' => "/testdir/local-backend/tempimages/cont1", - 'cont2' => "/testdir/local-backend/tempimages/cont2" - ) - ) ) - ); - $this->repo_hl0 = new LocalRepo( array( 'hashLevels' => 0 ) + $info ); - $this->repo_hl2 = new LocalRepo( array( 'hashLevels' => 2 ) + $info ); - $this->repo_lc = new LocalRepo( array( 'initialCapital' => false ) + $info ); - $this->file_hl0 = $this->repo_hl0->newFile( 'test!' ); - $this->file_hl2 = $this->repo_hl2->newFile( 'test!' ); - $this->file_lc = $this->repo_lc->newFile( 'test!' ); - } - - 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() ); - } - - 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() ); - } - - 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() ); - } - - 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( '!' ) ); - } - - 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' ) ); - } - - 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( '!' ) ); - } - - 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' ) ); - } - - 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( '!' ) ); - } - - 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( '!' ) ); - } - - public function testGetUrl() { - $this->assertEquals( '/testurl/Test%21', $this->file_hl0->getUrl() ); - $this->assertEquals( '/testurl/a/a2/Test%21', $this->file_hl2->getUrl() ); - } - - 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/LocalisationCacheTest.php b/tests/phpunit/includes/LocalisationCacheTest.php deleted file mode 100644 index b34847aa..00000000 --- a/tests/phpunit/includes/LocalisationCacheTest.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php - -class LocalisationCacheTest extends MediaWikiTestCase { - public function testPuralRulesFallback() { - $cache = Language::getLocalisationCache(); - - $this->assertEquals( - $cache->getItem( 'ar', 'pluralRules' ), - $cache->getItem( 'arz', 'pluralRules' ), - 'arz plural rules (undefined) fallback to ar (defined)' - ); - - $this->assertEquals( - $cache->getItem( 'ar', 'compiledPluralRules' ), - $cache->getItem( 'arz', 'compiledPluralRules' ), - 'arz compiled plural rules (undefined) fallback to ar (defined)' - ); - - $this->assertNotEquals( - $cache->getItem( 'ksh', 'pluralRules' ), - $cache->getItem( 'de', 'pluralRules' ), - 'ksh plural rules (defined) dont fallback to de (defined)' - ); - - $this->assertNotEquals( - $cache->getItem( 'ksh', 'compiledPluralRules' ), - $cache->getItem( 'de', 'compiledPluralRules' ), - 'ksh compiled plural rules (defined) dont fallback to de (defined)' - ); - } -} diff --git a/tests/phpunit/includes/MWExceptionHandlerTest.php b/tests/phpunit/includes/MWExceptionHandlerTest.php deleted file mode 100644 index 987dfa83..00000000 --- a/tests/phpunit/includes/MWExceptionHandlerTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * Tests for includes/Exception.php. - * - * @author Antoine Musso - * @copyright Copyright © 2013, Antoine Musso - * @copyright Copyright © 2013, Wikimedia Foundation Inc. - * @file - */ - -class MWExceptionHandlerTest extends MediaWikiTestCase { - - /** - * @covers MWExceptionHandler::getRedactedTrace - */ - function testGetRedactedTrace() { - try { - $array = array( 'a', 'b' ); - $object = new StdClass(); - self::helperThrowAnException( $array, $object ); - } catch (Exception $e) { - } - - # Make sure our strack trace contains an array and an object passed to - # some function in the stacktrace. Else, we can not assert the trace - # redaction achieved its job. - $trace = $e->getTrace(); - $hasObject = false; - $hasArray = false; - foreach ( $trace as $frame ) { - if ( ! isset( $frame['args'] ) ) { - continue; - } - foreach ( $frame['args'] as $arg ) { - $hasObject = $hasObject || is_object( $arg ); - $hasArray = $hasArray || is_array( $arg ); - } - - if( $hasObject && $hasArray ) { - break; - } - } - $this->assertTrue( $hasObject, - "The stacktrace must have a function having an object has parameter" ); - $this->assertTrue( $hasArray, - "The stacktrace must have a function having an array has parameter" ); - - # Now we redact the trace.. and make sure no function arguments are - # arrays or objects. - $redacted = MWExceptionHandler::getRedactedTrace( $e ); - - foreach ( $redacted as $frame ) { - if ( ! isset( $frame['args'] ) ) { - continue; - } - foreach ( $frame['args'] as $arg ) { - $this->assertNotInternalType( 'array', $arg); - $this->assertNotInternalType( 'object', $arg); - } - } - } - - /** - * Helper function for testExpandArgumentsInCall - * - * Pass it an object and an array :-) - * - * @throws Exception - */ - protected static function helperThrowAnException( $a, $b ) { - throw new Exception(); - } -} diff --git a/tests/phpunit/includes/MWFunctionTest.php b/tests/phpunit/includes/MWFunctionTest.php deleted file mode 100644 index d86f2c9b..00000000 --- a/tests/phpunit/includes/MWFunctionTest.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -class MWFunctionTest extends MediaWikiTestCase { - public function testNewObjFunction() { - $arg1 = 'Foo'; - $arg2 = 'Bar'; - $arg3 = array( 'Baz' ); - $arg4 = new ExampleObject; - - $args = array( $arg1, $arg2, $arg3, $arg4 ); - - $newObject = new MWBlankClass( $arg1, $arg2, $arg3, $arg4 ); - $this->assertEquals( - MWFunction::newObj( 'MWBlankClass', $args )->args, - $newObject->args - ); - } -} - -class MWBlankClass { - - public $args = array(); - - function __construct( $arg1, $arg2, $arg3, $arg4 ) { - $this->args = array( $arg1, $arg2, $arg3, $arg4 ); - } -} - -class ExampleObject { -} diff --git a/tests/phpunit/includes/MWNamespaceTest.php b/tests/phpunit/includes/MWNamespaceTest.php deleted file mode 100644 index 10e9db61..00000000 --- a/tests/phpunit/includes/MWNamespaceTest.php +++ /dev/null @@ -1,571 +0,0 @@ -<?php -/** - * @author Antoine Musso - * @copyright Copyright © 2011, Antoine Musso - * @file - */ - -/** - * Test class for MWNamespace. - * Generated by PHPUnit on 2011-02-20 at 21:01:55. - * - */ -class MWNamespaceTest extends MediaWikiTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgContentNamespaces' => array( NS_MAIN ), - 'wgNamespacesWithSubpages' => array( - NS_TALK => true, - NS_USER => true, - NS_USER_TALK => true, - ), - 'wgCapitalLinks' => true, - 'wgCapitalLinkOverrides' => array(), - 'wgNonincludableNamespaces' => array(), - ) ); - } - -#### START OF TESTS ######################################################### - - /** - * @todo Write more texts, handle $wgAllowImageMoving setting - */ - public function testIsMovable() { - $this->assertFalse( MWNamespace::isMovable( NS_CATEGORY ) ); - # @todo FIXME: Write more tests!! - } - - /** - * Please make sure to change testIsTalk() if you change the assertions below - */ - public function testIsSubject() { - // Special namespaces - $this->assertIsSubject( NS_MEDIA ); - $this->assertIsSubject( NS_SPECIAL ); - - // Subject pages - $this->assertIsSubject( NS_MAIN ); - $this->assertIsSubject( NS_USER ); - $this->assertIsSubject( 100 ); # user defined - - // Talk pages - $this->assertIsNotSubject( NS_TALK ); - $this->assertIsNotSubject( NS_USER_TALK ); - $this->assertIsNotSubject( 101 ); # user defined - } - - /** - * Reverse of testIsSubject(). - * Please update testIsSubject() if you change assertions below - */ - public function testIsTalk() { - // Special namespaces - $this->assertIsNotTalk( NS_MEDIA ); - $this->assertIsNotTalk( NS_SPECIAL ); - - // Subject pages - $this->assertIsNotTalk( NS_MAIN ); - $this->assertIsNotTalk( NS_USER ); - $this->assertIsNotTalk( 100 ); # user defined - - // Talk pages - $this->assertIsTalk( NS_TALK ); - $this->assertIsTalk( NS_USER_TALK ); - $this->assertIsTalk( 101 ); # user defined - } - - /** - */ - public function testGetSubject() { - // Special namespaces are their own subjects - $this->assertEquals( NS_MEDIA, MWNamespace::getSubject( NS_MEDIA ) ); - $this->assertEquals( NS_SPECIAL, MWNamespace::getSubject( NS_SPECIAL ) ); - - $this->assertEquals( NS_MAIN, MWNamespace::getSubject( NS_TALK ) ); - $this->assertEquals( NS_USER, MWNamespace::getSubject( NS_USER_TALK ) ); - } - - /** - * Regular getTalk() calls - * Namespaces without a talk page (NS_MEDIA, NS_SPECIAL) are tested in - * the function testGetTalkExceptions() - */ - public function testGetTalk() { - $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_MAIN ) ); - $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_TALK ) ); - $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER ) ); - $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER_TALK ) ); - } - - /** - * Exceptions with getTalk() - * NS_MEDIA does not have talk pages. MediaWiki raise an exception for them. - * @expectedException MWException - */ - public function testGetTalkExceptionsForNsMedia() { - $this->assertNull( MWNamespace::getTalk( NS_MEDIA ) ); - } - - /** - * Exceptions with getTalk() - * NS_SPECIAL does not have talk pages. MediaWiki raise an exception for them. - * @expectedException MWException - */ - public function testGetTalkExceptionsForNsSpecial() { - $this->assertNull( MWNamespace::getTalk( NS_SPECIAL ) ); - } - - /** - * Regular getAssociated() calls - * Namespaces without an associated page (NS_MEDIA, NS_SPECIAL) are tested in - * the function testGetAssociatedExceptions() - */ - public function testGetAssociated() { - $this->assertEquals( NS_TALK, MWNamespace::getAssociated( NS_MAIN ) ); - $this->assertEquals( NS_MAIN, MWNamespace::getAssociated( NS_TALK ) ); - } - - ### Exceptions with getAssociated() - ### NS_MEDIA and NS_SPECIAL do not have talk pages. MediaWiki raises - ### an exception for them. - /** - * @expectedException MWException - */ - public function testGetAssociatedExceptionsForNsMedia() { - $this->assertNull( MWNamespace::getAssociated( NS_MEDIA ) ); - } - - /** - * @expectedException MWException - */ - public function testGetAssociatedExceptionsForNsSpecial() { - $this->assertNull( MWNamespace::getAssociated( NS_SPECIAL ) ); - } - - /** - * @todo Implement testExists(). - */ - /* - public function testExists() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - - /** - * Test MWNamespace::equals - * Note if we add a namespace registration system with keys like 'MAIN' - * we should add tests here for equivilance on things like 'MAIN' == 0 - * and 'MAIN' == NS_MAIN. - */ - public function testEquals() { - $this->assertTrue( MWNamespace::equals( NS_MAIN, NS_MAIN ) ); - $this->assertTrue( MWNamespace::equals( NS_MAIN, 0 ) ); // In case we make NS_MAIN 'MAIN' - $this->assertTrue( MWNamespace::equals( NS_USER, NS_USER ) ); - $this->assertTrue( MWNamespace::equals( NS_USER, 2 ) ); - $this->assertTrue( MWNamespace::equals( NS_USER_TALK, NS_USER_TALK ) ); - $this->assertTrue( MWNamespace::equals( NS_SPECIAL, NS_SPECIAL ) ); - $this->assertFalse( MWNamespace::equals( NS_MAIN, NS_TALK ) ); - $this->assertFalse( MWNamespace::equals( NS_USER, NS_USER_TALK ) ); - $this->assertFalse( MWNamespace::equals( NS_PROJECT, NS_TEMPLATE ) ); - } - - /** - * Test MWNamespace::subjectEquals - */ - public function testSubjectEquals() { - $this->assertSameSubject( NS_MAIN, NS_MAIN ); - $this->assertSameSubject( NS_MAIN, 0 ); // In case we make NS_MAIN 'MAIN' - $this->assertSameSubject( NS_USER, NS_USER ); - $this->assertSameSubject( NS_USER, 2 ); - $this->assertSameSubject( NS_USER_TALK, NS_USER_TALK ); - $this->assertSameSubject( NS_SPECIAL, NS_SPECIAL ); - $this->assertSameSubject( NS_MAIN, NS_TALK ); - $this->assertSameSubject( NS_USER, NS_USER_TALK ); - - $this->assertDifferentSubject( NS_PROJECT, NS_TEMPLATE ); - $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN ); - } - - public function testSpecialAndMediaAreDifferentSubjects() { - $this->assertDifferentSubject( - NS_MEDIA, NS_SPECIAL, - "NS_MEDIA and NS_SPECIAL are different subject namespaces" - ); - $this->assertDifferentSubject( - NS_SPECIAL, NS_MEDIA, - "NS_SPECIAL and NS_MEDIA are different subject namespaces" - ); - } - - /** - * @todo Implement testGetCanonicalNamespaces(). - */ - /* - public function testGetCanonicalNamespaces() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - /** - * @todo Implement testGetCanonicalName(). - */ - /* - public function testGetCanonicalName() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - /** - * @todo Implement testGetCanonicalIndex(). - */ - /* - public function testGetCanonicalIndex() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - - /** - * @todo Implement testGetValidNamespaces(). - */ - /* - public function testGetValidNamespaces() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } - */ - - /** - */ - public function testCanTalk() { - $this->assertCanNotTalk( NS_MEDIA ); - $this->assertCanNotTalk( NS_SPECIAL ); - - $this->assertCanTalk( NS_MAIN ); - $this->assertCanTalk( NS_TALK ); - $this->assertCanTalk( NS_USER ); - $this->assertCanTalk( NS_USER_TALK ); - - // User defined namespaces - $this->assertCanTalk( 100 ); - $this->assertCanTalk( 101 ); - } - - /** - */ - public function testIsContent() { - // NS_MAIN is a content namespace per DefaultSettings.php - // and per function definition. - - $this->assertIsContent( NS_MAIN ); - - // Other namespaces which are not expected to be content - - $this->assertIsNotContent( NS_MEDIA ); - $this->assertIsNotContent( NS_SPECIAL ); - $this->assertIsNotContent( NS_TALK ); - $this->assertIsNotContent( NS_USER ); - $this->assertIsNotContent( NS_CATEGORY ); - $this->assertIsNotContent( 100 ); - } - - /** - * Similar to testIsContent() but alters the $wgContentNamespaces - * global variable. - */ - public function testIsContentAdvanced() { - global $wgContentNamespaces; - - // Test that user defined namespace #252 is not content - $this->assertIsNotContent( 252 ); - - // Bless namespace # 252 as a content namespace - $wgContentNamespaces[] = 252; - - $this->assertIsContent( 252 ); - - // Makes sure NS_MAIN was not impacted - $this->assertIsContent( NS_MAIN ); - } - - public function testIsWatchable() { - // Specials namespaces are not watchable - $this->assertIsNotWatchable( NS_MEDIA ); - $this->assertIsNotWatchable( NS_SPECIAL ); - - // Core defined namespaces are watchables - $this->assertIsWatchable( NS_MAIN ); - $this->assertIsWatchable( NS_TALK ); - - // Additional, user defined namespaces are watchables - $this->assertIsWatchable( 100 ); - $this->assertIsWatchable( 101 ); - } - - public function testHasSubpages() { - global $wgNamespacesWithSubpages; - - // Special namespaces: - $this->assertHasNotSubpages( NS_MEDIA ); - $this->assertHasNotSubpages( NS_SPECIAL ); - - // Namespaces without subpages - $this->assertHasNotSubpages( NS_MAIN ); - - $wgNamespacesWithSubpages[NS_MAIN] = true; - $this->assertHasSubpages( NS_MAIN ); - - $wgNamespacesWithSubpages[NS_MAIN] = false; - $this->assertHasNotSubpages( NS_MAIN ); - - // Some namespaces with subpages - $this->assertHasSubpages( NS_TALK ); - $this->assertHasSubpages( NS_USER ); - $this->assertHasSubpages( NS_USER_TALK ); - } - - /** - */ - public function testGetContentNamespaces() { - global $wgContentNamespaces; - - $this->assertEquals( - array( NS_MAIN ), - MWNamespace::getContentNamespaces(), - '$wgContentNamespaces is an array with only NS_MAIN by default' - ); - - # test !is_array( $wgcontentNamespaces ) - $wgContentNamespaces = ''; - $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); - - $wgContentNamespaces = false; - $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); - - $wgContentNamespaces = null; - $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); - - $wgContentNamespaces = 5; - $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); - - # test $wgContentNamespaces === array() - $wgContentNamespaces = array(); - $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(), - 'NS_MAIN is forced in $wgContentNamespaces even if unwanted' - ); - - # test other cases, return $wgcontentNamespaces as is - $wgContentNamespaces = array( NS_MAIN ); - $this->assertEquals( - array( NS_MAIN ), - MWNamespace::getContentNamespaces() - ); - - $wgContentNamespaces = array( NS_MAIN, NS_USER, NS_CATEGORY ); - $this->assertEquals( - array( NS_MAIN, NS_USER, NS_CATEGORY ), - MWNamespace::getContentNamespaces() - ); - } - - /** - */ - public function testGetSubjectNamespaces() { - $subjectsNS = MWNamespace::getSubjectNamespaces(); - $this->assertContains( NS_MAIN, $subjectsNS, - "Talk namespaces should have NS_MAIN" ); - $this->assertNotContains( NS_TALK, $subjectsNS, - "Talk namespaces should have NS_TALK" ); - - $this->assertNotContains( NS_MEDIA, $subjectsNS, - "Talk namespaces should not have NS_MEDIA" ); - $this->assertNotContains( NS_SPECIAL, $subjectsNS, - "Talk namespaces should not have NS_SPECIAL" ); - } - - /** - */ - public function testGetTalkNamespaces() { - $talkNS = MWNamespace::getTalkNamespaces(); - $this->assertContains( NS_TALK, $talkNS, - "Subject namespaces should have NS_TALK" ); - $this->assertNotContains( NS_MAIN, $talkNS, - "Subject namespaces should not have NS_MAIN" ); - - $this->assertNotContains( NS_MEDIA, $talkNS, - "Subject namespaces should not have NS_MEDIA" ); - $this->assertNotContains( NS_SPECIAL, $talkNS, - "Subject namespaces should not have NS_SPECIAL" ); - } - - /** - * Some namespaces are always capitalized per code definition - * in MWNamespace::$alwaysCapitalizedNamespaces - */ - public function testIsCapitalizedHardcodedAssertions() { - // NS_MEDIA and NS_FILE are treated the same - $this->assertEquals( - MWNamespace::isCapitalized( NS_MEDIA ), - MWNamespace::isCapitalized( NS_FILE ), - 'NS_MEDIA and NS_FILE have same capitalization rendering' - ); - - // Boths are capitalized by default - $this->assertIsCapitalized( NS_MEDIA ); - $this->assertIsCapitalized( NS_FILE ); - - // Always capitalized namespaces - // @see MWNamespace::$alwaysCapitalizedNamespaces - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - } - - /** - * Follows up for testIsCapitalizedHardcodedAssertions() but alter the - * global $wgCapitalLink setting to have extended coverage. - * - * MWNamespace::isCapitalized() rely on two global settings: - * $wgCapitalLinkOverrides = array(); by default - * $wgCapitalLinks = true; by default - * This function test $wgCapitalLinks - * - * Global setting correctness is tested against the NS_PROJECT and - * NS_PROJECT_TALK namespaces since they are not hardcoded nor specials - */ - public function testIsCapitalizedWithWgCapitalLinks() { - global $wgCapitalLinks; - - $this->assertIsCapitalized( NS_PROJECT ); - $this->assertIsCapitalized( NS_PROJECT_TALK ); - - $wgCapitalLinks = false; - - // hardcoded namespaces (see above function) are still capitalized: - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - - // setting is correctly applied - $this->assertIsNotCapitalized( NS_PROJECT ); - $this->assertIsNotCapitalized( NS_PROJECT_TALK ); - } - - /** - * Counter part for MWNamespace::testIsCapitalizedWithWgCapitalLinks() now - * testing the $wgCapitalLinkOverrides global. - * - * @todo split groups of assertions in autonomous testing functions - */ - public function testIsCapitalizedWithWgCapitalLinkOverrides() { - global $wgCapitalLinkOverrides; - - // Test default settings - $this->assertIsCapitalized( NS_PROJECT ); - $this->assertIsCapitalized( NS_PROJECT_TALK ); - - // hardcoded namespaces (see above function) are capitalized: - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - - // Hardcoded namespaces remains capitalized - $wgCapitalLinkOverrides[NS_SPECIAL] = false; - $wgCapitalLinkOverrides[NS_USER] = false; - $wgCapitalLinkOverrides[NS_MEDIAWIKI] = false; - - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - - $wgCapitalLinkOverrides[NS_PROJECT] = false; - $this->assertIsNotCapitalized( NS_PROJECT ); - - $wgCapitalLinkOverrides[NS_PROJECT] = true; - $this->assertIsCapitalized( NS_PROJECT ); - - unset( $wgCapitalLinkOverrides[NS_PROJECT] ); - $this->assertIsCapitalized( NS_PROJECT ); - } - - public function testHasGenderDistinction() { - // Namespaces with gender distinctions - $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER ) ); - $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER_TALK ) ); - - // Other ones, "genderless" - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MEDIA ) ); - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_SPECIAL ) ); - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MAIN ) ); - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_TALK ) ); - } - - public function testIsNonincludable() { - global $wgNonincludableNamespaces; - - $wgNonincludableNamespaces = array( NS_USER ); - - $this->assertTrue( MWNamespace::isNonincludable( NS_USER ) ); - $this->assertFalse( MWNamespace::isNonincludable( NS_TEMPLATE ) ); - } - - ####### HELPERS ########################################################### - function __call( $method, $args ) { - // Call the real method if it exists - if ( method_exists( $this, $method ) ) { - return $this->$method( $args ); - } - - if ( preg_match( '/^assert(Has|Is|Can)(Not|)(Subject|Talk|Watchable|Content|Subpages|Capitalized)$/', $method, $m ) ) { - # Interprets arguments: - $ns = $args[0]; - $msg = isset( $args[1] ) ? $args[1] : " dummy message"; - - # Forge the namespace constant name: - if ( $ns === 0 ) { - $ns_name = "NS_MAIN"; - } else { - $ns_name = "NS_" . strtoupper( MWNamespace::getCanonicalName( $ns ) ); - } - # ... and the MWNamespace method name - $nsMethod = strtolower( $m[1] ) . $m[3]; - - $expect = ( $m[2] === '' ); - $expect_name = $expect ? 'TRUE' : 'FALSE'; - - return $this->assertEquals( $expect, - MWNamespace::$nsMethod( $ns, $msg ), - "MWNamespace::$nsMethod( $ns_name ) should returns $expect_name" - ); - } - - throw new Exception( __METHOD__ . " could not find a method named $method\n" ); - } - - function assertSameSubject( $ns1, $ns2, $msg = '' ) { - $this->assertTrue( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) ); - } - - function assertDifferentSubject( $ns1, $ns2, $msg = '' ) { - $this->assertFalse( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) ); - } -} diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php deleted file mode 100644 index 1e18f975..00000000 --- a/tests/phpunit/includes/MessageTest.php +++ /dev/null @@ -1,130 +0,0 @@ -<?php - -class MessageTest extends MediaWikiLangTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgLang' => Language::factory( 'en' ), - 'wgForceUIMsgAsContentMsg' => array(), - ) ); - } - - public function testExists() { - $this->assertTrue( wfMessage( 'mainpage' )->exists() ); - $this->assertTrue( wfMessage( 'mainpage' )->params( array() )->exists() ); - $this->assertTrue( wfMessage( 'mainpage' )->rawParams( 'foo', 123 )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->params( array() )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->rawParams( 'foo', 123 )->exists() ); - } - - public function testKey() { - $this->assertInstanceOf( 'Message', wfMessage( 'mainpage' ) ); - $this->assertInstanceOf( 'Message', wfMessage( 'i-dont-exist-evar' ) ); - $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() ); - $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->text() ); - $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->plain() ); - $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->escaped() ); - } - - 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() ); - } - - 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() ); - } - - 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() ); - } - - 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' ); - } - - /** - * 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' ); - } - - public function testInContentLanguageEnabled() { - $this->setMwGlobals( array( - 'wgLang' => Language::factory( 'fr' ), - 'wgForceUIMsgAsContentMsg' => array( 'mainpage' ), - ) ); - - $this->assertEquals( 'Accueil', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg enabled' ); - } - - /** - * @expectedException MWException - */ - public function testInLanguageThrows() { - wfMessage( 'foo' )->inLanguage( 123 ); - } -} diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php deleted file mode 100644 index 56bb0fce..00000000 --- a/tests/phpunit/includes/OutputPageTest.php +++ /dev/null @@ -1,133 +0,0 @@ -<?php - -/** - * - * @author Matthew Flaschen - * - * @group Output - * - */ -class OutputPageTest extends MediaWikiTestCase { - const SCREEN_MEDIA_QUERY = 'screen and (min-width: 982px)'; - const SCREEN_ONLY_MEDIA_QUERY = 'only screen and (min-width: 982px)'; - - /** - * Tests a particular case of transformCssMedia, using the given input, globals, - * expected return, and message - * - * Asserts that $expectedReturn is returned. - * - * 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['media'] - passed into the method under the same name - * options['expectedReturn'] - expected return value - * options['message'] - PHPUnit message for assertion - * - * @param array $args key-value array of arguments as shown above - */ - protected function assertTransformCssMediaCase( $args ) { - $queryData = array(); - if ( isset( $args['printableQuery'] ) ) { - $queryData['printable'] = $args['printableQuery']; - } - - if ( isset( $args['handheldQuery'] ) ) { - $queryData['handheld'] = $args['handheldQuery']; - } - - $fauxRequest = new FauxRequest( $queryData, false ); - $this->setMWGlobals( array( - 'wgRequest' => $fauxRequest, - ) ); - - $actualReturn = OutputPage::transformCssMedia( $args['media'] ); - $this->assertSame( $args['expectedReturn'], $actualReturn, $args['message'] ); - } - - /** - * Tests print requests - */ - public function testPrintRequests() { - $this->assertTransformCssMediaCase( array( - 'printableQuery' => '1', - 'media' => 'screen', - 'expectedReturn' => null, - 'message' => 'On printable request, screen returns null' - ) ); - - $this->assertTransformCssMediaCase( array( - 'printableQuery' => '1', - 'media' => self::SCREEN_MEDIA_QUERY, - 'expectedReturn' => null, - 'message' => 'On printable request, screen media query returns null' - ) ); - - $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->assertTransformCssMediaCase( array( - 'printableQuery' => '1', - 'media' => 'print', - 'expectedReturn' => '', - 'message' => 'On printable request, media print returns empty string' - ) ); - } - - /** - * Tests screen requests, without either query parameter set - */ - public function testScreenRequests() { - $this->assertTransformCssMediaCase( array( - 'media' => 'screen', - 'expectedReturn' => 'screen', - '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->assertTransformCssMediaCase( array( - 'media' => self::SCREEN_MEDIA_QUERY, - 'expectedReturn' => self::SCREEN_MEDIA_QUERY, - 'message' => 'On screen request, screen media query is preserved.' - ) ); - - $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->assertTransformCssMediaCase( array( - 'media' => 'print', - 'expectedReturn' => 'print', - 'message' => 'On screen request, print media type is preserved' - ) ); - } - - /** - * Tests handheld behavior - */ - public function testHandheld() { - $this->assertTransformCssMediaCase( array( - 'handheldQuery' => '1', - 'media' => 'handheld', - 'expectedReturn' => '', - 'message' => 'On request with handheld querystring and media is handheld, returns empty string' - ) ); - - $this->assertTransformCssMediaCase( array( - 'handheldQuery' => '1', - 'media' => 'screen', - 'expectedReturn' => null, - 'message' => 'On request with handheld querystring and media is screen, returns null' - ) ); - } -} diff --git a/tests/phpunit/includes/PathRouterTest.php b/tests/phpunit/includes/PathRouterTest.php deleted file mode 100644 index adfb215a..00000000 --- a/tests/phpunit/includes/PathRouterTest.php +++ /dev/null @@ -1,263 +0,0 @@ -<?php -/** - * Tests for the PathRouter parsing. - * - * @todo Add covers tags. - */ - -class PathRouterTest extends MediaWikiTestCase { - - /** - * @var PathRouter - */ - protected $basicRouter; - - protected function setUp() { - parent::setUp(); - $router = new PathRouter; - $router->add( "/wiki/$1" ); - $this->basicRouter = $router; - } - - /** - * Test basic path parsing - */ - public function testBasic() { - $matches = $this->basicRouter->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - } - - /** - * Test loose path auto-$1 - */ - public function testLoose() { - $router = new PathRouter; - $router->add( "/" ); # Should be the same as "/$1" - $matches = $router->parse( "/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - - $router = new PathRouter; - $router->add( "/wiki" ); # Should be the same as /wiki/$1 - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - - $router = new PathRouter; - $router->add( "/wiki/" ); # Should be the same as /wiki/$1 - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - } - - /** - * Test to ensure that path is based on specifity, not order - */ - public function testOrder() { - $router = new PathRouter; - $router->add( "/$1" ); - $router->add( "/a/$1" ); - $router->add( "/b/$1" ); - $matches = $router->parse( "/a/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - - $router = new PathRouter; - $router->add( "/b/$1" ); - $router->add( "/a/$1" ); - $router->add( "/$1" ); - $matches = $router->parse( "/a/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - } - - /** - * Test the handling of key based arrays with a url parameter - */ - public function testKeyParameter() { - $router = new PathRouter; - $router->add( array( 'edit' => "/edit/$1" ), array( 'action' => '$key' ) ); - $matches = $router->parse( "/edit/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'action' => 'edit' ) ); - } - - /** - * Test the handling of $2 inside paths - */ - public function testAdditionalParameter() { - // Basic $2 - $router = new PathRouter; - $router->add( '/$2/$1', array( 'test' => '$2' ) ); - $matches = $router->parse( "/asdf/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'test' => 'asdf' ) ); - } - - /** - * Test additional restricted value parameter - */ - public function testRestrictedValue() { - $router = new PathRouter; - $router->add( '/$2/$1', - array( 'test' => '$2' ), - array( '$2' => array( 'a', 'b' ) ) - ); - $router->add( '/$2/$1', - array( 'test2' => '$2' ), - array( '$2' => 'c' ) - ); - $router->add( '/$1' ); - - $matches = $router->parse( "/asdf/Foo" ); - $this->assertEquals( $matches, array( 'title' => "asdf/Foo" ) ); - - $matches = $router->parse( "/a/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'test' => 'a' ) ); - - $matches = $router->parse( "/c/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'test2' => 'c' ) ); - } - - public function callbackForTest( &$matches, $data ) { - $matches['x'] = $data['$1']; - $matches['foo'] = $data['foo']; - } - - public function testCallback() { - $router = new PathRouter; - $router->add( "/$1", - array( 'a' => 'b', 'data:foo' => 'bar' ), - array( 'callback' => array( $this, 'callbackForTest' ) ) - ); - $matches = $router->parse( '/Foo' ); - $this->assertEquals( $matches, array( - 'title' => "Foo", - 'x' => 'Foo', - 'a' => 'b', - 'foo' => 'bar' - ) ); - } - - /** - * Test to ensure that matches are not made if a parameter expects nonexistent input - */ - public function testFail() { - $router = new PathRouter; - $router->add( "/wiki/$1", array( 'title' => "$1$2" ) ); - $matches = $router->parse( "/wiki/A" ); - $this->assertEquals( array(), $matches ); - } - - /** - * Test to ensure weight of paths is handled correctly - */ - public function testWeight() { - $router = new PathRouter; - $router->addStrict( "/Bar", array( 'ping' => 'pong' ) ); - $router->add( "/asdf-$1", array( 'title' => 'qwerty-$1' ) ); - $router->add( "/$1" ); - $router->add( "/qwerty-$1", array( 'title' => 'asdf-$1' ) ); - $router->addStrict( "/Baz", array( 'marco' => 'polo' ) ); - $router->add( "/a/$1" ); - $router->add( "/asdf/$1" ); - $router->add( "/$2/$1", array( 'unrestricted' => '$2' ) ); - $router->add( array( 'qwerty' => "/qwerty/$1" ), array( 'qwerty' => '$key' ) ); - $router->add( "/$2/$1", array( 'restricted-to-y' => '$2' ), array( '$2' => 'y' ) ); - - foreach ( - array( - '/Foo' => array( 'title' => 'Foo' ), - '/Bar' => array( 'ping' => 'pong' ), - '/Baz' => array( 'marco' => 'polo' ), - '/asdf-foo' => array( 'title' => 'qwerty-foo' ), - '/qwerty-bar' => array( 'title' => 'asdf-bar' ), - '/a/Foo' => array( 'title' => 'Foo' ), - '/asdf/Foo' => array( 'title' => 'Foo' ), - '/qwerty/Foo' => array( 'title' => 'Foo', 'qwerty' => 'qwerty' ), - '/baz/Foo' => array( 'title' => 'Foo', 'unrestricted' => 'baz' ), - '/y/Foo' => array( 'title' => 'Foo', 'restricted-to-y' => 'y' ), - ) as $path => $result - ) { - $this->assertEquals( $router->parse( $path ), $result ); - } - } - - /** - * Make sure the router handles titles like Special:Recentchanges correctly - */ - public function testSpecial() { - $matches = $this->basicRouter->parse( "/wiki/Special:Recentchanges" ); - $this->assertEquals( $matches, array( 'title' => "Special:Recentchanges" ) ); - } - - /** - * Make sure the router decodes urlencoding properly - */ - public function testUrlencoding() { - $matches = $this->basicRouter->parse( "/wiki/Title_With%20Space" ); - $this->assertEquals( $matches, array( 'title' => "Title_With Space" ) ); - } - - public static function provideRegexpChars() { - return array( - array( "$" ), - array( "$1" ), - array( "\\" ), - array( "\\$1" ), - ); - } - - /** - * Make sure the router doesn't break on special characters like $ used in regexp replacements - * @dataProvider provideRegexpChars - */ - public function testRegexpChars( $char ) { - $matches = $this->basicRouter->parse( "/wiki/$char" ); - $this->assertEquals( $matches, array( 'title' => "$char" ) ); - } - - /** - * Make sure the router handles characters like +&() properly - */ - public function testCharacters() { - $matches = $this->basicRouter->parse( "/wiki/Plus+And&Dollar\\Stuff();[]{}*" ); - $this->assertEquals( $matches, array( 'title' => "Plus+And&Dollar\\Stuff();[]{}*" ) ); - } - - /** - * Make sure the router handles unicode characters correctly - * @depends testSpecial - * @depends testUrlencoding - * @depends testCharacters - */ - public function testUnicode() { - $matches = $this->basicRouter->parse( "/wiki/Spécial:Modifications_récentes" ); - $this->assertEquals( $matches, array( 'title' => "Spécial:Modifications_récentes" ) ); - - $matches = $this->basicRouter->parse( "/wiki/Sp%C3%A9cial:Modifications_r%C3%A9centes" ); - $this->assertEquals( $matches, array( 'title' => "Spécial:Modifications_récentes" ) ); - } - - /** - * Ensure the router doesn't choke on long paths. - */ - public function testLength() { - $matches = $this->basicRouter->parse( "/wiki/Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum." ); - $this->assertEquals( $matches, array( 'title' => "Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum." ) ); - } - - - /** - * Ensure that the php passed site of parameter values are not urldecoded - */ - public function testPatternUrlencoding() { - $router = new PathRouter; - $router->add( "/wiki/$1", array( 'title' => '%20:$1' ) ); - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => '%20:Foo' ) ); - } - - /** - * Ensure that raw parameter values do not have any variable replacements or urldecoding - */ - public function testRawParamValue() { - $router = new PathRouter; - $router->add( "/wiki/$1", array( 'title' => array( 'value' => 'bar%20$1' ) ) ); - $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 deleted file mode 100644 index 3dec2da0..00000000 --- a/tests/phpunit/includes/PreferencesTest.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php - -/** - * @group Database - */ -class PreferencesTest extends MediaWikiTestCase { - /** - * @var User[] - */ - private $prefUsers; - /** - * @var RequestContext - */ - private $context; - - public function __construct() { - parent::__construct(); - - $this->prefUsers['noemail'] = new User; - - $this->prefUsers['notauth'] = new User; - $this->prefUsers['notauth'] - ->setEmail( 'noauth@example.org' ); - - $this->prefUsers['auth'] = new User; - $this->prefUsers['auth'] - ->setEmail( 'noauth@example.org' ); - $this->prefUsers['auth'] - ->setEmailAuthenticationTimestamp( 1330946623 ); - - $this->context = new RequestContext; - $this->context->setTitle( Title::newFromText( 'PreferencesTest' ) ); - } - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgEnableEmail' => true, - 'wgEmailAuthentication' => true, - ) ); - } - - /** - * Placeholder to verify bug 34302 - * @covers Preferences::profilePreferences - */ - public function testEmailFieldsWhenUserHasNoEmail() { - $prefs = $this->prefsFor( 'noemail' ); - $this->assertArrayHasKey( 'cssclass', - $prefs['emailaddress'] - ); - $this->assertEquals( 'mw-email-none', $prefs['emailaddress']['cssclass'] ); - } - - /** - * Placeholder to verify bug 34302 - * @covers Preferences::profilePreferences - */ - public function testEmailFieldsWhenUserEmailNotAuthenticated() { - $prefs = $this->prefsFor( 'notauth' ); - $this->assertArrayHasKey( 'cssclass', - $prefs['emailaddress'] - ); - $this->assertEquals( 'mw-email-not-authenticated', $prefs['emailaddress']['cssclass'] ); - } - - /** - * Placeholder to verify bug 34302 - * @covers Preferences::profilePreferences - */ - public function testEmailFieldsWhenUserEmailIsAuthenticated() { - $prefs = $this->prefsFor( 'auth' ); - $this->assertArrayHasKey( 'cssclass', - $prefs['emailaddress'] - ); - $this->assertEquals( 'mw-email-authenticated', $prefs['emailaddress']['cssclass'] ); - } - - /** Helper */ - protected function prefsFor( $user_key ) { - $preferences = array(); - Preferences::profilePreferences( - $this->prefUsers[$user_key] - , $this->context - , $preferences - ); - - return $preferences; - } -} diff --git a/tests/phpunit/includes/RecentChangeTest.php b/tests/phpunit/includes/RecentChangeTest.php deleted file mode 100644 index cfa3e777..00000000 --- a/tests/phpunit/includes/RecentChangeTest.php +++ /dev/null @@ -1,280 +0,0 @@ -<?php -/** - * @group Database - */ -class RecentChangeTest extends MediaWikiTestCase { - protected $title; - protected $target; - protected $user; - protected $user_comment; - protected $context; - - public function __construct() { - parent::__construct(); - - $this->title = Title::newFromText( 'SomeTitle' ); - $this->target = Title::newFromText( 'TestTarget' ); - $this->user = User::newFromName( 'UserName' ); - - $this->user_comment = '<User comment about action>'; - $this->context = RequestContext::newExtraneousContext( $this->title ); - } - - /** - * The testIrcMsgForAction* tests are supposed to cover the hacky - * LogFormatter::getIRCActionText / bug 34508 - * - * Third parties bots listen to those messages. They are clever enough - * to fetch the i18n messages from the wiki and then analyze the IRC feed - * to reverse engineer the $1, $2 messages. - * One thing bots can not detect is when MediaWiki change the meaning of - * a message like what happened when we deployed 1.19. $1 became the user - * performing the action which broke basically all bots around. - * - * Should cover the following log actions (which are most commonly used by bots): - * - block/block - * - block/unblock - * - delete/delete - * - delete/restore - * - newusers/create - * - newusers/create2 - * - newusers/autocreate - * - move/move - * - move/move_redir - * - protect/protect - * - protect/modifyprotect - * - protect/unprotect - * - upload/upload - * - * As well as the following Auto Edit Summaries: - * - blank - * - replace - * - rollback - * - undo - */ - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeBlock() { - $sep = $this->context->msg( 'colon-separator' )->text(); - - # block/block - $this->assertIRCComment( - $this->context->msg( 'blocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'block', 'block', - array(), - $this->user_comment - ); - # block/unblock - $this->assertIRCComment( - $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'block', 'unblock', - array(), - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeDelete() { - $sep = $this->context->msg( 'colon-separator' )->text(); - - # delete/delete - $this->assertIRCComment( - $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'delete', 'delete', - array(), - $this->user_comment - ); - - # delete/restore - $this->assertIRCComment( - $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'delete', 'restore', - array(), - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeNewusers() { - $this->assertIRCComment( - 'New user account', - 'newusers', 'newusers', - array() - ); - $this->assertIRCComment( - 'New user account', - 'newusers', 'create', - array() - ); - $this->assertIRCComment( - 'created new account SomeTitle', - 'newusers', 'create2', - array() - ); - $this->assertIRCComment( - 'Account created automatically', - 'newusers', 'autocreate', - array() - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeMove() { - $move_params = array( - '4::target' => $this->target->getPrefixedText(), - '5::noredir' => 0, - ); - $sep = $this->context->msg( 'colon-separator' )->text(); - - # move/move - $this->assertIRCComment( - $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )->plain() . $sep . $this->user_comment, - 'move', 'move', - $move_params, - $this->user_comment - ); - - # move/move_redir - $this->assertIRCComment( - $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )->plain() . $sep . $this->user_comment, - 'move', 'move_redir', - $move_params, - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypePatrol() { - # patrol/patrol - $this->assertIRCComment( - $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(), - 'patrol', 'patrol', - array( - '4::curid' => '777', - '5::previd' => '666', - '6::auto' => 0, - ) - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeProtect() { - $protectParams = array( - '[edit=sysop] (indefinite) [move=sysop] (indefinite)' - ); - $sep = $this->context->msg( 'colon-separator' )->text(); - - # protect/protect - $this->assertIRCComment( - $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams[0] )->plain() . $sep . $this->user_comment, - 'protect', 'protect', - $protectParams, - $this->user_comment - ); - - # protect/unprotect - $this->assertIRCComment( - $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'protect', 'unprotect', - array(), - $this->user_comment - ); - - # protect/modify - $this->assertIRCComment( - $this->context->msg( 'modifiedarticleprotection', 'SomeTitle ' . $protectParams[0] )->plain() . $sep . $this->user_comment, - 'protect', 'modify', - $protectParams, - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - public function testIrcMsgForLogTypeUpload() { - $sep = $this->context->msg( 'colon-separator' )->text(); - - # upload/upload - $this->assertIRCComment( - $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'upload', 'upload', - array(), - $this->user_comment - ); - - # upload/overwrite - $this->assertIRCComment( - $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . $sep . $this->user_comment, - 'upload', 'overwrite', - array(), - $this->user_comment - ); - } - - /** - * @todo Emulate these edits somehow and extract - * raw edit summary from RecentChange object - * -- - */ - /* - public function testIrcMsgForBlankingAES() { - // $this->context->msg( 'autosumm-blank', .. ); - } - - public function testIrcMsgForReplaceAES() { - // $this->context->msg( 'autosumm-replace', .. ); - } - - public function testIrcMsgForRollbackAES() { - // $this->context->msg( 'revertpage', .. ); - } - - public function testIrcMsgForUndoAES() { - // $this->context->msg( 'undo-summary', .. ); - } - */ - - /** - * @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 :-) - */ - protected function assertIRCComment( $expected, $type, $action, $params, $comment = null, $msg = '' ) { - - $logEntry = new ManualLogEntry( $type, $action ); - $logEntry->setPerformer( $this->user ); - $logEntry->setTarget( $this->title ); - if ( $comment !== null ) { - $logEntry->setComment( $comment ); - } - $logEntry->setParameters( $params ); - - $formatter = LogFormatter::newFromEntry( $logEntry ); - $formatter->setContext( $this->context ); - - // Apply the same transformation as done in IRCColourfulRCFeedFormatter::getLine for rc_comment - $ircRcComment = IRCColourfulRCFeedFormatter::cleanupForIRC( $formatter->getIRCActionComment() ); - - $this->assertEquals( - $expected, - $ircRcComment, - $msg - ); - } -} diff --git a/tests/phpunit/includes/RequestContextTest.php b/tests/phpunit/includes/RequestContextTest.php deleted file mode 100644 index 1776b5d5..00000000 --- a/tests/phpunit/includes/RequestContextTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php - -/** - * @group Database - */ -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(); - - $curTitle = Title::newFromText( "A" ); - $context->setTitle( $curTitle ); - $this->assertTrue( $curTitle->equals( $context->getWikiPage()->getTitle() ), - "When a title is first set WikiPage should be created on-demand for that title." ); - - $curTitle = Title::newFromText( "B" ); - $context->setWikiPage( WikiPage::factory( $curTitle ) ); - $this->assertTrue( $curTitle->equals( $context->getTitle() ), - "Title must be updated when a new WikiPage is provided." ); - - $curTitle = Title::newFromText( "C" ); - $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(); - - $oInfo = $context->exportSession(); - $this->assertEquals( '127.0.0.1', $oInfo['ip'], "Correct initial IP address." ); - $this->assertEquals( 0, $oInfo['userId'], "Correct initial user ID." ); - - $user = User::newFromName( 'UnitTestContextUser' ); - $user->addToDatabase(); - - $sinfo = array( - 'sessionId' => 'd612ee607c87e749ef14da4983a702cd', - 'userId' => $user->getId(), - 'ip' => '192.0.2.0', - 'headers' => array( 'USER-AGENT' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0' ) - ); - $sc = RequestContext::importScopedSession( $sinfo ); // load new context - - $info = $context->exportSession(); - $this->assertEquals( $sinfo['ip'], $info['ip'], "Correct IP address." ); - $this->assertEquals( $sinfo['headers'], $info['headers'], "Correct headers." ); - $this->assertEquals( $sinfo['sessionId'], $info['sessionId'], "Correct session ID." ); - $this->assertEquals( $sinfo['userId'], $info['userId'], "Correct user ID." ); - $this->assertEquals( $sinfo['ip'], $context->getRequest()->getIP(), "Correct context IP address." ); - $this->assertEquals( $sinfo['headers'], $context->getRequest()->getAllHeaders(), "Correct context headers." ); - $this->assertEquals( $sinfo['sessionId'], session_id(), "Correct context session ID." ); - $this->assertEquals( true, $context->getUser()->isLoggedIn(), "Correct context user." ); - $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 - - $info = $context->exportSession(); - $this->assertEquals( $oInfo['ip'], $info['ip'], "Correct initial IP address." ); - $this->assertEquals( $oInfo['headers'], $info['headers'], "Correct initial headers." ); - $this->assertEquals( $oInfo['sessionId'], $info['sessionId'], "Correct initial session ID." ); - $this->assertEquals( $oInfo['userId'], $info['userId'], "Correct initial user ID." ); - } -} diff --git a/tests/phpunit/includes/ResourceLoaderTest.php b/tests/phpunit/includes/ResourceLoaderTest.php deleted file mode 100644 index ca8b2b6e..00000000 --- a/tests/phpunit/includes/ResourceLoaderTest.php +++ /dev/null @@ -1,149 +0,0 @@ -<?php - -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 */ - - /** - * ResourceLoaderRegisterModules hook - */ - public static function resourceLoaderRegisterModules( &$resourceLoader ) { - self::$resourceLoaderRegisterModulesHook = true; - - return true; - } - - /* Provider Methods */ - public static function provideValidModules() { - return array( - array( 'TEST.validModule1', new ResourceLoaderTestModule() ), - ); - } - - public static function provideResourceLoaderContext() { - $resourceLoader = new ResourceLoader(); - $request = new FauxRequest(); - return array( - array( new ResourceLoaderContext( $resourceLoader, $request ) ), - ); - } - - /* Test Methods */ - - /** - * Ensures that the ResourceLoaderRegisterModules hook is called when a new ResourceLoader object is constructed - * @covers ResourceLoader::__construct - */ - public function testCreatingNewResourceLoaderCallsRegistrationHook() { - self::$resourceLoaderRegisterModulesHook = false; - $resourceLoader = new ResourceLoader(); - $this->assertTrue( self::$resourceLoaderRegisterModulesHook ); - - return $resourceLoader; - } - - /** - * @dataProvider provideValidModules - * @depends testCreatingNewResourceLoaderCallsRegistrationHook - * @covers ResourceLoader::register - * @covers ResourceLoader::getModule - */ - public function testRegisteredValidModulesAreAccessible( - $name, ResourceLoaderModule $module, ResourceLoader $resourceLoader - ) { - $resourceLoader->register( $name, $module ); - $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 ); - } - - /** - * @dataProvider providePackedModules - * @covers ResourceLoaderContext::expandModuleNames - */ - public function testexpandModuleNames( $desc, $modules, $packed ) { - $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc ); - } - - public static function providePackedModules() { - return array( - array( - 'Example from makePackedModulesString doc comment', - array( 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' ), - 'foo.bar,baz|bar.baz,quux', - ), - array( - 'Example from expandModuleNames doc comment', - array( 'jquery.foo', 'jquery.bar', 'jquery.ui.baz', 'jquery.ui.quux' ), - 'jquery.foo,bar|jquery.ui.baz,quux', - ), - array( - '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 { -} - -/* Hooks */ -global $wgHooks; -$wgHooks['ResourceLoaderRegisterModules'][] = 'ResourceLoaderTest::resourceLoaderRegisterModules'; diff --git a/tests/phpunit/includes/RevisionStorageTest.php b/tests/phpunit/includes/RevisionStorageTest.php deleted file mode 100644 index e17c7b0f..00000000 --- a/tests/phpunit/includes/RevisionStorageTest.php +++ /dev/null @@ -1,546 +0,0 @@ -<?php - -/** - * Test class for Revision storage. - * - * @group ContentHandler - * @group Database - * ^--- important, causes temporary tables to be used instead of the real database - * - * @group medium - * ^--- important, causes tests not to fail with timeout - */ -class RevisionStorageTest extends MediaWikiTestCase { - - /** - * @var WikiPage $the_page - */ - var $the_page; - - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - - $this->tablesUsed = array_merge( $this->tablesUsed, - array( 'page', - 'revision', - 'text', - - 'recentchanges', - 'logging', - - 'page_props', - 'pagelinks', - 'categorylinks', - 'langlinks', - 'externallinks', - 'imagelinks', - 'templatelinks', - 'iwlinks' ) ); - } - - protected function setUp() { - global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - - parent::setUp(); - - $wgExtraNamespaces[12312] = 'Dummy'; - $wgExtraNamespaces[12313] = 'Dummy_talk'; - - $wgNamespaceContentModels[12312] = 'DUMMY'; - $wgContentHandlers['DUMMY'] = 'DummyContentHandlerForTesting'; - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - if ( !$this->the_page ) { - $this->the_page = $this->createPage( 'RevisionStorageTest_the_page', "just a dummy page", CONTENT_MODEL_WIKITEXT ); - } - } - - public function tearDown() { - global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - - parent::tearDown(); - - unset( $wgExtraNamespaces[12312] ); - unset( $wgExtraNamespaces[12313] ); - - unset( $wgNamespaceContentModels[12312] ); - unset( $wgContentHandlers['DUMMY'] ); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - protected function makeRevision( $props = null ) { - if ( $props === null ) { - $props = array(); - } - - if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) { - $props['text'] = 'Lorem Ipsum'; - } - - if ( !isset( $props['comment'] ) ) { - $props['comment'] = 'just a test'; - } - - if ( !isset( $props['page'] ) ) { - $props['page'] = $this->the_page->getId(); - } - - $rev = new Revision( $props ); - - $dbw = wfgetDB( DB_MASTER ); - $rev->insertOn( $dbw ); - - return $rev; - } - - protected function createPage( $page, $text, $model = null ) { - if ( is_string( $page ) ) { - if ( !preg_match( '/:/', $page ) && - ( $model === null || $model === CONTENT_MODEL_WIKITEXT ) - ) { - $ns = $this->getDefaultWikitextNS(); - $page = MWNamespace::getCanonicalName( $ns ) . ':' . $page; - } - - $page = Title::newFromText( $page ); - } - - if ( $page instanceof Title ) { - $page = new WikiPage( $page ); - } - - if ( $page->exists() ) { - $page->doDeleteArticle( "done" ); - } - - $content = ContentHandler::makeContent( $text, $page->getTitle(), $model ); - $page->doEditContent( $content, "testing", EDIT_NEW ); - - return $page; - } - - protected function assertRevEquals( Revision $orig, Revision $rev = null ) { - $this->assertNotNull( $rev, 'missing revision' ); - - $this->assertEquals( $orig->getId(), $rev->getId() ); - $this->assertEquals( $orig->getPage(), $rev->getPage() ); - $this->assertEquals( $orig->getTimestamp(), $rev->getTimestamp() ); - $this->assertEquals( $orig->getUser(), $rev->getUser() ); - $this->assertEquals( $orig->getContentModel(), $rev->getContentModel() ); - $this->assertEquals( $orig->getContentFormat(), $rev->getContentFormat() ); - $this->assertEquals( $orig->getSha1(), $rev->getSha1() ); - } - - /** - * @covers Revision::__construct - */ - public function testConstructFromRow() { - $orig = $this->makeRevision(); - - $dbr = wfgetDB( DB_SLAVE ); - $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) ); - $this->assertTrue( is_object( $res ), 'query failed' ); - - $row = $res->fetchObject(); - $res->free(); - - $rev = new Revision( $row ); - - $this->assertRevEquals( $orig, $rev ); - } - - /** - * @covers Revision::newFromRow - */ - public function testNewFromRow() { - $orig = $this->makeRevision(); - - $dbr = wfgetDB( DB_SLAVE ); - $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) ); - $this->assertTrue( is_object( $res ), 'query failed' ); - - $row = $res->fetchObject(); - $res->free(); - - $rev = Revision::newFromRow( $row ); - - $this->assertRevEquals( $orig, $rev ); - } - - - /** - * @covers Revision::newFromArchiveRow - */ - public function testNewFromArchiveRow() { - $page = $this->createPage( 'RevisionStorageTest_testNewFromArchiveRow', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT ); - $orig = $page->getRevision(); - $page->doDeleteArticle( 'test Revision::newFromArchiveRow' ); - - $dbr = wfgetDB( DB_SLAVE ); - $res = $dbr->select( 'archive', '*', array( 'ar_rev_id' => $orig->getId() ) ); - $this->assertTrue( is_object( $res ), 'query failed' ); - - $row = $res->fetchObject(); - $res->free(); - - $rev = Revision::newFromArchiveRow( $row ); - - $this->assertRevEquals( $orig, $rev ); - } - - /** - * @covers Revision::newFromId - */ - public function testNewFromId() { - $orig = $this->makeRevision(); - - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertRevEquals( $orig, $rev ); - } - - /** - * @covers Revision::fetchRevision - */ - public function testFetchRevision() { - $page = $this->createPage( 'RevisionStorageTest_testFetchRevision', 'one', CONTENT_MODEL_WIKITEXT ); - $id1 = $page->getRevision()->getId(); - - $page->doEditContent( new WikitextContent( 'two' ), 'second rev' ); - $id2 = $page->getRevision()->getId(); - - $res = Revision::fetchRevision( $page->getTitle() ); - - #note: order is unspecified - $rows = array(); - while ( ( $row = $res->fetchObject() ) ) { - $rows[$row->rev_id] = $row; - } - - $row = $res->fetchObject(); - $this->assertEquals( 1, count( $rows ), 'expected exactly one revision' ); - $this->assertArrayHasKey( $id2, $rows, 'missing revision with id ' . $id2 ); - } - - /** - * @covers Revision::selectFields - */ - public function testSelectFields() { - global $wgContentHandlerUseDB; - - $fields = Revision::selectFields(); - - $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields' ); - $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields' ); - $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields' ); - $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields' ); - - if ( $wgContentHandlerUseDB ) { - $this->assertTrue( in_array( 'rev_content_model', $fields ), - 'missing rev_content_model in list of fields' ); - $this->assertTrue( in_array( 'rev_content_format', $fields ), - 'missing rev_content_format in list of fields' ); - } - } - - /** - * @covers Revision::getPage - */ - public function testGetPage() { - $page = $this->the_page; - - $orig = $this->makeRevision( array( 'page' => $page->getId() ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( $page->getId(), $rev->getPage() ); - } - - /** - * @covers Revision::getText - */ - public function testGetText() { - $this->hideDeprecated( 'Revision::getText' ); - - $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello.', $rev->getText() ); - } - - /** - * @covers Revision::getContent - */ - public function testGetContent_failure() { - $rev = new Revision( array( - 'page' => $this->the_page->getId(), - 'content_model' => $this->the_page->getContentModel(), - 'text_id' => 123456789, // not in the test DB - ) ); - - $this->assertNull( $rev->getContent(), - "getContent() should return null if the revision's text blob could not be loaded." ); - - //NOTE: check this twice, once for lazy initialization, and once with the cached value. - $this->assertNull( $rev->getContent(), - "getContent() should return null if the revision's text blob could not be loaded." ); - } - - /** - * @covers Revision::getContent - */ - public function testGetContent() { - $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello.', $rev->getContent()->getNativeData() ); - } - - /** - * @covers Revision::revText - */ - public function testRevText() { - $this->hideDeprecated( 'Revision::revText' ); - $orig = $this->makeRevision( array( 'text' => 'hello hello rev.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello rev.', $rev->revText() ); - } - - /** - * @covers Revision::getRawText - */ - public function testGetRawText() { - $this->hideDeprecated( 'Revision::getRawText' ); - - $orig = $this->makeRevision( array( 'text' => 'hello hello raw.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello raw.', $rev->getRawText() ); - } - - /** - * @covers Revision::getContentModel - */ - public function testGetContentModel() { - global $wgContentHandlerUseDB; - - if ( !$wgContentHandlerUseDB ) { - $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); - } - - $orig = $this->makeRevision( array( 'text' => 'hello hello.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); - } - - /** - * @covers Revision::getContentFormat - */ - public function testGetContentFormat() { - global $wgContentHandlerUseDB; - - if ( !$wgContentHandlerUseDB ) { - $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); - } - - $orig = $this->makeRevision( array( - 'text' => 'hello hello.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT, - 'content_format' => CONTENT_FORMAT_JAVASCRIPT - ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( CONTENT_FORMAT_JAVASCRIPT, $rev->getContentFormat() ); - } - - /** - * @covers Revision::isCurrent - */ - public function testIsCurrent() { - $page = $this->createPage( 'RevisionStorageTest_testIsCurrent', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT ); - $rev1 = $page->getRevision(); - - # @todo find out if this should be true - # $this->assertTrue( $rev1->isCurrent() ); - - $rev1x = Revision::newFromId( $rev1->getId() ); - $this->assertTrue( $rev1x->isCurrent() ); - - $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), 'second rev' ); - $rev2 = $page->getRevision(); - - # @todo find out if this should be true - # $this->assertTrue( $rev2->isCurrent() ); - - $rev1x = Revision::newFromId( $rev1->getId() ); - $this->assertFalse( $rev1x->isCurrent() ); - - $rev2x = Revision::newFromId( $rev2->getId() ); - $this->assertTrue( $rev2x->isCurrent() ); - } - - /** - * @covers Revision::getPrevious - */ - public function testGetPrevious() { - $page = $this->createPage( 'RevisionStorageTest_testGetPrevious', 'Lorem Ipsum testGetPrevious', CONTENT_MODEL_WIKITEXT ); - $rev1 = $page->getRevision(); - - $this->assertNull( $rev1->getPrevious() ); - - $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), - 'second rev testGetPrevious' ); - $rev2 = $page->getRevision(); - - $this->assertNotNull( $rev2->getPrevious() ); - $this->assertEquals( $rev1->getId(), $rev2->getPrevious()->getId() ); - } - - /** - * @covers Revision::getNext - */ - public function testGetNext() { - $page = $this->createPage( 'RevisionStorageTest_testGetNext', 'Lorem Ipsum testGetNext', CONTENT_MODEL_WIKITEXT ); - $rev1 = $page->getRevision(); - - $this->assertNull( $rev1->getNext() ); - - $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), - 'second rev testGetNext' ); - $rev2 = $page->getRevision(); - - $this->assertNotNull( $rev1->getNext() ); - $this->assertEquals( $rev2->getId(), $rev1->getNext()->getId() ); - } - - /** - * @covers Revision::newNullRevision - */ - public function testNewNullRevision() { - $page = $this->createPage( 'RevisionStorageTest_testNewNullRevision', 'some testing text', CONTENT_MODEL_WIKITEXT ); - $orig = $page->getRevision(); - - $dbw = wfGetDB( DB_MASTER ); - $rev = Revision::newNullRevision( $dbw, $page->getId(), 'a null revision', false ); - - $this->assertNotEquals( $orig->getId(), $rev->getId(), - 'new null revision shold have a different id from the original revision' ); - $this->assertEquals( $orig->getTextId(), $rev->getTextId(), - 'new null revision shold have the same text id as the original revision' ); - $this->assertEquals( 'some testing text', $rev->getContent()->getNativeData() ); - } - - public static function provideUserWasLastToEdit() { - return array( - array( #0 - 3, true, # actually the last edit - ), - array( #1 - 2, true, # not the current edit, but still by this user - ), - array( #2 - 1, false, # edit by another user - ), - array( #3 - 0, false, # first edit, by this user, but another user edited in the mean time - ), - ); - } - - /** - * @dataProvider provideUserWasLastToEdit - */ - public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) { - $userA = User::newFromName( "RevisionStorageTest_userA" ); - $userB = User::newFromName( "RevisionStorageTest_userB" ); - - if ( $userA->getId() === 0 ) { - $userA = User::createNew( $userA->getName() ); - } - - if ( $userB->getId() === 0 ) { - $userB = User::createNew( $userB->getName() ); - } - - $ns = $this->getDefaultWikitextNS(); - - $dbw = wfGetDB( DB_MASTER ); - $revisions = array(); - - // create revisions ----------------------------- - $page = WikiPage::factory( Title::newFromText( - 'RevisionStorageTest_testUserWasLastToEdit', $ns ) ); - - # zero - $revisions[0] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), // we need the title to determine the page's default content model - 'timestamp' => '20120101000000', - 'user' => $userA->getId(), - 'text' => 'zero', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit zero' - ) ); - $revisions[0]->insertOn( $dbw ); - - # one - $revisions[1] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), // still need the title, because $page->getId() is 0 (there's no entry in the page table) - 'timestamp' => '20120101000100', - 'user' => $userA->getId(), - 'text' => 'one', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit one' - ) ); - $revisions[1]->insertOn( $dbw ); - - # two - $revisions[2] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), - 'timestamp' => '20120101000200', - 'user' => $userB->getId(), - 'text' => 'two', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit two' - ) ); - $revisions[2]->insertOn( $dbw ); - - # three - $revisions[3] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), - 'timestamp' => '20120101000300', - 'user' => $userA->getId(), - 'text' => 'three', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit three' - ) ); - $revisions[3]->insertOn( $dbw ); - - # four - $revisions[4] = new Revision( array( - 'page' => $page->getId(), - 'title' => $page->getTitle(), - 'timestamp' => '20120101000200', - 'user' => $userA->getId(), - 'text' => 'zero', - 'content_model' => CONTENT_MODEL_WIKITEXT, - 'summary' => 'edit four' - ) ); - $revisions[4]->insertOn( $dbw ); - - // test it --------------------------------- - $since = $revisions[$sinceIdx]->getTimestamp(); - - $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since ); - - $this->assertEquals( $expectedLast, $wasLast ); - } -} diff --git a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php b/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php deleted file mode 100644 index 4e83e355..00000000 --- a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- important, causes temporary tables to be used instead of the real database - */ -class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { - - protected function setUp() { - $this->setMwGlobals( 'wgContentHandlerUseDB', false ); - - $dbw = wfGetDB( DB_MASTER ); - - $page_table = $dbw->tableName( 'page' ); - $revision_table = $dbw->tableName( 'revision' ); - $archive_table = $dbw->tableName( 'archive' ); - - if ( $dbw->fieldExists( $page_table, 'page_content_model' ) ) { - $dbw->query( "alter table $page_table drop column page_content_model" ); - $dbw->query( "alter table $revision_table drop column rev_content_model" ); - $dbw->query( "alter table $revision_table drop column rev_content_format" ); - $dbw->query( "alter table $archive_table drop column ar_content_model" ); - $dbw->query( "alter table $archive_table drop column ar_content_format" ); - } - - parent::setUp(); - } - - /** - * @covers Revision::selectFields - */ - public function testSelectFields() { - $fields = Revision::selectFields(); - - $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields' ); - $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields' ); - $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields' ); - $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields' ); - - $this->assertFalse( in_array( 'rev_content_model', $fields ), 'missing rev_content_model in list of fields' ); - $this->assertFalse( in_array( 'rev_content_format', $fields ), 'missing rev_content_format in list of fields' ); - } - - /** - * @covers Revision::getContentModel - */ - public function testGetContentModel() { - try { - $this->makeRevision( array( 'text' => 'hello hello.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT ) ); - - $this->fail( "Creating JavaScript content on a wikitext page should fail with " - . "\$wgContentHandlerUseDB disabled" ); - } catch ( MWException $ex ) { - $this->assertTrue( true ); // ok - } - } - - - /** - * @covers Revision::getContentFormat - */ - public function testGetContentFormat() { - try { - // @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. - - $this->makeRevision( array( 'text' => 'hello hello.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT, - 'content_format' => 'text/javascript' ) ); - - $this->fail( "Creating JavaScript content on a wikitext page should fail with " - . "\$wgContentHandlerUseDB disabled" ); - } catch ( MWException $ex ) { - $this->assertTrue( true ); // ok - } - } -} diff --git a/tests/phpunit/includes/RevisionTest.php b/tests/phpunit/includes/RevisionTest.php deleted file mode 100644 index b5819ff6..00000000 --- a/tests/phpunit/includes/RevisionTest.php +++ /dev/null @@ -1,481 +0,0 @@ -<?php - -/** - * @group ContentHandler - */ -class RevisionTest extends MediaWikiTestCase { - protected function setUp() { - global $wgContLang; - - parent::setUp(); - - $this->setMwGlobals( array( - 'wgContLang' => Language::factory( 'en' ), - 'wgLanguageCode' => 'en', - 'wgLegacyEncoding' => false, - 'wgCompressRevisions' => false, - - 'wgContentHandlerTextFallback' => 'ignore', - ) ); - - $this->mergeMwGlobalArrayValue( - 'wgExtraNamespaces', - array( - 12312 => 'Dummy', - 12313 => 'Dummy_talk', - ) - ); - - $this->mergeMwGlobalArrayValue( - 'wgNamespaceContentModels', - array( - 12312 => 'testing', - ) - ); - - $this->mergeMwGlobalArrayValue( - 'wgContentHandlers', - array( - 'testing' => 'DummyContentHandlerForTesting', - 'RevisionTestModifyableContent' => 'RevisionTestModifyableContentHandler', - ) - ); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - function tearDown() { - global $wgContLang; - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - - parent::tearDown(); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionText() { - $row = new stdClass; - $row->old_flags = ''; - $row->old_text = 'This is a bunch of revision text.'; - $this->assertEquals( - 'This is a bunch of revision text.', - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextGzip() { - $this->checkPHPExtension( 'zlib' ); - - $row = new stdClass; - $row->old_flags = 'gzip'; - $row->old_text = gzdeflate( 'This is a bunch of revision text.' ); - $this->assertEquals( - 'This is a bunch of revision text.', - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextUtf8Native() { - $row = new stdClass; - $row->old_flags = 'utf-8'; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextUtf8Legacy() { - $row = new stdClass; - $row->old_flags = ''; - $row->old_text = "Wiki est l'\xe9cole superieur !"; - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextUtf8NativeGzip() { - $this->checkPHPExtension( 'zlib' ); - - $row = new stdClass; - $row->old_flags = 'gzip,utf-8'; - $row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" ); - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - /** - * @covers Revision::getRevisionText - */ - public function testGetRevisionTextUtf8LegacyGzip() { - $this->checkPHPExtension( 'zlib' ); - - $row = new stdClass; - $row->old_flags = 'gzip'; - $row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" ); - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - /** - * @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 ); - $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), - "Flags should contain 'utf-8'" ); - $this->assertFalse( false !== strpos( $row->old_flags, 'gzip' ), - "Flags should not contain 'gzip'" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - $row->old_text, "Direct check" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ), "getRevisionText" ); - } - - /** - * @covers Revision::compressRevisionText - */ - public function testCompressRevisionTextUtf8Gzip() { - $this->checkPHPExtension( 'zlib' ); - $this->setMwGlobals( 'wgCompressRevisions', true ); - - $row = new stdClass; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $row->old_flags = Revision::compressRevisionText( $row->old_text ); - $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), - "Flags should contain 'utf-8'" ); - $this->assertTrue( false !== strpos( $row->old_flags, 'gzip' ), - "Flags should contain 'gzip'" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - gzinflate( $row->old_text ), "Direct check" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ), "getRevisionText" ); - } - - # ================================================================================================================= - - /** - * @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 ) { - if ( is_string( $title ) ) { - $title = Title::newFromText( $title ); - } - - $content = ContentHandler::makeContent( $text, $title, $model, $format ); - - $rev = new Revision( - array( - 'id' => 42, - 'page' => 23, - 'title' => $title, - - 'content' => $content, - 'length' => $content->getSize(), - 'comment' => "testing", - 'minor_edit' => false, - - 'content_format' => $format, - ) - ); - - return $rev; - } - - function dataGetContentModel() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, CONTENT_MODEL_WIKITEXT ), - array( 'hello world', 'User:hello/there.css', null, null, CONTENT_MODEL_CSS ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ), - ); - } - - /** - * @group Database - * @dataProvider dataGetContentModel - * @covers Revision::getContentModel - */ - public function testGetContentModel( $text, $title, $model, $format, $expectedModel ) { - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedModel, $rev->getContentModel() ); - } - - function dataGetContentFormat() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, CONTENT_FORMAT_WIKITEXT ), - array( 'hello world', 'Help:Hello', CONTENT_MODEL_CSS, null, CONTENT_FORMAT_CSS ), - array( 'hello world', 'User:hello/there.css', null, null, CONTENT_FORMAT_CSS ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ), - ); - } - - /** - * @group Database - * @dataProvider dataGetContentFormat - * @covers Revision::getContentFormat - */ - public function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) { - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedFormat, $rev->getContentFormat() ); - } - - function dataGetContentHandler() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, 'WikitextContentHandler' ), - array( 'hello world', 'User:hello/there.css', null, null, 'CssContentHandler' ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, 'DummyContentHandlerForTesting' ), - ); - } - - /** - * @group Database - * @dataProvider dataGetContentHandler - * @covers Revision::getContentHandler - */ - public function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) { - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedClass, get_class( $rev->getContentHandler() ) ); - } - - function dataGetContent() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ), - array( serialize( 'hello world' ), 'Hello', "testing", null, Revision::FOR_PUBLIC, serialize( 'hello world' ) ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, serialize( 'hello world' ) ), - ); - } - - /** - * @group Database - * @dataProvider dataGetContent - * @covers Revision::getContent - */ - public function testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization ) { - $rev = $this->newTestRevision( $text, $title, $model, $format ); - $content = $rev->getContent( $audience ); - - $this->assertEquals( $expectedSerialization, is_null( $content ) ? null : $content->serialize( $format ) ); - } - - function dataGetText() { - //NOTE: we expect the help namespace to always contain wikitext - return array( - array( 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ), - array( serialize( 'hello world' ), 'Hello', "testing", null, Revision::FOR_PUBLIC, null ), - array( serialize( 'hello world' ), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, null ), - ); - } - - /** - * @group Database - * @dataProvider dataGetText - * @covers Revision::getText - */ - public function testGetText( $text, $title, $model, $format, $audience, $expectedText ) { - $this->hideDeprecated( 'Revision::getText' ); - - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedText, $rev->getText( $audience ) ); - } - - /** - * @group Database - * @dataProvider dataGetText - * @covers Revision::getRawText - */ - public function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) { - $this->hideDeprecated( 'Revision::getRawText' ); - - $rev = $this->newTestRevision( $text, $title, $model, $format ); - - $this->assertEquals( $expectedText, $rev->getRawText( $audience ) ); - } - - - public function dataGetSize() { - return array( - array( "hello world.", CONTENT_MODEL_WIKITEXT, 12 ), - array( serialize( "hello world." ), "testing", 12 ), - ); - } - - /** - * @covers Revision::getSize - * @group Database - * @dataProvider dataGetSize - */ - public function testGetSize( $text, $model, $expected_size ) { - $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSize', $model ); - $this->assertEquals( $expected_size, $rev->getSize() ); - } - - public function dataGetSha1() { - return array( - array( "hello world.", CONTENT_MODEL_WIKITEXT, Revision::base36Sha1( "hello world." ) ), - array( serialize( "hello world." ), "testing", Revision::base36Sha1( serialize( "hello world." ) ) ), - ); - } - - /** - * @covers Revision::getSha1 - * @group Database - * @dataProvider dataGetSha1 - */ - public function testGetSha1( $text, $model, $expected_hash ) { - $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSha1', $model ); - $this->assertEquals( $expected_hash, $rev->getSha1() ); - } - - /** - * @covers Revision::__construct - */ - public function testConstructWithText() { - $this->hideDeprecated( "Revision::getText" ); - - $rev = new Revision( array( - 'text' => 'hello world.', - 'content_model' => CONTENT_MODEL_JAVASCRIPT - ) ); - - $this->assertNotNull( $rev->getText(), 'no content text' ); - $this->assertNotNull( $rev->getContent(), 'no content object available' ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel() ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); - } - - /** - * @covers Revision::__construct - */ - public function testConstructWithContent() { - $this->hideDeprecated( "Revision::getText" ); - - $title = Title::newFromText( 'RevisionTest_testConstructWithContent' ); - - $rev = new Revision( array( - 'content' => ContentHandler::makeContent( 'hello world.', $title, CONTENT_MODEL_JAVASCRIPT ), - ) ); - - $this->assertNotNull( $rev->getText(), 'no content text' ); - $this->assertNotNull( $rev->getContent(), 'no content object available' ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel() ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); - } - - /** - * Tests whether $rev->getContent() returns a clone when needed. - * - * @group Database - * @covers Revision::getContent - */ - public function testGetContentClone() { - $content = new RevisionTestModifyableContent( "foo" ); - - $rev = new Revision( - array( - 'id' => 42, - 'page' => 23, - 'title' => Title::newFromText( "testGetContentClone_dummy" ), - - 'content' => $content, - 'length' => $content->getSize(), - 'comment' => "testing", - 'minor_edit' => false, - ) - ); - - $content = $rev->getContent( Revision::RAW ); - $content->setText( "bar" ); - - $content2 = $rev->getContent( Revision::RAW ); - $this->assertNotSame( $content, $content2, "expected a clone" ); // content is mutable, expect clone - $this->assertEquals( "foo", $content2->getText() ); // clone should contain the original text - - $content2->setText( "bla bla" ); - $this->assertEquals( "bar", $content->getText() ); // clones should be independent - } - - - /** - * Tests whether $rev->getContent() returns the same object repeatedly if appropriate. - * - * @group Database - * @covers Revision::getContent - */ - public function testGetContentUncloned() { - $rev = $this->newTestRevision( "hello", "testGetContentUncloned_dummy", CONTENT_MODEL_WIKITEXT ); - $content = $rev->getContent( Revision::RAW ); - $content2 = $rev->getContent( Revision::RAW ); - - // for immutable content like wikitext, this should be the same object - $this->assertSame( $content, $content2 ); - } -} - -class RevisionTestModifyableContent extends TextContent { - public function __construct( $text ) { - parent::__construct( $text, "RevisionTestModifyableContent" ); - } - - public function copy() { - return new RevisionTestModifyableContent( $this->mText ); - } - - public function getText() { - return $this->mText; - } - - public function setText( $text ) { - $this->mText = $text; - } -} - -class RevisionTestModifyableContentHandler extends TextContentHandler { - - public function __construct() { - parent::__construct( "RevisionTestModifyableContent", array( CONTENT_FORMAT_TEXT ) ); - } - - public function unserializeContent( $text, $format = null ) { - $this->checkFormat( $format ); - - return new RevisionTestModifyableContent( $text ); - } - - public function makeEmptyContent() { - return new RevisionTestModifyableContent( '' ); - } -} diff --git a/tests/phpunit/includes/SampleTest.php b/tests/phpunit/includes/SampleTest.php deleted file mode 100644 index 8516a4ce..00000000 --- a/tests/phpunit/includes/SampleTest.php +++ /dev/null @@ -1,105 +0,0 @@ -<?php - -class TestSample extends MediaWikiLangTestCase { - - /** - * Anything that needs to happen before your tests should go here. - */ - protected function setUp() { - // Be sure to do call the parent setup and teardown functions. - // This makes sure that all the various cleanup and restorations - // happen as they should (including the restoration for setMwGlobals). - parent::setUp(); - - // This sets the globals and will restore them automatically - // after each test. - $this->setMwGlobals( array( - 'wgContLang' => Language::factory( 'en' ), - 'wgLanguageCode' => 'en', - ) ); - } - - /** - * Anything cleanup you need to do should go here. - */ - protected function tearDown() { - parent::tearDown(); - } - - /** - * Name tests so that PHPUnit can turn them into sentences when - * they run. While MediaWiki isn't strictly an Agile Programming - * project, you are encouraged to use the naming described under - * "Agile Documentation" at - * http://www.phpunit.de/manual/3.4/en/other-uses-for-tests.html - */ - public function testTitleObjectStringConversion() { - $title = Title::newFromText( "text" ); - $this->assertInstanceOf( 'Title', $title, "Title creation" ); - $this->assertEquals( "Text", $title, "Automatic string conversion" ); - - $title = Title::newFromText( "text", NS_MEDIA ); - $this->assertEquals( "Media:Text", $title, "Title creation with namespace" ); - } - - /** - * If you want to run a the same test with a variety of data. use a data provider. - * see: http://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html - * - * Note: Data providers are always called statically and outside setUp/tearDown! - */ - public static function provideTitles() { - return array( - array( 'Text', NS_MEDIA, 'Media:Text' ), - array( 'Text', null, 'Text' ), - array( 'text', null, 'Text' ), - array( 'Text', NS_USER, 'User:Text' ), - array( 'Photo.jpg', NS_FILE, 'File:Photo.jpg' ) - ); - } - - /** - * @dataProvider provideTitles - * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.dataProvider - */ - public function testCreateBasicListOfTitles( $titleName, $ns, $text ) { - $title = Title::newFromText( $titleName, $ns ); - $this->assertEquals( $text, "$title", "see if '$titleName' matches '$text'" ); - } - - public function testSetUpMainPageTitleForNextTest() { - $title = Title::newMainPage(); - $this->assertEquals( "Main Page", "$title", "Test initial creation of a title" ); - - return $title; - } - - /** - * Instead of putting a bunch of tests in a single test method, - * you should put only one or two tests in each test method. This - * way, the test method names can remain descriptive. - * - * If you want to make tests depend on data created in another - * method, you can create dependencies feed whatever you return - * from the dependant method (e.g. testInitialCreation in this - * example) as arguments to the next method (e.g. $title in - * testTitleDepends is whatever testInitialCreatiion returned.) - */ - - /** - * @depends testSetUpMainPageTitleForNextTest - * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.depends - */ - public function testCheckMainPageTitleIsConsideredLocal( $title ) { - $this->assertTrue( $title->isLocal() ); - } - - /** - * @expectedException MWException object - * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.expectedException - */ - 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 deleted file mode 100644 index 81246d33..00000000 --- a/tests/phpunit/includes/SanitizerTest.php +++ /dev/null @@ -1,302 +0,0 @@ -<?php - -/** - * @todo Tests covering decodeCharReferences can be refactored into a single - * method and dataprovider. - */ -class SanitizerTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - AutoLoader::loadClass( 'Sanitizer' ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testDecodeNamedEntities() { - $this->assertEquals( - "\xc3\xa9cole", - Sanitizer::decodeCharReferences( 'école' ), - 'decode named entities' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testDecodeNumericEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole!", - Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), - 'decode numeric entities' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testDecodeMixedEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole!", - Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), - 'decode mixed numeric/named entities' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testDecodeMixedComplexEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas Ĉio dans l'école)", - Sanitizer::decodeCharReferences( - "Ĉio bonas dans l'école! (mais pas &#x108;io dans l'&eacute;cole)" - ), - 'decode mixed complex entities' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testInvalidAmpersand() { - $this->assertEquals( - 'a & b', - Sanitizer::decodeCharReferences( 'a & b' ), - 'Invalid ampersand' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testInvalidEntities() { - $this->assertEquals( - '&foo;', - Sanitizer::decodeCharReferences( '&foo;' ), - 'Invalid named entity' - ); - } - - /** - * @covers Sanitizer::decodeCharReferences - */ - public function testInvalidNumberedEntities() { - $this->assertEquals( UTF8_REPLACEMENT, Sanitizer::decodeCharReferences( "�" ), 'Invalid numbered entity' ); - } - - /** - * @covers Sanitizer::removeHTMLtags - * @dataProvider provideHtml5Tags - * - * @param String $tag Name of an HTML5 element (ie: 'video') - * @param Boolean $escaped Wheter sanitizer let the tag in or escape it (ie: '<video>') - */ - public function testRemovehtmltagsOnHtml5Tags( $tag, $escaped ) { - $this->setMwGlobals( array( - 'wgUseTidy' => false - ) ); - - if ( $escaped ) { - $this->assertEquals( "<$tag>", - Sanitizer::removeHTMLtags( "<$tag>" ) - ); - } else { - $this->assertEquals( "<$tag></$tag>\n", - Sanitizer::removeHTMLtags( "<$tag>" ) - ); - } - } - - /** - * Provide HTML5 tags - */ - public static function provideHtml5Tags() { - $ESCAPED = true; # We want tag to be escaped - $VERBATIM = false; # We want to keep the tag - return array( - array( 'data', $VERBATIM ), - array( 'mark', $VERBATIM ), - array( 'time', $VERBATIM ), - array( 'video', $ESCAPED ), - ); - } - - function dataRemoveHTMLtags() { - return array( - // former testSelfClosingTag - array( - '<div>Hello world</div />', - '<div>Hello world</div>', - 'Self-closing closing div' - ), - // Make sure special nested HTML5 semantics are not broken - // http://www.whatwg.org/html/text-level-semantics.html#the-kbd-element - array( - '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>', - '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>', - 'Nested <kbd>.' - ), - // http://www.whatwg.org/html/text-level-semantics.html#the-sub-and-sup-elements - array( - '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>', - '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>', - 'Nested <var>.' - ), - // http://www.whatwg.org/html/text-level-semantics.html#the-dfn-element - array( - '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>', - '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>', - '<abbr> inside <dfn>', - ), - ); - } - - /** - * @dataProvider dataRemoveHTMLtags - * @covers Sanitizer::removeHTMLtags - */ - public function testRemoveHTMLtags( $input, $output, $msg = null ) { - $GLOBALS['wgUseTidy'] = false; - $this->assertEquals( $output, Sanitizer::removeHTMLtags( $input ), $msg ); - } - - /** - * @dataProvider provideTagAttributesToDecode - * @covers Sanitizer::decodeTagAttributes - */ - public function testDecodeTagAttributes( $expected, $attributes, $message = '' ) { - $this->assertEquals( $expected, - Sanitizer::decodeTagAttributes( $attributes ), - $message - ); - } - - public static function provideTagAttributesToDecode() { - return array( - array( array( 'foo' => 'bar' ), 'foo=bar', 'Unquoted attribute' ), - array( array( 'foo' => 'bar' ), ' foo = bar ', 'Spaced attribute' ), - array( array( 'foo' => 'bar' ), 'foo="bar"', 'Double-quoted attribute' ), - array( array( 'foo' => 'bar' ), 'foo=\'bar\'', 'Single-quoted attribute' ), - array( array( 'foo' => 'bar', 'baz' => 'foo' ), 'foo=\'bar\' baz="foo"', 'Several attributes' ), - array( array( 'foo' => 'bar', 'baz' => 'foo' ), 'foo=\'bar\' baz="foo"', 'Several attributes' ), - array( array( 'foo' => 'bar', 'baz' => 'foo' ), 'foo=\'bar\' baz="foo"', 'Several attributes' ), - array( array( ':foo' => 'bar' ), ':foo=\'bar\'', 'Leading :' ), - array( array( '_foo' => 'bar' ), '_foo=\'bar\'', 'Leading _' ), - array( array( 'foo' => 'bar' ), 'Foo=\'bar\'', 'Leading capital' ), - array( array( 'foo' => 'BAR' ), 'FOO=BAR', 'Attribute keys are normalized to lowercase' ), - - # Invalid beginning - array( array(), '-foo=bar', 'Leading - is forbidden' ), - array( array(), '.foo=bar', 'Leading . is forbidden' ), - array( array( 'foo-bar' => 'bar' ), 'foo-bar=bar', 'A - is allowed inside the attribute' ), - array( array( 'foo-' => 'bar' ), 'foo-=bar', 'A - is allowed inside the attribute' ), - array( array( 'foo.bar' => 'baz' ), 'foo.bar=baz', 'A . is allowed inside the attribute' ), - 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' ), - array( array(), 'foo$=baz', 'Symbols are not allowed' ), - array( array(), 'foo@=baz', 'Symbols are not allowed' ), - array( array(), 'foo~=baz', 'Symbols are not allowed' ), - array( array( 'foo' => '1[#^`*%w/(' ), 'foo=1[#^`*%w/(', 'All kind of characters are allowed as values' ), - array( array( 'foo' => '1[#^`*%\'w/(' ), 'foo="1[#^`*%\'w/("', 'Double quotes are allowed if quoted by single quotes' ), - array( array( 'foo' => '1[#^`*%"w/(' ), 'foo=\'1[#^`*%"w/(\'', 'Single quotes are allowed if quoted by double quotes' ), - array( array( 'foo' => '&"' ), 'foo=&"', 'Special chars can be provided as entities' ), - array( array( 'foo' => '&foobar;' ), 'foo=&foobar;', 'Entity-like items are accepted' ), - ); - } - - /** - * @dataProvider provideDeprecatedAttributes - * @covers Sanitizer::fixTagAttributes - */ - public function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl, $message = '' ) { - $this->assertEquals( " $inputAttr", - Sanitizer::fixTagAttributes( $inputAttr, $inputEl ), - $message - ); - } - - public static function provideDeprecatedAttributes() { - /** array( <attribute>, <element>, [message] ) */ - return array( - array( 'clear="left"', 'br' ), - array( 'clear="all"', 'br' ), - array( 'width="100"', 'td' ), - array( 'nowrap="true"', 'td' ), - array( 'nowrap=""', 'td' ), - array( 'align="right"', 'td' ), - array( 'align="center"', 'table' ), - array( 'align="left"', 'tr' ), - array( 'align="center"', 'div' ), - array( 'align="left"', 'h1' ), - array( 'align="left"', 'span' ), - ); - } - - /** - * @dataProvider provideCssCommentsFixtures - * @covers Sanitizer::checkCss - */ - public function testCssCommentsChecking( $expected, $css, $message = '' ) { - $this->assertEquals( $expected, - Sanitizer::checkCss( $css ), - $message - ); - } - - public static function provideCssCommentsFixtures() { - /** array( <expected>, <css>, [message] ) */ - return array( - // Valid comments spanning entire input - array( '/**/', '/**/' ), - array( '/* comment */', '/* comment */' ), - // Weird stuff - array( ' ', '/****/' ), - 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' ), - array( '', "\\2f\\2a unifinished comment'", - 'Remove anything after a backslash-escaped comment-start token' ), - array( '/* insecure input */', 'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\');' ), - array( '/* insecure input */', '-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\')";' ), - array( '/* insecure input */', 'width: expression(1+1);' ), - array( '/* insecure input */', 'background-image: image(asdf.png);' ), - array( '/* insecure input */', 'background-image: -webkit-image(asdf.png);' ), - array( '/* insecure input */', 'background-image: -moz-image(asdf.png);' ), - array( '/* insecure input */', 'background-image: image-set("asdf.png" 1x, "asdf.png" 2x);' ), - array( '/* insecure input */', 'background-image: -webkit-image-set("asdf.png" 1x, "asdf.png" 2x);' ), - array( '/* insecure input */', 'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);' ), - ); - } - - /** - * Test for support or lack of support for specific attributes in the attribute whitelist. - */ - public static function provideAttributeSupport() { - /** array( <attributes>, <expected>, <message> ) */ - return array( - array( 'div', ' role="presentation"', ' role="presentation"', 'Support for WAI-ARIA\'s role="presentation".' ), - array( 'div', ' role="main"', '', "Other WAI-ARIA roles are currently not supported." ), - ); - } - - /** - * @dataProvider provideAttributeSupport - * @covers Sanitizer::fixTagAttributes - */ - 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 deleted file mode 100644 index f13e8382..00000000 --- a/tests/phpunit/includes/SanitizerValidateEmailTest.php +++ /dev/null @@ -1,103 +0,0 @@ -<?php - -/** - * @covers Sanitizer::validateEmail - * @TODO all test methods in this class should be refactored and... - * use a single test method and a single data provider... - */ -class SanitizerValidateEmailTest extends MediaWikiTestCase { - - private function checkEmail( $addr, $expected = true, $msg = '' ) { - if ( $msg == '' ) { - $msg = "Testing $addr"; - } - - $this->assertEquals( - $expected, - Sanitizer::validateEmail( $addr ), - $msg - ); - } - - private function valid( $addr, $msg = '' ) { - $this->checkEmail( $addr, true, $msg ); - } - - private function invalid( $addr, $msg = '' ) { - $this->checkEmail( $addr, false, $msg ); - } - - public function testEmailWellKnownUserAtHostDotTldAreValid() { - $this->valid( 'user@example.com' ); - $this->valid( 'user@example.museum' ); - } - - public function testEmailWithUpperCaseCharactersAreValid() { - $this->valid( 'USER@example.com' ); - $this->valid( 'user@EXAMPLE.COM' ); - $this->valid( 'user@Example.com' ); - $this->valid( 'USER@eXAMPLE.com' ); - } - - public function testEmailWithAPlusInUserName() { - $this->valid( 'user+sub@example.com' ); - $this->valid( 'user+@example.com' ); - } - - public function testEmailDoesNotNeedATopLevelDomain() { - $this->valid( "user@localhost" ); - $this->valid( "FooBar@localdomain" ); - $this->valid( "nobody@mycompany" ); - } - - public function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { - $this->invalid( " user@host.com" ); - $this->invalid( "user@host.com " ); - $this->invalid( "\tuser@host.com" ); - $this->invalid( "user@host.com\t" ); - } - - 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 - */ - public function testEmailWithCommasAreInvalids() { - $this->invalid( "user,foo@example.org" ); - $this->invalid( "userfoo@ex,ample.org" ); - } - - public function testEmailWithHyphens() { - $this->valid( "user-foo@example.org" ); - $this->valid( "userfoo@ex-ample.org" ); - } - - public function testEmailDomainCanNotBeginWithDot() { - $this->invalid( "user@." ); - $this->invalid( "user@.localdomain" ); - $this->invalid( "user@localdomain." ); - $this->valid( "user.@localdomain" ); - $this->valid( ".@localdomain" ); - $this->invalid( ".@a............" ); - } - - public function testEmailWithFunnyCharacters() { - $this->valid( "\$user!ex{this}@123.com" ); - } - - public function testEmailTopLevelDomainCanBeNumerical() { - $this->valid( "user@example.1234" ); - } - - public function testEmailWithoutAtSignIsInvalid() { - $this->invalid( 'useràexample.com' ); - } - - public function testEmailWithOneCharacterDomainIsValid() { - $this->valid( 'user@a' ); - } -} diff --git a/tests/phpunit/includes/SiteConfigurationTest.php b/tests/phpunit/includes/SiteConfigurationTest.php deleted file mode 100644 index 053d8a7d..00000000 --- a/tests/phpunit/includes/SiteConfigurationTest.php +++ /dev/null @@ -1,335 +0,0 @@ -<?php - -function getSiteParams( $conf, $wiki ) { - $site = null; - $lang = null; - foreach ( $conf->suffixes as $suffix ) { - if ( substr( $wiki, -strlen( $suffix ) ) == $suffix ) { - $site = $suffix; - $lang = substr( $wiki, 0, -strlen( $suffix ) ); - break; - } - } - - return array( - 'suffix' => $site, - 'lang' => $lang, - 'params' => array( - 'lang' => $lang, - 'site' => $site, - 'wiki' => $wiki, - ), - 'tags' => array( 'tag' ), - ); -} - -class SiteConfigurationTest extends MediaWikiTestCase { - - /** - * @var SiteConfiguration - */ - protected $mConf; - - protected function setUp() { - parent::setUp(); - - $this->mConf = new SiteConfiguration; - - $this->mConf->suffixes = array( 'wikipedia' => 'wiki' ); - $this->mConf->wikis = array( 'enwiki', 'dewiki', 'frwiki' ); - $this->mConf->settings = array( - 'simple' => array( - 'wiki' => 'wiki', - 'tag' => 'tag', - 'enwiki' => 'enwiki', - 'dewiki' => 'dewiki', - 'frwiki' => 'frwiki', - ), - - 'fallback' => array( - 'default' => 'default', - 'wiki' => 'wiki', - 'tag' => 'tag', - ), - - 'params' => array( - 'default' => '$lang $site $wiki', - ), - - '+global' => array( - 'wiki' => array( - 'wiki' => 'wiki', - ), - 'tag' => array( - 'tag' => 'tag', - ), - 'enwiki' => array( - 'enwiki' => 'enwiki', - ), - 'dewiki' => array( - 'dewiki' => 'dewiki', - ), - 'frwiki' => array( - 'frwiki' => 'frwiki', - ), - ), - - 'merge' => array( - '+wiki' => array( - 'wiki' => 'wiki', - ), - '+tag' => array( - 'tag' => 'tag', - ), - 'default' => array( - 'default' => 'default', - ), - '+enwiki' => array( - 'enwiki' => 'enwiki', - ), - '+dewiki' => array( - 'dewiki' => 'dewiki', - ), - '+frwiki' => array( - 'frwiki' => 'frwiki', - ), - ), - ); - - $GLOBALS['global'] = array( 'global' => 'global' ); - } - - /** - * @covers SiteConfiguration::siteFromDB - */ - public function testSiteFromDb() { - $this->assertEquals( - array( 'wikipedia', 'en' ), - $this->mConf->siteFromDB( 'enwiki' ), - 'siteFromDB()' - ); - $this->assertEquals( - array( 'wikipedia', '' ), - $this->mConf->siteFromDB( 'wiki' ), - 'siteFromDB() on a suffix' - ); - $this->assertEquals( - array( null, null ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() on a non-existing wiki' - ); - - $this->mConf->suffixes = array( 'wiki', '' ); - $this->assertEquals( - array( '', 'wikien' ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() on a non-existing wiki (2)' - ); - } - - /** - * @covers SiteConfiguration::getLocalDatabases - */ - public function testGetLocalDatabases() { - $this->assertEquals( - array( 'enwiki', 'dewiki', 'frwiki' ), - $this->mConf->getLocalDatabases(), - 'getLocalDatabases()' - ); - } - - /** - * @covers SiteConfiguration::get - */ - public function testGetConfVariables() { - $this->assertEquals( - 'enwiki', - $this->mConf->get( 'simple', 'enwiki', 'wiki' ), - 'get(): simple setting on an existing wiki' - ); - $this->assertEquals( - 'dewiki', - $this->mConf->get( 'simple', 'dewiki', 'wiki' ), - 'get(): simple setting on an existing wiki (2)' - ); - $this->assertEquals( - 'frwiki', - $this->mConf->get( 'simple', 'frwiki', 'wiki' ), - 'get(): simple setting on an existing wiki (3)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'simple', 'wiki', 'wiki' ), - 'get(): simple setting on an suffix' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'simple', 'eswiki', 'wiki' ), - 'get(): simple setting on an non-existing wiki' - ); - - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'enwiki', 'wiki' ), - 'get(): fallback setting on an existing wiki' - ); - $this->assertEquals( - 'tag', - $this->mConf->get( 'fallback', 'dewiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an existing wiki (with wiki tag)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'wiki', 'wiki' ), - 'get(): fallback setting on an suffix' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'wiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an suffix (with wiki tag)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'eswiki', 'wiki' ), - 'get(): fallback setting on an non-existing wiki' - ); - $this->assertEquals( - 'tag', - $this->mConf->get( 'fallback', 'eswiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an non-existing wiki (with wiki tag)' - ); - - $common = array( 'wiki' => 'wiki', 'default' => 'default' ); - $commonTag = array( 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ); - $this->assertEquals( - array( 'enwiki' => 'enwiki' ) + $common, - $this->mConf->get( 'merge', 'enwiki', 'wiki' ), - 'get(): merging setting on an existing wiki' - ); - $this->assertEquals( - array( 'enwiki' => 'enwiki' ) + $commonTag, - $this->mConf->get( 'merge', 'enwiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (with tag)' - ); - $this->assertEquals( - array( 'dewiki' => 'dewiki' ) + $common, - $this->mConf->get( 'merge', 'dewiki', 'wiki' ), - 'get(): merging setting on an existing wiki (2)' - ); - $this->assertEquals( - array( 'dewiki' => 'dewiki' ) + $commonTag, - $this->mConf->get( 'merge', 'dewiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (2) (with tag)' - ); - $this->assertEquals( - array( 'frwiki' => 'frwiki' ) + $common, - $this->mConf->get( 'merge', 'frwiki', 'wiki' ), - 'get(): merging setting on an existing wiki (3)' - ); - $this->assertEquals( - array( 'frwiki' => 'frwiki' ) + $commonTag, - $this->mConf->get( 'merge', 'frwiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (3) (with tag)' - ); - $this->assertEquals( - array( 'wiki' => 'wiki' ) + $common, - $this->mConf->get( 'merge', 'wiki', 'wiki' ), - 'get(): merging setting on an suffix' - ); - $this->assertEquals( - array( 'wiki' => 'wiki' ) + $commonTag, - $this->mConf->get( 'merge', 'wiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an suffix (with tag)' - ); - $this->assertEquals( - $common, - $this->mConf->get( 'merge', 'eswiki', 'wiki' ), - 'get(): merging setting on an non-existing wiki' - ); - $this->assertEquals( - $commonTag, - $this->mConf->get( 'merge', 'eswiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an non-existing wiki (with tag)' - ); - } - - /** - * @covers SiteConfiguration::siteFromDB - */ - public function testSiteFromDbWithCallback() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $this->assertEquals( - array( 'wiki', 'en' ), - $this->mConf->siteFromDB( 'enwiki' ), - 'siteFromDB() with callback' - ); - $this->assertEquals( - array( 'wiki', '' ), - $this->mConf->siteFromDB( 'wiki' ), - 'siteFromDB() with callback on a suffix' - ); - $this->assertEquals( - array( null, null ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() with callback on a non-existing wiki' - ); - } - - /** - * @covers SiteConfiguration::get - */ - public function testParameterReplacement() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $this->assertEquals( - 'en wiki enwiki', - $this->mConf->get( 'params', 'enwiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki' - ); - $this->assertEquals( - 'de wiki dewiki', - $this->mConf->get( 'params', 'dewiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki (2)' - ); - $this->assertEquals( - 'fr wiki frwiki', - $this->mConf->get( 'params', 'frwiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki (3)' - ); - $this->assertEquals( - ' wiki wiki', - $this->mConf->get( 'params', 'wiki', 'wiki' ), - 'get(): parameter replacement on an suffix' - ); - $this->assertEquals( - 'es wiki eswiki', - $this->mConf->get( 'params', 'eswiki', 'wiki' ), - 'get(): parameter replacement on an non-existing wiki' - ); - } - - /** - * @covers SiteConfiguration::getAll - */ - public function testGetAllGlobals() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $getall = array( - 'simple' => 'enwiki', - 'fallback' => 'tag', - 'params' => 'en wiki enwiki', - 'global' => array( 'enwiki' => 'enwiki' ) + $GLOBALS['global'], - 'merge' => array( 'enwiki' => 'enwiki', 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ), - ); - $this->assertEquals( $getall, $this->mConf->getAll( 'enwiki' ), 'getAll()' ); - - $this->mConf->extractAllGlobals( 'enwiki', 'wiki' ); - - $this->assertEquals( $getall['simple'], $GLOBALS['simple'], 'extractAllGlobals(): simple setting' ); - $this->assertEquals( $getall['fallback'], $GLOBALS['fallback'], 'extractAllGlobals(): fallback setting' ); - $this->assertEquals( $getall['params'], $GLOBALS['params'], 'extractAllGlobals(): parameter replacement' ); - $this->assertEquals( $getall['global'], $GLOBALS['global'], 'extractAllGlobals(): merging with global' ); - $this->assertEquals( $getall['merge'], $GLOBALS['merge'], 'extractAllGlobals(): merging setting' ); - } -} diff --git a/tests/phpunit/includes/StringUtilsTest.php b/tests/phpunit/includes/StringUtilsTest.php deleted file mode 100644 index 89759e5c..00000000 --- a/tests/phpunit/includes/StringUtilsTest.php +++ /dev/null @@ -1,147 +0,0 @@ -<?php - -class StringUtilsTest extends MediaWikiTestCase { - - /** - * This tests StringUtils::isUtf8 whenever we have the mbstring extension - * loaded. - * - * @covers StringUtils::isUtf8 - * @dataProvider provideStringsForIsUtf8Check - */ - public function testIsUtf8WithMbstring( $expected, $string ) { - if ( !function_exists( 'mb_check_encoding' ) ) { - $this->markTestSkipped( 'Test requires the mbstring PHP extension' ); - } - $this->assertEquals( $expected, - StringUtils::isUtf8( $string ), - 'Testing string "' . $this->escaped( $string ) . '" with mb_check_encoding' - ); - } - - /** - * 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 - */ - public function testIsUtf8WithPhpFallbackImplementation( $expected, $string ) { - $this->assertEquals( $expected, - StringUtils::isUtf8( $string, /** disable mbstring: */true ), - 'Testing string "' . $this->escaped( $string ) . '" with pure PHP implementation' - ); - } - - /** - * Print high range characters as an hexadecimal - */ - function escaped( $string ) { - $escaped = ''; - $length = strlen( $string ); - for ( $i = 0; $i < $length; $i++ ) { - $char = $string[$i]; - $val = ord( $char ); - if ( $val > 127 ) { - $escaped .= '\x' . dechex( $val ); - } else { - $escaped .= $char; - } - } - - return $escaped; - } - - /** - * See also "UTF-8 decoder capability and stress test" by - * Markus Kuhn: - * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt - */ - public static function provideStringsForIsUtf8Check() { - // Expected return values for StringUtils::isUtf8() - $PASS = true; - $FAIL = false; - - return array( - '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 deleted file mode 100644 index fb63a564..00000000 --- a/tests/phpunit/includes/TemplateCategoriesTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -/** - * @group Database - */ -require __DIR__ . "/../../../maintenance/runJobs.php"; - -class TemplateCategoriesTest extends MediaWikiLangTestCase { - - /** - * @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' ); - - $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' ) ); - - $template->doEditContent( - new WikitextContent( '[[Category:Solved bugs]]' ), - 'Add a category through a template', - 0, - false, - $user - ); - - // Run the job queue - JobQueueGroup::destroySingletons(); - $jobs = new RunJobs; - $jobs->loadParamsAndArgs( null, array( 'quiet' => true ), null ); - $jobs->execute(); - - $this->assertEquals( - array( 'Category:Solved_bugs' => $title->getPrefixedText() ) - , $title->getParentCategories() - ); - } -} diff --git a/tests/phpunit/includes/TestUser.php b/tests/phpunit/includes/TestUser.php deleted file mode 100644 index 23e65031..00000000 --- a/tests/phpunit/includes/TestUser.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -/** - * Wraps the user object, so we can also retain full access to properties like password if we log in via the API - */ -class TestUser { - public $username; - public $password; - public $email; - public $groups; - public $user; - - public function __construct( $username, $realname = 'Real Name', $email = 'sample@example.com', $groups = array() ) { - $this->username = $username; - $this->realname = $realname; - $this->email = $email; - $this->groups = $groups; - - // don't allow user to hardcode or select passwords -- people sometimes run tests - // on live wikis. Sometimes we create sysop users in these tests. A sysop user with - // a known password would be a Bad Thing. - $this->password = User::randomPassword(); - - $this->user = User::newFromName( $this->username ); - $this->user->load(); - - // In an ideal world we'd have a new wiki (or mock data store) for every single test. - // But for now, we just need to create or update the user with the desired properties. - // we particularly need the new password, since we just generated it randomly. - // In core MediaWiki, there is no functionality to delete users, so this is the best we can do. - if ( !$this->user->getID() ) { - // create the user - $this->user = User::createNew( - $this->username, array( - "email" => $this->email, - "real_name" => $this->realname - ) - ); - if ( !$this->user ) { - throw new Exception( "error creating user" ); - } - } - - // update the user to use the new random password and other details - $this->user->setPassword( $this->password ); - $this->user->setEmail( $this->email ); - $this->user->setRealName( $this->realname ); - // remove all groups, replace with any groups specified - foreach ( $this->user->getGroups() as $group ) { - $this->user->removeGroup( $group ); - } - if ( count( $this->groups ) ) { - foreach ( $this->groups as $group ) { - $this->user->addGroup( $group ); - } - } - $this->user->saveSettings(); - } -} diff --git a/tests/phpunit/includes/TimeAdjustTest.php b/tests/phpunit/includes/TimeAdjustTest.php deleted file mode 100644 index 0b368c25..00000000 --- a/tests/phpunit/includes/TimeAdjustTest.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -class TimeAdjustTest extends MediaWikiLangTestCase { - protected function setUp() { - parent::setUp(); - - $this->iniSet( 'precision', 15 ); - } - - /** - * 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 ); - - $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 ), - array( 20061231235959, 60, 20070101005959 ), - array( 20061231235959, 90, 20070101012959 ), - array( 20061231235959, 120, 20070101015959 ), - array( 20061231235959, 540, 20070101085959 ), - array( 20061231235959, -5, 20061231235459 ), - array( 20061231235959, -30, 20061231232959 ), - array( 20061231235959, -60, 20061231225959 ), - ); - } -} diff --git a/tests/phpunit/includes/TimestampTest.php b/tests/phpunit/includes/TimestampTest.php deleted file mode 100644 index 53388392..00000000 --- a/tests/phpunit/includes/TimestampTest.php +++ /dev/null @@ -1,304 +0,0 @@ -<?php - -/** - * Tests timestamp parsing and output. - */ -class TimestampTest extends MediaWikiLangTestCase { - - protected function setUp() { - parent::setUp(); - - RequestContext::getMain()->setLanguage( Language::factory( 'en' ) ); - } - - /** - * Test parsing of valid timestamps and outputing to MW format. - * @dataProvider provideValidTimestamps - * @covers MWTimestamp::getTimestamp - */ - public function testValidParse( $format, $original, $expected ) { - $timestamp = new MWTimestamp( $original ); - $this->assertEquals( $expected, $timestamp->getTimestamp( TS_MW ) ); - } - - /** - * Test outputting valid timestamps to different formats. - * @dataProvider provideValidTimestamps - * @covers MWTimestamp::getTimestamp - */ - public function testValidOutput( $format, $expected, $original ) { - $timestamp = new MWTimestamp( $original ); - $this->assertEquals( $expected, (string)$timestamp->getTimestamp( $format ) ); - } - - /** - * Test an invalid timestamp. - * @expectedException TimestampException - * @covers MWTimestamp - */ - public function testInvalidParse() { - new MWTimestamp( "This is not a timestamp." ); - } - - /** - * Test requesting an invalid output format. - * @expectedException TimestampException - * @covers MWTimestamp::getTimestamp - */ - public function testInvalidOutput() { - $timestamp = new MWTimestamp( '1343761268' ); - $timestamp->getTimestamp( 98 ); - } - - /** - * Returns a list of valid timestamps in the format: - * array( type, timestamp_of_type, timestamp_in_MW ) - */ - public static function provideValidTimestamps() { - return array( - // Various formats - array( TS_UNIX, '1343761268', '20120731190108' ), - array( TS_MW, '20120731190108', '20120731190108' ), - array( TS_DB, '2012-07-31 19:01:08', '20120731190108' ), - array( TS_ISO_8601, '2012-07-31T19:01:08Z', '20120731190108' ), - array( TS_ISO_8601_BASIC, '20120731T190108Z', '20120731190108' ), - array( TS_EXIF, '2012:07:31 19:01:08', '20120731190108' ), - array( TS_RFC2822, 'Tue, 31 Jul 2012 19:01:08 GMT', '20120731190108' ), - array( TS_ORACLE, '31-07-2012 19:01:08.000000', '20120731190108' ), - array( TS_POSTGRES, '2012-07-31 19:01:08 GMT', '20120731190108' ), - // Some extremes and weird values - array( TS_ISO_8601, '9999-12-31T23:59:59Z', '99991231235959' ), - 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 deleted file mode 100644 index 3079d73a..00000000 --- a/tests/phpunit/includes/TitleMethodsTest.php +++ /dev/null @@ -1,300 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * - * @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() { - global $wgContLang; - - parent::setUp(); - - $this->mergeMwGlobalArrayValue( - 'wgExtraNamespaces', - array( - 12302 => 'TEST-JS', - 12303 => 'TEST-JS_TALK', - ) - ); - - $this->mergeMwGlobalArrayValue( - 'wgNamespaceContentModels', - array( - 12302 => CONTENT_MODEL_JAVASCRIPT, - ) - ); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - public function tearDown() { - global $wgContLang; - - parent::tearDown(); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - public static function provideEquals() { - return array( - array( 'Main Page', 'Main Page', true ), - array( 'Main Page', 'Not The Main Page', false ), - array( 'Main Page', 'Project:Main Page', false ), - array( 'File:Example.png', 'Image:Example.png', true ), - array( 'Special:Version', 'Special:Version', true ), - array( 'Special:Version', 'Special:Recentchanges', false ), - array( 'Special:Version', 'Main Page', false ), - ); - } - - /** - * @dataProvider provideEquals - * @covers Title::equals - */ - public function testEquals( $titleA, $titleB, $expectedBool ) { - $titleA = Title::newFromText( $titleA ); - $titleB = Title::newFromText( $titleB ); - - $this->assertEquals( $expectedBool, $titleA->equals( $titleB ) ); - $this->assertEquals( $expectedBool, $titleB->equals( $titleA ) ); - } - - public static function provideInNamespace() { - return array( - array( 'Main Page', NS_MAIN, true ), - array( 'Main Page', NS_TALK, false ), - array( 'Main Page', NS_USER, false ), - array( 'User:Foo', NS_USER, true ), - array( 'User:Foo', NS_USER_TALK, false ), - array( 'User:Foo', NS_TEMPLATE, false ), - array( 'User_talk:Foo', NS_USER_TALK, true ), - array( 'User_talk:Foo', NS_USER, false ), - ); - } - - /** - * @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 ) ); - $this->assertTrue( $mainpage->inNamespaces( array( NS_MAIN, NS_USER ) ) ); - $this->assertTrue( $mainpage->inNamespaces( array( NS_USER, NS_MAIN ) ) ); - $this->assertFalse( $mainpage->inNamespaces( array( NS_PROJECT, NS_TEMPLATE ) ) ); - } - - public static function provideHasSubjectNamespace() { - return array( - array( 'Main Page', NS_MAIN, true ), - array( 'Main Page', NS_TALK, true ), - array( 'Main Page', NS_USER, false ), - array( 'User:Foo', NS_USER, true ), - array( 'User:Foo', NS_USER_TALK, true ), - array( 'User:Foo', NS_TEMPLATE, false ), - array( 'User_talk:Foo', NS_USER_TALK, true ), - array( 'User_talk:Foo', NS_USER, true ), - ); - } - - /** - * @dataProvider provideHasSubjectNamespace - * @covers Title::hasSubjectNamespace - */ - public function testHasSubjectNamespace( $title, $ns, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->hasSubjectNamespace( $ns ) ); - } - - public function dataGetContentModel() { - return array( - array( 'Help:Foo', CONTENT_MODEL_WIKITEXT ), - array( 'Help:Foo.js', CONTENT_MODEL_WIKITEXT ), - array( 'Help:Foo/bar.js', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo.js', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'User:Foo/bar.css', CONTENT_MODEL_CSS ), - array( 'User talk:Foo/bar.css', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.js.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'MediaWiki:Foo.css', CONTENT_MODEL_CSS ), - array( 'MediaWiki:Foo/bar.css', CONTENT_MODEL_CSS ), - array( 'MediaWiki:Foo.JS', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.CSS', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.css.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'TEST-JS:Foo', CONTENT_MODEL_JAVASCRIPT ), - array( 'TEST-JS:Foo.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'TEST-JS:Foo/bar.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'TEST-JS_TALK:Foo.js', CONTENT_MODEL_WIKITEXT ), - ); - } - - /** - * @dataProvider dataGetContentModel - * @covers Title::getContentModel - */ - public function testGetContentModel( $title, $expectedModelId ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedModelId, $title->getContentModel() ); - } - - /** - * @dataProvider dataGetContentModel - * @covers Title::hasContentModel - */ - public function testHasContentModel( $title, $expectedModelId ) { - $title = Title::newFromText( $title ); - $this->assertTrue( $title->hasContentModel( $expectedModelId ) ); - } - - public static function provideIsCssOrJsPage() { - return array( - array( 'Help:Foo', false ), - array( 'Help:Foo.js', false ), - array( 'Help:Foo/bar.js', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo/bar.js', false ), - array( 'User:Foo/bar.css', false ), - array( 'User talk:Foo/bar.css', false ), - array( 'User:Foo/bar.js.xxx', false ), - array( 'User:Foo/bar.xxx', false ), - array( 'MediaWiki:Foo.js', true ), - array( 'MediaWiki:Foo.css', true ), - array( 'MediaWiki:Foo.JS', false ), - array( 'MediaWiki:Foo.CSS', false ), - array( 'MediaWiki:Foo.css.xxx', false ), - array( 'TEST-JS:Foo', false ), - array( 'TEST-JS:Foo.js', false ), - ); - } - - /** - * @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 ), - array( 'Help:Foo.js', false ), - array( 'Help:Foo/bar.js', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo/bar.js', true ), - array( 'User:Foo/bar.css', true ), - array( 'User talk:Foo/bar.css', false ), - array( 'User:Foo/bar.js.xxx', false ), - array( 'User:Foo/bar.xxx', false ), - array( 'MediaWiki:Foo.js', false ), - array( 'User:Foo/bar.JS', false ), - array( 'User:Foo/bar.CSS', false ), - array( 'TEST-JS:Foo', false ), - array( 'TEST-JS:Foo.js', false ), - ); - } - - /** - * @dataProvider provideIsCssJsSubpage - * @covers Title::isCssJsSubpage - */ - public function testIsCssJsSubpage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssJsSubpage() ); - } - - public static function provideIsCssSubpage() { - return array( - array( 'Help:Foo', false ), - array( 'Help:Foo.css', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo.css', false ), - array( 'User:Foo/bar.js', false ), - array( 'User:Foo/bar.css', true ), - ); - } - - /** - * @dataProvider provideIsCssSubpage - * @covers Title::isCssSubpage - */ - public function testIsCssSubpage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssSubpage() ); - } - - public static function provideIsJsSubpage() { - return array( - array( 'Help:Foo', false ), - array( 'Help:Foo.css', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo.css', false ), - array( 'User:Foo/bar.js', true ), - array( 'User:Foo/bar.css', false ), - ); - } - - /** - * @dataProvider provideIsJsSubpage - * @covers Title::isJsSubpage - */ - public function testIsJsSubpage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isJsSubpage() ); - } - - public static function provideIsWikitextPage() { - return array( - array( 'Help:Foo', true ), - array( 'Help:Foo.js', true ), - array( 'Help:Foo/bar.js', true ), - array( 'User:Foo', true ), - array( 'User:Foo.js', true ), - array( 'User:Foo/bar.js', false ), - array( 'User:Foo/bar.css', false ), - array( 'User talk:Foo/bar.css', true ), - array( 'User:Foo/bar.js.xxx', true ), - array( 'User:Foo/bar.xxx', true ), - array( 'MediaWiki:Foo.js', false ), - array( 'MediaWiki:Foo.css', false ), - array( 'MediaWiki:Foo/bar.css', false ), - array( 'User:Foo/bar.JS', true ), - array( 'User:Foo/bar.CSS', true ), - array( 'TEST-JS:Foo', false ), - array( 'TEST-JS:Foo.js', false ), - array( 'TEST-JS_TALK:Foo.js', true ), - ); - } - - /** - * @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 deleted file mode 100644 index f15c1772..00000000 --- a/tests/phpunit/includes/TitlePermissionTest.php +++ /dev/null @@ -1,742 +0,0 @@ -<?php - -/** - * @group Database - * @todo covers tags - */ -class TitlePermissionTest extends MediaWikiLangTestCase { - - /** - * @var string - */ - protected $userName, $altUserName; - - /** - * @var Title - */ - protected $title; - - /** - * @var User - */ - protected $user, $anonUser, $userUser, $altUser; - - protected function setUp() { - parent::setUp(); - - $langObj = Language::factory( 'en' ); - $localZone = 'UTC'; - $localOffset = date( 'Z' ) / 60; - - $this->setMwGlobals( array( - 'wgMemc' => new EmptyBagOStuff, - 'wgContLang' => $langObj, - 'wgLanguageCode' => 'en', - 'wgLang' => $langObj, - 'wgLocaltimezone' => $localZone, - 'wgLocalTZoffset' => $localOffset, - 'wgNamespaceProtection' => array( - NS_MEDIAWIKI => 'editinterface', - ), - ) ); - - $this->userName = 'Useruser'; - $this->altUserName = 'Altuseruser'; - date_default_timezone_set( $localZone ); - - $this->title = Title::makeTitle( NS_MAIN, "Main Page" ); - if ( !isset( $this->userUser ) || !( $this->userUser instanceOf User ) ) { - $this->userUser = User::newFromName( $this->userName ); - - if ( !$this->userUser->getID() ) { - $this->userUser = User::createNew( $this->userName, array( - "email" => "test@example.com", - "real_name" => "Test User" ) ); - $this->userUser->load(); - } - - $this->altUser = User::newFromName( $this->altUserName ); - if ( !$this->altUser->getID() ) { - $this->altUser = User::createNew( $this->altUserName, array( - "email" => "alttest@example.com", - "real_name" => "Test User Alt" ) ); - $this->altUser->load(); - } - - $this->anonUser = User::newFromId( 0 ); - - $this->user = $this->userUser; - } - } - - protected function setUserPerm( $perm ) { - // Setting member variables is evil!!! - - if ( is_array( $perm ) ) { - $this->user->mRights = $perm; - } else { - $this->user->mRights = array( $perm ); - } - } - - protected function setTitle( $ns, $title = "Main_Page" ) { - $this->title = Title::makeTitle( $ns, $title ); - } - - protected function setUser( $userName = null ) { - if ( $userName === 'anon' ) { - $this->user = $this->anonUser; - } elseif ( $userName === null || $userName === $this->userName ) { - $this->user = $this->userUser; - } else { - $this->user = $this->altUser; - } - } - - /** - * @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 ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( "nocreatetext" ) ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); - - $this->setUser( $this->userName ); - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setUser( $this->userName ); - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), $res ); - - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setUser( $this->userName ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ) ); - - $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), - array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ) ); - - if ( $this->isWikitextNS( NS_MAIN ) ) { - //NOTE: some content models don't allow moving - // @todo find a Wikitext namespace for testing - - $this->setTitle( NS_MAIN ); - $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array() ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ), - array( array( 'movenologintext' ) ) ); - - $this->setUser( $this->userName ); - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ) ); - - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array() ); - - $this->setUser( 'anon' ); - $this->setUserPerm( 'move' ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setUserPerm( '' ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); - } - - $this->setTitle( NS_USER ); - $this->setUser( $this->userName ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setUserPerm( "move" ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( array( 'cant-move-to-user-page' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_USER, "User/subpage" ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setUserPerm( "move" ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setUser( 'anon' ); - $check = array( 'edit' => array( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ) ), - array( array( 'badaccess-group0' ) ), - array(), true ), - 'protect' => array( array( array( 'badaccess-groups', "[[$prefix:Administrators|Administrators]]", 1 ), array( 'protect-cantedit' ) ), - array( array( 'badaccess-group0' ), array( 'protect-cantedit' ) ), - array( array( 'protect-cantedit' ) ), false ), - '' => array( array(), array(), array(), true ) ); - - foreach ( array( "edit", "protect", "" ) as $action ) { - $this->setUserPerm( null ); - $this->assertEquals( $check[$action][0], - $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); - - global $wgGroupPermissions; - $old = $wgGroupPermissions; - $wgGroupPermissions = array(); - - $this->assertEquals( $check[$action][1], - $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); - $wgGroupPermissions = $old; - - $this->setUserPerm( $action ); - $this->assertEquals( $check[$action][2], - $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); - - $this->setUserPerm( $action ); - $this->assertEquals( $check[$action][3], - $this->title->userCan( $action, $this->user, true ) ); - $this->assertEquals( $check[$action][3], - $this->title->quickUserCan( $action, $this->user ) ); - # count( User::getGroupsWithPermissions( $action ) ) < 1 - } - } - - protected function runGroupPermissions( $action, $result, $result2 = null ) { - global $wgGroupPermissions; - - if ( $result2 === null ) { - $result2 = $result; - } - - $wgGroupPermissions['autoconfirmed']['move'] = false; - $wgGroupPermissions['user']['move'] = false; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = true; - $wgGroupPermissions['user']['move'] = false; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result2, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = true; - $wgGroupPermissions['user']['move'] = true; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result2, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = false; - $wgGroupPermissions['user']['move'] = true; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result2, $res ); - } - - /** - * @todo This test method should be split up into separate test methods and - * data providers - */ - public function testSpecialsAndNSPermissions() { - global $wgNamespaceProtection; - $this->setUser( $this->userName ); - - $this->setTitle( NS_SPECIAL ); - - $this->assertEquals( array( array( 'badaccess-group0' ), array( 'ns-specialprotected' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $wgNamespaceProtection[NS_USER] = array( 'bogus' ); - - $this->setTitle( NS_USER ); - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ), array( 'namespaceprotected', 'User' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( array( 'protectedinterface' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( array( 'protectedinterface' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $wgNamespaceProtection = null; - - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'bogus', $this->user ) ); - - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'bogus', $this->user ) ); - } - - /** - * @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( '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' ) ) - ); - - $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' ) ) - ); - } - - protected function runCSSandJSPermissions( $result0, $result1, $result2, $result3, $result4 ) { - $this->setUserPerm( '' ); - $this->assertEquals( $result0, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - - $this->setUserPerm( 'editmyusercss' ); - $this->assertEquals( $result1, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - - $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', - $this->user ) ); - - $this->setUserPerm( array( 'edituserjs', 'editusercss' ) ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - } - - /** - * @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 ); - - $this->setTitle( NS_MAIN ); - $this->title->mRestrictionsLoaded = true; - $this->setUserPerm( "edit" ); - $this->title->mRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'edit', - $this->user ) ); - - $this->assertEquals( true, - $this->title->quickUserCan( 'edit', $this->user ) ); - $this->title->mRestrictions = array( "edit" => array( 'bogus', "sysop", "protect", "" ), - "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $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( "" ); - $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( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ), - array( 'protectedpagetext', 'bogus' ), - 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' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - $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, - $this->title->quickUserCan( 'edit', $this->user ) ); - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'edit', - $this->user ) ); - } - - public function testCascadingSourcesRestrictions() { - $this->setTitle( NS_MAIN, "test page" ); - $this->setUserPerm( array( "edit", "bogus" ) ); - - $this->title->mCascadeSources = array( Title::makeTitle( NS_MAIN, "Bogus" ), Title::makeTitle( NS_MAIN, "UnBogus" ) ); - $this->title->mCascadingRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $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 ) ); - - $this->assertEquals( true, - $this->title->userCan( 'edit', $this->user ) ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); - } - - /** - * @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'] = ''; - $this->title->mTitleProtection['pt_user'] = $this->user->getID(); - $this->title->mTitleProtection['pt_expiry'] = wfGetDB( DB_SLAVE )->getInfinity(); - $this->title->mTitleProtection['pt_reason'] = 'test'; - $this->title->mCascadeRestriction = false; - - $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), - $this->title->getUserPermissionsErrors( 'create', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'create', $this->user ) ); - - $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 ) ); - $this->assertEquals( false, - $this->title->userCan( 'create', $this->user ) ); - - $this->setTitle( NS_MEDIA, "test page" ); - $this->setUserPerm( array( "move" ) ); - $this->assertEquals( false, - $this->title->userCan( 'move', $this->user ) ); - $this->assertEquals( array( array( 'immobile-source-namespace', 'Media' ) ), - $this->title->getUserPermissionsErrors( 'move', $this->user ) ); - - $this->setTitle( NS_HELP, "test page" ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'move', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'move', $this->user ) ); - - $this->title->mInterwiki = "no"; - $this->assertEquals( array( array( 'immobile-source-page' ) ), - $this->title->getUserPermissionsErrors( 'move', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'move', $this->user ) ); - - $this->setTitle( NS_MEDIA, "test page" ); - $this->assertEquals( false, - $this->title->userCan( 'move-target', $this->user ) ); - $this->assertEquals( array( array( 'immobile-target-namespace', 'Media' ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - - $this->setTitle( NS_HELP, "test page" ); - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'move-target', $this->user ) ); - - $this->title->mInterwiki = "no"; - $this->assertEquals( array( array( 'immobile-target-page' ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'move-target', $this->user ) ); - } - - public function testUserBlock() { - global $wgEmailConfirmToEdit, $wgEmailAuthentication; - $wgEmailConfirmToEdit = true; - $wgEmailAuthentication = true; - - $this->setUserPerm( array( "createpage", "move" ) ); - $this->setTitle( NS_HELP, "test page" ); - - # $short - $this->assertEquals( array( array( 'confirmedittext' ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $wgEmailConfirmToEdit = false; - $this->assertEquals( true, $this->title->userCan( 'move-target', $this->user ) ); - - # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount' - $this->assertEquals( array(), - $this->title->getUserPermissionsErrors( 'move-target', - $this->user ) ); - - global $wgLang; - $prev = time(); - $now = time() + 120; - $this->user->mBlockedby = $this->user->getId(); - $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(), - 'no reason given', $prev + 3600, 1, 0 ); - $this->user->mBlock->mTimestamp = 0; - $this->assertEquals( array( array( 'autoblockedtext', - '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', - 'Useruser', null, 'infinite', '127.0.8.1', - $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ) ), - $this->title->getUserPermissionsErrors( 'move-target', - $this->user ) ); - - $this->assertEquals( false, $this->title->userCan( 'move-target', $this->user ) ); - // quickUserCan should ignore user blocks - $this->assertEquals( true, $this->title->quickUserCan( 'move-target', $this->user ) ); - - global $wgLocalTZoffset; - $wgLocalTZoffset = -60; - $this->user->mBlockedby = $this->user->getName(); - $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 deleted file mode 100644 index 6bfe5453..00000000 --- a/tests/phpunit/includes/TitleTest.php +++ /dev/null @@ -1,485 +0,0 @@ -<?php - -/** - * @group Database - * ^--- needed for language cache stuff - */ -class TitleTest extends MediaWikiTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgLanguageCode' => 'en', - 'wgContLang' => Language::factory( 'en' ), - // User language - 'wgLang' => Language::factory( 'en' ), - 'wgAllowUserJs' => false, - 'wgDefaultLanguageVariant' => false, - ) ); - } - - /** - * @covers Title::legalChars - */ - public function testLegalChars() { - $titlechars = Title::legalChars(); - - foreach ( range( 1, 255 ) as $num ) { - $chr = chr( $num ); - if ( strpos( "#[]{}<>|", $chr ) !== false || preg_match( "/[\\x00-\\x1f\\x7f]/", $chr ) ) { - $this->assertFalse( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is not a valid titlechar" ); - } else { - $this->assertTrue( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is a valid titlechar" ); - } - } - } - - /** - * See also mediawiki.Title.test.js - * @covers Title::secureAndSplit - * @todo This method should be split into 2 separate tests each with a provider - */ - public function testSecureAndSplit() { - // Valid - foreach ( array( - 'Sandbox', - 'A "B"', - 'A \'B\'', - '.com', - '~', - '"', - '\'', - 'Talk:Sandbox', - 'Talk:Foo:Sandbox', - 'File:Example.svg', - 'File_talk:Example.svg', - 'Foo/.../Sandbox', - 'Sandbox/...', - 'A~~', - // Length is 256 total, but only title part matters - 'Category:' . str_repeat( 'x', 248 ), - str_repeat( 'x', 252 ) - ) as $text ) { - $this->assertInstanceOf( 'Title', Title::newFromText( $text ), "Valid: $text" ); - } - - // Invalid - foreach ( array( - '', - '__ __', - ' __ ', - // Bad characters forbidden regardless of wgLegalTitleChars - 'A [ B', - 'A ] B', - 'A { B', - 'A } B', - 'A < B', - 'A > B', - 'A | B', - // URL encoding - 'A%20B', - 'A%23B', - 'A%2523B', - // XML/HTML character entity references - // Note: Commented out because they are not marked invalid by the PHP test as - // Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first. - //'A é B', - //'A é B', - //'A é B', - // Subject of NS_TALK does not roundtrip to NS_MAIN - 'Talk:File:Example.svg', - // Directory navigation - '.', - '..', - './Sandbox', - '../Sandbox', - 'Foo/./Sandbox', - 'Foo/../Sandbox', - 'Sandbox/.', - 'Sandbox/..', - // Tilde - 'A ~~~ Name', - 'A ~~~~ Signature', - 'A ~~~~~ Timestamp', - str_repeat( 'x', 256 ), - // Namespace prefix without actual title - // ':', // bug 54044 - 'Talk:', - 'Category: ', - 'Category: #bar' - ) as $text ) { - $this->assertNull( Title::newFromText( $text ), "Invalid: $text" ); - } - } - - public static function provideConvertByteClassToUnicodeClass() { - return array( - array( - ' %!"$&\'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+', - ' %!"$&\'()*,\\-./0-9:;=?@A-Z\\\\\\^_`a-z~+\\u0080-\\uFFFF', - ), - array( - 'QWERTYf-\\xFF+', - 'QWERTYf-\\x7F+\\u0080-\\uFFFF', - ), - array( - 'QWERTY\\x66-\\xFD+', - 'QWERTYf-\\x7F+\\u0080-\\uFFFF', - ), - array( - 'QWERTYf-y+', - 'QWERTYf-y+', - ), - array( - 'QWERTYf-\\x80+', - 'QWERTYf-\\x7F+\\u0080-\\uFFFF', - ), - array( - 'QWERTY\\x66-\\x80+\\x23', - 'QWERTYf-\\x7F+#\\u0080-\\uFFFF', - ), - array( - 'QWERTY\\x66-\\x80+\\xD3', - 'QWERTYf-\\x7F+\\u0080-\\uFFFF', - ), - array( - '\\\\\\x99', - '\\\\\\u0080-\\uFFFF', - ), - array( - '-\\x99', - '\\-\\u0080-\\uFFFF', - ), - array( - 'QWERTY\\-\\x99', - 'QWERTY\\-\\u0080-\\uFFFF', - ), - array( - '\\\\x99', - '\\\\x99', - ), - array( - 'A-\\x9F', - 'A-\\x7F\\u0080-\\uFFFF', - ), - array( - '\\x66-\\x77QWERTY\\x88-\\x91FXZ', - 'f-wQWERTYFXZ\\u0080-\\uFFFF', - ), - array( - '\\x66-\\x99QWERTY\\xAA-\\xEEFXZ', - 'f-\\x7FQWERTYFXZ\\u0080-\\uFFFF', - ), - ); - } - - /** - * @dataProvider provideConvertByteClassToUnicodeClass - * @covers Title::convertByteClassToUnicodeClass - */ - public function testConvertByteClassToUnicodeClass( $byteClass, $unicodeClass ) { - $this->assertEquals( $unicodeClass, Title::convertByteClassToUnicodeClass( $byteClass ) ); - } - - /** - * @dataProvider provideBug31100 - * @covers Title::fixSpecialName - */ - public function testBug31100FixSpecialName( $text, $expectedParam ) { - $title = Title::newFromText( $text ); - $fixed = $title->fixSpecialName(); - $stuff = explode( '/', $fixed->getDBkey(), 2 ); - if ( count( $stuff ) == 2 ) { - $par = $stuff[1]; - } else { - $par = null; - } - $this->assertEquals( $expectedParam, $par, "Bug 31100 regression check: Title->fixSpecialName() should preserve parameter" ); - } - - public static function provideBug31100() { - return array( - array( 'Special:Version', null ), - array( 'Special:Version/', '' ), - array( 'Special:Version/param', 'param' ), - ); - } - - /** - * Auth-less test of Title::isValidMoveOperation - * - * @group Database - * @param string $source - * @param string $target - * @param array|string|bool $expected Required error - * @dataProvider provideTestIsValidMoveOperation - * @covers Title::isValidMoveOperation - */ - public function testIsValidMoveOperation( $source, $target, $expected ) { - $title = Title::newFromText( $source ); - $nt = Title::newFromText( $target ); - $errors = $title->isValidMoveOperation( $nt, false ); - if ( $expected === true ) { - $this->assertTrue( $errors ); - } else { - $errors = $this->flattenErrorsArray( $errors ); - foreach ( (array)$expected as $error ) { - $this->assertContains( $error, $errors ); - } - } - } - - /** - * Provides test parameter values for testIsValidMoveOperation() - */ - public function dataTestIsValidMoveOperation() { - return array( - array( 'Test', 'Test', 'selfmove' ), - array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ) - ); - } - - /** - * Auth-less test of Title::userCan - * - * @param array $whitelistRegexp - * @param string $source - * @param string $action - * @param array|string|bool $expected Required error - * - * @covers Title::checkReadPermissions - * @dataProvider dataWgWhitelistReadRegexp - */ - 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 - // type requisite. - if ( is_string( $whitelistRegexp ) ) { - $whitelistRegexp = array( $whitelistRegexp ); - } - - $title = Title::newFromDBkey( $source ); - - global $wgGroupPermissions; - $oldPermissions = $wgGroupPermissions; - // Disallow all so we can ensure our regex works - $wgGroupPermissions = array(); - $wgGroupPermissions['*']['read'] = false; - - global $wgWhitelistRead; - $oldWhitelist = $wgWhitelistRead; - // Undo any LocalSettings explicite whitelists so they won't cause a - // failing test to succeed. Set it to some random non sense just - // to make sure we properly test Title::checkReadPermissions() - $wgWhitelistRead = array( 'some random non sense title' ); - - global $wgWhitelistReadRegexp; - $oldWhitelistRegexp = $wgWhitelistReadRegexp; - $wgWhitelistReadRegexp = $whitelistRegexp; - - // Just use $wgUser which in test is a user object for '127.0.0.1' - global $wgUser; - // Invalidate user rights cache to take in account $wgGroupPermissions - // change above. - $wgUser->clearInstanceCache(); - $errors = $title->userCan( $action, $wgUser ); - - // Restore globals - $wgGroupPermissions = $oldPermissions; - $wgWhitelistRead = $oldWhitelist; - $wgWhitelistReadRegexp = $oldWhitelistRegexp; - - if ( is_bool( $expected ) ) { - # Forge the assertion message depending on the assertion expectation - $allowableness = $expected - ? " should be allowed" - : " should NOT be allowed"; - $this->assertEquals( $expected, $errors, "User action '$action' on [[$source]] $allowableness." ); - } else { - $errors = $this->flattenErrorsArray( $errors ); - foreach ( (array)$expected as $error ) { - $this->assertContains( $error, $errors ); - } - } - } - - /** - * Provides test parameter values for testWgWhitelistReadRegexp() - */ - public function dataWgWhitelistReadRegexp() { - $ALLOWED = true; - $DISALLOWED = false; - - return array( - // Everything, if this doesn't work, we're really in trouble - array( '/.*/', 'Main_Page', 'read', $ALLOWED ), - array( '/.*/', 'Main_Page', 'edit', $DISALLOWED ), - - // We validate against the title name, not the db key - array( '/^Main_Page$/', 'Main_Page', 'read', $DISALLOWED ), - // Main page - array( '/^Main/', 'Main_Page', 'read', $ALLOWED ), - array( '/^Main.*/', 'Main_Page', 'read', $ALLOWED ), - // With spaces - array( '/Mic\sCheck/', 'Mic Check', 'read', $ALLOWED ), - // Unicode multibyte - // ...without unicode modifier - array( '/Unicode Test . Yes/', 'Unicode Test Ñ Yes', 'read', $DISALLOWED ), - // ...with unicode modifier - array( '/Unicode Test . Yes/u', 'Unicode Test Ñ Yes', 'read', $ALLOWED ), - // Case insensitive - array( '/MiC ChEcK/', 'mic check', 'read', $DISALLOWED ), - array( '/MiC ChEcK/i', 'mic check', 'read', $ALLOWED ), - - // From DefaultSettings.php: - array( "@^UsEr.*@i", 'User is banned', 'read', $ALLOWED ), - array( "@^UsEr.*@i", 'User:John Doe', 'read', $ALLOWED ), - - // With namespaces: - array( '/^Special:NewPages$/', 'Special:NewPages', 'read', $ALLOWED ), - array( null, 'Special:Newpages', 'read', $DISALLOWED ), - - ); - } - - public function flattenErrorsArray( $errors ) { - $result = array(); - foreach ( $errors as $error ) { - $result[] = $error[0]; - } - - return $result; - } - - public static function provideTestIsValidMoveOperation() { - return array( - array( 'Test', 'Test', 'selfmove' ), - array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ) - ); - } - - /** - * @dataProvider provideGetPageViewLanguage - * @covers Title::getPageViewLanguage - */ - public function testGetPageViewLanguage( $expected, $titleText, $contLang, $lang, $variant, $msg = '' ) { - global $wgLanguageCode, $wgContLang, $wgLang, $wgDefaultLanguageVariant, $wgAllowUserJs; - - // Setup environnement for this test - $wgLanguageCode = $contLang; - $wgContLang = Language::factory( $contLang ); - $wgLang = Language::factory( $lang ); - $wgDefaultLanguageVariant = $variant; - $wgAllowUserJs = true; - - $title = Title::newFromText( $titleText ); - $this->assertInstanceOf( 'Title', $title, - "Test must be passed a valid title text, you gave '$titleText'" - ); - $this->assertEquals( $expected, - $title->getPageViewLanguage()->getCode(), - $msg - ); - } - - public static function provideGetPageViewLanguage() { - # Format: - # - expected - # - Title name - # - wgContLang (expected in most case) - # - wgLang (on some specific pages) - # - wgDefaultLanguageVariant - # - Optional message - return array( - array( 'fr', 'Help:I_need_somebody', 'fr', 'fr', false ), - array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', false ), - array( 'zh', 'Help:I_need_somebody', 'zh', 'zh-tw', false ), - - array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', 'zh-cn' ), - array( 'es', 'MediaWiki:About', 'es', 'zh-tw', 'zh-cn' ), - array( 'es', 'MediaWiki:About/', 'es', 'zh-tw', 'zh-cn' ), - array( 'de', 'MediaWiki:About/de', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.js', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.css', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Common.js', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ), - - array( 'zh-cn', 'Help:I_need_somebody', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh', 'MediaWiki:About', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh', 'MediaWiki:About/', 'zh', 'zh-tw', 'zh-cn' ), - array( 'de', 'MediaWiki:About/de', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh-cn', 'MediaWiki:About/zh-cn', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh-tw', 'MediaWiki:About/zh-tw', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.js', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.css', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Common.js', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ), - - array( 'zh-tw', 'Special:NewPages', 'es', 'zh-tw', 'zh-cn' ), - array( 'zh-tw', 'Special:NewPages', 'zh', 'zh-tw', 'zh-cn' ), - - ); - } - - /** - * @dataProvider provideBaseTitleCases - * @covers Title::getBaseText - */ - public function testGetBaseText( $title, $expected, $msg = '' ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expected, - $title->getBaseText(), - $msg - ); - } - - public static function provideBaseTitleCases() { - return array( - # Title, expected base, optional message - array( 'User:John_Doe/subOne/subTwo', 'John Doe/subOne' ), - array( 'User:Foo/Bar/Baz', 'Foo/Bar' ), - ); - } - - /** - * @dataProvider provideRootTitleCases - * @covers Title::getRootText - */ - public function testGetRootText( $title, $expected, $msg = '' ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expected, - $title->getRootText(), - $msg - ); - } - - public static function provideRootTitleCases() { - return array( - # Title, expected base, optional message - array( 'User:John_Doe/subOne/subTwo', 'John Doe' ), - array( 'User:Foo/Bar/Baz', 'Foo' ), - ); - } - - /** - * @todo Handle $wgNamespacesWithSubpages cases - * @dataProvider provideSubpageTitleCases - * @covers Title::getSubpageText - */ - public function testGetSubpageText( $title, $expected, $msg = '' ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expected, - $title->getSubpageText(), - $msg - ); - } - - public static function provideSubpageTitleCases() { - return array( - # Title, expected base, optional message - array( 'User:John_Doe/subOne/subTwo', 'subTwo' ), - array( 'User:John_Doe/subOne', 'subOne' ), - ); - } -} diff --git a/tests/phpunit/includes/UIDGeneratorTest.php b/tests/phpunit/includes/UIDGeneratorTest.php deleted file mode 100644 index 8f78ae51..00000000 --- a/tests/phpunit/includes/UIDGeneratorTest.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php - -class UIDGeneratorTest extends MediaWikiTestCase { - - /** - * @dataProvider provider_testTimestampedUID - * @covers UIDGenerator::newTimestampedUID128 - * @covers UIDGenerator::newTimestampedUID88 - */ - public function testTimestampedUID( $method, $digitlen, $bits, $tbits, $hostbits ) { - $id = call_user_func( array( 'UIDGenerator', $method ) ); - $this->assertEquals( true, ctype_digit( $id ), "UID made of digit characters" ); - $this->assertLessThanOrEqual( $digitlen, strlen( $id ), - "UID has the right number of digits" ); - $this->assertLessThanOrEqual( $bits, strlen( wfBaseConvert( $id, 10, 2 ) ), - "UID has the right number of bits" ); - - $ids = array(); - for ( $i = 0; $i < 300; $i++ ) { - $ids[] = call_user_func( array( 'UIDGenerator', $method ) ); - } - - $lastId = array_shift( $ids ); - if ( $hostbits ) { - $lastHost = substr( wfBaseConvert( $lastId, 10, 2, $bits ), -$hostbits ); - } - - $this->assertArrayEquals( array_unique( $ids ), $ids, "All generated IDs are unique." ); - - foreach ( $ids as $id ) { - $id_bin = wfBaseConvert( $id, 10, 2 ); - $lastId_bin = wfBaseConvert( $lastId, 10, 2 ); - - $this->assertGreaterThanOrEqual( - substr( $id_bin, 0, $tbits ), - substr( $lastId_bin, 0, $tbits ), - "New ID timestamp ($id_bin) >= prior one ($lastId_bin)." ); - - if ( $hostbits ) { - $this->assertEquals( - substr( $id_bin, 0, -$hostbits ), - substr( $lastId_bin, 0, -$hostbits ), - "Host ID of ($id_bin) is same as prior one ($lastId_bin)." ); - } - - $lastId = $id; - } - } - - /** - * array( method, length, bits, hostbits ) - * NOTE: When adding a new method name here please update the covers tags for the tests! - */ - public static function provider_testTimestampedUID() { - return array( - array( 'newTimestampedUID128', 39, 128, 46, 48 ), - array( 'newTimestampedUID128', 39, 128, 46, 48 ), - array( 'newTimestampedUID88', 27, 88, 46, 32 ), - ); - } - - /** - * @covers UIDGenerator::newUUIDv4 - */ - public function testUUIDv4() { - for ( $i = 0; $i < 100; $i++ ) { - $id = UIDGenerator::newUUIDv4(); - $this->assertEquals( true, - preg_match( '!^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$!', $id ), - "UID $id has the right format" ); - } - } - - /** - * @covers UIDGenerator::newRawUUIDv4 - */ - public function testRawUUIDv4() { - for ( $i = 0; $i < 100; $i++ ) { - $id = UIDGenerator::newRawUUIDv4(); - $this->assertEquals( true, - preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ), - "UID $id has the right format" ); - } - } - - /** - * @covers UIDGenerator::newRawUUIDv4 - */ - public function testRawUUIDv4QuickRand() { - for ( $i = 0; $i < 100; $i++ ) { - $id = UIDGenerator::newRawUUIDv4( UIDGenerator::QUICK_RAND ); - $this->assertEquals( true, - preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ), - "UID $id has the right format" ); - } - } - -} diff --git a/tests/phpunit/includes/UserMailerTest.php b/tests/phpunit/includes/UserMailerTest.php deleted file mode 100644 index 278edfaa..00000000 --- a/tests/phpunit/includes/UserMailerTest.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php - -class UserMailerTest extends MediaWikiLangTestCase { - - /** - * @covers UserMailer::quotedPrintable - */ - public function testQuotedPrintable() { - $this->assertEquals( - "=?UTF-8?Q?=C4=88u=20legebla=3F?=", - UserMailer::quotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) ); - } - -}
\ No newline at end of file diff --git a/tests/phpunit/includes/UserTest.php b/tests/phpunit/includes/UserTest.php deleted file mode 100644 index ff33e825..00000000 --- a/tests/phpunit/includes/UserTest.php +++ /dev/null @@ -1,237 +0,0 @@ -<?php - -define( 'NS_UNITTEST', 5600 ); -define( 'NS_UNITTEST_TALK', 5601 ); - -/** - * @group Database - */ -class UserTest extends MediaWikiTestCase { - /** - * @var User - */ - protected $user; - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgGroupPermissions' => array(), - 'wgRevokePermissions' => array(), - ) ); - - $this->setUpPermissionGlobals(); - - $this->user = new User; - $this->user->addGroup( 'unittesters' ); - } - - private function setUpPermissionGlobals() { - global $wgGroupPermissions, $wgRevokePermissions; - - # Data for regular $wgGroupPermissions test - $wgGroupPermissions['unittesters'] = array( - 'test' => true, - 'runtest' => true, - 'writetest' => false, - 'nukeworld' => false, - ); - $wgGroupPermissions['testwriters'] = array( - 'test' => true, - 'writetest' => true, - 'modifytest' => true, - ); - - # Data for regular $wgRevokePermissions test - $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 ); - $this->assertNotContains( 'writetest', $rights ); - $this->assertNotContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - - $rights = User::getGroupPermissions( array( 'unittesters', 'testwriters' ) ); - $this->assertContains( 'runtest', $rights ); - $this->assertContains( 'writetest', $rights ); - $this->assertContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - } - - /** - * @covers User::getGroupPermissions - */ - public function testRevokePermissions() { - $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) ); - $this->assertNotContains( 'runtest', $rights ); - $this->assertNotContains( 'writetest', $rights ); - $this->assertNotContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - } - - /** - * @covers User::getRights - */ - public function testUserPermissions() { - $rights = $this->user->getRights(); - $this->assertContains( 'runtest', $rights ); - $this->assertNotContains( 'writetest', $rights ); - $this->assertNotContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - } - - /** - * @dataProvider provideGetGroupsWithPermission - * @covers User::getGroupsWithPermission - */ - public function testGetGroupsWithPermission( $expected, $right ) { - $result = User::getGroupsWithPermission( $right ); - sort( $result ); - sort( $expected ); - - $this->assertEquals( $expected, $result, "Groups with permission $right" ); - } - - public static function provideGetGroupsWithPermission() { - return array( - array( - array( 'unittesters', 'testwriters' ), - 'test' - ), - array( - array( 'unittesters' ), - 'runtest' - ), - array( - array( 'testwriters' ), - 'writetest' - ), - array( - array( 'testwriters' ), - 'modifytest' - ), - ); - } - - /** - * @dataProvider provideUserNames - * @covers User::isValidUserName - */ - public function testIsValidUserName( $username, $result, $message ) { - $this->assertEquals( $this->user->isValidUserName( $username ), $result, $message ); - } - - public static function provideUserNames() { - return array( - array( '', false, 'Empty string' ), - array( ' ', false, 'Blank space' ), - array( 'abcd', false, 'Starts with small letter' ), - array( 'Ab/cd', false, 'Contains slash' ), - array( 'Ab cd', true, 'Whitespace' ), - array( '192.168.1.1', false, 'IP' ), - array( 'User:Abcd', false, 'Reserved Namespace' ), - array( '12abcd232', true, 'Starts with Numbers' ), - array( '?abcd', true, 'Start with ? mark' ), - array( '#abcd', false, 'Start with #' ), - array( 'Abcdകഖഗഘ', true, ' Mixed scripts' ), - array( 'ജോസ്തോമസ്', false, 'ZWNJ- Format control character' ), - array( 'Ab cd', false, ' Ideographic space' ), - ); - } - - /** - * Test, if for all rights a right- message exist, - * which is used on Special:ListGroupRights as help text - * Extensions and core - */ - public function testAllRightsWithMessage() { - //Getting all user rights, for core: User::$mCoreRights, for extensions: $wgAvailableRights - $allRights = User::getAllRights(); - $allMessageKeys = Language::getMessageKeysFor( 'en' ); - - $rightsWithMessage = array(); - foreach ( $allMessageKeys as $message ) { - // === 0: must be at beginning of string (position 0) - if ( strpos( $message, 'right-' ) === 0 ) { - $rightsWithMessage[] = substr( $message, strlen( 'right-' ) ); - } - } - - sort( $allRights ); - sort( $rightsWithMessage ); - - $this->assertEquals( - $allRights, - $rightsWithMessage, - 'Each user rights (core/extensions) has a corresponding right- message.' - ); - } - - /** - * Test User::editCount - * @group medium - * @covers User::getEditCount - */ - public function testEditCount() { - $user = User::newFromName( 'UnitTestUser' ); - $user->loadDefaults(); - $user->addToDatabase(); - - // let the user have a few (3) edits - $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) ); - for ( $i = 0; $i < 3; $i++ ) { - $page->doEdit( (string)$i, 'test', 0, false, $user ); - } - - $user->clearInstanceCache(); - $this->assertEquals( 3, $user->getEditCount(), 'After three edits, the user edit count should be 3' ); - - // increase the edit count and clear the cache - $user->incEditCount(); - - $user->clearInstanceCache(); - $this->assertEquals( 4, $user->getEditCount(), 'After increasing the edit count manually, the user edit count should be 4' ); - } - - /** - * Test changing user options. - * @covers User::setOption - * @covers User::getOption - */ - public function testOptions() { - $user = User::newFromName( 'UnitTestUser' ); - $user->addToDatabase(); - - $user->setOption( 'someoption', 'test' ); - $user->setOption( 'cols', 200 ); - $user->saveSettings(); - - $user = User::newFromName( 'UnitTestUser' ); - $this->assertEquals( 'test', $user->getOption( 'someoption' ) ); - $this->assertEquals( 200, $user->getOption( 'cols' ) ); - } - - /** - * Bug 37963 - * Make sure defaults are loaded when setOption is called. - * @covers User::loadOptions - */ - public function testAnonOptions() { - global $wgDefaultUserOptions; - $this->user->setOption( 'someoption', 'test' ); - $this->assertEquals( $wgDefaultUserOptions['cols'], $this->user->getOption( 'cols' ) ); - $this->assertEquals( 'test', $this->user->getOption( 'someoption' ) ); - } -} diff --git a/tests/phpunit/includes/WebRequestTest.php b/tests/phpunit/includes/WebRequestTest.php deleted file mode 100644 index f8ed14b6..00000000 --- a/tests/phpunit/includes/WebRequestTest.php +++ /dev/null @@ -1,310 +0,0 @@ -<?php - -/** - * @group WebRequest - */ -class WebRequestTest extends MediaWikiTestCase { - protected $oldServer; - - protected function setUp() { - parent::setUp(); - - $this->oldServer = $_SERVER; - } - - protected function tearDown() { - $_SERVER = $this->oldServer; - - parent::tearDown(); - } - - /** - * @dataProvider provideDetectServer - * @covers WebRequest::detectServer - */ - public function testDetectServer( $expected, $input, $description ) { - $_SERVER = $input; - $result = WebRequest::detectServer(); - $this->assertEquals( $expected, $result, $description ); - } - - public static function provideDetectServer() { - return array( - array( - 'http://x', - array( - 'HTTP_HOST' => 'x' - ), - 'Host header' - ), - array( - 'https://x', - array( - 'HTTP_HOST' => 'x', - 'HTTPS' => 'on', - ), - 'Host header with secure' - ), - array( - 'http://x', - array( - 'HTTP_HOST' => 'x', - 'SERVER_PORT' => 80, - ), - 'Default SERVER_PORT', - ), - array( - 'http://x', - array( - 'HTTP_HOST' => 'x', - 'HTTPS' => 'off', - ), - 'Secure off' - ), - array( - 'http://y', - array( - 'SERVER_NAME' => 'y', - ), - 'Server name' - ), - array( - 'http://x', - array( - 'HTTP_HOST' => 'x', - 'SERVER_NAME' => 'y', - ), - 'Host server name precedence' - ), - array( - 'http://[::1]:81', - array( - 'HTTP_HOST' => '[::1]', - 'SERVER_NAME' => '::1', - 'SERVER_PORT' => '81', - ), - 'Apache bug 26005' - ), - array( - 'http://localhost', - array( - 'SERVER_NAME' => '[2001' - ), - 'Kind of like lighttpd per commit message in MW r83847', - ), - array( - 'http://[2a01:e35:2eb4:1::2]:777', - array( - 'SERVER_NAME' => '[2a01:e35:2eb4:1::2]:777' - ), - 'Possible lighttpd environment per bug 14977 comment 13', - ), - ); - } - - /** - * @dataProvider provideGetIP - * @covers WebRequest::getIP - */ - public function testGetIP( $expected, $input, $squid, $xffList, $private, $description ) { - $_SERVER = $input; - $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 ); - } - - public static function provideGetIP() { - return array( - array( - '127.0.0.1', - array( - 'REMOTE_ADDR' => '127.0.0.1' - ), - array(), - array(), - false, - 'Simple IPv4' - ), - array( - '::1', - array( - 'REMOTE_ADDR' => '::1' - ), - array(), - array(), - false, - 'Simple IPv6' - ), - array( - '12.0.0.1', - array( - 'REMOTE_ADDR' => 'abcd:0001:002:03:4:555:6666:7777', - 'HTTP_X_FORWARDED_FOR' => '12.0.0.1, abcd:0001:002:03:4:555:6666:7777', - ), - array( 'ABCD:1:2:3:4:555:6666:7777' ), - array(), - false, - 'IPv6 normalisation' - ), - array( - '12.0.0.3', - array( - 'REMOTE_ADDR' => '12.0.0.1', - 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' - ), - array( '12.0.0.1', '12.0.0.2' ), - array(), - false, - 'With X-Forwaded-For' - ), - array( - '12.0.0.1', - array( - 'REMOTE_ADDR' => '12.0.0.1', - 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' - ), - array(), - array(), - false, - 'With X-Forwaded-For and disallowed server' - ), - 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( '12.0.0.1' ), - array(), - false, - 'With multiple X-Forwaded-For and only one allowed server' - ), - 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(), - false, - 'With X-Forwaded-For and private IP (from cache proxy)' - ), - 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', '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 - */ - public function testGetIpLackOfRemoteAddrThrowAnException() { - $request = new WebRequest(); - # Next call throw an exception about lacking an IP - $request->getIP(); - } - - public static function provideLanguageData() { - return array( - array( '', array(), 'Empty Accept-Language header' ), - array( 'en', array( 'en' => 1 ), 'One language' ), - array( 'en, ar', array( 'en' => 1, 'ar' => 1 ), 'Two languages listed in appearance order.' ), - array( 'zh-cn,zh-tw', array( 'zh-cn' => 1, 'zh-tw' => 1 ), 'Two equally prefered languages, listed in appearance order per rfc3282. Checks c9119' ), - array( 'es, en; q=0.5', array( 'es' => 1, 'en' => '0.5' ), 'Spanish as first language and English and second' ), - array( 'en; q=0.5, es', array( 'es' => 1, 'en' => '0.5' ), 'Less prefered language first' ), - array( 'fr, en; q=0.5, es', array( 'fr' => 1, 'es' => 1, 'en' => '0.5' ), 'Three languages' ), - array( 'en; q=0.5, es', array( 'es' => 1, 'en' => '0.5' ), 'Two languages' ), - array( 'en, zh;q=0', array( 'en' => 1 ), "It's Chinese to me" ), - array( 'es; q=1, pt;q=0.7, it; q=0.6, de; q=0.1, ru;q=0', array( 'es' => '1', 'pt' => '0.7', 'it' => '0.6', 'de' => '0.1' ), 'Preference for romance languages' ), - array( 'en-gb, en-us; q=1', array( 'en-gb' => 1, 'en-us' => '1' ), 'Two equally prefered English variants' ), - ); - } - - /** - * @dataProvider provideLanguageData - * @covers WebRequest::getAcceptLang - */ - 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 deleted file mode 100644 index e0d786b9..00000000 --- a/tests/phpunit/includes/WikiPageTest.php +++ /dev/null @@ -1,1074 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- important, causes temporary tables to be used instead of the real database - * @group medium - **/ -class WikiPageTest extends MediaWikiLangTestCase { - - protected $pages_to_delete; - - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - - $this->tablesUsed = array_merge( - $this->tablesUsed, - array( 'page', - 'revision', - 'text', - - 'recentchanges', - 'logging', - - 'page_props', - 'pagelinks', - 'categorylinks', - 'langlinks', - 'externallinks', - 'imagelinks', - 'templatelinks', - 'iwlinks' ) ); - } - - protected function setUp() { - parent::setUp(); - $this->pages_to_delete = array(); - - LinkCache::singleton()->clear(); # avoid cached redirect status, etc - } - - protected function tearDown() { - foreach ( $this->pages_to_delete as $p ) { - /* @var $p WikiPage */ - - try { - if ( $p->exists() ) { - $p->doDeleteArticle( "testing done." ); - } - } catch ( MWException $ex ) { - // fail silently - } - } - parent::tearDown(); - } - - /** - * @param Title $title - * @param String $model - * @return WikiPage - */ - protected function newPage( $title, $model = null ) { - if ( is_string( $title ) ) { - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( $title, $ns ); - } - - $p = new WikiPage( $title ); - - $this->pages_to_delete[] = $p; - - return $p; - } - - /** - * @param String|Title|WikiPage $page - * @param String $text - * @param int $model - * - * @return WikiPage - */ - protected function createPage( $page, $text, $model = null ) { - if ( is_string( $page ) || $page instanceof Title ) { - $page = $this->newPage( $page, $model ); - } - - $content = ContentHandler::makeContent( $text, $page->getTitle(), $model ); - $page->doEditContent( $content, "testing", EDIT_NEW ); - - return $page; - } - - /** - * @covers WikiPage::doEditContent - */ - public function testDoEditContent() { - $page = $this->newPage( "WikiPageTest_testDoEditContent" ); - $title = $page->getTitle(); - - $content = ContentHandler::makeContent( "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam " - . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.", - $title, CONTENT_MODEL_WIKITEXT ); - - $page->doEditContent( $content, "[[testing]] 1" ); - - $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" ); - $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" ); - $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" ); - $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" ); - - $id = $page->getId(); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' ); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getContent(); - $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' ); - - # ------------------------ - $content = ContentHandler::makeContent( "At vero eos et accusam et justo duo [[dolores]] et ea rebum. " - . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.", - $title, CONTENT_MODEL_WIKITEXT ); - - $page->doEditContent( $content, "testing 2" ); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getContent(); - $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $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" ); - $this->hideDeprecated( "Revision::getText" ); - - //NOTE: assume help namespace will default to wikitext - $title = Title::newFromText( "Help:WikiPageTest_testDoEdit" ); - - $page = $this->newPage( $title ); - - $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam " - . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat."; - - $page->doEdit( $text, "[[testing]] 1" ); - - $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" ); - $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" ); - $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" ); - $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" ); - - $id = $page->getId(); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' ); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getText(); - $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' ); - - # ------------------------ - $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. " - . "Stet clita kasd [[gubergren]], no sea takimata sanctus est."; - - $page->doEdit( $text, "testing 2" ); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getText(); - $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' ); - } - - /** - * @covers WikiPage::doQuickEdit - */ - public function testDoQuickEdit() { - global $wgUser; - - $this->hideDeprecated( "WikiPage::doQuickEdit" ); - - //NOTE: assume help namespace will default to wikitext - $page = $this->createPage( "Help:WikiPageTest_testDoQuickEdit", "original text" ); - - $text = "quick text"; - $page->doQuickEdit( $text, $wgUser, "testing q" ); - - # --------------------- - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( $text, $page->getText() ); - } - - /** - * @covers WikiPage::doQuickEditContent - */ - public function testDoQuickEditContent() { - global $wgUser; - - $page = $this->createPage( "WikiPageTest_testDoQuickEditContent", "original text", CONTENT_MODEL_WIKITEXT ); - - $content = ContentHandler::makeContent( "quick text", $page->getTitle(), CONTENT_MODEL_WIKITEXT ); - $page->doQuickEditContent( $content, $wgUser, "testing q" ); - - # --------------------- - $page = new WikiPage( $page->getTitle() ); - $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(); - - $page->doDeleteArticle( "testing deletion" ); - - $this->assertFalse( $page->getTitle()->getArticleID() > 0, "Title object should now have page id 0" ); - $this->assertFalse( $page->getId() > 0, "WikiPage should now have page id 0" ); - $this->assertFalse( $page->exists(), "WikiPage::exists should return false after page was deleted" ); - $this->assertNull( $page->getContent(), "WikiPage::getContent should return null after page was deleted" ); - $this->assertFalse( $page->getText(), "WikiPage::getText should return false after page was deleted" ); - - $t = Title::newFromText( $page->getTitle()->getPrefixedText() ); - $this->assertFalse( $t->exists(), "Title::exists should return false after page was deleted" ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $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(); - - $page->doDeleteUpdates( $id ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' ); - } - - /** - * @covers WikiPage::getRevision - */ - public function testGetRevision() { - $page = $this->newPage( "WikiPageTest_testGetRevision" ); - - $rev = $page->getRevision(); - $this->assertNull( $rev ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - - $rev = $page->getRevision(); - - $this->assertEquals( $page->getLatest(), $rev->getId() ); - $this->assertEquals( "some text", $rev->getContent()->getNativeData() ); - } - - /** - * @covers WikiPage::getContent - */ - public function testGetContent() { - $page = $this->newPage( "WikiPageTest_testGetContent" ); - - $content = $page->getContent(); - $this->assertNull( $content ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - - $content = $page->getContent(); - $this->assertEquals( "some text", $content->getNativeData() ); - } - - /** - * @covers WikiPage::getText - */ - public function testGetText() { - $this->hideDeprecated( "WikiPage::getText" ); - - $page = $this->newPage( "WikiPageTest_testGetText" ); - - $text = $page->getText(); - $this->assertFalse( $text ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - - $text = $page->getText(); - $this->assertEquals( "some text", $text ); - } - - /** - * @covers WikiPage::getRawText - */ - public function testGetRawText() { - $this->hideDeprecated( "WikiPage::getRawText" ); - - $page = $this->newPage( "WikiPageTest_testGetRawText" ); - - $text = $page->getRawText(); - $this->assertFalse( $text ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - - $text = $page->getRawText(); - $this->assertEquals( "some text", $text ); - } - - /** - * @covers WikiPage::getContentModel - */ - public function testGetContentModel() { - global $wgContentHandlerUseDB; - - if ( !$wgContentHandlerUseDB ) { - $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); - } - - $page = $this->createPage( "WikiPageTest_testGetContentModel", "some text", CONTENT_MODEL_JAVASCRIPT ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() ); - } - - /** - * @covers WikiPage::getContentHandler - */ - public function testGetContentHandler() { - global $wgContentHandlerUseDB; - - if ( !$wgContentHandlerUseDB ) { - $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); - } - - $page = $this->createPage( "WikiPageTest_testGetContentHandler", "some text", CONTENT_MODEL_JAVASCRIPT ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( 'JavaScriptContentHandler', get_class( $page->getContentHandler() ) ); - } - - /** - * @covers WikiPage::exists - */ - public function testExists() { - $page = $this->newPage( "WikiPageTest_testExists" ); - $this->assertFalse( $page->exists() ); - - # ----------------- - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - $this->assertTrue( $page->exists() ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertTrue( $page->exists() ); - - # ----------------- - $page->doDeleteArticle( "done testing" ); - $this->assertFalse( $page->exists() ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertFalse( $page->exists() ); - } - - public static function provideHasViewableContent() { - return array( - array( 'WikiPageTest_testHasViewableContent', false, true ), - array( 'Special:WikiPageTest_testHasViewableContent', false ), - array( 'MediaWiki:WikiPageTest_testHasViewableContent', false ), - array( 'Special:Userlogin', true ), - array( 'MediaWiki:help', true ), - ); - } - - /** - * @dataProvider provideHasViewableContent - * @covers WikiPage::hasViewableContent - */ - public function testHasViewableContent( $title, $viewable, $create = false ) { - $page = $this->newPage( $title ); - $this->assertEquals( $viewable, $page->hasViewableContent() ); - - if ( $create ) { - $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT ); - $this->assertTrue( $page->hasViewableContent() ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertTrue( $page->hasViewableContent() ); - } - } - - public static function provideGetRedirectTarget() { - return array( - array( 'WikiPageTest_testGetRedirectTarget_1', CONTENT_MODEL_WIKITEXT, "hello world", null ), - array( 'WikiPageTest_testGetRedirectTarget_2', CONTENT_MODEL_WIKITEXT, "#REDIRECT [[hello world]]", "Hello world" ), - ); - } - - /** - * @dataProvider provideGetRedirectTarget - * @covers WikiPage::getRedirectTarget - */ - public function testGetRedirectTarget( $title, $model, $text, $target ) { - $page = $this->createPage( $title, $text, $model ); - - # sanity check, because this test seems to fail for no reason for some people. - $c = $page->getContent(); - $this->assertEquals( 'WikitextContent', get_class( $c ) ); - - # now, test the actual redirect - $t = $page->getRedirectTarget(); - $this->assertEquals( $target, is_null( $t ) ? null : $t->getPrefixedText() ); - } - - /** - * @dataProvider provideGetRedirectTarget - * @covers WikiPage::isRedirect - */ - public function testIsRedirect( $title, $model, $text, $target ) { - $page = $this->createPage( $title, $text, $model ); - $this->assertEquals( !is_null( $target ), $page->isRedirect() ); - } - - public static function provideIsCountable() { - return array( - - // any - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - '', - 'any', - true - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo', - 'any', - true - ), - - // comma - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo', - 'comma', - false - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo, bar', - 'comma', - true - ), - - // link - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo', - 'link', - false - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo [[bar]]', - 'link', - true - ), - - // redirects - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - '#REDIRECT [[bar]]', - 'any', - false - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - '#REDIRECT [[bar]]', - 'comma', - false - ), - array( 'WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - '#REDIRECT [[bar]]', - 'link', - false - ), - - // not a content namespace - array( 'Talk:WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo', - 'any', - false - ), - array( 'Talk:WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo, bar', - 'comma', - false - ), - array( 'Talk:WikiPageTest_testIsCountable', - CONTENT_MODEL_WIKITEXT, - 'Foo [[bar]]', - 'link', - false - ), - - // not a content namespace, different model - array( 'MediaWiki:WikiPageTest_testIsCountable.js', - null, - 'Foo', - 'any', - false - ), - array( 'MediaWiki:WikiPageTest_testIsCountable.js', - null, - 'Foo, bar', - 'comma', - false - ), - array( 'MediaWiki:WikiPageTest_testIsCountable.js', - null, - 'Foo [[bar]]', - 'link', - false - ), - ); - } - - - /** - * @dataProvider provideIsCountable - * @covers WikiPage::isCountable - */ - public function testIsCountable( $title, $model, $text, $mode, $expected ) { - global $wgContentHandlerUseDB; - - $this->setMwGlobals( 'wgArticleCountMethod', $mode ); - - $title = Title::newFromText( $title ); - - if ( !$wgContentHandlerUseDB && $model && ContentHandler::getDefaultModelFor( $title ) != $model ) { - $this->markTestSkipped( "Can not use non-default content model $model for " - . $title->getPrefixedDBkey() . " with \$wgContentHandlerUseDB disabled." ); - } - - $page = $this->createPage( $title, $text, $model ); - $hasLinks = wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1, - array( 'pl_from' => $page->getId() ), __METHOD__ ); - - $editInfo = $page->prepareContentForEdit( $page->getContent() ); - - $v = $page->isCountable(); - $w = $page->isCountable( $editInfo ); - - $this->assertEquals( $expected, $v, "isCountable( null ) returned unexpected value " . var_export( $v, true ) - . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); - - $this->assertEquals( $expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true ) - . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); - } - - public static function provideGetParserOutput() { - return array( - array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ), - // @todo more...? - ); - } - - /** - * @dataProvider provideGetParserOutput - * @covers WikiPage::getParserOutput - */ - public function testGetParserOutput( $model, $text, $expectedHtml ) { - $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text, $model ); - - $opt = $page->makeParserOptions( 'canonical' ); - $po = $page->getParserOutput( $opt ); - $text = $po->getText(); - - $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments - $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us - - $this->assertEquals( $expectedHtml, $text ); - - return $po; - } - - /** - * @covers WikiPage::getParserOutput - */ - public function testGetParserOutput_nonexisting() { - static $count = 0; - $count++; - - $page = new WikiPage( new Title( "WikiPageTest_testGetParserOutput_nonexisting_$count" ) ); - - $opt = new ParserOptions(); - $po = $page->getParserOutput( $opt ); - - $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 - - $this->assertFalse( $po, "getParserOutput() shall return false for non-existing revisions." ); - } - - static $sections = - - "Intro - -== stuff == -hello world - -== test == -just a test - -== foo == -more stuff -"; - - - public function dataReplaceSection() { - //NOTE: assume the Help namespace to contain wikitext - return array( - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "0", - "No more", - null, - trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) ) - ), - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "", - "No more", - null, - "No more" - ), - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "2", - "== TEST ==\nmore fun", - null, - trim( preg_replace( '/^== test ==.*== foo ==/sm', - "== TEST ==\nmore fun\n\n== foo ==", - WikiPageTest::$sections ) ) - ), - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "8", - "No more", - null, - trim( WikiPageTest::$sections ) - ), - array( 'Help:WikiPageTest_testReplaceSection', - CONTENT_MODEL_WIKITEXT, - WikiPageTest::$sections, - "new", - "No more", - "New", - trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more" - ), - ); - } - - /** - * @dataProvider dataReplaceSection - * @covers WikiPage::replaceSection - */ - public function testReplaceSection( $title, $model, $text, $section, $with, $sectionTitle, $expected ) { - $this->hideDeprecated( "WikiPage::replaceSection" ); - - $page = $this->createPage( $title, $text, $model ); - $text = $page->replaceSection( $section, $with, $sectionTitle ); - $text = trim( $text ); - - $this->assertEquals( $expected, $text ); - } - - /** - * @dataProvider dataReplaceSection - * @covers WikiPage::replaceSectionContent - */ - public function testReplaceSectionContent( $title, $model, $text, $section, $with, $sectionTitle, $expected ) { - $page = $this->createPage( $title, $text, $model ); - - $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() ); - $c = $page->replaceSectionContent( $section, $content, $sectionTitle ); - - $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getNativeData() ) ); - } - - /* @todo FIXME: fix this! - public function testGetUndoText() { - $this->checkHasDiff3(); - - $text = "one"; - $page = $this->createPage( "WikiPageTest_testGetUndoText", $text ); - $rev1 = $page->getRevision(); - - $text .= "\n\ntwo"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two"); - $rev2 = $page->getRevision(); - - $text .= "\n\nthree"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three"); - $rev3 = $page->getRevision(); - - $text .= "\n\nfour"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four"); - $rev4 = $page->getRevision(); - - $text .= "\n\nfive"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five"); - $rev5 = $page->getRevision(); - - $text .= "\n\nsix"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six"); - $rev6 = $page->getRevision(); - - $undo6 = $page->getUndoText( $rev6 ); - if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" ); - $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 ); - - $undo3 = $page->getUndoText( $rev4, $rev2 ); - if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" ); - $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 ); - - $undo2 = $page->getUndoText( $rev2 ); - if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" ); - $this->assertEquals( "one\n\nfive", $undo2 ); - } - */ - - /** - * @todo FIXME: this is a better rollback test than the one below, but it keeps failing in jenkins for some reason. - */ - public function broken_testDoRollback() { - $admin = new User(); - $admin->setName( "Admin" ); - - $text = "one"; - $page = $this->newPage( "WikiPageTest_testDoRollback" ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), - "section one", EDIT_NEW, false, $admin ); - - $user1 = new User(); - $user1->setName( "127.0.1.11" ); - $text .= "\n\ntwo"; - $page = new WikiPage( $page->getTitle() ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), - "adding section two", 0, false, $user1 ); - - $user2 = new User(); - $user2->setName( "127.0.2.13" ); - $text .= "\n\nthree"; - $page = new WikiPage( $page->getTitle() ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), - "adding section three", 0, false, $user2 ); - - # we are having issues with doRollback spuriously failing. apparently the last revision somehow goes missing - # or not committed under some circumstances. so, make sure the last revision has the right user name. - $dbr = wfGetDB( DB_SLAVE ); - $this->assertEquals( 3, Revision::countByPageId( $dbr, $page->getId() ) ); - - $page = new WikiPage( $page->getTitle() ); - $rev3 = $page->getRevision(); - $this->assertEquals( '127.0.2.13', $rev3->getUserText() ); - - $rev2 = $rev3->getPrevious(); - $this->assertEquals( '127.0.1.11', $rev2->getUserText() ); - - $rev1 = $rev2->getPrevious(); - $this->assertEquals( 'Admin', $rev1->getUserText() ); - - # now, try the actual rollback - $admin->addGroup( "sysop" ); #XXX: make the test user a sysop... - $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user2->getName() ), null ); - $errors = $page->doRollback( $user2->getName(), "testing revert", $token, false, $details, $admin ); - - if ( $errors ) { - $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) ); - } - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(), - "rollback did not revert to the correct revision" ); - $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() ); - } - - /** - * @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(); - $admin->setName( "Admin" ); - - $text = "one"; - $page = $this->newPage( "WikiPageTest_testDoRollback" ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ), - "section one", EDIT_NEW, false, $admin ); - $rev1 = $page->getRevision(); - - $user1 = new User(); - $user1->setName( "127.0.1.11" ); - $text .= "\n\ntwo"; - $page = new WikiPage( $page->getTitle() ); - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ), - "adding section two", 0, false, $user1 ); - - # now, try the rollback - $admin->addGroup( "sysop" ); #XXX: make the test user a sysop... - $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null ); - $errors = $page->doRollback( $user1->getName(), "testing revert", $token, false, $details, $admin ); - - if ( $errors ) { - $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) ); - } - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(), - "rollback did not revert to the correct revision" ); - $this->assertEquals( "one", $page->getContent()->getNativeData() ); - } - - public static function provideGetAutosummary() { - return array( - array( - 'Hello there, world!', - '#REDIRECT [[Foo]]', - 0, - '/^Redirected page .*Foo/' - ), - - array( - null, - 'Hello world!', - EDIT_NEW, - '/^Created page .*Hello/' - ), - - array( - 'Hello there, world!', - '', - 0, - '/^Blanked/' - ), - - array( - 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut - labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et - ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', - 'Hello world!', - 0, - '/^Replaced .*Hello/' - ), - - array( - 'foo', - 'bar', - 0, - '/^$/' - ), - ); - } - - /** - * @dataProvider provideGetAutoSummary - * @covers WikiPage::getAutosummary - */ - public function testGetAutosummary( $old, $new, $flags, $expected ) { - $this->hideDeprecated( "WikiPage::getAutosummary" ); - - $page = $this->newPage( "WikiPageTest_testGetAutosummary" ); - - $summary = $page->getAutosummary( $old, $new, $flags ); - - $this->assertTrue( (bool)preg_match( $expected, $summary ), - "Autosummary didn't match expected pattern $expected: $summary" ); - } - - public static function provideGetAutoDeleteReason() { - return array( - array( - array(), - false, - false - ), - - array( - array( - array( "first edit", null ), - ), - "/first edit.*only contributor/", - false - ), - - array( - array( - array( "first edit", null ), - array( "second edit", null ), - ), - "/second edit.*only contributor/", - true - ), - - array( - array( - array( "first edit", "127.0.2.22" ), - array( "second edit", "127.0.3.33" ), - ), - "/second edit/", - true - ), - - array( - array( - array( "first edit: " - . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam " - . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. " - . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea " - . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ), - ), - '/first edit:.*\.\.\."/', - false - ), - - array( - array( - array( "first edit", "127.0.2.22" ), - array( "", "127.0.3.33" ), - ), - "/before blanking.*first edit/", - true - ), - - ); - } - - /** - * @dataProvider provideGetAutoDeleteReason - * @covers WikiPage::getAutoDeleteReason - */ - public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) { - global $wgUser; - - //NOTE: assume Help namespace to contain wikitext - $page = $this->newPage( "Help:WikiPageTest_testGetAutoDeleteReason" ); - - $c = 1; - - foreach ( $edits as $edit ) { - $user = new User(); - - if ( !empty( $edit[1] ) ) { - $user->setName( $edit[1] ); - } else { - $user = $wgUser; - } - - $content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() ); - - $page->doEditContent( $content, "test edit $c", $c < 2 ? EDIT_NEW : 0, false, $user ); - - $c += 1; - } - - $reason = $page->getAutoDeleteReason( $hasHistory ); - - if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) { - $this->assertEquals( $expectedResult, $reason ); - } else { - $this->assertTrue( (bool)preg_match( $expectedResult, $reason ), - "Autosummary didn't match expected pattern $expectedResult: $reason" ); - } - - $this->assertEquals( $expectedHistory, $hasHistory, - "expected \$hasHistory to be " . var_export( $expectedHistory, true ) ); - - $page->doDeleteArticle( "done" ); - } - - public static function providePreSaveTransform() { - return array( - array( 'hello this is ~~~', - "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]", - ), - array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - ), - ); - } - - /** - * @dataProvider providePreSaveTransform - * @covers WikiPage::preSaveTransform - */ - public function testPreSaveTransform( $text, $expected ) { - $this->hideDeprecated( 'WikiPage::preSaveTransform' ); - $user = new User(); - $user->setName( "127.0.0.1" ); - - //NOTE: assume Help namespace to contain wikitext - $page = $this->newPage( "Help:WikiPageTest_testPreloadTransform" ); - $text = $page->preSaveTransform( $text, $user ); - - $this->assertEquals( $expected, $text ); - } -} diff --git a/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php b/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php deleted file mode 100644 index 2a723e85..00000000 --- a/tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- important, causes temporary tables to be used instead of the real database - */ -class WikiPageTest_ContentHandlerUseDB extends WikiPageTest { - - protected function setUp() { - parent::setUp(); - $this->setMwGlobals( 'wgContentHandlerUseDB', false ); - - $dbw = wfGetDB( DB_MASTER ); - - $page_table = $dbw->tableName( 'page' ); - $revision_table = $dbw->tableName( 'revision' ); - $archive_table = $dbw->tableName( 'archive' ); - - if ( $dbw->fieldExists( $page_table, 'page_content_model' ) ) { - $dbw->query( "alter table $page_table drop column page_content_model" ); - $dbw->query( "alter table $revision_table drop column rev_content_model" ); - $dbw->query( "alter table $revision_table drop column rev_content_format" ); - $dbw->query( "alter table $archive_table drop column ar_content_model" ); - $dbw->query( "alter table $archive_table drop column ar_content_format" ); - } - } - - /** - * @covers WikiPage::getContentModel - */ - public function testGetContentModel() { - $page = $this->createPage( "WikiPageTest_testGetContentModel", "some text", CONTENT_MODEL_JAVASCRIPT ); - - $page = new WikiPage( $page->getTitle() ); - - // NOTE: since the content model is not recorded in the database, - // we expect to get the default, namely CONTENT_MODEL_WIKITEXT - $this->assertEquals( CONTENT_MODEL_WIKITEXT, $page->getContentModel() ); - } - - /** - * @covers WikiPage::getContentHandler - */ - public function testGetContentHandler() { - $page = $this->createPage( "WikiPageTest_testGetContentHandler", "some text", CONTENT_MODEL_JAVASCRIPT ); - - // NOTE: since the content model is not recorded in the database, - // we expect to get the default, namely CONTENT_MODEL_WIKITEXT - $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 deleted file mode 100644 index 161468e2..00000000 --- a/tests/phpunit/includes/XmlJsTest.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php - -/** - * @group Xml - */ -class XmlJs extends MediaWikiTestCase { - - /** - * @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 deleted file mode 100644 index 56d28b54..00000000 --- a/tests/phpunit/includes/XmlSelectTest.php +++ /dev/null @@ -1,173 +0,0 @@ -<?php - -/** - * @group Xml - */ -class XmlSelectTest extends MediaWikiTestCase { - - /** - * @var XmlSelect - */ - protected $select; - - protected function setUp() { - parent::setUp(); - $this->setMwGlobals( array( - 'wgWellFormedXml' => true, - ) ); - $this->select = new XmlSelect(); - } - - protected function tearDown() { - parent::tearDown(); - $this->select = null; - } - - /** - * @covers XmlSelect::__construct - */ - public function testConstructWithoutParameters() { - $this->assertEquals( '<select></select>', $this->select->getHTML() ); - } - - /** - * 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 ); - $this->assertEquals( $expected, $this->select->getHTML() ); - } - - /** - * Provide parameters for testConstructParameters() which use three - * parameters: - * - $name (default: false) - * - $id (default: false) - * - $default (default: false) - * Provides a fourth parameters representing the expected HTML output - */ - public static function provideConstructionParameters() { - return array( - /** - * Values are set following a 3-bit Gray code where two successive - * values differ by only one value. - * See http://en.wikipedia.org/wiki/Gray_code - */ - # $name $id $default - array( false, false, false, '<select></select>' ), - array( false, false, 'foo', '<select></select>' ), - array( false, 'id', 'foo', '<select id="id"></select>' ), - array( false, 'id', false, '<select id="id"></select>' ), - array( 'name', 'id', false, '<select name="name" id="id"></select>' ), - array( 'name', 'id', 'foo', '<select name="name" id="id"></select>' ), - array( 'name', false, 'foo', '<select name="name"></select>' ), - array( 'name', false, false, '<select name="name"></select>' ), - ); - } - - /** - * @covers XmlSelect::addOption - */ - public function testAddOption() { - $this->select->addOption( 'foo' ); - $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() ); - } - - /** - * @covers XmlSelect::addOption - */ - public function testAddOptionWithDefault() { - $this->select->addOption( 'foo', true ); - $this->assertEquals( '<select><option value="1">foo</option></select>', $this->select->getHTML() ); - } - - /** - * @covers XmlSelect::addOption - */ - public function testAddOptionWithFalse() { - $this->select->addOption( 'foo', false ); - $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() ); - } - - /** - * @covers XmlSelect::addOption - */ - public function testAddOptionWithValueZero() { - $this->select->addOption( 'foo', 0 ); - $this->assertEquals( '<select><option value="0">foo</option></select>', $this->select->getHTML() ); - } - - /** - * @covers XmlSelect::setDefault - */ - public function testSetDefault() { - $this->select->setDefault( 'bar1' ); - $this->select->addOption( 'foo1' ); - $this->select->addOption( 'bar1' ); - $this->select->addOption( 'foo2' ); - $this->assertEquals( - '<select><option value="foo1">foo1</option>' . "\n" . - '<option value="bar1" selected="">bar1</option>' . "\n" . - '<option value="foo2">foo2</option></select>', $this->select->getHTML() ); - } - - /** - * 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' ); - $this->select->addOption( 'bar1' ); - $this->select->addOption( 'foo2' ); - $this->select->setDefault( 'bar1' ); # setting default after adding options - $this->assertEquals( - '<select><option value="foo1">foo1</option>' . "\n" . - '<option value="bar1" selected="">bar1</option>' . "\n" . - '<option value="foo2">foo2</option></select>', $this->select->getHTML() ); - } - - /** - * @covers XmlSelect::setAttribute - * @covers XmlSelect::getAttribute - */ - public function testGetAttributes() { - # create some attributes - $this->select->setAttribute( 'dummy', 0x777 ); - $this->select->setAttribute( 'string', 'euro €' ); - $this->select->setAttribute( 1911, 'razor' ); - - # verify we can retrieve them - $this->assertEquals( - $this->select->getAttribute( 'dummy' ), - 0x777 - ); - $this->assertEquals( - $this->select->getAttribute( 'string' ), - 'euro €' - ); - $this->assertEquals( - $this->select->getAttribute( 1911 ), - 'razor' - ); - - # inexistant keys should give us 'null' - $this->assertEquals( - $this->select->getAttribute( 'I DO NOT EXIT' ), - null - ); - - # verify string / integer - $this->assertEquals( - $this->select->getAttribute( '1911' ), - 'razor' - ); - $this->assertEquals( - $this->select->getAttribute( 'dummy' ), - 0x777 - ); - } -} diff --git a/tests/phpunit/includes/XmlTest.php b/tests/phpunit/includes/XmlTest.php deleted file mode 100644 index 8205029f..00000000 --- a/tests/phpunit/includes/XmlTest.php +++ /dev/null @@ -1,402 +0,0 @@ -<?php - -/** - * @group Xml - */ -class XmlTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $langObj = Language::factory( 'en' ); - $langObj->setNamespaces( array( - -2 => 'Media', - -1 => 'Special', - 0 => '', - 1 => 'Talk', - 2 => 'User', - 3 => 'User_talk', - 4 => 'MyWiki', - 5 => 'MyWiki_Talk', - 6 => 'File', - 7 => 'File_talk', - 8 => 'MediaWiki', - 9 => 'MediaWiki_talk', - 10 => 'Template', - 11 => 'Template_talk', - 100 => 'Custom', - 101 => 'Custom_talk', - ) ); - - $this->setMwGlobals( array( - 'wgLang' => $langObj, - 'wgWellFormedXml' => true, - ) ); - } - - /** - * @covers Xml::expandAttributes - */ - public function testExpandAttributes() { - $this->assertNull( Xml::expandAttributes( null ), - 'Converting a null list of attributes' - ); - $this->assertEquals( '', Xml::expandAttributes( array() ), - 'Converting an empty list of attributes' - ); - } - - /** - * @covers Xml::expandAttributes - */ - public function testExpandAttributesException() { - $this->setExpectedException( 'MWException' ); - Xml::expandAttributes( 'string' ); - } - - /** - * @covers Xml::element - */ - public function testElementOpen() { - $this->assertEquals( - '<element>', - Xml::element( 'element', null, null ), - 'Opening element with no attributes' - ); - } - - /** - * @covers Xml::element - */ - public function testElementEmpty() { - $this->assertEquals( - '<element />', - Xml::element( 'element', null, '' ), - 'Terminated empty element' - ); - } - - /** - * @covers Xml::input - */ - public function testElementInputCanHaveAValueOfZero() { - $this->assertEquals( - '<input name="name" value="0" />', - Xml::input( 'name', false, 0 ), - 'Input with a value of 0 (bug 23797)' - ); - } - - /** - * @covers Xml::element - */ - public function testElementEscaping() { - $this->assertEquals( - '<element>hello <there> you & you</element>', - Xml::element( 'element', null, 'hello <there> you & you' ), - 'Element with no attributes and content that needs escaping' - ); - } - - /** - * @covers Xml::escapeTagsOnly - */ - public function testEscapeTagsOnly() { - $this->assertEquals( '"><', Xml::escapeTagsOnly( '"><' ), - 'replace " > and < with their HTML entitites' - ); - } - - /** - * @covers Xml::element - */ - public function testElementAttributes() { - $this->assertEquals( - '<element key="value" <>="<>">', - Xml::element( 'element', array( 'key' => 'value', '<>' => '<>' ), null ), - 'Element attributes, keys are not escaped' - ); - } - - /** - * @covers Xml::openElement - */ - public function testOpenElement() { - $this->assertEquals( - '<element k="v">', - Xml::openElement( 'element', array( 'k' => 'v' ) ), - 'openElement() shortcut' - ); - } - - /** - * @covers Xml::closeElement - */ - public function testCloseElement() { - $this->assertEquals( '</element>', Xml::closeElement( 'element' ), 'closeElement() shortcut' ); - } - - /** - * @covers Xml::dateMenu - */ - public function testDateMenu() { - $curYear = intval( gmdate( 'Y' ) ); - $prevYear = $curYear - 1; - - $curMonth = intval( gmdate( 'n' ) ); - $prevMonth = $curMonth - 1; - if ( $prevMonth == 0 ) { - $prevMonth = 12; - } - $nextMonth = $curMonth + 1; - if ( $nextMonth == 13 ) { - $nextMonth = 1; - } - - $this->assertEquals( - '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" . - '<option value="1">January</option>' . "\n" . - '<option value="2" selected="">February</option>' . "\n" . - '<option value="3">March</option>' . "\n" . - '<option value="4">April</option>' . "\n" . - '<option value="5">May</option>' . "\n" . - '<option value="6">June</option>' . "\n" . - '<option value="7">July</option>' . "\n" . - '<option value="8">August</option>' . "\n" . - '<option value="9">September</option>' . "\n" . - '<option value="10">October</option>' . "\n" . - '<option value="11">November</option>' . "\n" . - '<option value="12">December</option></select>', - Xml::dateMenu( 2011, 02 ), - "Date menu for february 2011" - ); - $this->assertEquals( - '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" . - '<option value="1">January</option>' . "\n" . - '<option value="2">February</option>' . "\n" . - '<option value="3">March</option>' . "\n" . - '<option value="4">April</option>' . "\n" . - '<option value="5">May</option>' . "\n" . - '<option value="6">June</option>' . "\n" . - '<option value="7">July</option>' . "\n" . - '<option value="8">August</option>' . "\n" . - '<option value="9">September</option>' . "\n" . - '<option value="10">October</option>' . "\n" . - '<option value="11">November</option>' . "\n" . - '<option value="12">December</option></select>', - Xml::dateMenu( 2011, -1 ), - "Date menu with negative month for 'All'" - ); - $this->assertEquals( - Xml::dateMenu( $curYear, $curMonth ), - Xml::dateMenu( '', $curMonth ), - "Date menu year is the current one when not specified" - ); - - $wantedYear = $nextMonth == 1 ? $curYear : $prevYear; - $this->assertEquals( - Xml::dateMenu( $wantedYear, $nextMonth ), - Xml::dateMenu( '', $nextMonth ), - "Date menu next month is 11 months ago" - ); - - $this->assertEquals( - '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" . - '<option value="1">January</option>' . "\n" . - '<option value="2">February</option>' . "\n" . - '<option value="3">March</option>' . "\n" . - '<option value="4">April</option>' . "\n" . - '<option value="5">May</option>' . "\n" . - '<option value="6">June</option>' . "\n" . - '<option value="7">July</option>' . "\n" . - '<option value="8">August</option>' . "\n" . - '<option value="9">September</option>' . "\n" . - '<option value="10">October</option>' . "\n" . - '<option value="11">November</option>' . "\n" . - '<option value="12">December</option></select>', - Xml::dateMenu( '', '' ), - "Date menu with neither year or month" - ); - } - - /** - * @covers Xml::textarea - */ - public function testTextareaNoContent() { - $this->assertEquals( - '<textarea name="name" id="name" cols="40" rows="5"></textarea>', - Xml::textarea( 'name', '' ), - 'textarea() with not content' - ); - } - - /** - * @covers Xml::textarea - */ - public function testTextareaAttribs() { - $this->assertEquals( - '<textarea name="name" id="name" cols="20" rows="10"><txt></textarea>', - Xml::textarea( 'name', '<txt>', 20, 10 ), - 'textarea() with custom attribs' - ); - } - - /** - * @covers Xml::label - */ - public function testLabelCreation() { - $this->assertEquals( - '<label for="id">name</label>', - Xml::label( 'name', 'id' ), - 'label() with no attribs' - ); - } - - /** - * @covers Xml::label - */ - public function testLabelAttributeCanOnlyBeClassOrTitle() { - $this->assertEquals( - '<label for="id">name</label>', - Xml::label( 'name', 'id', array( 'generated' => true ) ), - 'label() can not be given a generated attribute' - ); - $this->assertEquals( - '<label for="id" class="nice">name</label>', - Xml::label( 'name', 'id', array( 'class' => 'nice' ) ), - 'label() can get a class attribute' - ); - $this->assertEquals( - '<label for="id" title="nice tooltip">name</label>', - Xml::label( 'name', 'id', array( 'title' => 'nice tooltip' ) ), - 'label() can get a title attribute' - ); - $this->assertEquals( - '<label for="id" class="nice" title="nice tooltip">name</label>', - Xml::label( 'name', 'id', array( - 'generated' => true, - 'class' => 'nice', - 'title' => 'nice tooltip', - 'anotherattr' => 'value', - ) - ), - 'label() skip all attributes but "class" and "title"' - ); - } - - /** - * @covers Xml::languageSelector - */ - public function testLanguageSelector() { - $select = Xml::languageSelector( 'en', true, null, - array( 'id' => 'testlang' ), wfMessage( 'yourlanguage' ) ); - $this->assertEquals( - '<label for="testlang">Language:</label>', - $select[0] - ); - } - - /** - * @covers Xml::escapeJsString - */ - public function testEscapeJsStringSpecialChars() { - $this->assertEquals( - '\\\\\r\n', - Xml::escapeJsString( "\\\r\n" ), - 'escapeJsString() with special characters' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarBoolean() { - $this->assertEquals( - 'true', - Xml::encodeJsVar( true ), - 'encodeJsVar() with boolean' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarNull() { - $this->assertEquals( - 'null', - Xml::encodeJsVar( null ), - 'encodeJsVar() with null' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarArray() { - $this->assertEquals( - '["a",1]', - Xml::encodeJsVar( array( 'a', 1 ) ), - 'encodeJsVar() with array' - ); - $this->assertEquals( - '{"a":"a","b":1}', - Xml::encodeJsVar( array( 'a' => 'a', 'b' => 1 ) ), - 'encodeJsVar() with associative array' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarObject() { - $this->assertEquals( - '{"a":"a","b":1}', - Xml::encodeJsVar( (object)array( 'a' => 'a', 'b' => 1 ) ), - 'encodeJsVar() with object' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarInt() { - $this->assertEquals( - '123456', - Xml::encodeJsVar( 123456 ), - 'encodeJsVar() with int' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarFloat() { - $this->assertEquals( - '1.23456', - Xml::encodeJsVar( 1.23456 ), - 'encodeJsVar() with float' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarIntString() { - $this->assertEquals( - '"123456"', - Xml::encodeJsVar( '123456' ), - 'encodeJsVar() with int-like string' - ); - } - - /** - * @covers Xml::encodeJsVar - */ - public function testEncodeJsVarFloatString() { - $this->assertEquals( - '"1.23456"', - Xml::encodeJsVar( '1.23456' ), - 'encodeJsVar() with float-like string' - ); - } -} diff --git a/tests/phpunit/includes/XmlTypeCheckTest.php b/tests/phpunit/includes/XmlTypeCheckTest.php deleted file mode 100644 index 8d6f1ed7..00000000 --- a/tests/phpunit/includes/XmlTypeCheckTest.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * PHPUnit tests for XMLTypeCheck. - * @author physikerwelt - * @group Xml - * @covers XMLTypeCheck - */ -class XmlTypeCheckTest extends MediaWikiTestCase { - const WELL_FORMED_XML = "<root><child /></root>"; - const MAL_FORMED_XML = "<root><child /></error>"; - - /** - * @covers XMLTypeCheck::newFromString - * @covers XMLTypeCheck::getRootElement - */ - public function testWellFormedXML() { - $testXML = XmlTypeCheck::newFromString( self::WELL_FORMED_XML ); - $this->assertTrue( $testXML->wellFormed ); - $this->assertEquals( 'root', $testXML->getRootElement() ); - } - - /** - * @covers XMLTypeCheck::newFromString - */ - public function testMalFormedXML() { - $testXML = XmlTypeCheck::newFromString( self::MAL_FORMED_XML ); - $this->assertFalse( $testXML->wellFormed ); - } - -} diff --git a/tests/phpunit/includes/ZipDirectoryReaderTest.php b/tests/phpunit/includes/ZipDirectoryReaderTest.php deleted file mode 100644 index 2627a417..00000000 --- a/tests/phpunit/includes/ZipDirectoryReaderTest.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php - -/** - * @covers ZipDirectoryReader - * NOTE: this test is more like an integration test than a unit test - */ -class ZipDirectoryReaderTest extends MediaWikiTestCase { - protected $zipDir; - protected $entries; - - protected function setUp() { - parent::setUp(); - $this->zipDir = __DIR__ . '/../data/zip'; - } - - function zipCallback( $entry ) { - $this->entries[] = $entry; - } - - function readZipAssertError( $file, $error, $assertMessage ) { - $this->entries = array(); - $status = ZipDirectoryReader::read( "{$this->zipDir}/$file", array( $this, 'zipCallback' ) ); - $this->assertTrue( $status->hasMessage( $error ), $assertMessage ); - } - - function readZipAssertSuccess( $file, $assertMessage ) { - $this->entries = array(); - $status = ZipDirectoryReader::read( "{$this->zipDir}/$file", array( $this, 'zipCallback' ) ); - $this->assertTrue( $status->isOK(), $assertMessage ); - } - - public function testEmpty() { - $this->readZipAssertSuccess( 'empty.zip', 'Empty zip' ); - } - - public function testMultiDisk0() { - $this->readZipAssertError( 'split.zip', 'zip-unsupported', - 'Split zip error' ); - } - - public function testNoSignature() { - $this->readZipAssertError( 'nosig.zip', 'zip-wrong-format', - 'No signature should give "wrong format" error' ); - } - - public function testSimple() { - $this->readZipAssertSuccess( 'class.zip', 'Simple ZIP' ); - $this->assertEquals( $this->entries, array( array( - 'name' => 'Class.class', - 'mtime' => '20010115000000', - 'size' => 1, - ) ) ); - } - - public function testBadCentralEntrySignature() { - $this->readZipAssertError( 'wrong-central-entry-sig.zip', 'zip-bad', - 'Bad central entry error' ); - } - - public function testTrailingBytes() { - $this->readZipAssertError( 'trail.zip', 'zip-bad', - 'Trailing bytes error' ); - } - - public function testWrongCDStart() { - $this->readZipAssertError( 'wrong-cd-start-disk.zip', 'zip-unsupported', - 'Wrong CD start disk error' ); - } - - - public function testCentralDirectoryGap() { - $this->readZipAssertError( 'cd-gap.zip', 'zip-bad', - 'CD gap error' ); - } - - public function testCentralDirectoryTruncated() { - $this->readZipAssertError( 'cd-truncated.zip', 'zip-bad', - 'CD truncated error (should hit unpack() overrun)' ); - } - - 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 deleted file mode 100644 index 68f80ac9..00000000 --- a/tests/phpunit/includes/api/ApiAccountCreationTest.php +++ /dev/null @@ -1,159 +0,0 @@ -<?php - -/** - * @group Database - * @group API - * @group medium - */ -class ApiCreateAccountTest extends ApiTestCase { - function setUp() { - parent::setUp(); - LoginForm::setCreateaccountToken(); - $this->setMwGlobals( array( 'wgEnableEmail' => true ) ); - } - - /** - * Test the account creation API with a valid request. Also - * make sure the new account can log in and is valid. - * - * This test does multiple API requests so it might end up being - * a bit slow. Raise the default timeout. - * @group medium - */ - public function testValid() { - global $wgServer; - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - - $password = User::randomPassword(); - - $ret = $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'Apitestnew', - 'password' => $password, - 'email' => 'test@domain.test', - 'realname' => 'Test Name' - ) ); - - $result = $ret[0]; - $this->assertNotInternalType( 'bool', $result ); - $this->assertNotInternalType( 'null', $result['createaccount'] ); - - // Should first ask for token. - $a = $result['createaccount']; - $this->assertEquals( 'needtoken', $a['result'] ); - $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] - ); - - $result = $ret[0]; - $this->assertNotInternalType( 'bool', $result ); - $this->assertEquals( 'success', $result['createaccount']['result'] ); - - // Try logging in with the new user. - $ret = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => 'Apitestnew', - 'lgpassword' => $password, - ) ); - - $result = $ret[0]; - $this->assertNotInternalType( 'bool', $result ); - $this->assertNotInternalType( 'null', $result['login'] ); - - $a = $result['login']['result']; - $this->assertEquals( 'NeedToken', $a ); - $token = $result['login']['token']; - - $ret = $this->doApiRequest( - array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => 'Apitestnew', - 'lgpassword' => $password, - ), - $ret[2] - ); - - $result = $ret[0]; - - $this->assertNotInternalType( 'bool', $result ); - $a = $result['login']['result']; - - $this->assertEquals( 'Success', $a ); - - // log out to destroy the session - $ret = $this->doApiRequest( - array( - 'action' => 'logout', - ), - $ret[2] - ); - $this->assertEquals( array(), $ret[0] ); - } - - /** - * Make sure requests with no names are invalid. - * @expectedException UsageException - */ - public function testNoName() { - $this->doApiRequest( array( - 'action' => 'createaccount', - 'token' => LoginForm::getCreateaccountToken(), - 'password' => 'password', - ) ); - } - - /** - * Make sure requests with no password are invalid. - * @expectedException UsageException - */ - public function testNoPassword() { - $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'testName', - 'token' => LoginForm::getCreateaccountToken(), - ) ); - } - - /** - * Make sure requests with existing users are invalid. - * @expectedException UsageException - */ - public function testExistingUser() { - $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'Apitestsysop', - 'token' => LoginForm::getCreateaccountToken(), - 'password' => 'password', - 'email' => 'test@domain.test', - ) ); - } - - /** - * Make sure requests with invalid emails are invalid. - * @expectedException UsageException - */ - public function testInvalidEmail() { - $this->doApiRequest( array( - 'action' => 'createaccount', - 'name' => 'Test User', - 'token' => LoginForm::getCreateaccountToken(), - 'password' => 'password', - 'email' => 'invalid', - ) ); - } -} diff --git a/tests/phpunit/includes/api/ApiBlockTest.php b/tests/phpunit/includes/api/ApiBlockTest.php deleted file mode 100644 index 8afb748a..00000000 --- a/tests/phpunit/includes/api/ApiBlockTest.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiBlockTest extends ApiTestCase { - protected function setUp() { - parent::setUp(); - $this->doLogin(); - } - - function getTokens() { - return $this->getTokenList( self::$users['sysop'] ); - } - - function addDBData() { - $user = User::newFromName( 'UTApiBlockee' ); - - if ( $user->getId() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTApiBlockeePassword' ); - - $user->saveSettings(); - } - } - - /** - * This test has probably always been broken and use an invalid token - * Bug tracking brokenness is https://bugzilla.wikimedia.org/35646 - * - * Root cause is https://gerrit.wikimedia.org/r/3434 - * Which made the Block/Unblock API to actually verify the token - * previously always considered valid (bug 34212). - */ - public function testMakeNormalBlock() { - $tokens = $this->getTokens(); - - $user = User::newFromName( 'UTApiBlockee' ); - - if ( !$user->getId() ) { - $this->markTestIncomplete( "The user UTApiBlockee does not exist" ); - } - - if ( !array_key_exists( 'blocktoken', $tokens ) ) { - $this->markTestIncomplete( "No block token found" ); - } - - $this->doApiRequest( array( - 'action' => 'block', - 'user' => 'UTApiBlockee', - 'reason' => 'Some reason', - 'token' => $tokens['blocktoken'] ), null, false, self::$users['sysop']->user ); - - $block = Block::newFromTarget( 'UTApiBlockee' ); - - $this->assertTrue( !is_null( $block ), 'Block is valid' ); - - $this->assertEquals( 'UTApiBlockee', (string)$block->getTarget() ); - $this->assertEquals( 'Some reason', $block->mReason ); - $this->assertEquals( 'infinity', $block->mExpiry ); - } - - /** - * Attempting to block without a token should give a UsageException with - * error message: - * "The token parameter must be set" - * - * @dataProvider provideBlockUnblockAction - * @expectedException UsageException - */ - public function testBlockingActionWithNoToken( $action ) { - $this->doApiRequest( - array( - 'action' => $action, - 'user' => 'UTApiBlockee', - 'reason' => 'Some reason', - ), - null, - false, - self::$users['sysop']->user - ); - } - - /** - * Just provide the 'block' and 'unblock' action to test both API calls - */ - 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 deleted file mode 100644 index 0c49b12b..00000000 --- a/tests/phpunit/includes/api/ApiEditPageTest.php +++ /dev/null @@ -1,417 +0,0 @@ -<?php - -/** - * Tests for MediaWiki api.php?action=edit. - * - * @author Daniel Kinzler - * - * @group API - * @group Database - * @group medium - */ -class ApiEditPageTest extends ApiTestCase { - - public function setUp() { - global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - - parent::setUp(); - - $wgExtraNamespaces[12312] = 'Dummy'; - $wgExtraNamespaces[12313] = 'Dummy_talk'; - - $wgNamespaceContentModels[12312] = "testing"; - $wgContentHandlers["testing"] = 'DummyContentHandlerForTesting'; - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - - $this->doLogin(); - } - - public function tearDown() { - global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; - - unset( $wgExtraNamespaces[12312] ); - unset( $wgExtraNamespaces[12313] ); - - unset( $wgNamespaceContentModels[12312] ); - unset( $wgContentHandlers["testing"] ); - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - - parent::tearDown(); - } - - public function testEdit() { - $name = 'Help:ApiEditPageTest_testEdit'; // assume Help namespace to default to wikitext - - // -- test new page -------------------------------------------- - $apiResult = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'some text', - ) ); - $apiResult = $apiResult[0]; - - // Validate API result data - $this->assertArrayHasKey( 'edit', $apiResult ); - $this->assertArrayHasKey( 'result', $apiResult['edit'] ); - $this->assertEquals( 'Success', $apiResult['edit']['result'] ); - - $this->assertArrayHasKey( 'new', $apiResult['edit'] ); - $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] ); - - $this->assertArrayHasKey( 'pageid', $apiResult['edit'] ); - - // -- test existing page, no change ---------------------------- - $data = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'some text', - ) ); - - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - $this->assertArrayNotHasKey( 'new', $data[0]['edit'] ); - $this->assertArrayHasKey( 'nochange', $data[0]['edit'] ); - - // -- test existing page, with change -------------------------- - $data = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'different text' - ) ); - - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - $this->assertArrayNotHasKey( 'new', $data[0]['edit'] ); - $this->assertArrayNotHasKey( 'nochange', $data[0]['edit'] ); - - $this->assertArrayHasKey( 'oldrevid', $data[0]['edit'] ); - $this->assertArrayHasKey( 'newrevid', $data[0]['edit'] ); - $this->assertNotEquals( - $data[0]['edit']['newrevid'], - $data[0]['edit']['oldrevid'], - "revision id should change after edit" - ); - } - - public function testNonTextEdit() { - $name = 'Dummy:ApiEditPageTest_testNonTextEdit'; - $data = serialize( 'some bla bla text' ); - - // -- test new page -------------------------------------------- - $apiResult = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => $data, ) ); - $apiResult = $apiResult[0]; - - // Validate API result data - $this->assertArrayHasKey( 'edit', $apiResult ); - $this->assertArrayHasKey( 'result', $apiResult['edit'] ); - $this->assertEquals( 'Success', $apiResult['edit']['result'] ); - - $this->assertArrayHasKey( 'new', $apiResult['edit'] ); - $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] ); - - $this->assertArrayHasKey( 'pageid', $apiResult['edit'] ); - - // validate resulting revision - $page = WikiPage::factory( Title::newFromText( $name ) ); - $this->assertEquals( "testing", $page->getContentModel() ); - $this->assertEquals( $data, $page->getContent()->serialize() ); - } - - public static function provideEditAppend() { - return array( - array( #0: append - 'foo', 'append', 'bar', "foobar" - ), - array( #1: prepend - 'foo', 'prepend', 'bar', "barfoo" - ), - array( #2: append to empty page - '', 'append', 'foo', "foo" - ), - array( #3: prepend to empty page - '', 'prepend', 'foo', "foo" - ), - array( #4: append to non-existing page - null, 'append', 'foo', "foo" - ), - array( #5: prepend to non-existing page - null, 'prepend', 'foo', "foo" - ), - ); - } - - /** - * @dataProvider provideEditAppend - */ - public function testEditAppend( $text, $op, $append, $expected ) { - static $count = 0; - $count++; - - // assume NS_HELP defaults to wikitext - $name = "Help:ApiEditPageTest_testEditAppend_$count"; - - // -- create page (or not) ----------------------------------------- - if ( $text !== null ) { - if ( $text === '' ) { - // can't create an empty page, so create it with some content - $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => '(dummy)', ) ); - } - - list( $re ) = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => $text, ) ); - - $this->assertEquals( 'Success', $re['edit']['result'] ); // sanity - } - - // -- try append/prepend -------------------------------------------- - list( $re ) = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - $op . 'text' => $append, ) ); - - $this->assertEquals( 'Success', $re['edit']['result'] ); - - // -- validate ----------------------------------------------------- - $page = new WikiPage( Title::newFromText( $name ) ); - $content = $page->getContent(); - $this->assertNotNull( $content, 'Page should have been created' ); - - $text = $content->getNativeData(); - - $this->assertEquals( $expected, $text ); - } - - /** - * 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' ); - } - } - - /** - * 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" ); - } - - public function testEditConflict() { - static $count = 0; - $count++; - - // assume NS_HELP defaults to wikitext - $name = "Help:ApiEditPageTest_testEditConflict_$count"; - $title = Title::newFromText( $name ); - - $page = WikiPage::factory( $title ); - - // base edit - $page->doEditContent( new WikitextContent( "Foo" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $page, '20120101000000' ); - $baseTime = $page->getRevision()->getTimestamp(); - - // conflicting edit - $page->doEditContent( new WikitextContent( "Foo bar" ), - "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); - $this->forceRevisionDate( $page, '20120101020202' ); - - // try to save edit, expect conflict - try { - $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'nix bar!', - 'basetimestamp' => $baseTime, - ), null, self::$users['sysop']->user ); - - $this->fail( 'edit conflict expected' ); - } catch ( UsageException $ex ) { - $this->assertEquals( 'editconflict', $ex->getCodeString() ); - } - } - - public function testEditConflict_redirect() { - static $count = 0; - $count++; - - // assume NS_HELP defaults to wikitext - $name = "Help:ApiEditPageTest_testEditConflict_redirect_$count"; - $title = Title::newFromText( $name ); - $page = WikiPage::factory( $title ); - - $rname = "Help:ApiEditPageTest_testEditConflict_redirect_r$count"; - $rtitle = Title::newFromText( $rname ); - $rpage = WikiPage::factory( $rtitle ); - - // base edit for content - $page->doEditContent( new WikitextContent( "Foo" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $page, '20120101000000' ); - $baseTime = $page->getRevision()->getTimestamp(); - - // base edit for redirect - $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $rpage, '20120101000000' ); - - // conflicting edit to redirect - $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]\n\n[[Category:Test]]" ), - "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); - $this->forceRevisionDate( $rpage, '20120101020202' ); - - // try to save edit; should work, because we follow the redirect - list( $re, , ) = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $rname, - 'text' => 'nix bar!', - 'basetimestamp' => $baseTime, - 'redirect' => true, - ), null, self::$users['sysop']->user ); - - $this->assertEquals( 'Success', $re['edit']['result'], - "no edit conflict expected when following redirect" ); - - // try again, without following the redirect. Should fail. - try { - $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $rname, - 'text' => 'nix bar!', - 'basetimestamp' => $baseTime, - ), null, self::$users['sysop']->user ); - - $this->fail( 'edit conflict expected' ); - } catch ( UsageException $ex ) { - $this->assertEquals( 'editconflict', $ex->getCodeString() ); - } - } - - 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' erroneously - * caused an edit conflict to be detected. - */ - - // assume NS_HELP defaults to wikitext - $name = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_$count"; - $title = Title::newFromText( $name ); - $page = WikiPage::factory( $title ); - - $rname = "Help:ApiEditPageTest_testEditConflict_redirect_bug41990_r$count"; - $rtitle = Title::newFromText( $rname ); - $rpage = WikiPage::factory( $rtitle ); - - // base edit for content - $page->doEditContent( new WikitextContent( "Foo" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $page, '20120101000000' ); - - // base edit for redirect - $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ), - "testing 1", EDIT_NEW, false, self::$users['sysop']->user ); - $this->forceRevisionDate( $rpage, '20120101000000' ); - $baseTime = $rpage->getRevision()->getTimestamp(); - - // new edit to content - $page->doEditContent( new WikitextContent( "Foo bar" ), - "testing 2", EDIT_UPDATE, $page->getLatest(), self::$users['uploader']->user ); - $this->forceRevisionDate( $rpage, '20120101020202' ); - - // try to save edit; should work, following the redirect. - list( $re, , ) = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $rname, - 'text' => 'nix bar!', - 'redirect' => true, - ), null, self::$users['sysop']->user ); - - $this->assertEquals( 'Success', $re['edit']['result'], - "no edit conflict expected here" ); - } - - protected function forceRevisionDate( WikiPage $page, $timestamp ) { - $dbw = wfGetDB( DB_MASTER ); - - $dbw->update( 'revision', - array( 'rev_timestamp' => $dbw->timestamp( $timestamp ) ), - array( 'rev_id' => $page->getLatest() ) ); - - $page->clear(); - } -} diff --git a/tests/phpunit/includes/api/ApiOptionsTest.php b/tests/phpunit/includes/api/ApiOptionsTest.php deleted file mode 100644 index ad1e73ab..00000000 --- a/tests/phpunit/includes/api/ApiOptionsTest.php +++ /dev/null @@ -1,420 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiOptionsTest extends MediaWikiLangTestCase { - - private $mTested, $mUserMock, $mContext, $mSession; - - private $mOldGetPreferencesHooks = false; - - private static $Success = array( 'options' => 'success' ); - - protected function setUp() { - parent::setUp(); - - $this->mUserMock = $this->getMockBuilder( 'User' ) - ->disableOriginalConstructor() - ->getMock(); - - // 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() ) - ->method( 'getOptionKinds' )->will( $this->returnCallback( array( $this, 'getOptionKinds' ) ) ); - - // Create a new context - $this->mContext = new DerivativeContext( new RequestContext() ); - $this->mContext->getContext()->setTitle( Title::newFromText( 'Test' ) ); - $this->mContext->setUser( $this->mUserMock ); - - $main = new ApiMain( $this->mContext ); - - // Empty session - $this->mSession = array(); - - $this->mTested = new ApiOptions( $main, 'options' ); - - global $wgHooks; - if ( !isset( $wgHooks['GetPreferences'] ) ) { - $wgHooks['GetPreferences'] = array(); - } - $this->mOldGetPreferencesHooks = $wgHooks['GetPreferences']; - $wgHooks['GetPreferences'][] = array( $this, 'hookGetPreferences' ); - } - - protected function tearDown() { - global $wgHooks; - - if ( $this->mOldGetPreferencesHooks !== false ) { - $wgHooks['GetPreferences'] = $this->mOldGetPreferencesHooks; - $this->mOldGetPreferencesHooks = false; - } - - parent::tearDown(); - } - - public function hookGetPreferences( $user, &$preferences ) { - $preferences = array(); - - foreach ( array( 'name', 'willBeNull', 'willBeEmpty', 'willBeHappy' ) as $k ) { - $preferences[$k] = array( - 'type' => 'text', - 'section' => 'test', - 'label' => ' ', - ); - } - - $preferences['testmultiselect'] = array( - 'type' => 'multiselect', - 'options' => array( - 'Test' => array( - '<span dir="auto">Some HTML here for option 1</span>' => 'opt1', - '<span dir="auto">Some HTML here for option 2</span>' => 'opt2', - '<span dir="auto">Some HTML here for option 3</span>' => 'opt3', - '<span dir="auto">Some HTML here for option 4</span>' => 'opt4', - ), - ), - 'section' => 'test', - 'label' => ' ', - 'prefix' => 'testmultiselect-', - 'default' => array(), - ); - - return true; - } - - public function getOptionKinds( IContextSource $context, $options = null ) { - // Match with above. - $kinds = array( - 'name' => 'registered', - 'willBeNull' => 'registered', - 'willBeEmpty' => 'registered', - 'willBeHappy' => 'registered', - 'testmultiselect-opt1' => 'registered-multiselect', - 'testmultiselect-opt2' => 'registered-multiselect', - 'testmultiselect-opt3' => 'registered-multiselect', - 'testmultiselect-opt4' => 'registered-multiselect', - ); - - if ( $options === null ) { - return $kinds; - } - - $mapping = array(); - foreach ( $options as $key => $value ) { - if ( isset( $kinds[$key] ) ) { - $mapping[$key] = $kinds[$key]; - } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) { - $mapping[$key] = 'userjs'; - } else { - $mapping[$key] = 'unused'; - } - } - - return $mapping; - } - - private function getSampleRequest( $custom = array() ) { - $request = array( - 'token' => '123ABC', - 'change' => null, - '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(); - } - - /** - * @expectedException UsageException - */ - public function testNoToken() { - $request = $this->getSampleRequest( array( 'token' => null ) ); - - $this->executeQuery( $request ); - } - - public function testAnon() { - $this->mUserMock->expects( $this->once() ) - ->method( 'isAnon' ) - ->will( $this->returnValue( true ) ); - - try { - $request = $this->getSampleRequest(); - - $this->executeQuery( $request ); - } catch ( UsageException $e ) { - $this->assertEquals( 'notloggedin', $e->getCodeString() ); - $this->assertEquals( 'Anonymous users cannot change preferences', $e->getMessage() ); - - return; - } - $this->fail( "UsageException was not thrown" ); - } - - public function testNoOptionname() { - try { - $request = $this->getSampleRequest( array( 'optionvalue' => '1' ) ); - - $this->executeQuery( $request ); - } 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" ); - } - - public function testNoChanges() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'setOption' ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'saveSettings' ); - - try { - $request = $this->getSampleRequest(); - - $this->executeQuery( $request ); - } catch ( UsageException $e ) { - $this->assertEquals( 'nochanges', $e->getCodeString() ); - $this->assertEquals( 'No changes were requested', $e->getMessage() ); - - return; - } - $this->fail( "UsageException was not thrown" ); - } - - public function testReset() { - $this->mUserMock->expects( $this->once() ) - ->method( 'resetOptions' ) - ->with( $this->equalTo( array( 'all' ) ) ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'setOption' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'reset' => '' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testResetKinds() { - $this->mUserMock->expects( $this->once() ) - ->method( 'resetOptions' ) - ->with( $this->equalTo( array( 'registered' ) ) ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'setOption' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'reset' => '', 'resetkinds' => 'registered' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testOptionWithValue() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'optionname' => 'name', 'optionvalue' => 'value' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testOptionResetValue() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'name' ), $this->identicalTo( null ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'optionname' => 'name' ) ); - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testChange() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 2 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 4 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeNull' ), $this->identicalTo( null ) ); - - $this->mUserMock->expects( $this->at( 5 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 6 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeEmpty' ), $this->equalTo( '' ) ); - - $this->mUserMock->expects( $this->at( 7 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 8 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'change' => 'willBeNull|willBeEmpty=|willBeHappy=Happy' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testResetChangeOption() { - $this->mUserMock->expects( $this->once() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 4 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 5 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); - - $this->mUserMock->expects( $this->at( 6 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 7 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $args = array( - 'reset' => '', - 'change' => 'willBeHappy=Happy', - 'optionname' => 'name', - 'optionvalue' => 'value' - ); - - $response = $this->executeQuery( $this->getSampleRequest( $args ) ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testMultiSelect() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 3 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'testmultiselect-opt1' ), $this->identicalTo( true ) ); - - $this->mUserMock->expects( $this->at( 4 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'testmultiselect-opt2' ), $this->identicalTo( null ) ); - - $this->mUserMock->expects( $this->at( 5 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'testmultiselect-opt3' ), $this->identicalTo( false ) ); - - $this->mUserMock->expects( $this->at( 6 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'testmultiselect-opt4' ), $this->identicalTo( false ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( - 'change' => 'testmultiselect-opt1=1|testmultiselect-opt2|testmultiselect-opt3=|testmultiselect-opt4=0' - ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testUnknownOption() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( - 'change' => 'unknownOption=1' - ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( array( - 'options' => 'success', - 'warnings' => array( - 'options' => array( - '*' => "Validation error for 'unknownOption': not a valid preference" - ) - ) - ), $response ); - } - - public function testUserjsOption() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 3 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'userjs-option' ), $this->equalTo( '1' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( - 'change' => 'userjs-option=1' - ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } -} diff --git a/tests/phpunit/includes/api/ApiParseTest.php b/tests/phpunit/includes/api/ApiParseTest.php deleted file mode 100644 index 2d714e65..00000000 --- a/tests/phpunit/includes/api/ApiParseTest.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiParseTest extends ApiTestCase { - - protected function setUp() { - parent::setUp(); - $this->doLogin(); - } - - public function testParseNonexistentPage() { - $somePage = mt_rand(); - - try { - $this->doApiRequest( array( - 'action' => 'parse', - 'page' => $somePage ) ); - - $this->fail( "API did not return an error when parsing a nonexistent page" ); - } catch ( UsageException $ex ) { - $this->assertEquals( 'missingtitle', $ex->getCodeString(), - "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 deleted file mode 100644 index 28b5ff4d..00000000 --- a/tests/phpunit/includes/api/ApiPurgeTest.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiPurgeTest extends ApiTestCase { - - protected function setUp() { - parent::setUp(); - $this->doLogin(); - } - - /** - * @group Broken - */ - public function testPurgeMainPage() { - if ( !Title::newFromText( 'UTPage' )->exists() ) { - $this->markTestIncomplete( "The article [[UTPage]] does not exist" ); - } - - $somePage = mt_rand(); - - $data = $this->doApiRequest( array( - 'action' => 'purge', - 'titles' => 'UTPage|' . $somePage . '|%5D' ) ); - - $this->assertArrayHasKey( 'purge', $data[0], - "Must receive a 'purge' result from API" ); - - $this->assertEquals( 3, count( $data[0]['purge'] ), - "Purge request for three articles should give back three results received: " . var_export( $data[0]['purge'], true ) ); - - $pages = array( 'UTPage' => 'purged', $somePage => 'missing', '%5D' => 'invalid' ); - foreach ( $data[0]['purge'] as $v ) { - $this->assertArrayHasKey( $pages[$v['title']], $v ); - } - } -} diff --git a/tests/phpunit/includes/api/ApiTest.php b/tests/phpunit/includes/api/ApiTest.php deleted file mode 100644 index 472f8c4a..00000000 --- a/tests/phpunit/includes/api/ApiTest.php +++ /dev/null @@ -1,259 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiTest extends ApiTestCase { - - public function testRequireOnlyOneParameterDefault() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => false ), "filename", "enablechunks" ) ); - } - - /** - * @expectedException UsageException - */ - public function testRequireOnlyOneParameterZero() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => 0 ), "filename", "enablechunks" ) ); - } - - /** - * @expectedException UsageException - */ - public function testRequireOnlyOneParameterTrue() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => true ), "filename", "enablechunks" ) ); - } - - /** - * Test that the API will accept a FauxRequest and execute. The help action - * (default) throws a UsageException. Just validate we're getting proper XML - * - * @expectedException UsageException - */ - public function testApi() { - $api = new ApiMain( - new FauxRequest( array( 'action' => 'help', 'format' => 'xml' ) ) - ); - $api->execute(); - $api->getPrinter()->setBufferResult( true ); - $api->printResult( false ); - $resp = $api->getPrinter()->getBuffer(); - - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $resp ); - $this->assertNotInternalType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - } - - /** - * Test result of attempted login with an empty username - */ - public function testApiLoginNoName() { - $data = $this->doApiRequest( array( 'action' => 'login', - 'lgname' => '', 'lgpassword' => self::$users['sysop']->password, - ) ); - $this->assertEquals( 'NoName', $data[0]['login']['result'] ); - } - - public function testApiLoginBadPass() { - global $wgServer; - - $user = self::$users['sysop']; - $user->user->logOut(); - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - $ret = $this->doApiRequest( array( - "action" => "login", - "lgname" => $user->username, - "lgpassword" => "bad", - ) ); - - $result = $ret[0]; - - $this->assertNotInternalType( "bool", $result ); - $a = $result["login"]["result"]; - $this->assertEquals( "NeedToken", $a ); - - $token = $result["login"]["token"]; - - $ret = $this->doApiRequest( - array( - "action" => "login", - "lgtoken" => $token, - "lgname" => $user->username, - "lgpassword" => "badnowayinhell", - ), - $ret[2] - ); - - $result = $ret[0]; - - $this->assertNotInternalType( "bool", $result ); - $a = $result["login"]["result"]; - - $this->assertEquals( "WrongPass", $a ); - } - - public function testApiLoginGoodPass() { - global $wgServer; - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - - $user = self::$users['sysop']; - $user->user->logOut(); - - $ret = $this->doApiRequest( array( - "action" => "login", - "lgname" => $user->username, - "lgpassword" => $user->password, - ) - ); - - $result = $ret[0]; - $this->assertNotInternalType( "bool", $result ); - $this->assertNotInternalType( "null", $result["login"] ); - - $a = $result["login"]["result"]; - $this->assertEquals( "NeedToken", $a ); - $token = $result["login"]["token"]; - - $ret = $this->doApiRequest( - array( - "action" => "login", - "lgtoken" => $token, - "lgname" => $user->username, - "lgpassword" => $user->password, - ), - $ret[2] - ); - - $result = $ret[0]; - - $this->assertNotInternalType( "bool", $result ); - $a = $result["login"]["result"]; - - $this->assertEquals( "Success", $a ); - } - - /** - * @group Broken - */ - public function testApiGotCookie() { - $this->markTestIncomplete( "The server can't do external HTTP requests, and the internal one won't give cookies" ); - - global $wgServer, $wgScriptPath; - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - $user = self::$users['sysop']; - - $req = MWHttpRequest::factory( self::$apiUrl . "?action=login&format=xml", - array( "method" => "POST", - "postData" => array( - "lgname" => $user->username, - "lgpassword" => $user->password - ) - ) - ); - $req->execute(); - - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $req->getContent() ); - $this->assertNotInternalType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - $this->assertNotInternalType( "null", $sxe->login[0] ); - - $a = $sxe->login[0]->attributes()->result[0]; - $this->assertEquals( ' result="NeedToken"', $a->asXML() ); - $token = (string)$sxe->login[0]->attributes()->token; - - $req->setData( array( - "lgtoken" => $token, - "lgname" => $user->username, - "lgpassword" => $user->password ) ); - $req->execute(); - - $cj = $req->getCookieJar(); - $serverName = parse_url( $wgServer, PHP_URL_HOST ); - $this->assertNotEquals( false, $serverName ); - $serializedCookie = $cj->serializeToHttpRequest( $wgScriptPath, $serverName ); - $this->assertNotEquals( '', $serializedCookie ); - $this->assertRegexp( '/_session=[^;]*; .*UserID=[0-9]*; .*UserName=' . $user->userName . '; .*Token=/', $serializedCookie ); - - return $cj; - } - - public function testRunLogin() { - $sysopUser = self::$users['sysop']; - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => $sysopUser->username, - 'lgpassword' => $sysopUser->password ) ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( array( - 'action' => 'login', - "lgtoken" => $token, - "lgname" => $sysopUser->username, - "lgpassword" => $sysopUser->password ), $data[2] ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "Success", $data[0]['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); - - return $data; - } - - public function testGettingToken() { - foreach ( self::$users as $user ) { - $this->runTokenTest( $user ); - } - } - - function runTokenTest( $user ) { - $tokens = $this->getTokenList( $user ); - - $rights = $user->user->getRights(); - - $this->assertArrayHasKey( 'edittoken', $tokens ); - $this->assertArrayHasKey( 'movetoken', $tokens ); - - if ( isset( $rights['delete'] ) ) { - $this->assertArrayHasKey( 'deletetoken', $tokens ); - } - - if ( isset( $rights['block'] ) ) { - $this->assertArrayHasKey( 'blocktoken', $tokens ); - $this->assertArrayHasKey( 'unblocktoken', $tokens ); - } - - if ( isset( $rights['protect'] ) ) { - $this->assertArrayHasKey( 'protecttoken', $tokens ); - } - - return $tokens; - } -} diff --git a/tests/phpunit/includes/api/ApiTestCase.php b/tests/phpunit/includes/api/ApiTestCase.php deleted file mode 100644 index 94ef9c68..00000000 --- a/tests/phpunit/includes/api/ApiTestCase.php +++ /dev/null @@ -1,253 +0,0 @@ -<?php - -abstract class ApiTestCase extends MediaWikiLangTestCase { - protected static $apiUrl; - - /** - * @var ApiTestContext - */ - protected $apiContext; - - protected function setUp() { - global $wgServer; - - parent::setUp(); - self::$apiUrl = $wgServer . wfScript( 'api' ); - - ApiQueryInfo::resetTokenCache(); // tokens are invalid because we cleared the session - - self::$users = array( - 'sysop' => new TestUser( - 'Apitestsysop', - 'Api Test Sysop', - 'api_test_sysop@example.com', - array( 'sysop' ) - ), - 'uploader' => new TestUser( - 'Apitestuser', - 'Api Test User', - 'api_test_user@example.com', - array() - ) - ); - - $this->setMwGlobals( array( - 'wgMemc' => new EmptyBagOStuff(), - 'wgAuth' => new StubObject( 'wgAuth', 'AuthPlugin' ), - 'wgRequest' => new FauxRequest( array() ), - 'wgUser' => self::$users['sysop']->user, - ) ); - - $this->apiContext = new ApiTestContext(); - } - - /** - * Edits or creates a page/revision - * @param $pageName string page title - * @param $text string content of the page - * @param $summary string optional summary string for the revision - * @param $defaultNs int optional namespace id - * @return array as returned by WikiPage::doEditContent() - */ - 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 ); - } - - /** - * Does the API request and returns the result. - * - * The returned value is an array containing - * - the result data (array) - * - the request (WebRequest) - * - the session data of the request (array) - * - if $appendModule is true, the Api module $module - * - * @param array $params - * @param array|null $session - * @param bool $appendModule - * @param User|null $user - * - * @return array - */ - protected function doApiRequest( array $params, array $session = null, $appendModule = false, User $user = null ) { - global $wgRequest, $wgUser; - - if ( is_null( $session ) ) { - // re-use existing global session by default - $session = $wgRequest->getSessionArray(); - } - - // set up global environment - if ( $user ) { - $wgUser = $user; - } - - $wgRequest = new FauxRequest( $params, true, $session ); - RequestContext::getMain()->setRequest( $wgRequest ); - - // set up local environment - $context = $this->apiContext->newTestContext( $wgRequest, $wgUser ); - - $module = new ApiMain( $context, true ); - - // run it! - $module->execute(); - - // construct result - $results = array( - $module->getResultData(), - $context->getRequest(), - $context->getRequest()->getSessionArray() - ); - - if ( $appendModule ) { - $results[] = $module; - } - - return $results; - } - - /** - * Add an edit token to the API request - * This is cheating a bit -- we grab a token in the correct format and then add it to the pseudo-session and to the - * request, without actually requesting a "real" edit token - * @param $params Array: key-value API params - * @param $session Array|null: session array - * @param $user User|null A User object for the context - * @return result of the API call - * @throws Exception in case wsToken is not set in the session - */ - protected function doApiRequestWithToken( array $params, array $session = null, User $user = null ) { - global $wgRequest; - - if ( $session === null ) { - $session = $wgRequest->getSessionArray(); - } - - if ( $session['wsToken'] ) { - // add edit token to fake session - $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( $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[ $user ]->username, - 'lgpassword' => self::$users[ $user ]->password ) ); - - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( - array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => self::$users[ $user ]->username, - 'lgpassword' => self::$users[ $user ]->password, - ), - $data[2] - ); - - return $data; - } - - protected function getTokenList( $user, $session = null ) { - $data = $this->doApiRequest( array( - '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() { - $groups = PHPUnit_Util_Test::getGroups( get_class( $this ) ); - $constraint = PHPUnit_Framework_Assert::logicalOr( - $this->contains( 'medium' ), - $this->contains( 'large' ) - ); - $this->assertThat( $groups, $constraint, - 'ApiTestCase::setUp can be slow, tests must be "medium" or "large"' - ); - } -} - -class UserWrapper { - public $userName; - public $password; - public $user; - - public function __construct( $userName, $password, $group = '' ) { - $this->userName = $userName; - $this->password = $password; - - $this->user = User::newFromName( $this->userName ); - if ( !$this->user->getID() ) { - $this->user = User::createNew( $this->userName, array( - "email" => "test@example.com", - "real_name" => "Test User" ) ); - } - $this->user->setPassword( $this->password ); - - if ( $group !== '' ) { - $this->user->addGroup( $group ); - } - $this->user->saveSettings(); - } -} - -class MockApi extends ApiBase { - public function execute() { - } - - public function getVersion() { - } - - public function __construct() { - } - - public function getAllowedParams() { - return array( - 'filename' => null, - 'enablechunks' => false, - 'sessionkey' => null, - ); - } -} - -class ApiTestContext extends RequestContext { - - /** - * Returns a DerivativeContext with the request variables in place - * - * @param $request WebRequest request object including parameters and session - * @param $user User or null - * @return DerivativeContext - */ - public function newTestContext( WebRequest $request, User $user = null ) { - $context = new DerivativeContext( $this ); - $context->setRequest( $request ); - if ( $user !== null ) { - $context->setUser( $user ); - } - - return $context; - } -} diff --git a/tests/phpunit/includes/api/ApiTestCaseUpload.php b/tests/phpunit/includes/api/ApiTestCaseUpload.php deleted file mode 100644 index 7e18b6ed..00000000 --- a/tests/phpunit/includes/api/ApiTestCaseUpload.php +++ /dev/null @@ -1,149 +0,0 @@ -<?php - -/** - * * Abstract class to support upload tests - */ - -abstract class ApiTestCaseUpload extends ApiTestCase { - /** - * Fixture -- run before every test - */ - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgEnableUploads' => true, - 'wgEnableAPI' => true, - ) ); - - wfSetupSession(); - - $this->clearFakeUploads(); - } - - protected function tearDown() { - $this->clearTempUpload(); - - parent::tearDown(); - } - - /** - * Helper function -- remove files and associated articles by Title - * @param $title Title: title to be removed - */ - public function deleteFileByTitle( $title ) { - if ( $title->exists() ) { - $file = wfFindFile( $title, array( 'ignoreRedirect' => true ) ); - $noOldArchive = ""; // yes this really needs to be set this way - $comment = "removing for test"; - $restrictDeletedVersions = false; - $status = FileDeleteForm::doDelete( $title, $file, $noOldArchive, $comment, $restrictDeletedVersions ); - if ( !$status->isGood() ) { - return false; - } - $page = WikiPage::factory( $title ); - $page->doDeleteArticle( "removing for test" ); - - // see if it now doesn't exist; reload - $title = Title::newFromText( $title->getText(), NS_FILE ); - } - - return !( $title && $title instanceof Title && $title->exists() ); - } - - /** - * Helper function -- remove files and associated articles with a particular filename - * @param $fileName String: filename to be removed - */ - public function deleteFileByFileName( $fileName ) { - return $this->deleteFileByTitle( Title::newFromText( $fileName, NS_FILE ) ); - } - - /** - * Helper function -- given a file on the filesystem, find matching content in the db (and associated articles) and remove them. - * @param $filePath String: path to file on the filesystem - */ - public function deleteFileByContent( $filePath ) { - $hash = FSFile::getSha1Base36FromPath( $filePath ); - $dupes = RepoGroup::singleton()->findBySha1( $hash ); - $success = true; - foreach ( $dupes as $dupe ) { - $success &= $this->deleteFileByTitle( $dupe->getTitle() ); - } - - return $success; - } - - /** - * Fake an upload by dumping the file into temp space, and adding info to $_FILES. - * (This is what PHP would normally do). - * @param $fieldName String: name this would have in the upload form - * @param $fileName String: name to title this - * @param $type String: mime type - * @param $filePath String: path where to find file contents - */ - function fakeUploadFile( $fieldName, $fileName, $type, $filePath ) { - $tmpName = tempnam( wfTempDir(), "" ); - if ( !file_exists( $filePath ) ) { - throw new Exception( "$filePath doesn't exist!" ); - } - - if ( !copy( $filePath, $tmpName ) ) { - throw new Exception( "couldn't copy $filePath to $tmpName" ); - } - - clearstatcache(); - $size = filesize( $tmpName ); - if ( $size === false ) { - throw new Exception( "couldn't stat $tmpName" ); - } - - $_FILES[$fieldName] = array( - 'name' => $fileName, - 'type' => $type, - 'tmp_name' => $tmpName, - 'size' => $size, - 'error' => null - ); - - return true; - } - - function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ) { - $tmpName = tempnam( wfTempDir(), "" ); - // copy the chunk data to temp location: - if ( !file_put_contents( $tmpName, $chunkData ) ) { - throw new Exception( "couldn't copy chunk data to $tmpName" ); - } - - clearstatcache(); - $size = filesize( $tmpName ); - if ( $size === false ) { - throw new Exception( "couldn't stat $tmpName" ); - } - - $_FILES[$fieldName] = array( - 'name' => $fileName, - 'type' => $type, - 'tmp_name' => $tmpName, - 'size' => $size, - 'error' => null - ); - } - - function clearTempUpload() { - if ( isset( $_FILES['file']['tmp_name'] ) ) { - $tmp = $_FILES['file']['tmp_name']; - if ( file_exists( $tmp ) ) { - unlink( $tmp ); - } - } - } - - /** - * Remove traces of previous fake uploads - */ - function clearFakeUploads() { - $_FILES = array(); - } -} diff --git a/tests/phpunit/includes/api/ApiUploadTest.php b/tests/phpunit/includes/api/ApiUploadTest.php deleted file mode 100644 index 1540af55..00000000 --- a/tests/phpunit/includes/api/ApiUploadTest.php +++ /dev/null @@ -1,561 +0,0 @@ -<?php - -/** - * @group API - * @group Database - */ - -/** - * n.b. Ensure that you can write to the images/ directory as the - * user that will run tests. - */ - -// Note for reviewers: this intentionally duplicates functionality already in "ApiSetup" and so on. -// This framework works better IMO and has less strangeness (such as test cases inheriting from "ApiSetup"...) -// (and in the case of the other Upload tests, this flat out just actually works... ) - -// TODO: port the other Upload tests, and other API tests to this framework - -require_once 'ApiTestCaseUpload.php'; - -/** - * @group Database - * @group Broken - * Broken test, reports false errors from time to time. - * See https://bugzilla.wikimedia.org/26169 - * - * This is pretty sucky... needs to be prettified. - */ -class ApiUploadTest extends ApiTestCaseUpload { - /** - * Testing login - * XXX this is a funny way of getting session context - */ - public function testLogin() { - $user = self::$users['uploader']; - - $params = array( - 'action' => 'login', - 'lgname' => $user->username, - 'lgpassword' => $user->password - ); - list( $result, , $session ) = $this->doApiRequest( $params ); - $this->assertArrayHasKey( "login", $result ); - $this->assertArrayHasKey( "result", $result['login'] ); - $this->assertEquals( "NeedToken", $result['login']['result'] ); - $token = $result['login']['token']; - - $params = array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => $user->username, - 'lgpassword' => $user->password - ); - list( $result, , $session ) = $this->doApiRequest( $params, $session ); - $this->assertArrayHasKey( "login", $result ); - $this->assertArrayHasKey( "result", $result['login'] ); - $this->assertEquals( "Success", $result['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $result['login'] ); - - $this->assertNotEmpty( $session, 'API Login must return a session' ); - - return $session; - } - - /** - * @depends testLogin - */ - public function testUploadRequiresToken( $session ) { - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload' - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The token parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - } - - /** - * @depends testLogin - */ - public function testUploadMissingParams( $session ) { - $exception = false; - try { - $this->doApiRequestWithToken( array( - 'action' => 'upload', - ), $session, self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "One of the parameters filekey, file, url, statuskey is required", - $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - } - - - /** - * @depends testLogin - */ - public function testUpload( $session ) { - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() ); - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $filePath = $filePaths[0]; - $fileSize = filesize( $filePath ); - $fileName = basename( $filePath ); - - $this->deleteFileByFileName( $fileName ); - $this->deleteFileByContent( $filePath ); - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - $exception = false; - try { - list( $result, , ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertEquals( $fileSize, (int)$result['upload']['imageinfo']['size'] ); - $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePath ); - } - - - /** - * @depends testLogin - */ - public function testUploadZeroLength( $session ) { - $mimeType = 'image/png'; - - $filePath = tempnam( wfTempDir(), "" ); - $fileName = "apiTestUploadZeroLength.png"; - - $this->deleteFileByFileName( $fileName ); - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - $exception = false; - try { - $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $this->assertContains( 'The file you submitted was empty', $e->getMessage() ); - $exception = true; - } - $this->assertTrue( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePath ); - } - - - /** - * @depends testLogin - */ - public function testUploadSameFileName( $session ) { - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 2, $extension, wfTempDir() ); - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - // we'll reuse this filename - $fileName = basename( $filePaths[0] ); - - // clear any other files with the same name - $this->deleteFileByFileName( $fileName ); - - // we reuse these params - $params = array( - 'action' => 'upload', - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - // first upload .... should succeed - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[0] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $exception = false; - try { - list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception ); - - // second upload with the same name (but different content) - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[1] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $exception = false; - try { - list( $result, , ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); // FIXME: leaks a temporary file - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Warning', $result['upload']['result'] ); - $this->assertTrue( isset( $result['upload']['warnings'] ) ); - $this->assertTrue( isset( $result['upload']['warnings']['exists'] ) ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePaths[0] ); - unlink( $filePaths[1] ); - } - - - /** - * @depends testLogin - */ - public function testUploadSameContent( $session ) { - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() ); - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $fileNames[0] = basename( $filePaths[0] ); - $fileNames[1] = "SameContentAs" . $fileNames[0]; - - // clear any other files with the same name or content - $this->deleteFileByContent( $filePaths[0] ); - $this->deleteFileByFileName( $fileNames[0] ); - $this->deleteFileByFileName( $fileNames[1] ); - - // first upload .... should succeed - - $params = array( - 'action' => 'upload', - 'filename' => $fileNames[0], - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for " . $fileNames[0], - ); - - if ( !$this->fakeUploadFile( 'file', $fileNames[0], $mimeType, $filePaths[0] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $exception = false; - try { - list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $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] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'filename' => $fileNames[1], - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for " . $fileNames[1], - ); - - $exception = false; - try { - list( $result ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); // FIXME: leaks a temporary file - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Warning', $result['upload']['result'] ); - $this->assertTrue( isset( $result['upload']['warnings'] ) ); - $this->assertTrue( isset( $result['upload']['warnings']['duplicate'] ) ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileNames[0] ); - $this->deleteFileByFilename( $fileNames[1] ); - unlink( $filePaths[0] ); - } - - /** - * @depends testLogin - */ - public function testUploadStash( $session ) { - $this->setMwGlobals( array( - 'wgUser' => self::$users['uploader']->user, // @todo FIXME: still used somewhere - ) ); - - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() ); - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $filePath = $filePaths[0]; - $fileSize = filesize( $filePath ); - $fileName = basename( $filePath ); - - $this->deleteFileByFileName( $fileName ); - $this->deleteFileByContent( $filePath ); - - if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'stash' => 1, - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - $exception = false; - try { - list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); // FIXME: leaks a temporary file - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertFalse( $exception ); - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $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'] ); - $filekey = $result['upload']['filekey']; - - // it should be visible from Special:UploadStash - // XXX ...but how to test this, with a fake WebRequest with the session? - - // now we should try to release the file from stash - $params = array( - 'action' => 'upload', - 'filekey' => $filekey, - 'filename' => $fileName, - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName, altered", - ); - - $this->clearFakeUploads(); - $exception = false; - try { - list( $result ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception, "No UsageException exception." ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePath ); - } - - /** - * @depends testLogin - */ - public function testUploadChunks( $session ) { - $this->setMwGlobals( array( - 'wgUser' => self::$users['uploader']->user, // @todo FIXME: still used somewhere - ) ); - - $chunkSize = 1048576; - // Download a large image file - // ( using RandomImageGenerator for large files is not stable ) - $mimeType = 'image/jpeg'; - $url = 'http://upload.wikimedia.org/wikipedia/commons/e/ed/Oberaargletscher_from_Oberaar%2C_2010_07.JPG'; - $filePath = wfTempDir() . '/Oberaargletscher_from_Oberaar.jpg'; - try { - // Only download if the file is not avaliable in the temp location: - if ( !is_file( $filePath ) ) { - copy( $url, $filePath ); - } - } catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $fileSize = filesize( $filePath ); - $fileName = basename( $filePath ); - - $this->deleteFileByFileName( $fileName ); - $this->deleteFileByContent( $filePath ); - - // Base upload params: - $params = array( - 'action' => 'upload', - 'stash' => 1, - 'filename' => $fileName, - 'filesize' => $fileSize, - 'offset' => 0, - ); - - // Upload chunks - $chunkSessionKey = false; - $resultOffset = 0; - // Open the file: - $handle = @fopen( $filePath, "r" ); - if ( $handle === false ) { - $this->markTestIncomplete( "could not open file: $filePath" ); - } - while ( !feof( $handle ) ) { - // Get the current chunk - $chunkData = @fread( $handle, $chunkSize ); - - // Upload the current chunk into the $_FILE object: - $this->fakeUploadChunk( 'chunk', 'blob', $mimeType, $chunkData ); - - // Check for chunkSessionKey - if ( !$chunkSessionKey ) { - // Upload fist chunk ( and get the session key ) - try { - 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: - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - // If we don't get a session key mark test incomplete. - if ( !isset( $result['upload']['filekey'] ) ) { - $this->markTestIncomplete( "no filekey provided" ); - } - $chunkSessionKey = $result['upload']['filekey']; - $this->assertEquals( 'Continue', $result['upload']['result'] ); - // First chunk should have chunkSize == offset - $this->assertEquals( $chunkSize, $result['upload']['offset'] ); - $resultOffset = $result['upload']['offset']; - continue; - } - // Filekey set to chunk session - $params['filekey'] = $chunkSessionKey; - // Update the offset ( always add chunkSize for subquent chunks should be in-sync with $result['upload']['offset'] ) - $params['offset'] += $chunkSize; - // Make sure param offset is insync with resultOffset: - $this->assertEquals( $resultOffset, $params['offset'] ); - // Upload current chunk - try { - 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: - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - - // Check if we were on the last chunk: - if ( $params['offset'] + $chunkSize >= $fileSize ) { - $this->assertEquals( 'Success', $result['upload']['result'] ); - break; - } else { - $this->assertEquals( 'Continue', $result['upload']['result'] ); - // update $resultOffset - $resultOffset = $result['upload']['offset']; - } - } - fclose( $handle ); - - // Check that we got a valid file result: - wfDebug( __METHOD__ . " hohoh filesize {$fileSize} info {$result['upload']['imageinfo']['size']}\n\n" ); - $this->assertEquals( $fileSize, $result['upload']['imageinfo']['size'] ); - $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - $filekey = $result['upload']['filekey']; - - // Now we should try to release the file from stash - $params = array( - 'action' => 'upload', - 'filekey' => $filekey, - 'filename' => $fileName, - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName, altered", - ); - $this->clearFakeUploads(); - $exception = false; - try { - list( $result ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - // 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 deleted file mode 100644 index 028ea9ff..00000000 --- a/tests/phpunit/includes/api/ApiWatchTest.php +++ /dev/null @@ -1,148 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - * @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() { - return $this->getTokenList( self::$users['sysop'] ); - } - - /** - */ - public function testWatchEdit() { - $tokens = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'edit', - 'title' => 'Help:UTPage', // Help namespace is hopefully wikitext - 'text' => 'new text', - 'token' => $tokens['edittoken'], - 'watchlist' => 'watch' ) ); - $this->assertArrayHasKey( 'edit', $data[0] ); - $this->assertArrayHasKey( 'result', $data[0]['edit'] ); - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - return $data; - } - - /** - * @depends testWatchEdit - */ - public function testWatchClear() { - $tokens = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ) ); - - if ( isset( $data[0]['query']['watchlist'] ) ) { - $wl = $data[0]['query']['watchlist']; - - foreach ( $wl as $page ) { - $data = $this->doApiRequest( array( - 'action' => 'watch', - 'title' => $page['title'], - 'unwatch' => true, - 'token' => $tokens['watchtoken'] ) ); - } - } - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ), $data ); - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'watchlist', $data[0]['query'] ); - $this->assertEquals( 0, count( $data[0]['query']['watchlist'] ) ); - - return $data; - } - - /** - */ - public function testWatchProtect() { - $tokens = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'protect', - 'token' => $tokens['protecttoken'], - 'title' => 'Help:UTPage', - 'protections' => 'edit=sysop', - 'watchlist' => 'unwatch' ) ); - - $this->assertArrayHasKey( 'protect', $data[0] ); - $this->assertArrayHasKey( 'protections', $data[0]['protect'] ); - $this->assertEquals( 1, count( $data[0]['protect']['protections'] ) ); - $this->assertArrayHasKey( 'edit', $data[0]['protect']['protections'][0] ); - } - - /** - */ - public function testGetRollbackToken() { - $this->getTokens(); - - if ( !Title::newFromText( 'Help:UTPage' )->exists() ) { - $this->markTestSkipped( "The article [[Help:UTPage]] does not exist" ); //TODO: just create it? - } - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'prop' => 'revisions', - 'titles' => 'Help:UTPage', - 'rvtoken' => 'rollback' ) ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - - if ( isset( $data[0]['query']['pages'][$key]['missing'] ) ) { - $this->markTestSkipped( "Target page (Help:UTPage) doesn't exist" ); - } - - $this->assertArrayHasKey( 'pageid', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'revisions', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 0, $data[0]['query']['pages'][$key]['revisions'] ); - $this->assertArrayHasKey( 'rollbacktoken', $data[0]['query']['pages'][$key]['revisions'][0] ); - - return $data; - } - - /** - * @group Broken - * Broken because there is currently no revision info in the $pageinfo - * - * @depends testGetRollbackToken - */ - public function testWatchRollback( $data ) { - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - $pageinfo = $data[0]['query']['pages'][$key]; - $revinfo = $pageinfo['revisions'][0]; - - try { - $data = $this->doApiRequest( array( - 'action' => 'rollback', - 'title' => 'Help:UTPage', - 'user' => $revinfo['user'], - 'token' => $pageinfo['rollbacktoken'], - 'watchlist' => 'watch' ) ); - - $this->assertArrayHasKey( 'rollback', $data[0] ); - $this->assertArrayHasKey( 'title', $data[0]['rollback'] ); - } catch ( UsageException $ue ) { - if ( $ue->getCodeString() == 'onlyauthor' ) { - $this->markTestIncomplete( "Only one author to 'Help:UTPage', cannot test rollback" ); - } else { - $this->fail( "Received error '" . $ue->getCodeString() . "'" ); - } - } - } -} diff --git a/tests/phpunit/includes/api/PrefixUniquenessTest.php b/tests/phpunit/includes/api/PrefixUniquenessTest.php deleted file mode 100644 index d9be85e3..00000000 --- a/tests/phpunit/includes/api/PrefixUniquenessTest.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -/** - * Checks that all API query modules, core and extensions, have unique prefixes. - * - * @group API - */ -class PrefixUniquenessTest extends MediaWikiTestCase { - public function testPrefixes() { - $main = new ApiMain( new FauxRequest() ); - $query = new ApiQuery( $main, 'foo', 'bar' ); - $modules = $query->getModuleManager()->getNamesWithClasses(); - $prefixes = array(); - - foreach ( $modules as $name => $class ) { - $module = new $class( $main, $name ); - $prefix = $module->getModulePrefix(); - if ( isset( $prefixes[$prefix] ) ) { - $this->fail( "Module prefix '{$prefix}' is shared between {$class} and {$prefixes[$prefix]}" ); - } - $prefixes[$module->getModulePrefix()] = $class; - } - $this->assertTrue( true ); // dummy call to make this test non-incomplete - } -} diff --git a/tests/phpunit/includes/api/RandomImageGenerator.php b/tests/phpunit/includes/api/RandomImageGenerator.php deleted file mode 100644 index 59756b21..00000000 --- a/tests/phpunit/includes/api/RandomImageGenerator.php +++ /dev/null @@ -1,468 +0,0 @@ -<?php - -/** - * RandomImageGenerator -- does what it says on the tin. - * Requires Imagick, the ImageMagick library for PHP, or the command line equivalent (usually 'convert'). - * - * Because MediaWiki tests the uniqueness of media upload content, and filenames, it is sometimes useful to generate - * files that are guaranteed (or at least very likely) to be unique in both those ways. - * This generates a number of filenames with random names and random content (colored triangles) - * - * It is also useful to have fresh content because our tests currently run in a "destructive" mode, and don't create a fresh new wiki for each - * test run. - * Consequently, if we just had a few static files we kept re-uploading, we'd get lots of warnings about matching content or filenames, - * and even if we deleted those files, we'd get warnings about archived files. - * - * This can also be used with a cronjob to generate random files all the time -- I use it to have a constant, never ending supply when I'm - * testing interactively. - * - * @file - * @author Neil Kandalgaonkar <neilk@wikimedia.org> - */ - -/** - * RandomImageGenerator: does what it says on the tin. - * Can fetch a random image, or also write a number of them to disk with random filenames. - */ -class RandomImageGenerator { - - private $dictionaryFile; - private $minWidth = 400; - private $maxWidth = 800; - private $minHeight = 400; - private $maxHeight = 800; - private $shapesToDraw = 5; - - /** - * 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) - */ - private static $orientations = array( - array( - '0thRow' => 'top', - '0thCol' => 'left', - 'exifCode' => 1, - 'counterRotation' => array( array( 1, 0 ), array( 0, 1 ) ) - ), - array( - '0thRow' => 'bottom', - '0thCol' => 'right', - 'exifCode' => 3, - 'counterRotation' => array( array( -1, 0 ), array( 0, -1 ) ) - ), - array( - '0thRow' => 'right', - '0thCol' => 'top', - 'exifCode' => 6, - 'counterRotation' => array( array( 0, 1 ), array( 1, 0 ) ) - ), - array( - '0thRow' => 'left', - '0thCol' => 'bottom', - 'exifCode' => 8, - 'counterRotation' => array( array( 0, -1 ), array( -1, 0 ) ) - ) - ); - - - public function __construct( $options = array() ) { - foreach ( array( 'dictionaryFile', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', 'shapesToDraw' ) as $property ) { - if ( isset( $options[$property] ) ) { - $this->$property = $options[$property]; - } - } - - // find the dictionary file, to generate random names - if ( !isset( $this->dictionaryFile ) ) { - foreach ( - array( - '/usr/share/dict/words', - '/usr/dict/words', - __DIR__ . '/words.txt' - ) as $dictionaryFile - ) { - if ( is_file( $dictionaryFile ) and is_readable( $dictionaryFile ) ) { - $this->dictionaryFile = $dictionaryFile; - break; - } - } - } - if ( !isset( $this->dictionaryFile ) ) { - throw new Exception( "RandomImageGenerator: dictionary file not found or not specified properly" ); - } - } - - /** - * Writes random images with random filenames to disk in the directory you specify, or current working directory - * - * @param $number Integer: number of filenames to write - * @param $format String: optional, must be understood by ImageMagick, such as 'jpg' or 'gif' - * @param $dir String: directory, optional (will default to current working directory) - * @return Array: filenames we just wrote - */ - function writeImages( $number, $format = 'jpg', $dir = null ) { - $filenames = $this->getRandomFilenames( $number, $format, $dir ); - $imageWriteMethod = $this->getImageWriteMethod( $format ); - foreach ( $filenames as $filename ) { - $this->{$imageWriteMethod}( $this->getImageSpec(), $format, $filename ); - } - - return $filenames; - } - - - /** - * Figure out how we write images. This is a factor of both format and the local system - * @param $format (a typical extension like 'svg', 'jpg', etc.) - */ - function getImageWriteMethod( $format ) { - global $wgUseImageMagick, $wgImageMagickConvertCommand; - if ( $format === 'svg' ) { - return 'writeSvg'; - } else { - // figure out how to write images - global $wgExiv2Command; - if ( class_exists( 'Imagick' ) && $wgExiv2Command && is_executable( $wgExiv2Command ) ) { - return 'writeImageWithApi'; - } elseif ( $wgUseImageMagick && $wgImageMagickConvertCommand && is_executable( $wgImageMagickConvertCommand ) ) { - return 'writeImageWithCommandLine'; - } - } - throw new Exception( "RandomImageGenerator: could not find a suitable method to write images in '$format' format" ); - } - - /** - * Return a number of randomly-generated filenames - * Each filename uses two words randomly drawn from the dictionary, like elephantine_spatula.jpg - * - * @param $number Integer: of filenames to generate - * @param $extension String: optional, defaults to 'jpg' - * @param $dir String: optional, defaults to current working directory - * @return Array: of filenames - */ - private function getRandomFilenames( $number, $extension = 'jpg', $dir = null ) { - if ( is_null( $dir ) ) { - $dir = getcwd(); - } - $filenames = array(); - foreach ( $this->getRandomWordPairs( $number ) as $pair ) { - $basename = $pair[0] . '_' . $pair[1]; - if ( !is_null( $extension ) ) { - $basename .= '.' . $extension; - } - $basename = preg_replace( '/\s+/', '', $basename ); - $filenames[] = "$dir/$basename"; - } - - return $filenames; - } - - - /** - * Generate data representing an image of random size (within limits), - * consisting of randomly colored and sized upward pointing triangles against a random background color - * (This data is used in the writeImage* methods). - * @return {Mixed} - */ - public function getImageSpec() { - $spec = array(); - - $spec['width'] = mt_rand( $this->minWidth, $this->maxWidth ); - $spec['height'] = mt_rand( $this->minHeight, $this->maxHeight ); - $spec['fill'] = $this->getRandomColor(); - - $diagonalLength = sqrt( pow( $spec['width'], 2 ) + pow( $spec['height'], 2 ) ); - - $draws = array(); - for ( $i = 0; $i <= $this->shapesToDraw; $i++ ) { - $radius = mt_rand( 0, $diagonalLength / 4 ); - if ( $radius == 0 ) { - continue; - } - $originX = mt_rand( -1 * $radius, $spec['width'] + $radius ); - $originY = mt_rand( -1 * $radius, $spec['height'] + $radius ); - $angle = mt_rand( 0, ( 3.141592 / 2 ) * $radius ) / $radius; - $legDeltaX = round( $radius * sin( $angle ) ); - $legDeltaY = round( $radius * cos( $angle ) ); - - $draw = array(); - $draw['fill'] = $this->getRandomColor(); - $draw['shape'] = array( - array( 'x' => $originX, 'y' => $originY - $radius ), - array( 'x' => $originX + $legDeltaX, 'y' => $originY + $legDeltaY ), - array( 'x' => $originX - $legDeltaX, 'y' => $originY + $legDeltaY ), - array( 'x' => $originX, 'y' => $originY - $radius ) - ); - $draws[] = $draw; - } - - $spec['draws'] = $draws; - - return $spec; - } - - /** - * Given array( array('x' => 10, 'y' => 20), array( 'x' => 30, y=> 5 ) ) - * returns "10,20 30,5" - * Useful for SVG and imagemagick command line arguments - * @param $shape: Array of arrays, each array containing x & y keys mapped to numeric values - * @return string - */ - static function shapePointsToString( $shape ) { - $points = array(); - foreach ( $shape as $point ) { - $points[] = $point['x'] . ',' . $point['y']; - } - - return join( " ", $points ); - } - - /** - * Based on image specification, write a very simple SVG file to disk. - * Ignores the background spec because transparency is cool. :) - * @param $spec: spec describing background and shapes to draw - * @param $format: file format to write (which is obviously always svg here) - * @param $filename: filename to write to - */ - public function writeSvg( $spec, $format, $filename ) { - $svg = new SimpleXmlElement( '<svg/>' ); - $svg->addAttribute( 'xmlns', 'http://www.w3.org/2000/svg' ); - $svg->addAttribute( 'version', '1.1' ); - $svg->addAttribute( 'width', $spec['width'] ); - $svg->addAttribute( 'height', $spec['height'] ); - $g = $svg->addChild( 'g' ); - foreach ( $spec['draws'] as $drawSpec ) { - $shape = $g->addChild( 'polygon' ); - $shape->addAttribute( 'fill', $drawSpec['fill'] ); - $shape->addAttribute( 'points', self::shapePointsToString( $drawSpec['shape'] ) ); - } - - if ( !$fh = fopen( $filename, 'w' ) ) { - throw new Exception( "couldn't open $filename for writing" ); - } - fwrite( $fh, $svg->asXML() ); - if ( !fclose( $fh ) ) { - throw new Exception( "couldn't close $filename" ); - } - } - - /** - * Based on an image specification, write such an image to disk, using Imagick PHP extension - * @param $spec: spec describing background and circles to draw - * @param $format: file format to write - * @param $filename: filename to write to - */ - public function writeImageWithApi( $spec, $format, $filename ) { - // this is a hack because I can't get setImageOrientation() to work. See below. - global $wgExiv2Command; - - $image = new Imagick(); - /** - * If the format is 'jpg', will also add a random orientation -- the image will be drawn rotated with triangle points - * facing in some direction (0, 90, 180 or 270 degrees) and a countering rotation should turn the triangle points upward again - */ - $orientation = self::$orientations[0]; // default is normal orientation - if ( $format == 'jpg' ) { - $orientation = self::$orientations[array_rand( self::$orientations )]; - $spec = self::rotateImageSpec( $spec, $orientation['counterRotation'] ); - } - - $image->newImage( $spec['width'], $spec['height'], new ImagickPixel( $spec['fill'] ) ); - - foreach ( $spec['draws'] as $drawSpec ) { - $draw = new ImagickDraw(); - $draw->setFillColor( $drawSpec['fill'] ); - $draw->polygon( $drawSpec['shape'] ); - $image->drawImage( $draw ); - } - - $image->setImageFormat( $format ); - - // this doesn't work, even though it's documented to do so... - // $image->setImageOrientation( $orientation['exifCode'] ); - - $image->writeImage( $filename ); - - // because the above setImageOrientation call doesn't work... nor can I get an external imagemagick binary to do this either... - // hacking this for now (only works if you have exiv2 installed, a program to read and manipulate exif) - if ( $wgExiv2Command ) { - $cmd = wfEscapeShellArg( $wgExiv2Command ) - . " -M " - . wfEscapeShellArg( "set Exif.Image.Orientation " . $orientation['exifCode'] ) - . " " - . wfEscapeShellArg( $filename ); - - $retval = 0; - $err = wfShellExec( $cmd, $retval ); - if ( $retval !== 0 ) { - print "Error with $cmd: $retval, $err\n"; - } - } - } - - /** - * Given an image specification, produce rotated version - * 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 - */ - private static function rotateImageSpec( &$spec, $matrix ) { - $tSpec = array(); - $dims = self::matrixMultiply2x2( $matrix, $spec['width'], $spec['height'] ); - $correctionX = 0; - $correctionY = 0; - if ( $dims['x'] < 0 ) { - $correctionX = abs( $dims['x'] ); - } - if ( $dims['y'] < 0 ) { - $correctionY = abs( $dims['y'] ); - } - $tSpec['width'] = abs( $dims['x'] ); - $tSpec['height'] = abs( $dims['y'] ); - $tSpec['fill'] = $spec['fill']; - $tSpec['draws'] = array(); - foreach ( $spec['draws'] as $draw ) { - $tDraw = array( - 'fill' => $draw['fill'], - 'shape' => array() - ); - foreach ( $draw['shape'] as $point ) { - $tPoint = self::matrixMultiply2x2( $matrix, $point['x'], $point['y'] ); - $tPoint['x'] += $correctionX; - $tPoint['y'] += $correctionY; - $tDraw['shape'][] = $tPoint; - } - $tSpec['draws'][] = $tDraw; - } - - return $tSpec; - } - - /** - * Given a matrix and a pair of images, return new position - * @param $matrix: 2x2 rotation matrix - * @param $x: x-coordinate number - * @param $y: y-coordinate number - * @return Array transformed with properties x, y - */ - private static function matrixMultiply2x2( $matrix, $x, $y ) { - return array( - 'x' => $x * $matrix[0][0] + $y * $matrix[0][1], - 'y' => $x * $matrix[1][0] + $y * $matrix[1][1] - ); - } - - - /** - * Based on an image specification, write such an image to disk, using the command line ImageMagick program ('convert'). - * - * Sample command line: - * $ convert -size 100x60 xc:rgb(90,87,45) \ - * -draw 'fill rgb(12,34,56) polygon 41,39 44,57 50,57 41,39' \ - * -draw 'fill rgb(99,123,231) circle 59,39 56,57' \ - * -draw 'fill rgb(240,12,32) circle 50,21 50,3' filename.png - * - * @param $spec: spec describing background and shapes to draw - * @param $format: file format to write (unused by this method but kept so it has the same signature as writeImageWithApi) - * @param $filename: filename to write to - */ - public function writeImageWithCommandLine( $spec, $format, $filename ) { - global $wgImageMagickConvertCommand; - $args = array(); - $args[] = "-size " . wfEscapeShellArg( $spec['width'] . 'x' . $spec['height'] ); - $args[] = wfEscapeShellArg( "xc:" . $spec['fill'] ); - foreach ( $spec['draws'] as $draw ) { - $fill = $draw['fill']; - $polygon = self::shapePointsToString( $draw['shape'] ); - $drawCommand = "fill $fill polygon $polygon"; - $args[] = '-draw ' . wfEscapeShellArg( $drawCommand ); - } - $args[] = wfEscapeShellArg( $filename ); - - $command = wfEscapeShellArg( $wgImageMagickConvertCommand ) . " " . implode( " ", $args ); - $retval = null; - wfShellExec( $command, $retval ); - - return ( $retval === 0 ); - } - - /** - * Generate a string of random colors for ImageMagick or SVG, like "rgb(12, 37, 98)" - * - * @return {String} - */ - public function getRandomColor() { - $components = array(); - for ( $i = 0; $i <= 2; $i++ ) { - $components[] = mt_rand( 0, 255 ); - } - - return 'rgb(' . join( ', ', $components ) . ')'; - } - - /** - * Get an array of random pairs of random words, like array( array( 'foo', 'bar' ), array( 'quux', 'baz' ) ); - * - * @param $number Integer: number of pairs - * @return Array: of two-element arrays - */ - private function getRandomWordPairs( $number ) { - $lines = $this->getRandomLines( $number * 2 ); - // construct pairs of words - $pairs = array(); - $count = count( $lines ); - for ( $i = 0; $i < $count; $i += 2 ) { - $pairs[] = array( $lines[$i], $lines[$i + 1] ); - } - - return $pairs; - } - - /** - * Return N random lines from a file - * - * Will throw exception if the file could not be read or if it had fewer lines than requested. - * - * @param $number_desired Integer: number of lines desired - * @return Array: of exactly n elements, drawn randomly from lines the file - */ - private function getRandomLines( $number_desired ) { - $filepath = $this->dictionaryFile; - - // initialize array of lines - $lines = array(); - for ( $i = 0; $i < $number_desired; $i++ ) { - $lines[] = null; - } - - /* - * This algorithm obtains N random lines from a file in one single pass. It does this by replacing elements of - * a fixed-size array of lines, less and less frequently as it reads the file. - */ - $fh = fopen( $filepath, "r" ); - if ( !$fh ) { - throw new Exception( "couldn't open $filepath" ); - } - $line_number = 0; - $max_index = $number_desired - 1; - while ( !feof( $fh ) ) { - $line = fgets( $fh ); - if ( $line !== false ) { - $line_number++; - $line = trim( $line ); - if ( mt_rand( 0, $line_number ) <= $max_index ) { - $lines[mt_rand( 0, $max_index )] = $line; - } - } - } - fclose( $fh ); - if ( $line_number < $number_desired ) { - throw new Exception( "not enough lines in $filepath" ); - } - - return $lines; - } -} diff --git a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php b/tests/phpunit/includes/api/format/ApiFormatPhpTest.php deleted file mode 100644 index a0bbb2dc..00000000 --- a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiFormatPhpTest extends ApiFormatTestBase { - - 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/format/ApiFormatTestBase.php b/tests/phpunit/includes/api/format/ApiFormatTestBase.php deleted file mode 100644 index 153f2cf4..00000000 --- a/tests/phpunit/includes/api/format/ApiFormatTestBase.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -abstract class ApiFormatTestBase extends ApiTestCase { - protected function apiRequest( $format, $params, $data = null ) { - $data = parent::doApiRequest( $params, $data, true ); - - $module = $data[3]; - - $printer = $module->createPrinterByName( $format ); - $printer->setUnescapeAmps( false ); - - $printer->initPrinter( false ); - - ob_start(); - $printer->execute(); - $out = ob_get_clean(); - - $printer->closePrinter(); - - return $out; - } -} diff --git a/tests/phpunit/includes/api/generateRandomImages.php b/tests/phpunit/includes/api/generateRandomImages.php deleted file mode 100644 index 87f5c4c0..00000000 --- a/tests/phpunit/includes/api/generateRandomImages.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Bootstrapping for test image file generation - * - * @file - */ - -// Start up MediaWiki in command-line mode -require_once __DIR__ . "/../../../../maintenance/Maintenance.php"; -require __DIR__ . "/RandomImageGenerator.php"; - -class GenerateRandomImages extends Maintenance { - - public function getDbType() { - return Maintenance::DB_NONE; - } - - public function execute() { - - $getOptSpec = array( - 'dictionaryFile::', - 'minWidth::', - 'maxWidth::', - 'minHeight::', - 'maxHeight::', - 'shapesToDraw::', - 'shape::', - - 'number::', - 'format::' - ); - $options = getopt( null, $getOptSpec ); - - $format = isset( $options['format'] ) ? $options['format'] : 'jpg'; - unset( $options['format'] ); - - $number = isset( $options['number'] ) ? intval( $options['number'] ) : 10; - unset( $options['number'] ); - - $randomImageGenerator = new RandomImageGenerator( $options ); - $randomImageGenerator->writeImages( $number, $format ); - } -} - -$maintClass = 'GenerateRandomImages'; -require RUN_MAINTENANCE_IF_MAIN; diff --git a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php b/tests/phpunit/includes/api/query/ApiQueryBasicTest.php deleted file mode 100644 index 1a2aa832..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php +++ /dev/null @@ -1,395 +0,0 @@ -<?php -/** - * - * - * Created on Feb 6, 2013 - * - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com" - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -require_once 'ApiQueryTestBase.php'; - -/** These tests validate basic functionality of the api query module - * - * @group API - * @group Database - * @group medium - */ -class ApiQueryBasicTest extends ApiQueryTestBase { - /** - * Create a set of pages. These must not change, otherwise the tests might give wrong results. - * @see MediaWikiTestCase::addDBData() - */ - function addDBData() { - try { - if ( Title::newFromText( 'AQBT-All' )->exists() ) { - return; - } - - // Ordering is important, as it will be returned in the same order as stored in the index - $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' ); - $this->editPage( 'AQBT-Categories', '[[Category:AQBT-Cat]]' ); - $this->editPage( 'AQBT-Links', '[[AQBT-All]] [[AQBT-Categories]] [[AQBT-Templates]]' ); - $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' ); - $this->editPage( 'AQBT-T', 'Content', '', NS_TEMPLATE ); - - // Refresh due to the bug with listing transclusions as links if they don't exist - $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' ); - $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' ); - } catch ( Exception $e ) { - $this->exceptionFromAddDBData = $e; - } - } - - private static $links = array( - array( 'prop' => 'links', 'titles' => 'AQBT-All' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All', - 'links' => array( - array( 'ns' => 0, 'title' => 'AQBT-Links' ), - ) - ) - ) ) - ); - - private static $templates = array( - array( 'prop' => 'templates', 'titles' => 'AQBT-All' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All', - 'templates' => array( - array( 'ns' => 10, 'title' => 'Template:AQBT-T' ), - ) - ) - ) ) - ); - - private static $categories = array( - array( 'prop' => 'categories', 'titles' => 'AQBT-All' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All', - 'categories' => array( - array( 'ns' => 14, 'title' => 'Category:AQBT-Cat' ), - ) - ) - ) ) - ); - - private static $allpages = array( - array( 'list' => 'allpages', 'apprefix' => 'AQBT-' ), - array( 'allpages' => array( - array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ), - 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-' ), - array( 'alllinks' => array( - array( 'ns' => 0, 'title' => 'AQBT-All' ), - 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-' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All' ), - '2' => array( - 'pageid' => 2, - 'ns' => 0, - 'title' => 'AQBT-Categories' ), - '3' => array( - 'pageid' => 3, - 'ns' => 0, - 'title' => 'AQBT-Links' ), - '4' => array( - 'pageid' => 4, - 'ns' => 0, - 'title' => 'AQBT-Templates' ), - ) ) - ); - - private static $generatorLinks = array( - array( 'generator' => 'links', 'titles' => 'AQBT-Links' ), - array( 'pages' => array( - '1' => array( - 'pageid' => 1, - 'ns' => 0, - 'title' => 'AQBT-All' ), - '2' => array( - 'pageid' => 2, - 'ns' => 0, - 'title' => 'AQBT-Categories' ), - '4' => array( - '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' ), - array( 'pages' => array( - '1' => array( 'templates' => array( - array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ), - '4' => array( 'templates' => array( - array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ), - ) ) - ); - - /** - * Test basic props - */ - public function testProps() { - $this->check( self::$links ); - $this->check( self::$templates ); - $this->check( self::$categories ); - } - - /** - * Test basic lists - */ - public function testLists() { - $this->check( self::$allpages ); - $this->check( self::$alllinks ); - $this->check( self::$alltransclusions ); - // This test is temporarily disabled until a sqlite bug is fixed - // $this->check( self::$allcategories ); - $this->check( self::$backlinks ); - $this->check( self::$embeddedin ); - $this->check( self::$categorymembers ); - } - - /** - * Test basic lists - */ - public function testAllTogether() { - - // All props together - $this->check( $this->merge( - self::$links, - self::$templates, - self::$categories - ) ); - - // All lists together - $this->check( $this->merge( - self::$allpages, - self::$alllinks, - self::$alltransclusions, - // This test is temporarily disabled until a sqlite bug is fixed - // self::$allcategories, - self::$backlinks, - self::$embeddedin, - self::$categorymembers - ) ); - - // All props+lists together - $this->check( $this->merge( - self::$links, - self::$templates, - self::$categories, - self::$allpages, - self::$alllinks, - self::$alltransclusions, - // This test is temporarily disabled until a sqlite bug is fixed - // self::$allcategories, - self::$backlinks, - self::$embeddedin, - self::$categorymembers - ) ); - } - - /** - * Test basic lists - */ - public function testGenerator() { - // generator=allpages - $this->check( self::$generatorAllpages ); - // generator=allpages & list=allpages - $this->check( $this->merge( - self::$generatorAllpages, - self::$allpages ) ); - // generator=links - $this->check( self::$generatorLinks ); - // generator=links & prop=links - $this->check( $this->merge( - self::$generatorLinks, - self::$generatorLinksPropLinks ) ); - // generator=links & prop=templates - $this->check( $this->merge( - self::$generatorLinks, - self::$generatorLinksPropTemplates ) ); - // generator=links & prop=links|templates - $this->check( $this->merge( - self::$generatorLinks, - self::$generatorLinksPropLinks, - self::$generatorLinksPropTemplates ) ); - // generator=links & prop=links|templates & list=allpages|... - $this->check( $this->merge( - self::$generatorLinks, - self::$generatorLinksPropLinks, - self::$generatorLinksPropTemplates, - self::$allpages, - self::$alllinks, - self::$alltransclusions, - // This test is temporarily disabled until a sqlite bug is fixed - // self::$allcategories, - self::$backlinks, - self::$embeddedin, - 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 - */ - private function mergeExpected( &$all, $item ) { - foreach ( $item as $k => $v ) { - if ( array_key_exists( $k, $all ) ) { - if ( is_array( $all[$k] ) ) { - $this->mergeExpected( $all[$k], $v ); - } else { - $this->assertEquals( $all[$k], $v ); - } - } else { - $all[$k] = $v; - } - } - } - - /** - * Recursively compare arrays, ignoring mismatches in numeric key and pageids. - * @param $expected array expected values - * @param $result array returned values - */ - private function assertQueryResults( $expected, $result ) { - reset( $expected ); - reset( $result ); - while ( true ) { - $e = each( $expected ); - $r = each( $result ); - // If either of the arrays is shorter, abort. If both are done, success. - $this->assertEquals( (bool)$e, (bool)$r ); - if ( !$e ) { - break; // done - } - // continue only if keys are identical or both keys are numeric - $this->assertTrue( $e['key'] === $r['key'] || ( is_numeric( $e['key'] ) && is_numeric( $r['key'] ) ) ); - // don't compare pageids - if ( $e['key'] !== 'pageid' ) { - // If values are arrays, compare recursively, otherwise compare with === - if ( is_array( $e['value'] ) && is_array( $r['value'] ) ) { - $this->assertQueryResults( $e['value'], $r['value'] ); - } else { - $this->assertEquals( $e['value'], $r['value'] ); - } - } - } - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php b/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php deleted file mode 100644 index 4d5ddbae..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryContinue2Test.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com" - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once 'ApiQueryContinueTestBase.php'; - -/** - * @group API - * @group Database - * @group medium - */ -class ApiQueryContinue2Test extends ApiQueryContinueTestBase { - /** - * Create a set of pages. These must not change, otherwise the tests might give wrong results. - * @see MediaWikiTestCase::addDBData() - */ - function addDBData() { - try { - $this->editPage( 'AQCT73462-A', '**AQCT73462-A** [[AQCT73462-B]] [[AQCT73462-C]]' ); - $this->editPage( 'AQCT73462-B', '[[AQCT73462-A]] **AQCT73462-B** [[AQCT73462-C]]' ); - $this->editPage( 'AQCT73462-C', '[[AQCT73462-A]] [[AQCT73462-B]] **AQCT73462-C**' ); - $this->editPage( 'AQCT73462-A', '**AQCT73462-A** [[AQCT73462-B]] [[AQCT73462-C]]' ); - $this->editPage( 'AQCT73462-B', '[[AQCT73462-A]] **AQCT73462-B** [[AQCT73462-C]]' ); - $this->editPage( 'AQCT73462-C', '[[AQCT73462-A]] [[AQCT73462-B]] **AQCT73462-C**' ); - } catch ( Exception $e ) { - $this->exceptionFromAddDBData = $e; - } - } - - /** - * @medium - */ - public function testA() { - $this->mVerbose = false; - $mk = function ( $g, $p, $gDir ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT73462-', - 'prop' => 'links', - 'gaplimit' => "$g", - 'pllimit' => "$p", - 'gapdir' => $gDir ? "ascending" : "descending", - ); - }; - // 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' ); - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryContinueTest.php b/tests/phpunit/includes/api/query/ApiQueryContinueTest.php deleted file mode 100644 index f494e9ca..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryContinueTest.php +++ /dev/null @@ -1,313 +0,0 @@ -<?php -/** - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com" - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - */ - -require_once 'ApiQueryContinueTestBase.php'; - -/** - * These tests validate the new continue functionality of the api query module by - * doing multiple requests with varying parameters, merging the results, and checking - * that the result matches the full data received in one no-limits call. - * - * @group API - * @group Database - * @group medium - */ -class ApiQueryContinueTest extends ApiQueryContinueTestBase { - /** - * Create a set of pages. These must not change, otherwise the tests might give wrong results. - * @see MediaWikiTestCase::addDBData() - */ - function addDBData() { - try { - $this->editPage( 'Template:AQCT-T1', '**Template:AQCT-T1**' ); - $this->editPage( 'Template:AQCT-T2', '**Template:AQCT-T2**' ); - $this->editPage( 'Template:AQCT-T3', '**Template:AQCT-T3**' ); - $this->editPage( 'Template:AQCT-T4', '**Template:AQCT-T4**' ); - $this->editPage( 'Template:AQCT-T5', '**Template:AQCT-T5**' ); - - $this->editPage( 'AQCT-1', '**AQCT-1** {{AQCT-T2}} {{AQCT-T3}} {{AQCT-T4}} {{AQCT-T5}}' ); - $this->editPage( 'AQCT-2', '[[AQCT-1]] **AQCT-2** {{AQCT-T3}} {{AQCT-T4}} {{AQCT-T5}}' ); - $this->editPage( 'AQCT-3', '[[AQCT-1]] [[AQCT-2]] **AQCT-3** {{AQCT-T4}} {{AQCT-T5}}' ); - $this->editPage( 'AQCT-4', '[[AQCT-1]] [[AQCT-2]] [[AQCT-3]] **AQCT-4** {{AQCT-T5}}' ); - $this->editPage( 'AQCT-5', '[[AQCT-1]] [[AQCT-2]] [[AQCT-3]] [[AQCT-4]] **AQCT-5**' ); - } catch ( Exception $e ) { - $this->exceptionFromAddDBData = $e; - } - } - - /** - * Test smart continue - list=allpages - * @medium - */ - public function test1List() { - $this->mVerbose = false; - $mk = function ( $l ) { - return array( - 'list' => 'allpages', - 'apprefix' => 'AQCT-', - 'aplimit' => "$l", - ); - }; - $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' ); - } - - /** - * Test smart continue - list=allpages|alltransclusions - * @medium - */ - public function test2Lists() { - $this->mVerbose = false; - $mk = function ( $l1, $l2 ) { - return array( - 'list' => 'allpages|alltransclusions', - 'apprefix' => 'AQCT-', - 'atprefix' => 'AQCT-', - 'atunique' => '', - 'aplimit' => "$l1", - 'atlimit' => "$l2", - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=allpages, prop=links - * @medium - */ - public function testGen1Prop() { - $this->mVerbose = false; - $mk = function ( $g, $p ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'prop' => 'links', - 'pllimit' => "$p", - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=allpages, prop=links|templates - * @medium - */ - public function testGen2Prop() { - $this->mVerbose = false; - $mk = function ( $g, $p1, $p2 ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'prop' => 'links|templates', - 'pllimit' => "$p1", - 'tllimit' => "$p2", - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=allpages, prop=links, list=alltransclusions - * @medium - */ - public function testGen1Prop1List() { - $this->mVerbose = false; - $mk = function ( $g, $p, $l ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'prop' => 'links', - 'pllimit' => "$p", - 'list' => 'alltransclusions', - 'atprefix' => 'AQCT-', - 'atunique' => '', - 'atlimit' => "$l", - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=allpages, prop=links|templates, - * list=alllinks|alltransclusions, meta=siteinfo - * @medium - */ - public function testGen2Prop2List1Meta() { - $this->mVerbose = false; - $mk = function ( $g, $p1, $p2, $l1, $l2 ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'prop' => 'links|templates', - 'pllimit' => "$p1", - 'tllimit' => "$p2", - 'list' => 'alllinks|alltransclusions', - 'alprefix' => 'AQCT-', - 'alunique' => '', - 'allimit' => "$l1", - 'atprefix' => 'AQCT-', - 'atunique' => '', - 'atlimit' => "$l2", - 'meta' => 'siteinfo', - 'siprop' => 'namespaces', - ); - }; - // 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' ); - } - - /** - * Test smart continue - generator=templates, prop=templates - * @medium - */ - public function testSameGenAndProp() { - $this->mVerbose = false; - $mk = function ( $g, $gDir, $p, $pDir ) { - return array( - 'titles' => 'AQCT-1', - 'generator' => 'templates', - 'gtllimit' => "$g", - 'gtldir' => $gDir ? 'ascending' : 'descending', - 'prop' => 'templates', - 'tllimit' => "$p", - 'tldir' => $pDir ? 'ascending' : 'descending', - ); - }; - // generator + 1 prop - $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, 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, 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' ); - } - - /** - * Test smart continue - generator=allpages, list=allpages - * @medium - */ - public function testSameGenList() { - $this->mVerbose = false; - $mk = function ( $g, $gDir, $l, $pDir ) { - return array( - 'generator' => 'allpages', - 'gapprefix' => 'AQCT-', - 'gaplimit' => "$g", - 'gapdir' => $gDir ? 'ascending' : 'descending', - 'list' => 'allpages', - 'apprefix' => 'AQCT-', - 'aplimit' => "$l", - 'apdir' => $pDir ? 'ascending' : 'descending', - ); - }; - // generator + 1 list - $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' ); - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php b/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php deleted file mode 100644 index fbb1e640..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php +++ /dev/null @@ -1,209 +0,0 @@ -<?php -/** - * - * - * Created on Jan 1, 2013 - * - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com" - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -require_once 'ApiQueryTestBase.php'; - -abstract class ApiQueryContinueTestBase extends ApiQueryTestBase { - - /** - * Enable to print in-depth debugging info during the test run - */ - protected $mVerbose = false; - - /** - * Run query() and compare against expected values - */ - protected function checkC( $expected, $params, $expectedCount, $id, $continue = true ) { - $result = $this->query( $params, $expectedCount, $id, $continue ); - $this->assertResult( $expected, $result, $id ); - } - - /** - * Run query in a loop until no more values are available - * @param array $params api parameters - * @param int $expectedCount max number of iterations - * @param string $id unit test id - * @param boolean $useContinue true to use smart continue - * @return mixed: merged results data array - * @throws Exception - */ - protected function query( $params, $expectedCount, $id, $useContinue = true ) { - if ( isset( $params['action'] ) ) { - $this->assertEquals( 'query', $params['action'], 'Invalid query action' ); - } else { - $params['action'] = 'query'; - } - if ( $useContinue && !isset( $params['continue'] ) ) { - $params['continue'] = ''; - } - $count = 0; - $result = array(); - $continue = array(); - do { - $request = array_merge( $params, $continue ); - 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"; - } - try { - $data = $this->doApiRequest( $request ); - } catch ( Exception $e ) { - throw new Exception( "$id on $count", 0, $e ); - } - $data = $data[0]; - if ( isset( $data['warnings'] ) ) { - $warnings = json_encode( $data['warnings'] ); - $this->fail( "$id Warnings on #$count in $reqStr\n$warnings" ); - } - $this->assertArrayHasKey( 'query', $data, "$id no 'query' on #$count in $reqStr" ); - if ( isset( $data['continue'] ) ) { - $continue = $data['continue']; - unset( $data['continue'] ); - } else { - $continue = array(); - } - if ( $this->mVerbose ) { - $this->printResult( $data ); - } - $this->mergeResult( $result, $data ); - $count++; - if ( empty( $continue ) ) { - // $this->assertEquals( $expectedCount, $count, "$id finished early" ); - 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 ); - } - - private function printResult( $data ) { - $q = $data['query']; - $print = array(); - if ( isset( $q['pages'] ) ) { - foreach ( $q['pages'] as $p ) { - $m = $p['title']; - if ( isset( $p['links'] ) ) { - $m .= '/[' . implode( ',', array_map( - function ( $v ) { - return $v['title']; - }, - $p['links'] ) ) . ']'; - } - if ( isset( $p['categories'] ) ) { - $m .= '/(' . implode( ',', array_map( - function ( $v ) { - return str_replace( 'Category:', '', $v['title'] ); - }, - $p['categories'] ) ) . ')'; - } - $print[] = $m; - } - } - 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"; - } - - private static function GetItems( $q, $moduleName, $name, &$print ) { - if ( isset( $q[$moduleName] ) ) { - $print[] = "*$name/[" . implode( ',', - array_map( function ( $v ) { - return $v['title']; - }, - $q[$moduleName] ) ) . ']'; - } - } - - /** - * Recursively merge the new result returned from the query to the previous results. - * @param mixed $results - * @param mixed $newResult - * @param bool $numericIds If true, treat keys as ids to be merged instead of appending - */ - protected function mergeResult( &$results, $newResult, $numericIds = false ) { - $this->assertEquals( is_array( $results ), is_array( $newResult ), 'Type of result and data do not match' ); - if ( !is_array( $results ) ) { - $this->assertEquals( $results, $newResult, 'Repeated result must be the same as before' ); - } else { - $sort = null; - 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 ) { - return strcmp( $a['title'], $b['title'] ); - }; - } else { - $sort = false; - } - } - $keyExists = array_key_exists( $key, $results ); - if ( is_numeric( $key ) ) { - if ( $numericIds ) { - if ( !$keyExists ) { - $results[$key] = $value; - } else { - $this->mergeResult( $results[$key], $value ); - } - } else { - $results[] = $value; - } - } elseif ( !$keyExists ) { - $results[$key] = $value; - } else { - $this->mergeResult( $results[$key], $value, $key === 'pages' ); - } - } - if ( $numericIds ) { - ksort( $results, SORT_NUMERIC ); - } elseif ( $sort !== null && $sort !== false ) { - uasort( $results, $sort ); - } - } - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php b/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php deleted file mode 100644 index 1bca2256..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiQueryRevisionsTest extends ApiTestCase { - - /** - * @group medium - */ - public function testContentComesWithContentModelAndFormat() { - $pageName = 'Help:' . __METHOD__; - $title = Title::newFromText( $pageName ); - $page = WikiPage::factory( $title ); - $page->doEdit( 'Some text', 'inserting content' ); - - $apiResult = $this->doApiRequest( array( - 'action' => 'query', - 'prop' => 'revisions', - 'titles' => $pageName, - 'rvprop' => 'content', - ) ); - $this->assertArrayHasKey( 'query', $apiResult[0] ); - $this->assertArrayHasKey( 'pages', $apiResult[0]['query'] ); - foreach ( $apiResult[0]['query']['pages'] as $page ) { - $this->assertArrayHasKey( 'revisions', $page ); - foreach ( $page['revisions'] as $revision ) { - $this->assertArrayHasKey( 'contentformat', $revision, - 'contentformat should be included when asking content so client knows how to interpret it' - ); - $this->assertArrayHasKey( 'contentmodel', $revision, - 'contentmodel should be included when asking content so client knows how to interpret it' - ); - } - } - } -} diff --git a/tests/phpunit/includes/api/query/ApiQueryTest.php b/tests/phpunit/includes/api/query/ApiQueryTest.php deleted file mode 100644 index f5645555..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryTest.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php - -/** - * @group API - * @group Database - * @group medium - */ -class ApiQueryTest extends ApiTestCase { - - protected function setUp() { - parent::setUp(); - $this->doLogin(); - } - - public function testTitlesGetNormalized() { - - global $wgMetaNamespace; - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => 'Project:articleA|article_B' ) ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'normalized', $data[0]['query'] ); - - // Forge a normalized title - $to = Title::newFromText( $wgMetaNamespace . ':ArticleA' ); - - $this->assertEquals( - array( - 'from' => 'Project:articleA', - 'to' => $to->getPrefixedText(), - ), - $data[0]['query']['normalized'][0] - ); - - $this->assertEquals( - array( - 'from' => 'article_B', - 'to' => 'Article B' - ), - $data[0]['query']['normalized'][1] - ); - } - - public function testTitlesAreRejectedIfInvalid() { - $title = false; - while ( !$title || Title::newFromText( $title )->exists() ) { - $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) ); - } - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => $title . '|Talk:' ) ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $this->assertEquals( 2, count( $data[0]['query']['pages'] ) ); - - $this->assertArrayHasKey( -2, $data[0]['query']['pages'] ); - $this->assertArrayHasKey( -1, $data[0]['query']['pages'] ); - - $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 deleted file mode 100644 index 8ee8ea96..00000000 --- a/tests/phpunit/includes/api/query/ApiQueryTestBase.php +++ /dev/null @@ -1,150 +0,0 @@ -<?php -/** - * - * - * Created on Feb 10, 2013 - * - * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com" - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -/** This class has some common functionality for testing query module - */ -abstract class ApiQueryTestBase extends ApiTestCase { - - const PARAM_ASSERT = <<<STR -Each parameter must be an array of two elements, -first - an array of params to the API call, -and the second array - expected results as returned by the API -STR; - - /** - * Merges all requests parameter + expected values into one - * @param ... list of arrays, each of which contains exactly two - * @return array - */ - protected function merge( /*...*/ ) { - $request = array(); - $expected = array(); - 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 ); - } - - /** - * Check that the parameter is a valid two element array, - * with the first element being API request and the second - expected result - */ - private function validateRequestExpectedPair( $v ) { - $this->assertType( 'array', $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; - } - - /** - * Recursively merges the expected values in the $item into the $all - */ - private function mergeExpected( &$all, $item ) { - foreach ( $item as $k => $v ) { - if ( array_key_exists( $k, $all ) ) { - if ( is_array( $all[$k] ) ) { - $this->mergeExpected( $all[$k], $v ); - } else { - $this->assertEquals( $all[$k], $v ); - } - } else { - $all[$k] = $v; - } - } - } - - /** - * Checks that the request's result matches the expected results. - * @param $values array is a two element array( request, expected_results ) - * @throws Exception - */ - protected function check( $values ) { - list( $req, $exp ) = $this->validateRequestExpectedPair( $values ); - if ( !array_key_exists( 'action', $req ) ) { - $req['action'] = 'query'; - } - foreach ( $req as &$val ) { - if ( is_array( $val ) ) { - $val = implode( '|', array_unique( $val ) ); - } - } - $result = $this->doApiRequest( $req ); - $this->assertResult( array( 'query' => $exp ), $result[0], $req ); - } - - protected function assertResult( $exp, $result, $message = '' ) { - try { - $this->assertResultRecursive( $exp, $result ); - } catch ( Exception $e ) { - if ( is_array( $message ) ) { - $message = http_build_query( $message ); - } - print "\nRequest: $message\n"; - print "\nExpected:\n"; - print_r( $exp ); - print "\nResult:\n"; - print_r( $result ); - throw $e; // rethrow it - } - } - - /** - * Recursively compare arrays, ignoring mismatches in numeric key and pageids. - * @param $expected array expected values - * @param $result array returned values - */ - private function assertResultRecursive( $expected, $result ) { - reset( $expected ); - reset( $result ); - while ( true ) { - $e = each( $expected ); - $r = each( $result ); - // If either of the arrays is shorter, abort. If both are done, success. - $this->assertEquals( (bool)$e, (bool)$r ); - if ( !$e ) { - break; // done - } - // continue only if keys are identical or both keys are numeric - $this->assertTrue( $e['key'] === $r['key'] || ( is_numeric( $e['key'] ) && is_numeric( $r['key'] ) ) ); - // don't compare pageids - if ( $e['key'] !== 'pageid' ) { - // If values are arrays, compare recursively, otherwise compare with === - if ( is_array( $e['value'] ) && is_array( $r['value'] ) ) { - $this->assertResultRecursive( $e['value'], $r['value'] ); - } else { - $this->assertEquals( $e['value'], $r['value'] ); - } - } - } - } -} diff --git a/tests/phpunit/includes/api/words.txt b/tests/phpunit/includes/api/words.txt deleted file mode 100644 index 7ce23ee3..00000000 --- a/tests/phpunit/includes/api/words.txt +++ /dev/null @@ -1,1000 +0,0 @@ -Andaquian -Anoplanthus -Araquaju -Astrophyton -Avarish -Batonga -Bdellidae -Betoyan -Bismarck -Britishness -Carmen -Chatillon -Clement -Coryphaena -Croton -Cyrillianism -Dagomba -Decimus -Dichorisandra -Duculinae -Empusa -Escallonia -Fathometer -Fon -Fundulinae -Gadswoons -Gederathite -Gemini -Gerbera -Gregarinida -Gyracanthus -Halopsychidae -Hasidim -Hemerobius -Ichthyosauridae -Iscariot -Jeames -Jesuitry -Jovian -Judaization -Katie -Ladin -Langhian -Lapithaean -Lisette -Macrochira -Malaxis -Malvastrum -Maranhao -Marxian -Maurist -Metrosideros -Micky -Microsporon -Odacidae -Ophiuchid -Osmorhiza -Paguma -Palesman -Papayaceae -Pastinaca -Philoxenian -Pleurostigma -Rarotongan -Rhodoraceae -Rong -Saho -Sanyakoan -Sardanapalian -Sauropoda -Sedentaria -Shambu -Shukulumbwe -Solonian -Spaniardization -Spirochaetaceae -Stomatopoda -Stratiotes -Taiwanhemp -Titanically -Venetianed -Victrola -Yuman -abatis -abaton -abjoint -acanthoma -acari -acceptance -actinography -acuteness -addiment -adelite -adelomorphic -adelphogamy -adipocele -aelurophobia -affined -aflaunt -agathokakological -aischrolatreia -alarmedly -alebench -aleurone -allelotropic -allerion -alloplastic -allowable -alternacy -alternariose -altricial -ambitionist -amendment -amiableness -amicableness -ammo -amortizable -anchorate -anemometrically -angelocracy -angelological -anodal -anomalure -antedate -antiagglutinin -antirationalist -antiscorbutic -antisplasher -antithesize -antiunionist -antoecian -apolegamic -appropriation -archididascalian -archival -arteriophlebotomy -articulable -asseveration -assignation -atelo -atrienses -atrophy -atterminement -atypic -automower -aveloz -awrist -azteca -bairnteam -balsamweed -bannerman -beardy -becry -beek -beggarwise -bescab -bestness -bethel -bewildering -bibliophilism -bitterblain -blakeberyed -boccarella -bocedization -boobyalla -bourbon -bowbent -bowerbird -brachygnathous -brail -branchiferous -brelaw -brew -brideweed -bridgeable -brombenzamide -buddler -burbankian -burr -buskin -cacochymical -calefactory -caliper -canaliculus -candidature -canellaceous -canniness -canning -cantilene -carbonatation -carthamic -caseum -caudated -causationist -ceruleite -chalder -chalta -charmel -chekan -chillness -chirogymnast -chirpling -chlorinous -cholanthrene -chondroblast -chromatography -chromophilous -chronical -cicatrice -cinchonine -city -clubbing -coastal -coaxially -coercible -coeternity -coff -coinventor -collyba -combinator -complanation -comprehensibility -conchuela -congenital -context -contranatural -corallum -cordately -cornupete -corolliferous -coroneted -corticosterone -coseat -cottage -crocetin -crossleted -crottels -curvedness -cycadeous -cyclism -cylindrically -cynanche -cyrtoceratitic -cystospasm -danceress -dancette -dawny -daydreamy -debar -decarburization -decorousness -decrepitness -delirious -deozonizer -dermatosis -desma -deutencephalic -diacetate -diarthrodial -diathermy -dicolic -dimastigate -dimidiation -dipetto -disavowable -disintrench -disman -dismay -disorder -disoxygenation -dithionous -dogman -dragonfly -dramatical -drawspan -drubbly -drunk -duskly -ecderonic -ectocuniform -ectocyst -ehrwaldite -electrocute -elemicin -embracing -emotionality -enactment -enamor -enclave -endameba -endochylous -endocrinologist -endolymph -endothecal -entasia -epigeous -episcopicide -epitrichial -erminee -erraticalness -eruptivity -erythrocytoschisis -esperance -estuous -eucrystalline -eugeny -evacuant -everbloomer -evocation -exarchateship -exasperate -excorticate -excrementary -exile -expandedly -exponency -expressionist -expulsion -extemporary -extollation -extortive -extrabulbar -extraprostatic -facticide -fairer -fakery -fasibitikite -fatiscent -fearless -febrifuge -ferie -fibrousness -fingered -fisheye -flagpole -flagrantness -fleche -fluidism -folliculin -footbreadth -forceps -forecontrive -forthbring -foveated -fuchsin -fungicidal -funori -gamelang -gametically -garvanzo -gasoliner -gastrophile -germproof -gerontism -gigantical -glaciology -godmotherhood -gooseherd -gordunite -gove -gracilis -greathead -grieveship -guidable -gyromancy -gyrostat -habitus -hailweed -handhole -hangalai -haznadar -heliced -hemihypertrophy -hemimorphic -hemistrumectomy -heptavalent -heptite -herbalist -herpetology -hesperid -hexacarbon -hieromnemon -hobbyless -holodactylic -homoeoarchy -hopperings -hospitable -houseboat -huh -huntedly -hydroponics -hydrosomal -hyperdactylia -hyperperistalsis -hypogeocarpous -ideogram -idiopathical -illegitimate -imambarah -impotently -improvise -impuberal -inaccurately -incarnant -inchoation -incliner -incredulous -indiscriminateness -indulgenced -inebriation -inexpressiveness -infibulate -inflectedness -iniome -ink -inquietly -insaturable -insinuative -instiller -institutive -insultproof -interactionist -intercensal -interpenetrable -intertranspicuous -intrinsicality -inwards -iridiocyte -iridoparalysis -irreportable -isoprene -isosmotic -izard -jacuaru -jaculative -jerkined -joe -joyous -julienne -justicehood -kali -kalidium -katha -kathal -keelage -keratomycosis -khaki -khedival -kinkily -knife -kolo -kraken -kwarta -labba -labber -laboress -lacunar -latch -lauric -lawter -lectotype -leeches -legible -lepidosteoid -leucobasalt -leverer -libellate -limnimeter -lithography -lithotypic -locomotor -logarithmetically -logistician -lyncine -lysogenesis -machan -macromyelon -maharana -mandibulate -manganapatite -marchpane -mas -masochistic -mastaba -matching -meditatively -megalopolitan -melaniline -mentum -mercaptides -mestome -metasomatism -meterless -micronuclear -micropetalous -microreaction -microsporophore -mileway -milliarium -millisecond -misbind -miscollocation -misreader -modernicide -modification -modulant -monkfish -monoamino -monocarbide -monographical -morphinomaniac -mullein -munge -mutilate -mycophagist -myelosarcoma -myospasm -myriadly -nagaika -naphthionate -natant -naviculaeform -nayward -neallotype -necrophilia -nectared -neigher -neogamous -neurodynia -neurorthopteran -nidation -nieceship -nitrobacteria -nitrosification -nogheaded -nonassertive -noneuphonious -nonextant -nonincrease -nonintermittent -nonmetallic -nonprehensile -nonremunerative -nonsocial -nonvesting -noontime -noreaster -nounal -nub -nucleoplasm -nullisome -numero -numerous -oblongatal -observe -obtusilingual -obvert -occipitoatlantal -oceanside -ochlophobist -odontiasis -opalescence -opticon -oraculousness -orarium -organically -orthopedically -ostosis -overadvance -overbuilt -overdiscouragement -overdoer -overhardy -overjocular -overmagnify -overofficered -overpotent -overprizer -overrunner -overshrink -oversimply -oversplash -ovology -oxskin -oxychloride -oxygenant -ozokerite -pactional -palaeoanthropography -palaeographical -palaeopsychology -palliasse -palpebral -pandaric -pantelegraph -papicolist -papulate -parakinetic -parasitism -parochialic -parochialize -passionlike -patch -paucidentate -pawnbrokeress -pecite -pecky -pedipulation -pellitory -perfilograph -periblast -perigemmal -periost -periplus -perishable -periwig -permansive -persistingly -persymmetrical -phantom -phasmatrope -philocaly -philogyny -philosophister -philotherianism -phorology -phototrophic -phrator -phratral -phthisipneumony -physogastry -phytologic -phytoptid -pianograph -picqueter -piculet -pigeoner -pimaric -pinesap -pist -planometer -platano -playful -plea -pleuropneumonic -plowwoman -plump -pluviographical -pneumocele -podophthalmate -polyad -polythalamian -poppyhead -portamento -portmanteau -portraitlike -possible -potassamide -powderer -praepubis -preanesthetic -prebarbaric -predealer -predomination -prefactory -preirrigational -prelector -presbytership -presecure -preservable -prespecialist -preventionism -prewound -princely -priorship -proannexationist -proanthropos -probeable -probouleutic -profitless -proplasma -prosectorial -protecting -protochemistry -protosulphate -pseudoataxia -psilology -psychoneurotic -pterygial -publicist -purgation -purplishness -putatively -pyracene -pyrenomycete -pyromancy -pyrophone -quadroon -quailhead -qualifier -quaternal -rabblelike -rambunctious -rapidness -ratably -rationalism -razor -reannoy -recultivation -regulable -reimplant -reimposition -reimprison -reinjure -reinspiration -reintroduce -remantle -reprehensibility -reptant -require -resteal -restful -returnability -revisableness -rewash -rewhirl -reyield -rhizotomy -rhodamine -rigwiddie -rimester -ripper -rippet -rockish -rockwards -rollicky -roosters -rooted -rosal -rozum -saccharated -sagamore -sagy -salesmanship -salivous -sallet -salta -saprostomous -satiation -sauropsid -sawarra -sawback -scabish -scabrate -scampavia -scientificophilosophical -scirrosity -scoliometer -scolopendrelloid -secantly -seignioral -semibull -semic -seminarianism -semiped -semiprivate -semispherical -semispontaneous -seneschal -septendecimal -serotherapist -servation -sesquisulphuret -severish -sextipartite -sextubercular -shipyard -shuckpen -siderosis -silex -sillyhow -silverbelly -silverbelly -simulacrum -sisham -sixte -skeiner -skiapod -slopped -slubby -smalts -sockmaker -solute -somethingness -somnify -southwester -spathilla -spectrochemical -sphagnology -spinales -spiriting -spirling -spirochetemia -spreadboard -spurflower -squawdom -squeezing -staircase -staker -stamphead -statolith -stekan -stellulate -stinker -stomodaea -streamingly -strikingness -strouthocamelian -stuprum -subacutely -subboreal -subcontractor -subendorsement -subprofitable -subserviate -subsneer -subungual -sucuruju -sugan -sulphocarbolate -summerwood -superficialist -superinference -superregenerative -supplicate -suspendible -synchronizer -syntectic -tachyglossate -tailless -taintment -takingly -taletelling -tarpon -tasteful -taxeater -taxy -teache -teachless -teg -tegmen -teletyper -temperable -ten -tenent -teskere -testes -thallogen -thapsia -thewness -thickety -thiobacteria -thorniness -throwing -thyroprivic -tinnitus -tocalote -tolerationist -tonalamatl -torvous -totality -tottering -toug -tracheopathia -tragedical -translucent -trifoveolate -trilaurin -trophoplasmatic -trunkless -turbanless -turnpiker -twangle -twitterboned -ultraornate -umbilication -unabatingly -unabjured -unadequateness -unaffectedness -unarriving -unassorted -unattacked -unbenumbed -unboasted -unburning -uncensorious -uncongested -uncontemnedly -uncontemporary -uncrook -uncrystallizability -uncurb -uncustomariness -underbillow -undercanopy -underestimation -underhanging -underpetticoated -underpropped -undersole -understocking -underworld -undevout -undisappointing -undistinctive -unfiscal -unfluted -unfreckled -ungentilize -unglobe -unhelped -unhomogeneously -unifoliate -uninflammable -uninterrogated -unisonal -unkindled -unlikeableness -unlisty -unlocked -unmoving -unmultipliable -unnestled -unnoticed -unobservable -unobviated -unoffensively -unofficerlike -unpoetic -unpractically -unquestionableness -unrehearsed -unrevised -unrhetorical -unsadden -unsaluting -unscriptural -unseeking -unshowed -unsolicitous -unsprouted -unsubjective -unsubsidized -unsymbolic -untenant -unterrified -untranquil -untraversed -untrusty -untying -unwillful -unwinding -upspring -uptwist -urachovesical -uropygial -vagabondism -varicoid -varletess -vasal -ventrocaudal -verisimilitude -vermigerous -vibrometer -viminal -virus -vocationalism -voguey -vulnerability -waggle -wamblingly -warmus -waxer -waying -wedgeable -wellmaker -whomever -wigged -witchlike -wokas -woodrowel -woodsman -woolding -xanthelasmic -xiphosternum -yachtman -yachtsmanlike -yelp -zoophytal
\ No newline at end of file diff --git a/tests/phpunit/includes/cache/GenderCacheTest.php b/tests/phpunit/includes/cache/GenderCacheTest.php deleted file mode 100644 index ce2db5d7..00000000 --- a/tests/phpunit/includes/cache/GenderCacheTest.php +++ /dev/null @@ -1,104 +0,0 @@ -<?php - -/** - * @group Database - * @group Cache - */ -class GenderCacheTest extends MediaWikiLangTestCase { - - protected function setUp() { - global $wgDefaultUserOptions; - parent::setUp(); - //ensure the correct default gender - $wgDefaultUserOptions['gender'] = 'unknown'; - } - - function addDBData() { - $user = User::newFromName( 'UTMale' ); - if ( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTMalePassword' ); - } - //ensure the right gender - $user->setOption( 'gender', 'male' ); - $user->saveSettings(); - - $user = User::newFromName( 'UTFemale' ); - if ( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTFemalePassword' ); - } - //ensure the right gender - $user->setOption( 'gender', 'female' ); - $user->saveSettings(); - - $user = User::newFromName( 'UTDefaultGender' ); - if ( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTDefaultGenderPassword' ); - } - //ensure the default gender - $user->setOption( 'gender', null ); - $user->saveSettings(); - } - - /** - * test usernames - * - * @dataProvider provideUserGenders - * @covers GenderCache::getGenderOf - */ - public function testUserName( $username, $expectedGender ) { - $genderCache = GenderCache::singleton(); - $gender = $genderCache->getGenderOf( $username ); - $this->assertEquals( $gender, $expectedGender, "GenderCache normal" ); - } - - /** - * genderCache should work with user objects, too - * - * @dataProvider provideUserGenders - * @covers GenderCache::getGenderOf - */ - public function testUserObjects( $username, $expectedGender ) { - $genderCache = GenderCache::singleton(); - $user = User::newFromName( $username ); - $gender = $genderCache->getGenderOf( $user ); - $this->assertEquals( $gender, $expectedGender, "GenderCache normal" ); - } - - public static function provideUserGenders() { - return array( - array( 'UTMale', 'male' ), - array( 'UTFemale', 'female' ), - array( 'UTDefaultGender', 'unknown' ), - array( 'UTNotExist', 'unknown' ), - //some not valid user - array( '127.0.0.1', 'unknown' ), - array( 'user@test', 'unknown' ), - ); - } - - /** - * test strip of subpages to avoid unnecessary queries - * against the never existing username - * - * @dataProvider provideStripSubpages - * @covers GenderCache::getGenderOf - */ - public function testStripSubpages( $pageWithSubpage, $expectedGender ) { - $genderCache = GenderCache::singleton(); - $gender = $genderCache->getGenderOf( $pageWithSubpage ); - $this->assertEquals( $gender, $expectedGender, "GenderCache must strip of subpages" ); - } - - public static function provideStripSubpages() { - return array( - array( 'UTMale/subpage', 'male' ), - array( 'UTFemale/subpage', 'female' ), - array( 'UTDefaultGender/subpage', 'unknown' ), - array( 'UTNotExist/subpage', 'unknown' ), - array( '127.0.0.1/subpage', 'unknown' ), - ); - } -} diff --git a/tests/phpunit/includes/cache/MessageCacheTest.php b/tests/phpunit/includes/cache/MessageCacheTest.php deleted file mode 100644 index 803acf73..00000000 --- a/tests/phpunit/includes/cache/MessageCacheTest.php +++ /dev/null @@ -1,128 +0,0 @@ -<?php - -/** - * @group Database - * @group Cache - * @covers MessageCache - */ -class MessageCacheTest extends MediaWikiLangTestCase { - - protected function setUp() { - parent::setUp(); - $this->configureLanguages(); - MessageCache::singleton()->enable(); - } - - /** - * Helper function -- setup site language for testing - */ - protected function configureLanguages() { - // for the test, we need the content language to be anything but English, - // let's choose e.g. German (de) - $langCode = 'de'; - $langObj = Language::factory( $langCode ); - - $this->setMwGlobals( array( - 'wgLanguageCode' => $langCode, - 'wgLang' => $langObj, - 'wgContLang' => $langObj, - ) ); - } - - function addDBData() { - $this->configureLanguages(); - - // Set up messages and fallbacks ab -> ru -> de - $this->makePage( 'FallbackLanguageTest-Full', 'ab' ); - $this->makePage( 'FallbackLanguageTest-Full', 'ru' ); - $this->makePage( 'FallbackLanguageTest-Full', 'de' ); - - // Fallbacks where ab does not exist - $this->makePage( 'FallbackLanguageTest-Partial', 'ru' ); - $this->makePage( 'FallbackLanguageTest-Partial', 'de' ); - - // Fallback to the content language - $this->makePage( 'FallbackLanguageTest-ContLang', 'de' ); - - // Add customizations for an existing message. - $this->makePage( 'sunday', 'ru' ); - - // Full key tests -- always want russian - $this->makePage( 'MessageCacheTest-FullKeyTest', 'ab' ); - $this->makePage( 'MessageCacheTest-FullKeyTest', 'ru' ); - - // In content language -- get base if no derivative - $this->makePage( 'FallbackLanguageTest-NoDervContLang', 'de', 'de/none', false ); - } - - /** - * Helper function for addDBData -- adds a simple page to the database - * - * @param string $title Title of page to be created - * @param string $lang Language and content of the created page - * @param string|null $content Content of the created page, or null for a generic string - * @param bool $createSubPage Set to false if a root page should be created - */ - protected function makePage( $title, $lang, $content = null, $createSubPage = true ) { - global $wgContLang; - - if ( $content === null ) { - $content = $lang; - } - if ( $lang !== $wgContLang->getCode() || $createSubPage ) { - $title = "$title/$lang"; - } - - $title = Title::newFromText( $title, NS_MEDIAWIKI ); - $wikiPage = new WikiPage( $title ); - $contentHandler = ContentHandler::makeContent( $content, $title ); - $wikiPage->doEditContent( $contentHandler, "$lang translation test case" ); - } - - /** - * Test message fallbacks, bug #1495 - * - * @dataProvider provideMessagesForFallback - */ - public function testMessageFallbacks( $message, $lang, $expectedContent ) { - $result = MessageCache::singleton()->get( $message, true, $lang ); - $this->assertEquals( $expectedContent, $result, "Message fallback failed." ); - } - - function provideMessagesForFallback() { - return array( - array( 'FallbackLanguageTest-Full', 'ab', 'ab' ), - array( 'FallbackLanguageTest-Partial', 'ab', 'ru' ), - array( 'FallbackLanguageTest-ContLang', 'ab', 'de' ), - array( 'FallbackLanguageTest-None', 'ab', false ), - - // Existing message with customizations on the fallbacks - array( 'sunday', 'ab', 'амҽыш' ), - - // bug 46579 - array( 'FallbackLanguageTest-NoDervContLang', 'de', 'de/none' ), - // UI language different from content language should only use de/none as last option - array( 'FallbackLanguageTest-NoDervContLang', 'fit', 'de/none' ), - ); - } - - /** - * There's a fallback case where the message key is given as fully qualified -- this - * should ignore the passed $lang and use the language from the key - * - * @dataProvider provideMessagesForFullKeys - */ - public function testFullKeyBehaviour( $message, $lang, $expectedContent ) { - $result = MessageCache::singleton()->get( $message, true, $lang, true ); - $this->assertEquals( $expectedContent, $result, "Full key message fallback failed." ); - } - - function provideMessagesForFullKeys() { - return array( - array( 'MessageCacheTest-FullKeyTest/ru', 'ru', 'ru' ), - array( 'MessageCacheTest-FullKeyTest/ru', 'ab', 'ru' ), - array( 'MessageCacheTest-FullKeyTest/ru/foo', 'ru', false ), - ); - } - -} diff --git a/tests/phpunit/includes/cache/ProcessCacheLRUTest.php b/tests/phpunit/includes/cache/ProcessCacheLRUTest.php deleted file mode 100644 index d3793d83..00000000 --- a/tests/phpunit/includes/cache/ProcessCacheLRUTest.php +++ /dev/null @@ -1,237 +0,0 @@ -<?php - -/** - * Test for ProcessCacheLRU class. - * - * Note that it uses the ProcessCacheLRUTestable class which extends some - * properties and methods visibility. That class is defined at the end of the - * file containing this class. - * - * @group Cache - */ -class ProcessCacheLRUTest extends MediaWikiTestCase { - - /** - * Helper to verify emptiness of a cache object. - * Compare against an array so we get the cache content difference. - */ - function assertCacheEmpty( $cache, $msg = 'Cache should be empty' ) { - $this->assertAttributeEquals( array(), 'cache', $cache, $msg ); - } - - /** - * Helper to fill a cache object passed by reference - */ - function fillCache( &$cache, $numEntries ) { - // Fill cache with three values - for ( $i = 1; $i <= $numEntries; $i++ ) { - $cache->set( "cache-key-$i", "prop-$i", "value-$i" ); - } - } - - /** - * Generates an array of what would be expected in cache for a given cache - * size and a number of entries filled in sequentially - */ - function getExpectedCache( $cacheMaxEntries, $entryToFill ) { - $expected = array(); - - if ( $entryToFill === 0 ) { - # The cache is empty! - return array(); - } elseif ( $entryToFill <= $cacheMaxEntries ) { - # Cache is not fully filled - $firstKey = 1; - } else { - # Cache overflowed - $firstKey = 1 + $entryToFill - $cacheMaxEntries; - } - - $lastKey = $entryToFill; - - for ( $i = $firstKey; $i <= $lastKey; $i++ ) { - $expected["cache-key-$i"] = array( "prop-$i" => "value-$i" ); - } - - return $expected; - } - - /** - * Highlight diff between assertEquals and assertNotSame - */ - public function testPhpUnitArrayEquality() { - $one = array( 'A' => 1, 'B' => 2 ); - $two = array( 'B' => 2, 'A' => 1 ); - $this->assertEquals( $one, $two ); // == - $this->assertNotSame( $one, $two ); // === - } - - /** - * @dataProvider provideInvalidConstructorArg - * @expectedException MWException - */ - public function testConstructorGivenInvalidValue( $maxSize ) { - new ProcessCacheLRUTestable( $maxSize ); - } - - /** - * Value which are forbidden by the constructor - */ - public static function provideInvalidConstructorArg() { - return array( - array( null ), - array( array() ), - array( new stdClass() ), - array( 0 ), - array( '5' ), - array( -1 ), - ); - } - - public function testAddAndGetAKey() { - $oneCache = new ProcessCacheLRUTestable( 1 ); - $this->assertCacheEmpty( $oneCache ); - - // First set just one value - $oneCache->set( 'cache-key', 'prop1', 'value1' ); - $this->assertEquals( 1, $oneCache->getEntriesCount() ); - $this->assertTrue( $oneCache->has( 'cache-key', 'prop1' ) ); - $this->assertEquals( 'value1', $oneCache->get( 'cache-key', 'prop1' ) ); - } - - public function testDeleteOldKey() { - $oneCache = new ProcessCacheLRUTestable( 1 ); - $this->assertCacheEmpty( $oneCache ); - - $oneCache->set( 'cache-key', 'prop1', 'value1' ); - $oneCache->set( 'cache-key', 'prop1', 'value2' ); - $this->assertEquals( 'value2', $oneCache->get( 'cache-key', 'prop1' ) ); - } - - /** - * This test that we properly overflow when filling a cache with - * a sequence of always different cache-keys. Meant to verify we correclty - * delete the older key. - * - * @dataProvider provideCacheFilling - * @param $cacheMaxEntries Maximum entry the created cache will hold - * @param $entryToFill Number of entries to insert in the created cache. - */ - public function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) { - $cache = new ProcessCacheLRUTestable( $cacheMaxEntries ); - $this->fillCache( $cache, $entryToFill ); - - $this->assertSame( - $this->getExpectedCache( $cacheMaxEntries, $entryToFill ), - $cache->getCache(), - "Filling a $cacheMaxEntries entries cache with $entryToFill entries" - ); - } - - /** - * Provider for testFillingCache - */ - public static function provideCacheFilling() { - // ($cacheMaxEntries, $entryToFill, $msg='') - return array( - array( 1, 0 ), - array( 1, 1 ), - array( 1, 2 ), # overflow - array( 5, 33 ), # overflow - ); - } - - /** - * Create a cache with only one remaining entry then update - * the first inserted entry. Should bump it to the top. - */ - public function testReplaceExistingKeyShouldBumpEntryToTop() { - $maxEntries = 3; - - $cache = new ProcessCacheLRUTestable( $maxEntries ); - // Fill cache leaving just one remaining slot - $this->fillCache( $cache, $maxEntries - 1 ); - - // Set an existing cache key - $cache->set( "cache-key-1", "prop-1", "new-value-for-1" ); - - $this->assertSame( - array( - 'cache-key-2' => array( 'prop-2' => 'value-2' ), - 'cache-key-1' => array( 'prop-1' => 'new-value-for-1' ), - ), - $cache->getCache() - ); - } - - public function testRecentlyAccessedKeyStickIn() { - $cache = new ProcessCacheLRUTestable( 2 ); - $cache->set( 'first', 'prop1', 'value1' ); - $cache->set( 'second', 'prop2', 'value2' ); - - // Get first - $cache->get( 'first', 'prop1' ); - // Cache a third value, should invalidate the least used one - $cache->set( 'third', 'prop3', 'value3' ); - - $this->assertFalse( $cache->has( 'second', 'prop2' ) ); - } - - /** - * This first create a full cache then update the value for the 2nd - * filled entry. - * 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). - */ - public function testReplaceExistingKeyInAFullCacheShouldBumpToTop() { - $maxEntries = 3; - - $cache = new ProcessCacheLRUTestable( $maxEntries ); - $this->fillCache( $cache, $maxEntries ); - - // Set an existing cache key - $cache->set( "cache-key-2", "prop-2", "new-value-for-2" ); - $this->assertSame( - array( - 'cache-key-1' => array( 'prop-1' => 'value-1' ), - 'cache-key-3' => array( 'prop-3' => 'value-3' ), - 'cache-key-2' => array( 'prop-2' => 'new-value-for-2' ), - ), - $cache->getCache() - ); - $this->assertEquals( 'new-value-for-2', - $cache->get( 'cache-key-2', 'prop-2' ) - ); - } - - public function testBumpExistingKeyToTop() { - $cache = new ProcessCacheLRUTestable( 3 ); - $this->fillCache( $cache, 3 ); - - // Set the very first cache key to a new value - $cache->set( "cache-key-1", "prop-1", "new value for 1" ); - $this->assertEquals( - array( - 'cache-key-2' => array( 'prop-2' => 'value-2' ), - 'cache-key-3' => array( 'prop-3' => 'value-3' ), - 'cache-key-1' => array( 'prop-1' => 'new value for 1' ), - ), - $cache->getCache() - ); - } -} - -/** - * Overrides some ProcessCacheLRU methods and properties accessibility. - */ -class ProcessCacheLRUTestable extends ProcessCacheLRU { - public $cache = array(); - - public function getCache() { - return $this->cache; - } - - public function getEntriesCount() { - return count( $this->cache ); - } -} diff --git a/tests/phpunit/includes/content/ContentHandlerTest.php b/tests/phpunit/includes/content/ContentHandlerTest.php deleted file mode 100644 index aedf594d..00000000 --- a/tests/phpunit/includes/content/ContentHandlerTest.php +++ /dev/null @@ -1,451 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * - * @note Declare that we are using the database, because otherwise we'll fail in the "databaseless" test run. - * This is because the LinkHolderArray used by the parser needs database access. - * - */ -class ContentHandlerTest extends MediaWikiTestCase { - - public function setUp() { - global $wgContLang; - parent::setUp(); - - $this->setMwGlobals( array( - 'wgExtraNamespaces' => array( - 12312 => 'Dummy', - 12313 => 'Dummy_talk', - ), - // The below tests assume that namespaces not mentioned here (Help, User, MediaWiki, ..) - // default to CONTENT_MODEL_WIKITEXT. - 'wgNamespaceContentModels' => array( - 12312 => 'testing', - ), - 'wgContentHandlers' => array( - CONTENT_MODEL_WIKITEXT => 'WikitextContentHandler', - CONTENT_MODEL_JAVASCRIPT => 'JavaScriptContentHandler', - CONTENT_MODEL_CSS => 'CssContentHandler', - CONTENT_MODEL_TEXT => 'TextContentHandler', - 'testing' => 'DummyContentHandlerForTesting', - ), - ) ); - - // Reset namespace cache - MWNamespace::getCanonicalNamespaces( true ); - $wgContLang->resetNamespaces(); - } - - public function tearDown() { - global $wgContLang; - - // Reset namespace cache - MWNamespace::getCanonicalNamespaces( true ); - $wgContLang->resetNamespaces(); - - parent::tearDown(); - } - - public static function dataGetDefaultModelFor() { - return array( - array( 'Help:Foo', CONTENT_MODEL_WIKITEXT ), - array( 'Help:Foo.js', CONTENT_MODEL_WIKITEXT ), - array( 'Help:Foo/bar.js', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo.js', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'User:Foo/bar.css', CONTENT_MODEL_CSS ), - array( 'User talk:Foo/bar.css', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.js.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'User:Foo/bar.xxx', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.js', CONTENT_MODEL_JAVASCRIPT ), - array( 'MediaWiki:Foo.css', CONTENT_MODEL_CSS ), - array( 'MediaWiki:Foo.JS', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.CSS', CONTENT_MODEL_WIKITEXT ), - array( 'MediaWiki:Foo.css.xxx', CONTENT_MODEL_WIKITEXT ), - ); - } - - /** - * @dataProvider dataGetDefaultModelFor - * @covers ContentHandler::getDefaultModelFor - */ - public function testGetDefaultModelFor( $title, $expectedModelId ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedModelId, ContentHandler::getDefaultModelFor( $title ) ); - } - - /** - * @dataProvider dataGetDefaultModelFor - * @covers ContentHandler::getForTitle - */ - public function testGetForTitle( $title, $expectedContentModel ) { - $title = Title::newFromText( $title ); - $handler = ContentHandler::getForTitle( $title ); - $this->assertEquals( $expectedContentModel, $handler->getModelID() ); - } - - public static function dataGetLocalizedName() { - return array( - array( null, null ), - array( "xyzzy", null ), - - // XXX: depends on content language - array( CONTENT_MODEL_JAVASCRIPT, '/javascript/i' ), - ); - } - - /** - * @dataProvider dataGetLocalizedName - * @covers ContentHandler::getLocalizedName - */ - public function testGetLocalizedName( $id, $expected ) { - $name = ContentHandler::getLocalizedName( $id ); - - if ( $expected ) { - $this->assertNotNull( $name, "no name found for content model $id" ); - $this->assertTrue( preg_match( $expected, $name ) > 0, - "content model name for #$id did not match pattern $expected" - ); - } else { - $this->assertEquals( $id, $name, "localization of unknown model $id should have " - . "fallen back to use the model id directly." - ); - } - } - - public static function dataGetPageLanguage() { - global $wgLanguageCode; - - return array( - array( "Main", $wgLanguageCode ), - array( "Dummy:Foo", $wgLanguageCode ), - array( "MediaWiki:common.js", 'en' ), - array( "User:Foo/common.js", 'en' ), - array( "MediaWiki:common.css", 'en' ), - array( "User:Foo/common.css", 'en' ), - array( "User:Foo", $wgLanguageCode ), - - array( CONTENT_MODEL_JAVASCRIPT, 'javascript' ), - ); - } - - /** - * @dataProvider dataGetPageLanguage - * @covers ContentHandler::getPageLanguage - */ - public function testGetPageLanguage( $title, $expected ) { - if ( is_string( $title ) ) { - $title = Title::newFromText( $title ); - } - - $expected = wfGetLangObj( $expected ); - - $handler = ContentHandler::getForTitle( $title ); - $lang = $handler->getPageLanguage( $title ); - - $this->assertEquals( $expected->getCode(), $lang->getCode() ); - } - - public static function dataGetContentText_Null() { - return array( - array( 'fail' ), - array( 'serialize' ), - array( 'ignore' ), - ); - } - - /** - * @dataProvider dataGetContentText_Null - * @covers ContentHandler::getContentText - */ - public function testGetContentText_Null( $contentHandlerTextFallback ) { - $this->setMwGlobals( 'wgContentHandlerTextFallback', $contentHandlerTextFallback ); - - $content = null; - - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( '', $text ); - } - - public static function dataGetContentText_TextContent() { - return array( - array( 'fail' ), - array( 'serialize' ), - array( 'ignore' ), - ); - } - - /** - * @dataProvider dataGetContentText_TextContent - * @covers ContentHandler::getContentText - */ - public function testGetContentText_TextContent( $contentHandlerTextFallback ) { - $this->setMwGlobals( 'wgContentHandlerTextFallback', $contentHandlerTextFallback ); - - $content = new WikitextContent( "hello world" ); - - $text = ContentHandler::getContentText( $content ); - $this->assertEquals( $content->getNativeData(), $text ); - } - - /** - * 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" ); - - ContentHandler::getContentText( $content ); - } - - /** - * @covers ContentHandler::getContentText - */ - public function testGetContentText_NonTextContent_serialize() { - $this->setMwGlobals( 'wgContentHandlerTextFallback', 'serialize' ); - - $content = new DummyContentForTesting( "hello world" ); - - $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" ); - - $text = ContentHandler::getContentText( $content ); - $this->assertNull( $text ); - } - - /* - public static function makeContent( $text, Title $title, $modelId = null, $format = null ) {} - */ - - public static function dataMakeContent() { - return array( - array( 'hallo', 'Help:Test', null, null, CONTENT_MODEL_WIKITEXT, 'hallo', false ), - array( 'hallo', 'MediaWiki:Test.js', null, null, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ), - array( serialize( 'hallo' ), 'Dummy:Test', null, null, "testing", 'hallo', false ), - - array( 'hallo', 'Help:Test', null, CONTENT_FORMAT_WIKITEXT, CONTENT_MODEL_WIKITEXT, 'hallo', false ), - array( 'hallo', 'MediaWiki:Test.js', null, CONTENT_FORMAT_JAVASCRIPT, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ), - array( serialize( 'hallo' ), 'Dummy:Test', null, "testing", "testing", 'hallo', false ), - - array( 'hallo', 'Help:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ), - array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ), - array( serialize( 'hallo' ), 'Dummy:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, serialize( 'hallo' ), false ), - - array( 'hallo', 'Help:Test', CONTENT_MODEL_WIKITEXT, "testing", null, null, true ), - array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, "testing", null, null, true ), - array( 'hallo', 'Dummy:Test', CONTENT_MODEL_JAVASCRIPT, "testing", null, null, true ), - ); - } - - /** - * @dataProvider dataMakeContent - * @covers ContentHandler::makeContent - */ - public function testMakeContent( $data, $title, $modelId, $format, $expectedModelId, $expectedNativeData, $shouldFail ) { - $title = Title::newFromText( $title ); - - try { - $content = ContentHandler::makeContent( $data, $title, $modelId, $format ); - - if ( $shouldFail ) { - $this->fail( "ContentHandler::makeContent should have failed!" ); - } - - $this->assertEquals( $expectedModelId, $content->getModel(), 'bad model id' ); - $this->assertEquals( $expectedNativeData, $content->getNativeData(), 'bads native data' ); - } catch ( MWException $ex ) { - if ( !$shouldFail ) { - $this->fail( "ContentHandler::makeContent failed unexpectedly: " . $ex->getMessage() ); - } else { - // dummy, so we don't get the "test did not perform any assertions" message. - $this->assertTrue( true ); - } - } - } - - /* - public function testSupportsSections() { - $this->markTestIncomplete( "not yet implemented" ); - } - */ - - /** - * @covers ContentHandler::runLegacyHooks - */ - public function testRunLegacyHooks() { - Hooks::register( 'testRunLegacyHooks', __CLASS__ . '::dummyHookHandler' ); - - $content = new WikitextContent( 'test text' ); - $ok = ContentHandler::runLegacyHooks( 'testRunLegacyHooks', array( 'foo', &$content, 'bar' ), false ); - - $this->assertTrue( $ok, "runLegacyHooks should have returned true" ); - $this->assertEquals( "TEST TEXT", $content->getNativeData() ); - } - - public static function dummyHookHandler( $foo, &$text, $bar ) { - if ( $text === null || $text === false ) { - return false; - } - - $text = strtoupper( $text ); - - return true; - } -} - -class DummyContentHandlerForTesting extends ContentHandler { - - public function __construct( $dataModel ) { - parent::__construct( $dataModel, array( "testing" ) ); - } - - /** - * Serializes Content object of the type supported by this ContentHandler. - * - * @param Content $content the Content object to serialize - * @param null $format the desired serialization format - * @return String serialized form of the content - */ - public function serializeContent( Content $content, $format = null ) { - return $content->serialize(); - } - - /** - * Unserializes a Content object of the type supported by this ContentHandler. - * - * @param $blob String serialized form of the content - * @param null $format the format used for serialization - * @return Content the Content object created by deserializing $blob - */ - public function unserializeContent( $blob, $format = null ) { - $d = unserialize( $blob ); - - return new DummyContentForTesting( $d ); - } - - /** - * Creates an empty Content object of the type supported by this ContentHandler. - * - */ - public function makeEmptyContent() { - return new DummyContentForTesting( '' ); - } -} - -class DummyContentForTesting extends AbstractContent { - - public function __construct( $data ) { - parent::__construct( "testing" ); - - $this->data = $data; - } - - public function serialize( $format = null ) { - return serialize( $this->data ); - } - - /** - * @return String a string representing the content in a way useful for building a full text search index. - * If no useful representation exists, this method returns an empty string. - */ - public function getTextForSearchIndex() { - return ''; - } - - /** - * @return String the wikitext to include when another page includes this content, or false if the content is not - * includable in a wikitext page. - */ - public function getWikitextForTransclusion() { - return false; - } - - /** - * Returns a textual representation of the content suitable for use in edit summaries and log messages. - * - * @param int $maxlength Maximum length of the summary text. - * @return string The summary text. - */ - public function getTextForSummary( $maxlength = 250 ) { - return ''; - } - - /** - * Returns native represenation of the data. Interpretation depends on the data model used, - * as given by getDataModel(). - * - * @return mixed the native representation of the content. Could be a string, a nested array - * structure, an object, a binary blob... anything, really. - */ - public function getNativeData() { - return $this->data; - } - - /** - * returns the content's nominal size in bogo-bytes. - * - * @return int - */ - public function getSize() { - return strlen( $this->data ); - } - - /** - * Return a copy of this Content object. The following must be true for the object returned - * if $copy = $original->copy() - * - * * get_class($original) === get_class($copy) - * * $original->getModel() === $copy->getModel() - * * $original->equals( $copy ) - * - * If and only if the Content object is imutable, the copy() method can and should - * return $this. That is, $copy === $original may be true, but only for imutable content - * objects. - * - * @return Content. A copy of this object. - */ - public function copy() { - return $this; - } - - /** - * Returns true if this content is countable as a "real" wiki page, provided - * that it's also in a countable location (e.g. a current revision in the main namespace). - * - * @param boolean $hasLinks if it is known whether this content contains links, provide this information here, - * to avoid redundant parsing to find out. - * @return boolean - */ - public function isCountable( $hasLinks = null ) { - return false; - } - - /** - * @param Title $title - * @param null $revId - * @param null|ParserOptions $options - * @param boolean $generateHtml whether to generate Html (default: true). If false, - * the result of calling getText() on the ParserOutput object returned by - * this method is undefined. - * - * @return ParserOutput - */ - public function getParserOutput( Title $title, $revId = null, ParserOptions $options = null, $generateHtml = true ) { - return new ParserOutput( $this->getNativeData() ); - } -} diff --git a/tests/phpunit/includes/content/CssContentTest.php b/tests/phpunit/includes/content/CssContentTest.php deleted file mode 100644 index bd6d41fe..00000000 --- a/tests/phpunit/includes/content/CssContentTest.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- needed, because we do need the database to test link updates - */ -class CssContentTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - // Anon user - $user = new User(); - $user->setName( '127.0.0.1' ); - - $this->setMwGlobals( array( - 'wgUser' => $user, - 'wgTextModelsToParse' => array( - CONTENT_MODEL_CSS, - ) - ) ); - } - - public function newContent( $text ) { - return new CssContent( $text ); - } - - public static function dataGetParserOutput() { - return array( - array( - 'MediaWiki:Test.css', - null, - "hello <world>\n", - "<pre class=\"mw-code mw-css\" dir=\"ltr\">\nhello <world>\n\n</pre>" - ), - array( - 'MediaWiki:Test.css', - null, - "/* hello [[world]] */\n", - "<pre class=\"mw-code mw-css\" dir=\"ltr\">\n/* hello [[world]] */\n\n</pre>", - array( - 'Links' => array( - array( 'World' => 0 ) - ) - ) - ), - - // TODO: more...? - ); - } - - /** - * @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.' ); - - $this->assertEquals( CONTENT_MODEL_CSS, $content->getContentHandler()->getModelID() ); - } - - public static function dataEquals() { - return array( - array( new CssContent( 'hallo' ), null, false ), - array( new CssContent( 'hallo' ), new CssContent( 'hallo' ), true ), - array( new CssContent( 'hallo' ), new WikitextContent( 'hallo' ), false ), - array( new CssContent( 'hallo' ), new CssContent( 'HALLO' ), false ), - ); - } - - /** - * @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 deleted file mode 100644 index c8616ff0..00000000 --- a/tests/phpunit/includes/content/JavaScriptContentTest.php +++ /dev/null @@ -1,287 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- needed, because we do need the database to test link updates - */ -class JavaScriptContentTest extends TextContentTest { - - public function newContent( $text ) { - return new JavaScriptContent( $text ); - } - - public static function dataGetParserOutput() { - return array( - array( - 'MediaWiki:Test.js', - null, - "hello <world>\n", - "<pre class=\"mw-code mw-js\" dir=\"ltr\">\nhello <world>\n\n</pre>" - ), - array( - 'MediaWiki:Test.js', - null, - "hello(); // [[world]]\n", - "<pre class=\"mw-code mw-js\" dir=\"ltr\">\nhello(); // [[world]]\n\n</pre>", - array( - 'Links' => array( - array( 'World' => 0 ) - ) - ) - ), - - // TODO: more...? - ); - } - - // XXX: Unused function - public static function dataGetSection() { - return array( - array( WikitextContentTest::$sections, - '0', - null - ), - array( WikitextContentTest::$sections, - '2', - null - ), - array( WikitextContentTest::$sections, - '8', - null - ), - ); - } - - // XXX: Unused function - public static function dataReplaceSection() { - return array( - array( WikitextContentTest::$sections, - '0', - 'No more', - null, - null - ), - array( WikitextContentTest::$sections, - '', - 'No more', - null, - null - ), - array( WikitextContentTest::$sections, - '2', - "== TEST ==\nmore fun", - null, - null - ), - array( WikitextContentTest::$sections, - '8', - 'No more', - null, - null - ), - array( WikitextContentTest::$sections, - 'new', - 'No more', - 'New', - null - ), - ); - } - - /** - * @covers JavaScriptContent::addSectionHeader - */ - public function testAddSectionHeader() { - $content = $this->newContent( 'hello world' ); - $c = $content->addSectionHeader( 'test' ); - - $this->assertTrue( $content->equals( $c ) ); - } - - // XXX: currently, preSaveTransform is applied to scripts. this may change or become optional. - public static function dataPreSaveTransform() { - return array( - array( 'hello this is ~~~', - "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]", - ), - array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - ), - array( " Foo \n ", - " Foo", - ), - ); - } - - public static function dataPreloadTransform() { - return array( - array( 'hello this is ~~~', - 'hello this is ~~~', - ), - array( 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>', - 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>', - ), - ); - } - - public static function dataGetRedirectTarget() { - return array( - array( '#REDIRECT [[Test]]', - null, - ), - array( '#REDIRECT Test', - null, - ), - array( '* #REDIRECT [[Test]]', - null, - ), - ); - } - - /** - * @todo Test needs database! - */ - /* - public function getRedirectChain() { - $text = $this->getNativeData(); - return Title::newFromRedirectArray( $text ); - } - */ - - /** - * @todo Test needs database! - */ - /* - public function getUltimateRedirectTarget() { - $text = $this->getNativeData(); - return Title::newFromRedirectRecurse( $text ); - } - */ - - public static function dataIsCountable() { - return array( - array( '', - null, - 'any', - true - ), - array( 'Foo', - null, - 'any', - true - ), - array( 'Foo', - null, - 'comma', - false - ), - array( 'Foo, bar', - null, - 'comma', - false - ), - array( 'Foo', - null, - 'link', - false - ), - array( 'Foo [[bar]]', - null, - 'link', - false - ), - array( 'Foo', - true, - 'link', - false - ), - array( 'Foo [[bar]]', - false, - 'link', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'any', - true - ), - array( '#REDIRECT [[bar]]', - true, - 'comma', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'link', - false - ), - ); - } - - public static function dataGetTextForSummary() { - return array( - array( "hello\nworld.", - 16, - 'hello world.', - ), - array( 'hello world.', - 8, - 'hello...', - ), - array( '[[hello world]].', - 8, - '[[hel...', - ), - ); - } - - /** - * @covers JavaScriptContent::matchMagicWord - */ - public function testMatchMagicWord() { - $mw = MagicWord::get( "staticredirect" ); - - $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" ); - $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" ); - - $content = $this->newContent( "#REDIRECT [[Someplace]]" ); - $newContent = $content->updateRedirect( $target ); - - $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." ); - - $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getContentHandler()->getModelID() ); - } - - public static function dataEquals() { - return array( - array( new JavaScriptContent( "hallo" ), null, false ), - array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "hallo" ), true ), - array( new JavaScriptContent( "hallo" ), new CssContent( "hallo" ), false ), - array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "HALLO" ), false ), - ); - } -} diff --git a/tests/phpunit/includes/content/TextContentTest.php b/tests/phpunit/includes/content/TextContentTest.php deleted file mode 100644 index a1f099f3..00000000 --- a/tests/phpunit/includes/content/TextContentTest.php +++ /dev/null @@ -1,458 +0,0 @@ -<?php - -/** - * @group ContentHandler - * @group Database - * ^--- needed, because we do need the database to test link updates - */ -class TextContentTest extends MediaWikiLangTestCase { - protected $context; - - protected function setUp() { - parent::setUp(); - - // Anon user - $user = new User(); - $user->setName( '127.0.0.1' ); - - $this->setMwGlobals( array( - 'wgUser' => $user, - 'wgTextModelsToParse' => array( - CONTENT_MODEL_WIKITEXT, - CONTENT_MODEL_CSS, - CONTENT_MODEL_JAVASCRIPT, - ), - 'wgUseTidy' => false, - 'wgAlwaysUseTidy' => false, - ) ); - - $this->context = new RequestContext( new FauxRequest() ); - $this->context->setTitle( Title::newFromText( 'Test' ) ); - $this->context->setUser( $user ); - } - - public function newContent( $text ) { - return new TextContent( $text ); - } - - public static function dataGetParserOutput() { - return array( - array( - 'TextContentTest_testGetParserOutput', - CONTENT_MODEL_TEXT, - "hello ''world'' & [[stuff]]\n", "hello ''world'' & [[stuff]]", - array( - 'Links' => array() - ) - ), - // TODO: more...? - ); - } - - /** - * @dataProvider dataGetParserOutput - * @covers TextContent::getParserOutput - */ - public function testGetParserOutput( $title, $model, $text, $expectedHtml, $expectedFields = null ) { - $title = Title::newFromText( $title ); - $content = ContentHandler::makeContent( $text, $title, $model ); - - $po = $content->getParserOutput( $title ); - - $html = $po->getText(); - $html = preg_replace( '#<!--.*?-->#sm', '', $html ); // strip comments - - $this->assertEquals( $expectedHtml, trim( $html ) ); - - if ( $expectedFields ) { - foreach ( $expectedFields as $field => $exp ) { - $f = 'get' . ucfirst( $field ); - $v = call_user_func( array( $po, $f ) ); - - if ( is_array( $exp ) ) { - $this->assertArrayEquals( $exp, $v ); - } else { - $this->assertEquals( $exp, $v ); - } - } - } - - // TODO: assert more properties - } - - public static function dataPreSaveTransform() { - return array( - array( - #0: no signature resolution - 'hello this is ~~~', - 'hello this is ~~~', - ), - array( - #1: rtrim - " Foo \n ", - ' Foo', - ), - ); - } - - /** - * @dataProvider dataPreSaveTransform - * @covers TextContent::preSaveTransform - */ - public function testPreSaveTransform( $text, $expected ) { - global $wgContLang; - - $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang ); - - $content = $this->newContent( $text ); - $content = $content->preSaveTransform( $this->context->getTitle(), $this->context->getUser(), $options ); - - $this->assertEquals( $expected, $content->getNativeData() ); - } - - public static function dataPreloadTransform() { - return array( - array( - 'hello this is ~~~', - 'hello this is ~~~', - ), - ); - } - - /** - * @dataProvider dataPreloadTransform - * @covers TextContent::preloadTransform - */ - public function testPreloadTransform( $text, $expected ) { - global $wgContLang; - $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang ); - - $content = $this->newContent( $text ); - $content = $content->preloadTransform( $this->context->getTitle(), $options ); - - $this->assertEquals( $expected, $content->getNativeData() ); - } - - public static function dataGetRedirectTarget() { - return array( - array( '#REDIRECT [[Test]]', - null, - ), - ); - } - - /** - * @dataProvider dataGetRedirectTarget - * @covers TextContent::getRedirectTarget - */ - public function testGetRedirectTarget( $text, $expected ) { - $content = $this->newContent( $text ); - $t = $content->getRedirectTarget(); - - if ( is_null( $expected ) ) { - $this->assertNull( $t, "text should not have generated a redirect target: $text" ); - } else { - $this->assertEquals( $expected, $t->getPrefixedText() ); - } - } - - /** - * @dataProvider dataGetRedirectTarget - * @covers TextContent::isRedirect - */ - public function testIsRedirect( $text, $expected ) { - $content = $this->newContent( $text ); - - $this->assertEquals( !is_null( $expected ), $content->isRedirect() ); - } - - /** - * @todo Test needs database! Should be done by a test class in the Database group. - */ - /* - public function getRedirectChain() { - $text = $this->getNativeData(); - return Title::newFromRedirectArray( $text ); - } - */ - - /** - * @todo Test needs database! Should be done by a test class in the Database group. - */ - /* - public function getUltimateRedirectTarget() { - $text = $this->getNativeData(); - return Title::newFromRedirectRecurse( $text ); - } - */ - - public static function dataIsCountable() { - return array( - array( '', - null, - 'any', - true - ), - array( 'Foo', - null, - 'any', - true - ), - array( 'Foo', - null, - 'comma', - false - ), - array( 'Foo, bar', - null, - 'comma', - false - ), - ); - } - - /** - * @dataProvider dataIsCountable - * @group Database - * @covers TextContent::isCountable - */ - public function testIsCountable( $text, $hasLinks, $mode, $expected ) { - $this->setMwGlobals( 'wgArticleCountMethod', $mode ); - - $content = $this->newContent( $text ); - - $v = $content->isCountable( $hasLinks, $this->context->getTitle() ); - - $this->assertEquals( $expected, $v, 'isCountable() returned unexpected value ' . var_export( $v, true ) - . ' instead of ' . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); - } - - public static function dataGetTextForSummary() { - return array( - array( "hello\nworld.", - 16, - 'hello world.', - ), - array( 'hello world.', - 8, - 'hello...', - ), - array( '[[hello world]].', - 8, - '[[hel...', - ), - ); - } - - /** - * @dataProvider dataGetTextForSummary - * @covers TextContent::getTextForSummary - */ - public function testGetTextForSummary( $text, $maxlength, $expected ) { - $content = $this->newContent( $text ); - - $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(); - - $this->assertTrue( $content->equals( $copy ), 'copy must be equal to original' ); - $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." ); - - $this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() ); - } - - public static function dataIsEmpty() { - return array( - array( '', true ), - array( ' ', false ), - array( '0', false ), - array( 'hallo welt.', false ), - ); - } - - /** - * @dataProvider dataIsEmpty - * @covers TextContent::isEmpty - */ - public function testIsEmpty( $text, $empty ) { - $content = $this->newContent( $text ); - - $this->assertEquals( $empty, $content->isEmpty() ); - } - - public static function dataEquals() { - return array( - array( new TextContent( "hallo" ), null, false ), - array( new TextContent( "hallo" ), new TextContent( "hallo" ), true ), - array( new TextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ), - array( new TextContent( "hallo" ), new WikitextContent( "hallo" ), false ), - array( new TextContent( "hallo" ), new TextContent( "HALLO" ), false ), - ); - } - - /** - * @dataProvider dataEquals - * @covers TextContent::equals - */ - public function testEquals( Content $a, Content $b = null, $equal = false ) { - $this->assertEquals( $equal, $a->equals( $b ) ); - } - - public static function dataGetDeletionUpdates() { - return array( - array( "TextContentTest_testGetSecondaryDataUpdates_1", - CONTENT_MODEL_TEXT, "hello ''world''\n", - array() - ), - array( "TextContentTest_testGetSecondaryDataUpdates_2", - CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n", - array() - ), - // TODO: more...? - ); - } - - /** - * @dataProvider dataGetDeletionUpdates - * @covers TextContent::getDeletionUpdates - */ - public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) { - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( $title, $ns ); - - $content = ContentHandler::makeContent( $text, $title, $model ); - - $page = WikiPage::factory( $title ); - $page->doEditContent( $content, '' ); - - $updates = $content->getDeletionUpdates( $page ); - - // make updates accessible by class name - foreach ( $updates as $update ) { - $class = get_class( $update ); - $updates[$class] = $update; - } - - if ( !$expectedStuff ) { - $this->assertTrue( true ); // make phpunit happy - return; - } - - foreach ( $expectedStuff as $class => $fieldValues ) { - $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" ); - - $update = $updates[$class]; - - foreach ( $fieldValues as $field => $value ) { - $v = $update->$field; #if the field doesn't exist, just crash and burn - $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" ); - } - } - - $page->doDeleteArticle( '' ); - } - - public static function provideConvert() { - return array( - array( // #0 - 'Hallo Welt', - CONTENT_MODEL_WIKITEXT, - 'lossless', - 'Hallo Welt' - ), - array( // #1 - 'Hallo Welt', - CONTENT_MODEL_WIKITEXT, - 'lossless', - 'Hallo Welt' - ), - array( // #1 - 'Hallo Welt', - CONTENT_MODEL_CSS, - 'lossless', - 'Hallo Welt' - ), - array( // #1 - 'Hallo Welt', - CONTENT_MODEL_JAVASCRIPT, - 'lossless', - 'Hallo Welt' - ), - ); - } - - /** - * @dataProvider provideConvert - * @covers TextContent::convert - */ - public function testConvert( $text, $model, $lossy, $expectedNative ) { - $content = $this->newContent( $text ); - - $converted = $content->convert( $model, $lossy ); - - if ( $expectedNative === false ) { - $this->assertFalse( $converted, "conversion to $model was expected to fail!" ); - } else { - $this->assertInstanceOf( 'Content', $converted ); - $this->assertEquals( $expectedNative, $converted->getNativeData() ); - } - } -} diff --git a/tests/phpunit/includes/content/WikitextContentHandlerTest.php b/tests/phpunit/includes/content/WikitextContentHandlerTest.php deleted file mode 100644 index 75a72784..00000000 --- a/tests/phpunit/includes/content/WikitextContentHandlerTest.php +++ /dev/null @@ -1,227 +0,0 @@ -<?php - -/** - * @group ContentHandler - */ -class WikitextContentHandlerTest extends MediaWikiLangTestCase { - - /** - * @var ContentHandler - */ - var $handler; - - public function setUp() { - parent::setUp(); - - $this->handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT ); - } - - /** - * @covers WikitextContentHandler::serializeContent - */ - public function testSerializeContent() { - $content = new WikitextContent( 'hello world' ); - - $this->assertEquals( 'hello world', $this->handler->serializeContent( $content ) ); - $this->assertEquals( 'hello world', $this->handler->serializeContent( $content, CONTENT_FORMAT_WIKITEXT ) ); - - try { - $this->handler->serializeContent( $content, 'dummy/foo' ); - $this->fail( "serializeContent() should have failed on unknown format" ); - } catch ( MWException $e ) { - // ok, as expected - } - } - - /** - * @covers WikitextContentHandler::unserializeContent - */ - public function testUnserializeContent() { - $content = $this->handler->unserializeContent( 'hello world' ); - $this->assertEquals( 'hello world', $content->getNativeData() ); - - $content = $this->handler->unserializeContent( 'hello world', CONTENT_FORMAT_WIKITEXT ); - $this->assertEquals( 'hello world', $content->getNativeData() ); - - try { - $this->handler->unserializeContent( 'hello world', 'dummy/foo' ); - $this->fail( "unserializeContent() should have failed on unknown format" ); - } catch ( MWException $e ) { - // ok, as expected - } - } - - /** - * @covers WikitextContentHandler::makeEmptyContent - */ - public function testMakeEmptyContent() { - $content = $this->handler->makeEmptyContent(); - - $this->assertTrue( $content->isEmpty() ); - $this->assertEquals( '', $content->getNativeData() ); - } - - public static function dataIsSupportedFormat() { - return array( - array( null, true ), - array( CONTENT_FORMAT_WIKITEXT, true ), - array( 99887766, false ), - ); - } - - /** - * @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 ) ); - } - - public static function dataMerge3() { - return array( - array( - "first paragraph - - second paragraph\n", - - "FIRST paragraph - - second paragraph\n", - - "first paragraph - - SECOND paragraph\n", - - "FIRST paragraph - - SECOND paragraph\n", - ), - - array( "first paragraph - second paragraph\n", - - "Bla bla\n", - - "Blubberdibla\n", - - false, - ), - ); - } - - /** - * @dataProvider dataMerge3 - * @covers WikitextContentHandler::merge3 - */ - public function testMerge3( $old, $mine, $yours, $expected ) { - $this->checkHasDiff3(); - - // test merge - $oldContent = new WikitextContent( $old ); - $myContent = new WikitextContent( $mine ); - $yourContent = new WikitextContent( $yours ); - - $merged = $this->handler->merge3( $oldContent, $myContent, $yourContent ); - - $this->assertEquals( $expected, $merged ? $merged->getNativeData() : $merged ); - } - - public static function dataGetAutosummary() { - return array( - array( - 'Hello there, world!', - '#REDIRECT [[Foo]]', - 0, - '/^Redirected page .*Foo/' - ), - - array( - null, - 'Hello world!', - EDIT_NEW, - '/^Created page .*Hello/' - ), - - array( - 'Hello there, world!', - '', - 0, - '/^Blanked/' - ), - - array( - 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut - labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et - ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', - 'Hello world!', - 0, - '/^Replaced .*Hello/' - ), - - array( - 'foo', - 'bar', - 0, - '/^$/' - ), - ); - } - - /** - * @dataProvider dataGetAutosummary - * @covers WikitextContentHandler::getAutosummary - */ - public function testGetAutosummary( $old, $new, $flags, $expected ) { - $oldContent = is_null( $old ) ? null : new WikitextContent( $old ); - $newContent = is_null( $new ) ? null : new WikitextContent( $new ); - - $summary = $this->handler->getAutosummary( $oldContent, $newContent, $flags ); - - $this->assertTrue( (bool)preg_match( $expected, $summary ), "Autosummary didn't match expected pattern $expected: $summary" ); - } - - /** - * @todo Text case requires database, should be done by a test class in the Database group - */ - /* - public function testGetAutoDeleteReason( Title $title, &$hasHistory ) {} - */ - - /** - * @todo Text case requires database, should be done by a test class in the Database group - */ - /* - 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 deleted file mode 100644 index 9f20073d..00000000 --- a/tests/phpunit/includes/content/WikitextContentTest.php +++ /dev/null @@ -1,404 +0,0 @@ -<?php - -/** - * @group ContentHandler - * - * @group Database - * ^--- needed, because we do need the database to test link updates - */ -class WikitextContentTest extends TextContentTest { - static $sections = "Intro - -== stuff == -hello world - -== test == -just a test - -== foo == -more stuff -"; - - public function newContent( $text ) { - return new WikitextContent( $text ); - } - - public static function dataGetParserOutput() { - return array( - array( - "WikitextContentTest_testGetParserOutput", - CONTENT_MODEL_WIKITEXT, - "hello ''world''\n", - "<p>hello <i>world</i>\n</p>" - ), - // TODO: more...? - ); - } - - public static function dataGetSecondaryDataUpdates() { - return array( - array( "WikitextContentTest_testGetSecondaryDataUpdates_1", - CONTENT_MODEL_WIKITEXT, "hello ''world''\n", - array( - 'LinksUpdate' => array( - 'mRecursive' => true, - 'mLinks' => array() - ) - ) - ), - array( "WikitextContentTest_testGetSecondaryDataUpdates_2", - CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n", - array( - 'LinksUpdate' => array( - 'mRecursive' => true, - 'mLinks' => array( - array( 'World_test_21344' => 0 ) - ) - ) - ) - ), - // TODO: more...? - ); - } - - /** - * @dataProvider dataGetSecondaryDataUpdates - * @group Database - * @covers WikitextContent::getSecondaryDataUpdates - */ - public function testGetSecondaryDataUpdates( $title, $model, $text, $expectedStuff ) { - $ns = $this->getDefaultWikitextNS(); - $title = Title::newFromText( $title, $ns ); - - $content = ContentHandler::makeContent( $text, $title, $model ); - - $page = WikiPage::factory( $title ); - $page->doEditContent( $content, '' ); - - $updates = $content->getSecondaryDataUpdates( $title ); - - // make updates accessible by class name - foreach ( $updates as $update ) { - $class = get_class( $update ); - $updates[$class] = $update; - } - - foreach ( $expectedStuff as $class => $fieldValues ) { - $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" ); - - $update = $updates[$class]; - - foreach ( $fieldValues as $field => $value ) { - $v = $update->$field; #if the field doesn't exist, just crash and burn - $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" ); - } - } - - $page->doDeleteArticle( '' ); - } - - public static function dataGetSection() { - return array( - array( WikitextContentTest::$sections, - "0", - "Intro" - ), - array( WikitextContentTest::$sections, - "2", - "== test == -just a test" - ), - array( WikitextContentTest::$sections, - "8", - false - ), - ); - } - - /** - * @dataProvider dataGetSection - * @covers WikitextContent::getSection - */ - public function testGetSection( $text, $sectionId, $expectedText ) { - $content = $this->newContent( $text ); - - $sectionContent = $content->getSection( $sectionId ); - if ( is_object( $sectionContent ) ) { - $sectionText = $sectionContent->getNativeData(); - } else { - $sectionText = $sectionContent; - } - - $this->assertEquals( $expectedText, $sectionText ); - } - - public static function dataReplaceSection() { - return array( - array( WikitextContentTest::$sections, - "0", - "No more", - null, - trim( preg_replace( '/^Intro/sm', 'No more', WikitextContentTest::$sections ) ) - ), - array( WikitextContentTest::$sections, - "", - "No more", - null, - "No more" - ), - array( WikitextContentTest::$sections, - "2", - "== TEST ==\nmore fun", - null, - trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikitextContentTest::$sections ) ) - ), - array( WikitextContentTest::$sections, - "8", - "No more", - null, - WikitextContentTest::$sections - ), - array( WikitextContentTest::$sections, - "new", - "No more", - "New", - trim( WikitextContentTest::$sections ) . "\n\n\n== New ==\n\nNo more" - ), - ); - } - - /** - * @dataProvider dataReplaceSection - * @covers WikitextContent::replaceSection - */ - public function testReplaceSection( $text, $section, $with, $sectionTitle, $expected ) { - $content = $this->newContent( $text ); - $c = $content->replaceSection( $section, $this->newContent( $with ), $sectionTitle ); - - $this->assertEquals( $expected, is_null( $c ) ? null : $c->getNativeData() ); - } - - /** - * @covers WikitextContent::addSectionHeader - */ - public function testAddSectionHeader() { - $content = $this->newContent( 'hello world' ); - $content = $content->addSectionHeader( 'test' ); - - $this->assertEquals( "== test ==\n\nhello world", $content->getNativeData() ); - } - - public static function dataPreSaveTransform() { - return array( - array( 'hello this is ~~~', - "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]", - ), - array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - ), - array( // rtrim - " Foo \n ", - " Foo", - ), - ); - } - - public static function dataPreloadTransform() { - return array( - array( 'hello this is ~~~', - "hello this is ~~~", - ), - array( 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>', - 'hello \'\'this\'\' is bar', - ), - ); - } - - public static function dataGetRedirectTarget() { - return array( - array( '#REDIRECT [[Test]]', - 'Test', - ), - array( '#REDIRECT Test', - null, - ), - array( '* #REDIRECT [[Test]]', - null, - ), - ); - } - - public static function dataGetTextForSummary() { - return array( - array( "hello\nworld.", - 16, - 'hello world.', - ), - array( 'hello world.', - 8, - 'hello...', - ), - array( '[[hello world]].', - 8, - 'hel...', - ), - ); - } - - /** - * @todo Test needs database! Should be done by a test class in the Database group. - */ - /* - public function getRedirectChain() { - $text = $this->getNativeData(); - return Title::newFromRedirectArray( $text ); - } - */ - - /** - * @todo Test needs database! Should be done by a test class in the Database group. - */ - /* - public function getUltimateRedirectTarget() { - $text = $this->getNativeData(); - return Title::newFromRedirectRecurse( $text ); - } - */ - - public static function dataIsCountable() { - return array( - array( '', - null, - 'any', - true - ), - array( 'Foo', - null, - 'any', - true - ), - array( 'Foo', - null, - 'comma', - false - ), - array( 'Foo, bar', - null, - 'comma', - true - ), - array( 'Foo', - null, - 'link', - false - ), - array( 'Foo [[bar]]', - null, - 'link', - true - ), - array( 'Foo', - true, - 'link', - true - ), - array( 'Foo [[bar]]', - false, - 'link', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'any', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'comma', - false - ), - array( '#REDIRECT [[bar]]', - true, - 'link', - false - ), - ); - } - - /** - * @covers WikitextContent::matchMagicWord - */ - public function testMatchMagicWord() { - $mw = MagicWord::get( "staticredirect" ); - - $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" ); - $this->assertTrue( $content->matchMagicWord( $mw ), "should have matched magic word" ); - - $content = $this->newContent( "#REDIRECT [[FOO]]" ); - $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word" ); - } - - /** - * @covers WikitextContent::updateRedirect - */ - public function testUpdateRedirect() { - $target = Title::newFromText( "testUpdateRedirect_target" ); - - // test with non-redirect page - $content = $this->newContent( "hello world." ); - $newContent = $content->updateRedirect( $target ); - - $this->assertTrue( $content->equals( $newContent ), "content should be unchanged" ); - - // test with actual redirect - $content = $this->newContent( "#REDIRECT [[Someplace]]" ); - $newContent = $content->updateRedirect( $target ); - - $this->assertFalse( $content->equals( $newContent ), "content should have changed" ); - $this->assertTrue( $newContent->isRedirect(), "new content should be a redirect" ); - - $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." ); - - $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() ); - } - - public static function dataEquals() { - return array( - array( new WikitextContent( "hallo" ), null, false ), - array( new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ), - array( new WikitextContent( "hallo" ), new JavaScriptContent( "hallo" ), false ), - array( new WikitextContent( "hallo" ), new TextContent( "hallo" ), false ), - array( new WikitextContent( "hallo" ), new WikitextContent( "HALLO" ), false ), - ); - } - - public static function dataGetDeletionUpdates() { - return array( - array( "WikitextContentTest_testGetSecondaryDataUpdates_1", - CONTENT_MODEL_WIKITEXT, "hello ''world''\n", - array( 'LinksDeletionUpdate' => array() ) - ), - array( "WikitextContentTest_testGetSecondaryDataUpdates_2", - CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n", - array( 'LinksDeletionUpdate' => array() ) - ), - // @todo more...? - ); - } -} diff --git a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php b/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php deleted file mode 100644 index ba63c091..00000000 --- a/tests/phpunit/includes/db/DatabaseMysqlBaseTest.php +++ /dev/null @@ -1,209 +0,0 @@ -<?php -/** - * Holds tests for DatabaseMysqlBase MediaWiki class. - * - * @section LICENSE - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @author Antoine Musso - * @author Bryan Davis - * @copyright © 2013 Antoine Musso - * @copyright © 2013 Bryan Davis - * @copyright © 2013 Wikimedia Foundation Inc. - */ - -/** - * Fake class around abstract class so we can call concrete methods. - */ -class FakeDatabaseMysqlBase extends DatabaseMysqlBase { - // From DatabaseBase - protected function closeConnection() {} - protected function doQuery( $sql ) {} - - // From DatabaseMysql - protected function mysqlConnect( $realServer ) {} - protected function mysqlFreeResult( $res ) {} - protected function mysqlFetchObject( $res ) {} - protected function mysqlFetchArray( $res ) {} - protected function mysqlNumRows( $res ) {} - protected function mysqlNumFields( $res ) {} - protected function mysqlFieldName( $res, $n ) {} - protected function mysqlDataSeek( $res, $row ) {} - protected function mysqlError( $conn = null ) {} - protected function mysqlFetchField( $res, $n ) {} - protected function mysqlPing() {} - - // From interface DatabaseType - function insertId() {} - function lastErrno() {} - function affectedRows() {} - function getServerVersion() {} -} - -class DatabaseMysqlBaseTest extends MediaWikiTestCase { - - /** - * @dataProvider provideDiapers - * @covers DatabaseMysqlBase::addIdentifierQuotes - */ - public function testAddIdentifierQuotes( $expected, $in ) { - $db = new FakeDatabaseMysqlBase(); - $quoted = $db->addIdentifierQuotes( $in ); - $this->assertEquals($expected, $quoted); - } - - - /** - * Feeds testAddIdentifierQuotes - * - * Named per bug 20281 convention. - */ - function provideDiapers() { - return array( - // Format: expected, input - array( '``', '' ), - - // Yeah I really hate loosely typed PHP idiocies nowadays - array( '``', null ), - - // Dear codereviewer, guess what addIdentifierQuotes() - // will return with thoses: - array( '``', false ), - array( '`1`', true ), - - // We never know what could happen - array( '`0`', 0 ), - array( '`1`', 1 ), - - // Whatchout! Should probably use something more meaningful - array( "`'`", "'" ), # single quote - array( '`"`', '"' ), # double quote - array( '````', '`' ), # backtick - array( '`’`', '’' ), # apostrophe (look at your encyclopedia) - - // sneaky NUL bytes are lurking everywhere - array( '``', "\0" ), - array( '`xyzzy`', "\0x\0y\0z\0z\0y\0" ), - - // unicode chars - array( - self::createUnicodeString( '`\u0001a\uFFFFb`' ), - self::createUnicodeString( '\u0001a\uFFFFb' ) - ), - array( - self::createUnicodeString( '`\u0001\uFFFF`' ), - self::createUnicodeString( '\u0001\u0000\uFFFF\u0000' ) - ), - array( '`☃`', '☃' ), - array( '`メインページ`', 'メインページ' ), - array( '`Басты_бет`', 'Басты_бет' ), - - // Real world: - array( '`Alix`', 'Alix' ), # while( ! $recovered ) { sleep(); } - array( '`Backtick: ```', 'Backtick: `' ), - array( '`This is a test`', 'This is a test' ), - ); - } - - private static function createUnicodeString($str) { - return json_decode( '"' . $str . '"' ); - } - - function getMockForViews() { - $db = $this->getMockBuilder( 'DatabaseMysql' ) - ->disableOriginalConstructor() - ->setMethods( array( 'fetchRow', 'query' ) ) - ->getMock(); - - $db->expects( $this->any() ) - ->method( 'query' ) - ->with( $this->anything() ) - ->will( - $this->returnValue( null ) - ); - - $db->expects( $this->any() ) - ->method( 'fetchRow' ) - ->with( $this->anything() ) - ->will( $this->onConsecutiveCalls( - array( 'Tables_in_' => 'view1' ), - array( 'Tables_in_' => 'view2' ), - array( 'Tables_in_' => 'myview' ), - false # no more rows - )); - return $db; - } - /** - * @covers DatabaseMysqlBase::listViews - */ - function testListviews() { - $db = $this->getMockForViews(); - - // The first call populate an internal cache of views - $this->assertEquals( array( 'view1', 'view2', 'myview'), - $db->listViews() ); - $this->assertEquals( array( 'view1', 'view2', 'myview'), - $db->listViews() ); - - // Prefix filtering - $this->assertEquals( array( 'view1', 'view2' ), - $db->listViews( 'view' ) ); - $this->assertEquals( array( 'myview' ), - $db->listViews( 'my' ) ); - $this->assertEquals( array(), - $db->listViews( 'UNUSED_PREFIX' ) ); - $this->assertEquals( array( 'view1', 'view2', 'myview'), - $db->listViews( '' ) ); - } - - /** - * @covers DatabaseMysqlBase::isView - * @dataProvider provideViewExistanceChecks - */ - function testIsView( $isView, $viewName ) { - $db = $this->getMockForViews(); - - switch( $isView ) { - case true: - $this->assertTrue( $db->isView( $viewName ), - "$viewName should be considered a view" ); - break; - - case false: - $this->assertFalse( $db->isView( $viewName ), - "$viewName has not been defined as a view" ); - break; - } - - } - - function provideViewExistanceChecks() { - return array( - // format: whether it is a view, view name - array( true, 'view1' ), - array( true, 'view2' ), - array( true, 'myview' ), - - array( false, 'user' ), - - array( false, 'view10' ), - array( false, 'my' ), - array( false, 'OH_MY_GOD' ), # they killed kenny! - ); - } - -} diff --git a/tests/phpunit/includes/db/DatabaseSQLTest.php b/tests/phpunit/includes/db/DatabaseSQLTest.php deleted file mode 100644 index bdd567e7..00000000 --- a/tests/phpunit/includes/db/DatabaseSQLTest.php +++ /dev/null @@ -1,721 +0,0 @@ -<?php - -/** - * Test the abstract database layer - * This is a non DBMS depending test. - */ -class DatabaseSQLTest extends MediaWikiTestCase { - - /** - * @var DatabaseTestHelper - */ - private $database; - - protected function setUp() { - parent::setUp(); - $this->database = new DatabaseTestHelper( __CLASS__ ); - } - - protected function assertLastSql( $sqlText ) { - $this->assertEquals( - $this->database->getLastSqls(), - $sqlText - ); - } - - /** - * @dataProvider provideSelect - * @covers DatabaseBase::select - */ - 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() - ); - $this->assertLastSql( $sqlText ); - } - - public static function provideSelect() { - return array( - array( - array( - 'tables' => 'table', - 'fields' => array( 'field', 'alias' => 'field2' ), - 'conds' => array( 'alias' => 'text' ), - ), - "SELECT field,field2 AS alias " . - "FROM table " . - "WHERE alias = 'text'" - ), - array( - array( - 'tables' => 'table', - 'fields' => array( 'field', 'alias' => 'field2' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), - ), - "SELECT field,field2 AS alias " . - "FROM table " . - "WHERE alias = 'text' " . - "ORDER BY field " . - "LIMIT 1" - ), - array( - array( - 'tables' => array( 'table', 't2' => 'table2' ), - 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), - 'join_conds' => array( 't2' => array( - 'LEFT JOIN', 'tid = t2.id' - ) ), - ), - "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" - ), - array( - array( - 'tables' => array( 'table', 't2' => 'table2' ), - 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'GROUP BY' => 'field', 'HAVING' => 'COUNT(*) > 1' ), - 'join_conds' => array( 't2' => array( - 'LEFT JOIN', 'tid = t2.id' - ) ), - ), - "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" - ), - array( - array( - 'tables' => array( 'table', 't2' => 'table2' ), - 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'GROUP BY' => array( 'field', 'field2' ), 'HAVING' => array( 'COUNT(*) > 1', 'field' => 1 ) ), - 'join_conds' => array( 't2' => array( - 'LEFT JOIN', 'tid = t2.id' - ) ), - ), - "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 - */ - public function testConditional( $sql, $sqlText ) { - $this->assertEquals( trim( $this->database->conditional( - $sql['conds'], - $sql['true'], - $sql['false'] - ) ), $sqlText ); - } - - public static function provideConditional() { - return array( - array( - array( - 'conds' => array( 'field' => 'text' ), - 'true' => 1, - 'false' => 'NULL', - ), - "(CASE WHEN field = 'text' THEN 1 ELSE NULL END)" - ), - array( - array( - 'conds' => array( 'field' => 'text', 'field2' => 'anothertext' ), - 'true' => 1, - 'false' => 'NULL', - ), - "(CASE WHEN field = 'text' AND field2 = 'anothertext' THEN 1 ELSE NULL END)" - ), - array( - array( - 'conds' => 'field=1', - 'true' => 1, - 'false' => 'NULL', - ), - "(CASE WHEN field=1 THEN 1 ELSE NULL END)" - ), - ); - } - - /** - * @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 deleted file mode 100644 index 70ee9465..00000000 --- a/tests/phpunit/includes/db/DatabaseSqliteTest.php +++ /dev/null @@ -1,421 +0,0 @@ -<?php - -class MockDatabaseSqlite extends DatabaseSqliteStandalone { - var $lastQuery; - - function __construct() { - parent::__construct( ':memory:' ); - } - - function query( $sql, $fname = '', $tempIgnore = false ) { - $this->lastQuery = $sql; - - return true; - } - - /** - * Override parent visibility to public - */ - public function replaceVars( $s ) { - return parent::replaceVars( $s ); - } -} - -/** - * @group sqlite - * @group Database - * @group medium - */ -class DatabaseSqliteTest extends MediaWikiTestCase { - - /** - * @var MockDatabaseSqlite - */ - var $db; - - protected function setUp() { - parent::setUp(); - - if ( !Sqlite::isPresent() ) { - $this->markTestSkipped( 'No SQLite support detected' ); - } - $this->db = new MockDatabaseSqlite(); - if ( version_compare( $this->db->getServerVersion(), '3.6.0', '<' ) ) { - $this->markTestSkipped( "SQLite at least 3.6 required, {$this->db->getServerVersion()} found" ); - } - } - - private function replaceVars( $sql ) { - // normalize spacing to hide implementation details - return preg_replace( '/\s+/', ' ', $this->db->replaceVars( $sql ) ); - } - - private function assertResultIs( $expected, $res ) { - $this->assertNotNull( $res ); - $i = 0; - foreach ( $res as $row ) { - foreach ( $expected[$i] as $key => $value ) { - $this->assertTrue( isset( $row->$key ) ); - $this->assertEquals( $value, $row->$key ); - } - $i++; - } - $this->assertEquals( count( $expected ), $i, 'Unexpected number of rows' ); - } - - public static function provideAddQuotes() { - return array( - array( // #0: empty - '', "''" - ), - array( // #1: simple - 'foo bar', "'foo bar'" - ), - array( // #2: including quote - 'foo\'bar', "'foo''bar'" - ), - array( // #3: including \0 (must be represented as hex, per https://bugs.php.net/bug.php?id=63419) - "x\0y", - "x'780079'", - ), - array( // #4: blob object (must be represented as hex) - new Blob( "hello" ), - "x'68656c6c6f'", - ), - ); - } - - /** - * @dataProvider provideAddQuotes() - * @covers DatabaseSqlite::addQuotes - */ - public function testAddQuotes( $value, $expected ) { - // check quoting - $db = new DatabaseSqliteStandalone( ':memory:' ); - $this->assertEquals( $expected, $db->addQuotes( $value ), 'string not quoted as expected' ); - - // ok, quoting works as expected, now try a round trip. - $re = $db->query( 'select ' . $db->addQuotes( $value ) ); - - $this->assertTrue( $re !== false, 'query failed' ); - - if ( $row = $re->fetchRow() ) { - if ( $value instanceof Blob ) { - $value = $value->fetch(); - } - - $this->assertEquals( $value, $row[0], 'string mangled by the database' ); - } else { - $this->fail( 'query returned no result' ); - } - } - - /** - * @covers DatabaseSqlite::replaceVars - */ - public function testReplaceVars() { - $this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" ); - - $this->assertEquals( "CREATE TABLE /**/foo (foo_key INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " - . "foo_bar TEXT, foo_name TEXT NOT NULL DEFAULT '', foo_int INTEGER, foo_int2 INTEGER );", - $this->replaceVars( "CREATE TABLE /**/foo (foo_key int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - foo_bar char(13), foo_name varchar(255) binary NOT NULL DEFAULT '', foo_int tinyint ( 8 ), foo_int2 int(16) ) ENGINE=MyISAM;" ) - ); - - $this->assertEquals( "CREATE TABLE foo ( foo1 REAL, foo2 REAL, foo3 REAL );", - $this->replaceVars( "CREATE TABLE foo ( foo1 FLOAT, foo2 DOUBLE( 1,10), foo3 DOUBLE PRECISION );" ) - ); - - $this->assertEquals( "CREATE TABLE foo ( foo_binary1 BLOB, foo_binary2 BLOB );", - $this->replaceVars( "CREATE TABLE foo ( foo_binary1 binary(16), foo_binary2 varbinary(32) );" ) - ); - - $this->assertEquals( "CREATE TABLE text ( text_foo TEXT );", - $this->replaceVars( "CREATE TABLE text ( text_foo tinytext );" ), - 'Table name changed' - ); - - $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );", - $this->replaceVars( "CREATE TABLE foo ( foobar INT PRIMARY KEY NOT NULL AUTO_INCREMENT );" ) - ); - $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );", - $this->replaceVars( "CREATE TABLE foo ( foobar INT PRIMARY KEY AUTO_INCREMENT NOT NULL );" ) - ); - - $this->assertEquals( "CREATE TABLE enums( enum1 TEXT, myenum TEXT)", - $this->replaceVars( "CREATE TABLE enums( enum1 ENUM('A', 'B'), myenum ENUM ('X', 'Y'))" ) - ); - - $this->assertEquals( "ALTER TABLE foo ADD COLUMN foo_bar INTEGER DEFAULT 42", - $this->replaceVars( "ALTER TABLE foo\nADD COLUMN foo_bar int(10) unsigned DEFAULT 42" ) - ); - } - - /** - * @covers DatabaseSqlite::tableName - */ - public function testTableName() { - // @todo Moar! - $db = new DatabaseSqliteStandalone( ':memory:' ); - $this->assertEquals( 'foo', $db->tableName( 'foo' ) ); - $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) ); - $db->tablePrefix( 'foo' ); - $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) ); - $this->assertEquals( 'foobar', $db->tableName( 'bar' ) ); - } - - /** - * @covers DatabaseSqlite::duplicateTableStructure - */ - public function testDuplicateTableStructure() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - $db->query( 'CREATE TABLE foo(foo, barfoo)' ); - - $db->duplicateTableStructure( 'foo', 'bar' ); - $this->assertEquals( 'CREATE TABLE "bar"(foo, barfoo)', - $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'bar' ) ), - 'Normal table duplication' - ); - - $db->duplicateTableStructure( 'foo', 'baz', true ); - $this->assertEquals( 'CREATE TABLE "baz"(foo, barfoo)', - $db->selectField( 'sqlite_temp_master', 'sql', array( 'name' => 'baz' ) ), - 'Creation of temporary duplicate' - ); - $this->assertEquals( 0, - $db->selectField( 'sqlite_master', 'COUNT(*)', array( 'name' => 'baz' ) ), - 'Create a temporary duplicate only' - ); - } - - /** - * @covers DatabaseSqlite::duplicateTableStructure - */ - public function testDuplicateTableStructureVirtual() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - if ( $db->getFulltextSearchModule() != 'FTS3' ) { - $this->markTestSkipped( 'FTS3 not supported, cannot create virtual tables' ); - } - $db->query( 'CREATE VIRTUAL TABLE "foo" USING FTS3(foobar)' ); - - $db->duplicateTableStructure( 'foo', 'bar' ); - $this->assertEquals( 'CREATE VIRTUAL TABLE "bar" USING FTS3(foobar)', - $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'bar' ) ), - 'Duplication of virtual tables' - ); - - $db->duplicateTableStructure( 'foo', 'baz', true ); - $this->assertEquals( 'CREATE VIRTUAL TABLE "baz" USING FTS3(foobar)', - $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'baz' ) ), - "Can't create temporary virtual tables, should fall back to non-temporary duplication" - ); - } - - /** - * @covers DatabaseSqlite::deleteJoin - */ - public function testDeleteJoin() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - $db->query( 'CREATE TABLE a (a_1)', __METHOD__ ); - $db->query( 'CREATE TABLE b (b_1, b_2)', __METHOD__ ); - $db->insert( 'a', array( - array( 'a_1' => 1 ), - array( 'a_1' => 2 ), - array( 'a_1' => 3 ), - ), - __METHOD__ - ); - $db->insert( 'b', array( - array( 'b_1' => 2, 'b_2' => 'a' ), - array( 'b_1' => 3, 'b_2' => 'b' ), - ), - __METHOD__ - ); - $db->deleteJoin( 'a', 'b', 'a_1', 'b_1', array( 'b_2' => 'a' ), __METHOD__ ); - $res = $db->query( "SELECT * FROM a", __METHOD__ ); - $this->assertResultIs( array( - array( 'a_1' => 1 ), - array( 'a_1' => 3 ), - ), - $res - ); - } - - public function testEntireSchema() { - global $IP; - - $result = Sqlite::checkSqlSyntax( "$IP/maintenance/tables.sql" ); - if ( $result !== true ) { - $this->fail( $result ); - } - $this->assertTrue( true ); // avoid test being marked as incomplete due to lack of assertions - } - - /** - * Runs upgrades of older databases and compares results with current schema - * @todo Currently only checks list of tables - */ - public function testUpgrades() { - global $IP, $wgVersion, $wgProfileToDatabase; - - // Versions tested - $versions = array( - //'1.13', disabled for now, was totally screwed up - // SQLite wasn't included in 1.14 - '1.15', - '1.16', - '1.17', - '1.18', - ); - - // Mismatches for these columns we can safely ignore - $ignoredColumns = array( - 'user_newtalk.user_last_timestamp', // r84185 - ); - - $currentDB = new DatabaseSqliteStandalone( ':memory:' ); - $currentDB->sourceFile( "$IP/maintenance/tables.sql" ); - if ( $wgProfileToDatabase ) { - $currentDB->sourceFile( "$IP/maintenance/sqlite/archives/patch-profiling.sql" ); - } - $currentTables = $this->getTables( $currentDB ); - sort( $currentTables ); - - foreach ( $versions as $version ) { - $versions = "upgrading from $version to $wgVersion"; - $db = $this->prepareDB( $version ); - $tables = $this->getTables( $db ); - $this->assertEquals( $currentTables, $tables, "Different tables $versions" ); - foreach ( $tables as $table ) { - $currentCols = $this->getColumns( $currentDB, $table ); - $cols = $this->getColumns( $db, $table ); - $this->assertEquals( - array_keys( $currentCols ), - array_keys( $cols ), - "Mismatching columns for table \"$table\" $versions" - ); - foreach ( $currentCols as $name => $column ) { - $fullName = "$table.$name"; - $this->assertEquals( - (bool)$column->pk, - (bool)$cols[$name]->pk, - "PRIMARY KEY status does not match for column $fullName $versions" - ); - if ( !in_array( $fullName, $ignoredColumns ) ) { - $this->assertEquals( - (bool)$column->notnull, - (bool)$cols[$name]->notnull, - "NOT NULL status does not match for column $fullName $versions" - ); - $this->assertEquals( - $column->dflt_value, - $cols[$name]->dflt_value, - "Default values does not match for column $fullName $versions" - ); - } - } - $currentIndexes = $this->getIndexes( $currentDB, $table ); - $indexes = $this->getIndexes( $db, $table ); - $this->assertEquals( - array_keys( $currentIndexes ), - array_keys( $indexes ), - "mismatching indexes for table \"$table\" $versions" - ); - } - $db->close(); - } - } - - /** - * @covers DatabaseSqlite::insertId - */ - public function testInsertIdType() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - - $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" ); - } - - private function prepareDB( $version ) { - static $maint = null; - if ( $maint === null ) { - $maint = new FakeMaintenance(); - $maint->loadParamsAndArgs( null, array( 'quiet' => 1 ) ); - } - - global $IP; - $db = new DatabaseSqliteStandalone( ':memory:' ); - $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', - 'searchindex_content', - 'searchindex_segments', - 'searchindex_segdir', - // FTS4 ready!!1 - 'searchindex_docsize', - 'searchindex_stat', - ); - foreach ( $excluded as $t ) { - unset( $list[$t] ); - } - $list = array_flip( $list ); - sort( $list ); - - return $list; - } - - private function getColumns( $db, $table ) { - $cols = array(); - $res = $db->query( "PRAGMA table_info($table)" ); - $this->assertNotNull( $res ); - foreach ( $res as $col ) { - $cols[$col->name] = $col; - } - ksort( $cols ); - - return $cols; - } - - private function getIndexes( $db, $table ) { - $indexes = array(); - $res = $db->query( "PRAGMA index_list($table)" ); - $this->assertNotNull( $res ); - foreach ( $res as $index ) { - $res2 = $db->query( "PRAGMA index_info({$index->name})" ); - $this->assertNotNull( $res2 ); - $index->columns = array(); - foreach ( $res2 as $col ) { - $index->columns[] = $col; - } - $indexes[$index->name] = $index; - } - ksort( $indexes ); - - return $indexes; - } - - public function testCaseInsensitiveLike() { - // TODO: Test this for all databases - $db = new DatabaseSqliteStandalone( ':memory:' ); - $res = $db->query( 'SELECT "a" LIKE "A" AS a' ); - $row = $res->fetchRow(); - $this->assertFalse( (bool)$row['a'] ); - } -} diff --git a/tests/phpunit/includes/db/DatabaseTest.php b/tests/phpunit/includes/db/DatabaseTest.php deleted file mode 100644 index 301fc990..00000000 --- a/tests/phpunit/includes/db/DatabaseTest.php +++ /dev/null @@ -1,234 +0,0 @@ -<?php - -/** - * @group Database - * @group DatabaseBase - */ -class DatabaseTest extends MediaWikiTestCase { - /** - * @var DatabaseBase - */ - var $db; - var $functionTest = false; - - protected function setUp() { - parent::setUp(); - $this->db = wfGetDB( DB_MASTER ); - } - - protected function tearDown() { - parent::tearDown(); - if ( $this->functionTest ) { - $this->dropFunctions(); - $this->functionTest = false; - } - } - /** - * @covers DatabaseBase::dropTable - */ - public function testAddQuotesNull() { - $check = "NULL"; - if ( $this->db->getType() === 'sqlite' || $this->db->getType() === 'oracle' ) { - $check = "''"; - } - $this->assertEquals( $check, $this->db->addQuotes( null ) ); - } - - public function testAddQuotesInt() { - # returning just "1234" should be ok too, though... - # maybe - $this->assertEquals( - "'1234'", - $this->db->addQuotes( 1234 ) ); - } - - public function testAddQuotesFloat() { - # returning just "1234.5678" would be ok too, though - $this->assertEquals( - "'1234.5678'", - $this->db->addQuotes( 1234.5678 ) ); - } - - public function testAddQuotesString() { - $this->assertEquals( - "'string'", - $this->db->addQuotes( 'string' ) ); - } - - public function testAddQuotesStringQuote() { - $check = "'string''s cause trouble'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "'string\'s cause trouble'"; - } - $this->assertEquals( - $check, - $this->db->addQuotes( "string's cause trouble" ) ); - } - - private function getSharedTableName( $table, $database, $prefix, $format = 'quoted' ) { - global $wgSharedDB, $wgSharedTables, $wgSharedPrefix; - - $oldName = $wgSharedDB; - $oldTables = $wgSharedTables; - $oldPrefix = $wgSharedPrefix; - - $wgSharedDB = $database; - $wgSharedTables = array( $table ); - $wgSharedPrefix = $prefix; - - $ret = $this->db->tableName( $table, $format ); - - $wgSharedDB = $oldName; - $wgSharedTables = $oldTables; - $wgSharedPrefix = $oldPrefix; - - return $ret; - } - - private function prefixAndQuote( $table, $database = null, $prefix = null, $format = 'quoted' ) { - if ( $this->db->getType() === 'sqlite' || $format !== 'quoted' ) { - $quote = ''; - } elseif ( $this->db->getType() === 'mysql' ) { - $quote = '`'; - } elseif ( $this->db->getType() === 'oracle' ) { - $quote = '/*Q*/'; - } else { - $quote = '"'; - } - - if ( $database !== null ) { - if ( $this->db->getType() === 'oracle' ) { - $database = $quote . $database . '.'; - } else { - $database = $quote . $database . $quote . '.'; - } - } - - if ( $prefix === null ) { - $prefix = $this->dbPrefix(); - } - - if ( $this->db->getType() === 'oracle' ) { - return strtoupper($database . $quote . $prefix . $table); - } else { - return $database . $quote . $prefix . $table . $quote; - } - } - - public function testTableNameLocal() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename' ), - $this->db->tableName( 'tablename' ) - ); - } - - public function testTableNameRawLocal() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', null, null, 'raw' ), - $this->db->tableName( 'tablename', 'raw' ) - ); - } - - public function testTableNameShared() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_' ), - $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_' ) - ); - - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', null ), - $this->getSharedTableName( 'tablename', 'sharedatabase', null ) - ); - } - - public function testTableNameRawShared() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_', 'raw' ), - $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_', 'raw' ) - ); - - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', null, 'raw' ), - $this->getSharedTableName( 'tablename', 'sharedatabase', null, 'raw' ) - ); - } - - public function testTableNameForeign() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'databasename', '' ), - $this->db->tableName( 'databasename.tablename' ) - ); - } - - public function testTableNameRawForeign() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'databasename', '', 'raw' ), - $this->db->tableName( 'databasename.tablename', 'raw' ) - ); - } - - public function testFillPreparedEmpty() { - $sql = $this->db->fillPrepared( - 'SELECT * FROM interwiki', array() ); - $this->assertEquals( - "SELECT * FROM interwiki", - $sql ); - } - - public function testFillPreparedQuestion() { - $sql = $this->db->fillPrepared( - 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?', - array( 4, "Snicker's_paradox" ) ); - - $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker''s_paradox'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker\'s_paradox'"; - } - $this->assertEquals( $check, $sql ); - } - - public function testFillPreparedBang() { - $sql = $this->db->fillPrepared( - 'SELECT user_id FROM ! WHERE user_name=?', - array( '"user"', "Slash's Dot" ) ); - - $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash''s Dot'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash\'s Dot'"; - } - $this->assertEquals( $check, $sql ); - } - - public function testFillPreparedRaw() { - $sql = $this->db->fillPrepared( - "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'", - array( '"user"', "Slash's Dot" ) ); - $this->assertEquals( - "SELECT * FROM cur WHERE cur_title='This_&_that,_WTF?!'", - $sql ); - } - - public function testStoredFunctions() { - if ( !in_array( wfGetDB( DB_MASTER )->getType(), array( 'mysql', 'postgres' ) ) ) { - $this->markTestSkipped( 'MySQL or Postgres required' ); - } - global $IP; - $this->dropFunctions(); - $this->functionTest = true; - $this->assertTrue( $this->db->sourceFile( "$IP/tests/phpunit/data/db/{$this->db->getType()}/functions.sql" ) ); - $res = $this->db->query( 'SELECT mw_test_function() AS test', __METHOD__ ); - $this->assertEquals( 42, $res->fetchObject()->test ); - } - - private function dropFunctions() { - $this->db->query( 'DROP FUNCTION IF EXISTS mw_test_function' - . ( $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 deleted file mode 100644 index 790f273c..00000000 --- a/tests/phpunit/includes/db/DatabaseTestHelper.php +++ /dev/null @@ -1,166 +0,0 @@ -<?php - -/** - * Helper for testing the methods from the DatabaseBase class - * @since 1.22 - */ -class DatabaseTestHelper extends DatabaseBase { - - /** - * __CLASS__ of the test suite, - * used to determine, if the function name is passed every time to query() - */ - protected $testName = array(); - - /** - * Array of lastSqls passed to query(), - * This is an array since some methods in DatabaseBase can do more than one - * query. Cleared when calling getLastSqls(). - */ - protected $lastSqls = array(); - - /** - * Array of tables to be considered as existing by tableExist() - * Use setExistingTables() to alter. - */ - protected $tablesExists; - - public function __construct( $testName ) { - $this->testName = $testName; - } - - /** - * Returns SQL queries grouped by '; ' - * Clear the list of queries that have been done so far. - */ - public function getLastSqls() { - $lastSqls = implode( '; ', $this->lastSqls ); - $this->lastSqls = array(); - - return $lastSqls; - } - - public function setExistingTables( $tablesExists ) { - $this->tablesExists = (array)$tablesExists; - } - - protected function addSql( $sql ) { - // clean up spaces before and after some words and the whole string - $this->lastSqls[] = trim( preg_replace( - '/\s{2,}(?=FROM|WHERE|GROUP BY|ORDER BY|LIMIT)|(?<=SELECT|INSERT|UPDATE)\s{2,}/', - ' ', $sql - ) ); - } - - protected function checkFunctionName( $fname ) { - if ( substr( $fname, 0, strlen( $this->testName ) ) !== $this->testName ) { - throw new MWException( 'function name does not start with test class. ' . - $fname . ' vs. ' . $this->testName . '. ' . - 'Please provide __METHOD__ to database methods.' ); - } - } - - function strencode( $s ) { - // Choose apos to avoid handling of escaping double quotes in quoted text - return str_replace( "'", "\'", $s ); - } - - public function addIdentifierQuotes( $s ) { - // no escaping to avoid handling of double quotes in quoted text - return $s; - } - - public function query( $sql, $fname = '', $tempIgnore = false ) { - $this->checkFunctionName( $fname ); - $this->addSql( $sql ); - - return parent::query( $sql, $fname, $tempIgnore ); - } - - public function tableExists( $table, $fname = __METHOD__ ) { - $this->checkFunctionName( $fname ); - - return in_array( $table, (array)$this->tablesExists ); - } - - // Redeclare parent method to make it public - public function nativeReplace( $table, $rows, $fname ) { - return parent::nativeReplace( $table, $rows, $fname ); - } - - function getType() { - return 'test'; - } - - function open( $server, $user, $password, $dbName ) { - return false; - } - - function fetchObject( $res ) { - return false; - } - - function fetchRow( $res ) { - return false; - } - - function numRows( $res ) { - return -1; - } - - function numFields( $res ) { - return -1; - } - - function fieldName( $res, $n ) { - return 'test'; - } - - function insertId() { - return -1; - } - - function dataSeek( $res, $row ) { - /* nop */ - } - - function lastErrno() { - return -1; - } - - function lastError() { - return 'test'; - } - - function fieldInfo( $table, $field ) { - return false; - } - - function indexInfo( $table, $index, $fname = 'Database::indexInfo' ) { - return false; - } - - function affectedRows() { - return -1; - } - - function getSoftwareLink() { - return 'test'; - } - - function getServerVersion() { - return 'test'; - } - - function getServerInfo() { - return 'test'; - } - - protected function closeConnection() { - return false; - } - - protected function doQuery( $sql ) { - return array(); - } -} diff --git a/tests/phpunit/includes/db/ORMRowTest.php b/tests/phpunit/includes/db/ORMRowTest.php deleted file mode 100644 index 27d4d0e8..00000000 --- a/tests/phpunit/includes/db/ORMRowTest.php +++ /dev/null @@ -1,226 +0,0 @@ -<?php - -/** - * Abstract class to construct tests for ORMRow deriving classes. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @since 1.20 - * - * @ingroup Test - * - * @group ORM - * - * The database group has as a side effect that temporal database tables are created. This makes - * it possible to test without poisoning a production database. - * @group Database - * - * Some of the tests takes more time, and needs therefor longer time before they can be aborted - * as non-functional. The reason why tests are aborted is assumed to be set up of temporal databases - * that hold the first tests in a pending state awaiting access to the database. - * @group medium - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -abstract class ORMRowTest extends \MediaWikiTestCase { - - /** - * @since 1.20 - * @return string - */ - abstract protected function getRowClass(); - - /** - * @since 1.20 - * @return IORMTable - */ - abstract protected function getTableInstance(); - - /** - * @since 1.20 - * @return array - */ - abstract public function constructorTestProvider(); - - /** - * @since 1.20 - * @param IORMRow $row - * @param array $data - */ - protected function verifyFields( IORMRow $row, array $data ) { - foreach ( array_keys( $data ) as $fieldName ) { - $this->assertEquals( $data[$fieldName], $row->getField( $fieldName ) ); - } - } - - /** - * @since 1.20 - * @param array $data - * @param boolean $loadDefaults - * @return IORMRow - */ - protected function getRowInstance( array $data, $loadDefaults ) { - $class = $this->getRowClass(); - - return new $class( $this->getTableInstance(), $data, $loadDefaults ); - } - - /** - * @since 1.20 - * @return array - */ - protected function getMockValues() { - return array( - 'id' => 1, - 'str' => 'foobar4645645', - 'int' => 42, - 'float' => 4.2, - 'bool' => true, - 'array' => array( 42, 'foobar' ), - 'blob' => new stdClass() - ); - } - - /** - * @since 1.20 - * @return array - */ - protected function getMockFields() { - $mockValues = $this->getMockValues(); - $mockFields = array(); - - foreach ( $this->getTableInstance()->getFields() as $name => $type ) { - if ( $name !== 'id' ) { - $mockFields[$name] = $mockValues[$type]; - } - } - - return $mockFields; - } - - /** - * @since 1.20 - * @return array of IORMRow - */ - public function instanceProvider() { - $instances = array(); - - foreach ( $this->constructorTestProvider() as $arguments ) { - $instances[] = array( call_user_func_array( array( $this, 'getRowInstance' ), $arguments ) ); - } - - return $instances; - } - - /** - * @dataProvider constructorTestProvider - */ - public function testConstructor( array $data, $loadDefaults ) { - $this->verifyFields( $this->getRowInstance( $data, $loadDefaults ), $data ); - } - - /** - * @dataProvider constructorTestProvider - */ - public function testSaveAndRemove( array $data, $loadDefaults ) { - $item = $this->getRowInstance( $data, $loadDefaults ); - - $this->assertTrue( $item->save() ); - - $this->assertTrue( $item->hasIdField() ); - $this->assertTrue( is_integer( $item->getId() ) ); - - $id = $item->getId(); - - $this->assertTrue( $item->save() ); - - $this->assertEquals( $id, $item->getId() ); - - $this->verifyFields( $item, $data ); - - $this->assertTrue( $item->remove() ); - - $this->assertFalse( $item->hasIdField() ); - - $this->assertTrue( $item->save() ); - - $this->verifyFields( $item, $data ); - - $this->assertTrue( $item->remove() ); - - $this->assertFalse( $item->hasIdField() ); - - $this->verifyFields( $item, $data ); - } - - /** - * @dataProvider instanceProvider - */ - public function testSetField( IORMRow $item ) { - foreach ( $this->getMockFields() as $name => $value ) { - $item->setField( $name, $value ); - $this->assertEquals( $value, $item->getField( $name ) ); - } - } - - /** - * @since 1.20 - * @param array $expected - * @param IORMRow $item - */ - protected function assertFieldValues( array $expected, IORMRow $item ) { - foreach ( $expected as $name => $type ) { - if ( $name !== 'id' ) { - $this->assertEquals( $expected[$name], $item->getField( $name ) ); - } - } - } - - /** - * @dataProvider instanceProvider - */ - public function testSetFields( IORMRow $item ) { - $originalValues = $item->getFields(); - - $item->setFields( array(), false ); - - foreach ( $item->getTable()->getFields() as $name => $type ) { - $originalHas = array_key_exists( $name, $originalValues ); - $newHas = $item->hasField( $name ); - - $this->assertEquals( $originalHas, $newHas ); - - if ( $originalHas && $newHas ) { - $this->assertEquals( $originalValues[$name], $item->getField( $name ) ); - } - } - - $mockFields = $this->getMockFields(); - - $item->setFields( $mockFields, false ); - - $this->assertFieldValues( $originalValues, $item ); - - $item->setFields( $mockFields, true ); - - $this->assertFieldValues( $mockFields, $item ); - } - - // TODO: test all of the methods! - -} diff --git a/tests/phpunit/includes/db/ORMTableTest.php b/tests/phpunit/includes/db/ORMTableTest.php deleted file mode 100644 index e583d1bc..00000000 --- a/tests/phpunit/includes/db/ORMTableTest.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php -/** - * Abstract class to construct tests for ORMTable deriving classes. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @since 1.21 - * - * @ingroup Test - * - * @group ORM - * @group Database - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - * @author Daniel Kinzler - */ -class ORMTableTest extends MediaWikiTestCase { - - /** - * @since 1.21 - * @return string - */ - protected function getTableClass() { - return 'PageORMTableForTesting'; - } - - /** - * @since 1.21 - * @return IORMTable - */ - public function getTable() { - $class = $this->getTableClass(); - - return $class::singleton(); - } - - /** - * @since 1.21 - * @return string - */ - public function getRowClass() { - return $this->getTable()->getRowClass(); - } - - /** - * @since 1.21 - */ - public function testSingleton() { - $class = $this->getTableClass(); - - $this->assertInstanceOf( $class, $class::singleton() ); - $this->assertTrue( $class::singleton() === $class::singleton() ); - } - - /** - * @since 1.21 - */ - public function testIgnoreErrorsOverride() { - $table = $this->getTable(); - - $db = $table->getReadDbConnection(); - $db->ignoreErrors( true ); - - try { - $table->rawSelect( "this is invalid" ); - $this->fail( "An invalid query should trigger a DBQueryError even if ignoreErrors is enabled." ); - } catch ( DBQueryError $ex ) { - $this->assertTrue( true, "just making phpunit happy" ); - } - - $db->ignoreErrors( false ); - } -} - -/** - * Dummy ORM table for testing, reading Title objects from the page table. - * - * @since 1.21 - */ - -class PageORMTableForTesting extends ORMTable { - - /** - * @see ORMTable::getName - * - * @return string - */ - public function getName() { - return 'page'; - } - - /** - * @see ORMTable::getRowClass - * - * @return string - */ - public function getRowClass() { - return 'Title'; - } - - /** - * @see ORMTable::newRow - * - * @return IORMRow - */ - public function newRow( array $data, $loadDefaults = false ) { - return Title::makeTitle( $data['namespace'], $data['title'] ); - } - - /** - * @see ORMTable::getFields - * - * @return array - */ - public function getFields() { - return array( - 'id' => 'int', - 'namespace' => 'int', - 'title' => 'str', - ); - } - - /** - * @see ORMTable::getFieldPrefix - * - * @return string - */ - protected function getFieldPrefix() { - return 'page_'; - } -} diff --git a/tests/phpunit/includes/db/TestORMRowTest.php b/tests/phpunit/includes/db/TestORMRowTest.php deleted file mode 100644 index f65642b8..00000000 --- a/tests/phpunit/includes/db/TestORMRowTest.php +++ /dev/null @@ -1,215 +0,0 @@ -<?php - -/** - * Tests for the TestORMRow class. - * TestORMRow is a dummy class to be able to test the abstract ORMRow class. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @since 1.20 - * - * @ingroup Test - * - * @group ORM - * - * The database group has as a side effect that temporal database tables are created. This makes - * it possible to test without poisoning a production database. - * @group Database - * - * Some of the tests takes more time, and needs therefor longer time before they can be aborted - * as non-functional. The reason why tests are aborted is assumed to be set up of temporal databases - * that hold the first tests in a pending state awaiting access to the database. - * @group medium - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -require_once __DIR__ . "/ORMRowTest.php"; - -class TestORMRowTest extends ORMRowTest { - - /** - * @since 1.20 - * @return string - */ - protected function getRowClass() { - return 'TestORMRow'; - } - - /** - * @since 1.20 - * @return IORMTable - */ - protected function getTableInstance() { - return TestORMTable::singleton(); - } - - protected function setUp() { - parent::setUp(); - - $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'; - - 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() { - $dbw = wfGetDB( DB_MASTER ); - $dbw->dropTable( 'orm_test', __METHOD__ ); - - parent::tearDown(); - } - - public function constructorTestProvider() { - $dbw = wfGetDB( DB_MASTER ); - return array( - array( - array( - 'name' => 'Foobar', - 'time' => $dbw->timestamp( '20120101020202' ), - 'age' => 42, - 'height' => 9000.1, - 'awesome' => true, - 'stuff' => array( 13, 11, 7, 5, 3, 2 ), - 'moarstuff' => (object)array( 'foo' => 'bar', 'bar' => array( 4, 2 ), 'baz' => true ) - ), - true - ), - ); - } - - /** - * @since 1.21 - * @return array - */ - protected function getMockValues() { - return array( - 'id' => 1, - 'str' => 'foobar4645645', - 'int' => 42, - 'float' => 4.2, - 'bool' => '', - 'array' => array( 42, 'foobar' ), - 'blob' => new stdClass() - ); - } -} - -class TestORMRow extends ORMRow { -} - -class TestORMTable extends ORMTable { - - /** - * Returns the name of the database table objects of this type are stored in. - * - * @since 1.20 - * - * @return string - */ - public function getName() { - return 'orm_test'; - } - - /** - * Returns the name of a IORMRow implementing class that - * represents single rows in this table. - * - * @since 1.20 - * - * @return string - */ - public function getRowClass() { - return 'TestORMRow'; - } - - /** - * Returns an array with the fields and their types this object contains. - * This corresponds directly to the fields in the database, without prefix. - * - * field name => type - * - * Allowed types: - * * id - * * str - * * int - * * float - * * bool - * * array - * * blob - * - * @since 1.20 - * - * @return array - */ - public function getFields() { - return array( - 'id' => 'id', - 'name' => 'str', - 'age' => 'int', - 'height' => 'float', - 'awesome' => 'bool', - 'stuff' => 'array', - 'moarstuff' => 'blob', - 'time' => 'str', // TS_MW - ); - } - - /** - * Gets the db field prefix. - * - * @since 1.20 - * - * @return string - */ - protected function getFieldPrefix() { - return 'test_'; - } -} diff --git a/tests/phpunit/includes/debug/MWDebugTest.php b/tests/phpunit/includes/debug/MWDebugTest.php deleted file mode 100644 index 6926b1c8..00000000 --- a/tests/phpunit/includes/debug/MWDebugTest.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php - -class MWDebugTest extends MediaWikiTestCase { - - - protected function setUp() { - parent::setUp(); - // Make sure MWDebug class is enabled - static $MWDebugEnabled = false; - if ( !$MWDebugEnabled ) { - MWDebug::init(); - $MWDebugEnabled = true; - } - /** Clear log before each test */ - MWDebug::clearLog(); - wfSuppressWarnings(); - } - - protected function tearDown() { - wfRestoreWarnings(); - parent::tearDown(); - } - - public function testAddLog() { - MWDebug::log( 'logging a string' ); - $this->assertEquals( - array( array( - 'msg' => 'logging a string', - 'type' => 'log', - 'caller' => __METHOD__, - ) ), - MWDebug::getLog() - ); - } - - public function testAddWarning() { - MWDebug::warning( 'Warning message' ); - $this->assertEquals( - array( array( - 'msg' => 'Warning message', - 'type' => 'warn', - 'caller' => 'MWDebugTest::testAddWarning', - ) ), - MWDebug::getLog() - ); - } - - public function testAvoidDuplicateDeprecations() { - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - - // assertCount() not available on WMF integration server - $this->assertEquals( 1, - count( MWDebug::getLog() ), - "Only one deprecated warning per function should be kept" - ); - } - - public function testAvoidNonConsecutivesDuplicateDeprecations() { - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - MWDebug::warning( 'some warning' ); - MWDebug::log( 'we could have logged something too' ); - // Another deprecation - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - - // assertCount() not available on WMF integration server - $this->assertEquals( 3, - count( MWDebug::getLog() ), - "Only one deprecated warning per function should be kept" - ); - } -} diff --git a/tests/phpunit/includes/filebackend/FileBackendTest.php b/tests/phpunit/includes/filebackend/FileBackendTest.php deleted file mode 100644 index fcfa724f..00000000 --- a/tests/phpunit/includes/filebackend/FileBackendTest.php +++ /dev/null @@ -1,2306 +0,0 @@ -<?php - -/** - * @group FileRepo - * @group FileBackend - * @group medium - */ -class FileBackendTest extends MediaWikiTestCase { - - /** @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(); - $uniqueId = time() . '-' . mt_rand(); - $tmpPrefix = wfTempDir() . '/filebackend-unittest-' . $uniqueId; - if ( $this->getCliArg( 'use-filebackend=' ) ) { - if ( self::$backendToUse ) { - $this->singleBackend = self::$backendToUse; - } else { - $name = $this->getCliArg( 'use-filebackend=' ); - $useConfig = array(); - foreach ( $wgFileBackends as $conf ) { - if ( $conf['name'] == $name ) { - $useConfig = $conf; - break; - } - } - $useConfig['name'] = 'localtesting'; // swap name - $useConfig['shardViaHashLevels'] = array( // test sharding - 'unittest-cont1' => array( 'levels' => 1, 'base' => 16, 'repeat' => 1 ) - ); - $class = $useConfig['class']; - self::$backendToUse = new $class( $useConfig ); - $this->singleBackend = self::$backendToUse; - } - } else { - $this->singleBackend = new FSFileBackend( array( - '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', - 'lockManager' => 'fsLockManager', - 'parallelize' => 'implicit', - 'wikiId' => wfWikiId() . $uniqueId, - 'backends' => array( - array( - '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', - 'containerPaths' => array( - 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti2-cont1", - 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti2-cont2" ), - 'isMultiMaster' => true - ) - ) - ) ); - $this->filesToPrune = array(); - } - - private static function baseStorePath() { - return 'mwstore://localtesting'; - } - - private function backendClass() { - return get_class( $this->backend ); - } - - /** - * @dataProvider provider_testIsStoragePath - * @covers FileBackend::isStoragePath - */ - public function testIsStoragePath( $path, $isStorePath ) { - $this->assertEquals( $isStorePath, FileBackend::isStoragePath( $path ), - "FileBackend::isStoragePath on path '$path'" ); - } - - public static function provider_testIsStoragePath() { - return array( - array( 'mwstore://', true ), - array( 'mwstore://backend', true ), - array( 'mwstore://backend/container', true ), - array( 'mwstore://backend/container/', true ), - array( 'mwstore://backend/container/path', true ), - array( 'mwstore://backend//container/', true ), - array( 'mwstore://backend//container//', true ), - array( 'mwstore://backend//container//path', true ), - array( 'mwstore:///', true ), - array( 'mwstore:/', false ), - array( 'mwstore:', false ), - ); - } - - /** - * @dataProvider provider_testSplitStoragePath - * @covers FileBackend::splitStoragePath - */ - public function testSplitStoragePath( $path, $res ) { - $this->assertEquals( $res, FileBackend::splitStoragePath( $path ), - "FileBackend::splitStoragePath on path '$path'" ); - } - - public static function provider_testSplitStoragePath() { - return array( - array( 'mwstore://backend/container', array( 'backend', 'container', '' ) ), - array( 'mwstore://backend/container/', array( 'backend', 'container', '' ) ), - array( 'mwstore://backend/container/path', array( 'backend', 'container', 'path' ) ), - array( 'mwstore://backend/container//path', array( 'backend', 'container', '/path' ) ), - array( 'mwstore://backend//container/path', array( null, null, null ) ), - array( 'mwstore://backend//container//path', array( null, null, null ) ), - array( 'mwstore://', array( null, null, null ) ), - array( 'mwstore://backend', array( null, null, null ) ), - array( 'mwstore:///', array( null, null, null ) ), - array( 'mwstore:/', array( null, null, null ) ), - array( 'mwstore:', array( null, null, null ) ) - ); - } - - /** - * @dataProvider provider_normalizeStoragePath - * @covers FileBackend::normalizeStoragePath - */ - public function testNormalizeStoragePath( $path, $res ) { - $this->assertEquals( $res, FileBackend::normalizeStoragePath( $path ), - "FileBackend::normalizeStoragePath on path '$path'" ); - } - - public static function provider_normalizeStoragePath() { - return array( - array( 'mwstore://backend/container', 'mwstore://backend/container' ), - array( 'mwstore://backend/container/', 'mwstore://backend/container' ), - array( 'mwstore://backend/container/path', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container//path', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container///path', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container///path//to///obj', 'mwstore://backend/container/path/to/obj' ), - array( 'mwstore://', null ), - array( 'mwstore://backend', null ), - array( 'mwstore://backend//container/path', null ), - array( 'mwstore://backend//container//path', null ), - array( 'mwstore:///', null ), - array( 'mwstore:/', null ), - array( 'mwstore:', null ), - ); - } - - /** - * @dataProvider provider_testParentStoragePath - * @covers FileBackend::parentStoragePath - */ - public function testParentStoragePath( $path, $res ) { - $this->assertEquals( $res, FileBackend::parentStoragePath( $path ), - "FileBackend::parentStoragePath on path '$path'" ); - } - - 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' ), - array( 'mwstore://backend/container/path', 'mwstore://backend/container' ), - array( 'mwstore://backend/container', null ), - array( 'mwstore://backend/container/path/to/obj/', 'mwstore://backend/container/path/to' ), - array( 'mwstore://backend/container/path/to/', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container/path/', 'mwstore://backend/container' ), - array( 'mwstore://backend/container/', null ), - ); - } - - /** - * @dataProvider provider_testExtensionFromPath - * @covers FileBackend::extensionFromPath - */ - public function testExtensionFromPath( $path, $res ) { - $this->assertEquals( $res, FileBackend::extensionFromPath( $path ), - "FileBackend::extensionFromPath on path '$path'" ); - } - - public static function provider_testExtensionFromPath() { - return array( - array( 'mwstore://backend/container/path.txt', 'txt' ), - array( 'mwstore://backend/container/path.svg.png', 'png' ), - array( 'mwstore://backend/container/path', '' ), - array( 'mwstore://backend/container/path.', '' ), - ); - } - - /** - * @dataProvider provider_testStore - */ - public function testStore( $op ) { - $this->filesToPrune[] = $op['src']; - - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestStore( $op ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestStore( $op ); - $this->filesToPrune[] = $op['src']; # avoid file leaking - $this->tearDownFiles(); - } - - /** - * @covers FileBackend::doOperation - */ - private function doTestStore( $op ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - file_put_contents( $source, "Unit test file" ); - - if ( isset( $op['overwrite'] ) || isset( $op['overwriteSame'] ) ) { - $this->backend->store( $op ); - } - - $status = $this->backend->doOperation( $op ); - - $this->assertGoodStatus( $status, - "Store from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Store from $source to $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Store from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( true, file_exists( $source ), - "Source file $source still exists ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists ($backendName)." ); - - $this->assertEquals( filesize( $source ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - - $props1 = FSFile::getPropsFromPath( $source ); - $props2 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( $props1, $props2, - "Source and destination have the same props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $dest ) ); - } - - public static function provider_testStore() { - $cases = array(); - - $tmpName = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - $toPath = self::baseStorePath() . '/unittest-cont1/e/fun/obj1.txt'; - $op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath ); - $cases[] = array( - $op, // operation - $tmpName, // source - $toPath, // dest - ); - - $op2 = $op; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - $tmpName, // source - $toPath, // dest - ); - - $op2 = $op; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - $tmpName, // source - $toPath, // dest - ); - - return $cases; - } - - /** - * @dataProvider provider_testCopy - * @covers FileBackend::doOperation - */ - public function testCopy( $op ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestCopy( $op ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestCopy( $op ); - $this->tearDownFiles(); - } - - private function doTestCopy( $op ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - if ( isset( $op['ignoreMissingSource'] ) ) { - $status = $this->backend->doOperation( $op ); - $this->assertGoodStatus( $status, - "Move from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Move from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "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 - } - - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - if ( isset( $op['overwrite'] ) || isset( $op['overwriteSame'] ) ) { - $this->backend->copy( $op ); - } - - $status = $this->backend->doOperation( $op ); - - $this->assertGoodStatus( $status, - "Copy from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Copy from $source to $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Copy from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $source ) ), - "Source file $source still exists ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists after copy ($backendName)." ); - - $this->assertEquals( - $this->backend->getFileSize( array( 'src' => $source ) ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); - $props2 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( $props1, $props2, - "Source and destination have the same props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $source, $dest ) ); - } - - public static function provider_testCopy() { - $cases = array(); - - $source = self::baseStorePath() . '/unittest-cont1/e/file.txt'; - $dest = self::baseStorePath() . '/unittest-cont2/a/fileMoved.txt'; - - $op = array( 'op' => 'copy', 'src' => $source, 'dst' => $dest ); - $cases[] = array( - $op, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['ignoreMissingSource'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['ignoreMissingSource'] = true; - $cases[] = array( - $op2, // operation - self::baseStorePath() . '/unittest-cont-bad/e/file.txt', // source - $dest, // dest - ); - - return $cases; - } - - /** - * @dataProvider provider_testMove - * @covers FileBackend::doOperation - */ - public function testMove( $op ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestMove( $op ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestMove( $op ); - $this->tearDownFiles(); - } - - private function doTestMove( $op ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - if ( isset( $op['ignoreMissingSource'] ) ) { - $status = $this->backend->doOperation( $op ); - $this->assertGoodStatus( $status, - "Move from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Move from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "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 - } - - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - if ( isset( $op['overwrite'] ) || isset( $op['overwriteSame'] ) ) { - $this->backend->copy( $op ); - } - - $status = $this->backend->doOperation( $op ); - $this->assertGoodStatus( $status, - "Move from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Move from $source to $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Move from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "Source file $source does not still exists ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists after move ($backendName)." ); - - $this->assertNotEquals( - $this->backend->getFileSize( array( 'src' => $source ) ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); - $props2 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( false, $props1['fileExists'], - "Source file does not exist accourding to props ($backendName)." ); - $this->assertEquals( true, $props2['fileExists'], - "Destination file exists accourding to props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $source, $dest ) ); - } - - public static function provider_testMove() { - $cases = array(); - - $source = self::baseStorePath() . '/unittest-cont1/e/file.txt'; - $dest = self::baseStorePath() . '/unittest-cont2/a/fileMoved.txt'; - - $op = array( 'op' => 'move', 'src' => $source, 'dst' => $dest ); - $cases[] = array( - $op, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['ignoreMissingSource'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['ignoreMissingSource'] = true; - $cases[] = array( - $op2, // operation - self::baseStorePath() . '/unittest-cont-bad/e/file.txt', // source - $dest, // dest - ); - - return $cases; - } - - /** - * @dataProvider provider_testDelete - * @covers FileBackend::doOperation - */ - public function testDelete( $op, $withSource, $okStatus ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDelete( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDelete( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - } - - private function doTestDelete( $op, $withSource, $okStatus ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - - if ( $withSource ) { - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - } - - $status = $this->backend->doOperation( $op ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Deletion of file at $source succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Deletion of file at $source succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Deletion of file at $source has proper 'success' field in Status ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Deletion of file at $source failed ($backendName)." ); - } - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "Source file $source does not exist after move ($backendName)." ); - - $this->assertFalse( - $this->backend->getFileSize( array( 'src' => $source ) ), - "Source file $source has correct size (false) ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); - $this->assertFalse( $props1['fileExists'], - "Source file $source does not exist according to props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $source ) ); - } - - public static function provider_testDelete() { - $cases = array(); - - $source = self::baseStorePath() . '/unittest-cont1/e/myfacefile.txt'; - - $op = array( 'op' => 'delete', 'src' => $source ); - $cases[] = array( - $op, // operation - true, // with source - true // succeeds - ); - - $cases[] = array( - $op, // operation - false, // without source - false // fails - ); - - $op['ignoreMissingSource'] = true; - $cases[] = array( - $op, // operation - false, // without source - true // succeeds - ); - - $op['ignoreMissingSource'] = true; - $op['src'] = self::baseStorePath() . '/unittest-cont-bad/e/file.txt'; - $cases[] = array( - $op, // operation - false, // without source - true // succeeds - ); - - return $cases; - } - - /** - * @dataProvider provider_testDescribe - * @covers FileBackend::doOperation - */ - public function testDescribe( $op, $withSource, $okStatus ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDescribe( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDescribe( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - } - - private function doTestDescribe( $op, $withSource, $okStatus ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - - if ( $withSource ) { - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - } - - $status = $this->backend->doOperation( $op ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Describe of file at $source succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Describe of file at $source succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Describe of file at $source has proper 'success' field in Status ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Describe of file at $source failed ($backendName)." ); - } - - $this->assertBackendPathsConsistent( array( $source ) ); - } - - public static function provider_testDescribe() { - $cases = array(); - - $source = self::baseStorePath() . '/unittest-cont1/e/myfacefile.txt'; - - $op = array( 'op' => 'describe', 'src' => $source, - 'headers' => array( 'X-Content-Length' => '91.3', 'Content-Old-Header' => '' ), - 'disposition' => 'inline' ); - $cases[] = array( - $op, // operation - true, // with source - true // succeeds - ); - - $cases[] = array( - $op, // operation - false, // without source - false // fails - ); - - return $cases; - } - - /** - * @dataProvider provider_testCreate - * @covers FileBackend::doOperation - */ - public function testCreate( $op, $alreadyExists, $okStatus, $newSize ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestCreate( $op, $alreadyExists, $okStatus, $newSize ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestCreate( $op, $alreadyExists, $okStatus, $newSize ); - $this->tearDownFiles(); - } - - private function doTestCreate( $op, $alreadyExists, $okStatus, $newSize ) { - $backendName = $this->backendClass(); - - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - $oldText = 'blah...blah...waahwaah'; - if ( $alreadyExists ) { - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $oldText, 'dst' => $dest ) ); - $this->assertGoodStatus( $status, - "Creation of file at $dest succeeded ($backendName)." ); - } - - $status = $this->backend->doOperation( $op ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Creation of file at $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of file at $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Creation of file at $dest has proper 'success' field in Status ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Creation of file at $dest failed ($backendName)." ); - } - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists after creation ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( true, $props1['fileExists'], - "Destination file $dest exists according to props ($backendName)." ); - if ( $okStatus ) { // file content is what we saved - $this->assertEquals( $newSize, $props1['size'], - "Destination file $dest has expected size according to props ($backendName)." ); - $this->assertEquals( $newSize, - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - } else { // file content is some other previous text - $this->assertEquals( strlen( $oldText ), $props1['size'], - "Destination file $dest has original size according to props ($backendName)." ); - $this->assertEquals( strlen( $oldText ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has original size according to props ($backendName)." ); - } - - $this->assertBackendPathsConsistent( array( $dest ) ); - } - - /** - * @dataProvider provider_testCreate - */ - public static function provider_testCreate() { - $cases = array(); - - $dest = self::baseStorePath() . '/unittest-cont2/a/myspacefile.txt'; - - $op = array( 'op' => 'create', 'content' => 'test test testing', 'dst' => $dest ); - $cases[] = array( - $op, // operation - false, // no dest already exists - true, // succeeds - strlen( $op['content'] ) - ); - - $op2 = $op; - $op2['content'] = "\n"; - $cases[] = array( - $op2, // operation - false, // no dest already exists - true, // succeeds - strlen( $op2['content'] ) - ); - - $op2 = $op; - $op2['content'] = "fsf\n waf 3kt"; - $cases[] = array( - $op2, // operation - true, // dest already exists - false, // fails - strlen( $op2['content'] ) - ); - - $op2 = $op; - $op2['content'] = "egm'g gkpe gpqg eqwgwqg"; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - true, // dest already exists - true, // succeeds - strlen( $op2['content'] ) - ); - - $op2 = $op; - $op2['content'] = "39qjmg3-qg"; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - true, // dest already exists - false, // succeeds - strlen( $op2['content'] ) - ); - - return $cases; - } - - /** - * @covers FileBackend::doQuickOperations - */ - public function testDoQuickOperations() { - $this->backend = $this->singleBackend; - $this->doTestDoQuickOperations(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->doTestDoQuickOperations(); - $this->tearDownFiles(); - } - - private function doTestDoQuickOperations() { - $backendName = $this->backendClass(); - - $base = self::baseStorePath(); - $files = array( - "$base/unittest-cont1/e/fileA.a", - "$base/unittest-cont1/e/fileB.a", - "$base/unittest-cont1/e/fileC.a" - ); - $createOps = array(); - $purgeOps = array(); - foreach ( $files as $path ) { - $status = $this->prepare( array( 'dir' => dirname( $path ) ) ); - $this->assertGoodStatus( $status, - "Preparing $path succeeded without warnings ($backendName)." ); - $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' ); - - $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." ); - } - - $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." ); - } - } - - /** - * @dataProvider provider_testConcatenate - */ - public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) { - $this->filesToPrune[] = $op['dst']; - - $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; - $this->tearDownFiles(); - $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ); - $this->filesToPrune[] = $op['dst']; # avoid file leaking - $this->tearDownFiles(); - } - - private function doTestConcatenate( $params, $srcs, $srcsContent, $alreadyExists, $okStatus ) { - $backendName = $this->backendClass(); - - $expContent = ''; - // Create sources - $ops = array(); - foreach ( $srcs as $i => $source ) { - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $ops[] = array( - 'op' => 'create', // operation - 'dst' => $source, // source - 'content' => $srcsContent[$i] - ); - $expContent .= $srcsContent[$i]; - } - $status = $this->backend->doOperations( $ops ); - - $this->assertGoodStatus( $status, - "Creation of source files succeeded ($backendName)." ); - - $dest = $params['dst']; - if ( $alreadyExists ) { - $ok = file_put_contents( $dest, 'blah...blah...waahwaah' ) !== false; - $this->assertEquals( true, $ok, - "Creation of file at $dest succeeded ($backendName)." ); - } else { - $ok = file_put_contents( $dest, '' ) !== false; - $this->assertEquals( true, $ok, - "Creation of 0-byte file at $dest succeeded ($backendName)." ); - } - - // Combine the files into one - $status = $this->backend->concatenate( $params ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Creation of concat file at $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of concat file at $dest succeeded ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Creation of concat file at $dest failed ($backendName)." ); - } - - if ( $okStatus ) { - $this->assertEquals( true, is_file( $dest ), - "Dest concat file $dest exists after creation ($backendName)." ); - } else { - $this->assertEquals( true, is_file( $dest ), - "Dest concat file $dest exists after failed creation ($backendName)." ); - } - - $contents = file_get_contents( $dest ); - $this->assertNotEquals( false, $contents, "File at $dest exists ($backendName)." ); - - if ( $okStatus ) { - $this->assertEquals( $expContent, $contents, - "Concat file at $dest has correct contents ($backendName)." ); - } else { - $this->assertNotEquals( $expContent, $contents, - "Concat file at $dest has correct contents ($backendName)." ); - } - } - - public static function provider_testConcatenate() { - $cases = array(); - - $rand = mt_rand( 0, 2000000000 ) . time(); - $dest = wfTempDir() . "/randomfile!$rand.txt"; - $srcs = array( - self::baseStorePath() . '/unittest-cont1/e/file1.txt', - self::baseStorePath() . '/unittest-cont1/e/file2.txt', - self::baseStorePath() . '/unittest-cont1/e/file3.txt', - self::baseStorePath() . '/unittest-cont1/e/file4.txt', - self::baseStorePath() . '/unittest-cont1/e/file5.txt', - self::baseStorePath() . '/unittest-cont1/e/file6.txt', - self::baseStorePath() . '/unittest-cont1/e/file7.txt', - self::baseStorePath() . '/unittest-cont1/e/file8.txt', - self::baseStorePath() . '/unittest-cont1/e/file9.txt', - self::baseStorePath() . '/unittest-cont1/e/file10.txt' - ); - $content = array( - 'egfage', - 'ageageag', - 'rhokohlr', - 'shgmslkg', - 'kenga', - 'owagmal', - 'kgmae', - 'g eak;g', - 'lkaem;a', - 'legma' - ); - $params = array( 'srcs' => $srcs, 'dst' => $dest ); - - $cases[] = array( - $params, // operation - $srcs, // sources - $content, // content for each source - false, // no dest already exists - true, // succeeds - ); - - $cases[] = array( - $params, // operation - $srcs, // sources - $content, // content for each source - true, // dest already exists - false, // succeeds - ); - - return $cases; - } - - /** - * @dataProvider provider_testGetFileStat - * @covers FileBackend::getFileStat - */ - public function testGetFileStat( $path, $content, $alreadyExists ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileStat( $path, $content, $alreadyExists ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileStat( $path, $content, $alreadyExists ); - $this->tearDownFiles(); - } - - private function doTestGetFileStat( $path, $content, $alreadyExists ) { - $backendName = $this->backendClass(); - - if ( $alreadyExists ) { - $this->prepare( array( 'dir' => dirname( $path ) ) ); - $status = $this->create( array( 'dst' => $path, 'content' => $content ) ); - $this->assertGoodStatus( $status, - "Creation of file at $path succeeded ($backendName)." ); - - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - $time = $this->backend->getFileTimestamp( array( 'src' => $path ) ); - $stat = $this->backend->getFileStat( array( 'src' => $path ) ); - - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - $this->assertTrue( abs( time() - wfTimestamp( TS_UNIX, $time ) ) < 10, - "Correct file timestamp of '$path'" ); - - $size = $stat['size']; - $time = $stat['mtime']; - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - $this->assertTrue( abs( time() - wfTimestamp( TS_UNIX, $time ) ) < 10, - "Correct file timestamp of '$path'" ); - - $this->backend->clearCache( array( $path ) ); - - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - - $this->backend->preloadCache( array( $path ) ); - - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - } else { - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - $time = $this->backend->getFileTimestamp( array( 'src' => $path ) ); - $stat = $this->backend->getFileStat( array( 'src' => $path ) ); - - $this->assertFalse( $size, "Correct file size of '$path'" ); - $this->assertFalse( $time, "Correct file timestamp of '$path'" ); - $this->assertFalse( $stat, "Correct file stat of '$path'" ); - } - } - - public static function provider_testGetFileStat() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/b/z/some_file.txt", "some file contents", true ); - $cases[] = array( "$base/unittest-cont1/e/b/some-other_file.txt", "", true ); - $cases[] = array( "$base/unittest-cont1/e/b/some-diff_file.txt", null, false ); - - return $cases; - } - - /** - * @dataProvider provider_testGetFileContents - * @covers FileBackend::getFileContents - * @covers FileBackend::getFileContentsMulti - */ - public function testGetFileContents( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileContents( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileContents( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetFileContents( $source, $content ) { - $backendName = $this->backendClass(); - - $srcs = (array)$source; - $content = (array)$content; - foreach ( $srcs as $i => $src ) { - $this->prepare( array( 'dir' => dirname( $src ) ) ); - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content[$i], 'dst' => $src ) ); - $this->assertGoodStatus( $status, - "Creation of file at $src succeeded ($backendName)." ); - } - - if ( is_array( $source ) ) { - $contents = $this->backend->getFileContentsMulti( array( 'srcs' => $source ) ); - foreach ( $contents as $path => $data ) { - $this->assertNotEquals( false, $data, "Contents of $path exists ($backendName)." ); - $this->assertEquals( current( $content ), $data, "Contents of $path is correct ($backendName)." ); - next( $content ); - } - $this->assertEquals( $source, array_keys( $contents ), "Contents in right order ($backendName)." ); - $this->assertEquals( count( $source ), count( $contents ), "Contents array size correct ($backendName)." ); - } else { - $data = $this->backend->getFileContents( array( 'src' => $source ) ); - $this->assertNotEquals( false, $data, "Contents of $source exists ($backendName)." ); - $this->assertEquals( $content[0], $data, "Contents of $source is correct ($backendName)." ); - } - } - - public static function provider_testGetFileContents() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/b/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/b/some-other_file.txt", "more file contents" ); - $cases[] = array( - array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt", - "$base/unittest-cont1/e/a/z.txt" ), - array( "contents xx", "contents xy", "contents xz" ) - ); - - return $cases; - } - - /** - * @dataProvider provider_testGetLocalCopy - * @covers FileBackend::getLocalCopy - */ - public function testGetLocalCopy( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopy( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopy( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetLocalCopy( $source, $content ) { - $backendName = $this->backendClass(); - - $srcs = (array)$source; - $content = (array)$content; - foreach ( $srcs as $i => $src ) { - $this->prepare( array( 'dir' => dirname( $src ) ) ); - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content[$i], 'dst' => $src ) ); - $this->assertGoodStatus( $status, - "Creation of file at $src succeeded ($backendName)." ); - } - - if ( is_array( $source ) ) { - $tmpFiles = $this->backend->getLocalCopyMulti( array( 'srcs' => $source ) ); - foreach ( $tmpFiles as $path => $tmpFile ) { - $this->assertNotNull( $tmpFile, - "Creation of local copy of $path succeeded ($backendName)." ); - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local copy of $path exists ($backendName)." ); - $this->assertEquals( current( $content ), $contents, "Local copy of $path is correct ($backendName)." ); - next( $content ); - } - $this->assertEquals( $source, array_keys( $tmpFiles ), "Local copies in right order ($backendName)." ); - $this->assertEquals( count( $source ), count( $tmpFiles ), "Local copies array size correct ($backendName)." ); - } else { - $tmpFile = $this->backend->getLocalCopy( array( 'src' => $source ) ); - $this->assertNotNull( $tmpFile, - "Creation of local copy of $source succeeded ($backendName)." ); - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." ); - $this->assertEquals( $content[0], $contents, "Local copy of $source is correct ($backendName)." ); - } - - $obj = new stdClass(); - $tmpFile->bind( $obj ); - } - - public static function provider_testGetLocalCopy() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" ); - $cases[] = array( - array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt", - "$base/unittest-cont1/e/a/z.txt" ), - array( "contents xx", "contents xy", "contents xz" ) - ); - - return $cases; - } - - /** - * @dataProvider provider_testGetLocalReference - * @covers FileBackend::getLocalReference - */ - public function testGetLocalReference( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetLocalReference( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetLocalReference( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetLocalReference( $source, $content ) { - $backendName = $this->backendClass(); - - $srcs = (array)$source; - $content = (array)$content; - foreach ( $srcs as $i => $src ) { - $this->prepare( array( 'dir' => dirname( $src ) ) ); - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content[$i], 'dst' => $src ) ); - $this->assertGoodStatus( $status, - "Creation of file at $src succeeded ($backendName)." ); - } - - if ( is_array( $source ) ) { - $tmpFiles = $this->backend->getLocalReferenceMulti( array( 'srcs' => $source ) ); - foreach ( $tmpFiles as $path => $tmpFile ) { - $this->assertNotNull( $tmpFile, - "Creation of local copy of $path succeeded ($backendName)." ); - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local ref of $path exists ($backendName)." ); - $this->assertEquals( current( $content ), $contents, "Local ref of $path is correct ($backendName)." ); - next( $content ); - } - $this->assertEquals( $source, array_keys( $tmpFiles ), "Local refs in right order ($backendName)." ); - $this->assertEquals( count( $source ), count( $tmpFiles ), "Local refs array size correct ($backendName)." ); - } else { - $tmpFile = $this->backend->getLocalReference( array( 'src' => $source ) ); - $this->assertNotNull( $tmpFile, - "Creation of local copy of $source succeeded ($backendName)." ); - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local ref of $source exists ($backendName)." ); - $this->assertEquals( $content[0], $contents, "Local ref of $source is correct ($backendName)." ); - } - } - - public static function provider_testGetLocalReference() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" ); - $cases[] = array( - array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt", - "$base/unittest-cont1/e/a/z.txt" ), - array( "contents xx", "contents xy", "contents xz" ) - ); - - return $cases; - } - - /** - * @covers FileBackend::getLocalCopy - * @covers FileBackend::getLocalReference - */ - public function testGetLocalCopyAndReference404() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopyAndReference404(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopyAndReference404(); - $this->tearDownFiles(); - } - - public function doTestGetLocalCopyAndReference404() { - $backendName = $this->backendClass(); - - $base = self::baseStorePath(); - - $tmpFile = $this->backend->getLocalCopy( array( - 'src' => "$base/unittest-cont1/not-there" ) ); - $this->assertEquals( null, $tmpFile, "Local copy of not existing file is null ($backendName)." ); - - $tmpFile = $this->backend->getLocalReference( array( - 'src' => "$base/unittest-cont1/not-there" ) ); - $this->assertEquals( null, $tmpFile, "Local ref of not existing file is null ($backendName)." ); - } - - /** - * @dataProvider provider_testGetFileHttpUrl - * @covers FileBackend::getFileHttpUrl - */ - public function testGetFileHttpUrl( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileHttpUrl( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileHttpUrl( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetFileHttpUrl( $source, $content ) { - $backendName = $this->backendClass(); - - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content, 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - $url = $this->backend->getFileHttpUrl( array( 'src' => $source ) ); - - if ( $url !== null ) { // supported - $data = Http::request( "GET", $url ); - $this->assertEquals( $content, $data, - "HTTP GET of URL has right contents ($backendName)." ); - } - } - - public static function provider_testGetFileHttpUrl() { - $cases = array(); - - $base = self::baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" ); - - return $cases; - } - - /** - * @dataProvider provider_testPrepareAndClean - * @covers FileBackend::prepare - * @covers FileBackend::clean - */ - public function testPrepareAndClean( $path, $isOK ) { - $this->backend = $this->singleBackend; - $this->doTestPrepareAndClean( $path, $isOK ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->doTestPrepareAndClean( $path, $isOK ); - $this->tearDownFiles(); - } - - 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 ), - # Specific to FS backend with no basePath field set - #array( "$base/unittest-cont3/a/z/some_file3.txt", false ), - ); - } - - private function doTestPrepareAndClean( $path, $isOK ) { - $backendName = $this->backendClass(); - - $status = $this->prepare( array( 'dir' => dirname( $path ) ) ); - if ( $isOK ) { - $this->assertGoodStatus( $status, - "Preparing dir $path succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Preparing dir $path succeeded ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Preparing dir $path failed ($backendName)." ); - } - - $status = $this->backend->clean( array( 'dir' => dirname( $path ) ) ); - if ( $isOK ) { - $this->assertGoodStatus( $status, - "Cleaning dir $path succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Cleaning dir $path succeeded ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Cleaning dir $path failed ($backendName)." ); - } - } - - public function testRecursiveClean() { - $this->backend = $this->singleBackend; - $this->doTestRecursiveClean(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->doTestRecursiveClean(); - $this->tearDownFiles(); - } - - /** - * @covers FileBackend::clean - */ - private function doTestRecursiveClean() { - $backendName = $this->backendClass(); - - $base = self::baseStorePath(); - $dirs = array( - "$base/unittest-cont1", - "$base/unittest-cont1/e", - "$base/unittest-cont1/e/a", - "$base/unittest-cont1/e/a/b", - "$base/unittest-cont1/e/a/b/c", - "$base/unittest-cont1/e/a/b/c/d0", - "$base/unittest-cont1/e/a/b/c/d1", - "$base/unittest-cont1/e/a/b/c/d2", - "$base/unittest-cont1/e/a/b/c/d0/1", - "$base/unittest-cont1/e/a/b/c/d0/2", - "$base/unittest-cont1/e/a/b/c/d1/3", - "$base/unittest-cont1/e/a/b/c/d1/4", - "$base/unittest-cont1/e/a/b/c/d2/5", - "$base/unittest-cont1/e/a/b/c/d2/6" - ); - foreach ( $dirs as $dir ) { - $status = $this->prepare( array( 'dir' => $dir ) ); - $this->assertGoodStatus( $status, - "Preparing dir $dir succeeded without warnings ($backendName)." ); - } - - if ( $this->backend instanceof FSFileBackend ) { - foreach ( $dirs as $dir ) { - $this->assertEquals( true, $this->backend->directoryExists( array( 'dir' => $dir ) ), - "Dir $dir exists ($backendName)." ); - } - } - - $status = $this->backend->clean( - array( 'dir' => "$base/unittest-cont1", 'recursive' => 1 ) ); - $this->assertGoodStatus( $status, - "Recursive cleaning of dir $dir succeeded without warnings ($backendName)." ); - - foreach ( $dirs as $dir ) { - $this->assertEquals( false, $this->backend->directoryExists( array( 'dir' => $dir ) ), - "Dir $dir no longer exists ($backendName)." ); - } - } - - // @todo testSecure - - /** - * @covers FileBackend::doOperations - */ - public function testDoOperations() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDoOperations(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDoOperations(); - $this->tearDownFiles(); - } - - private function doTestDoOperations() { - $base = self::baseStorePath(); - - $fileA = "$base/unittest-cont1/e/a/b/fileA.txt"; - $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileB = "$base/unittest-cont1/e/a/b/fileB.txt"; - $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileC = "$base/unittest-cont1/e/a/b/fileC.txt"; - $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - $fileD = "$base/unittest-cont1/e/a/b/fileD.txt"; - - $this->prepare( array( 'dir' => dirname( $fileA ) ) ); - $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); - $this->prepare( array( 'dir' => dirname( $fileB ) ) ); - $this->create( array( 'dst' => $fileB, 'content' => $fileBContents ) ); - $this->prepare( array( 'dir' => dirname( $fileC ) ) ); - $this->create( array( 'dst' => $fileC, 'content' => $fileCContents ) ); - $this->prepare( array( 'dir' => dirname( $fileD ) ) ); - - $status = $this->backend->doOperations( array( - array( 'op' => 'describe', 'src' => $fileA, - 'headers' => array( 'X-Content-Length' => '91.3' ), 'disposition' => 'inline' ), - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (file:<orginal contents>) - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<empty>, D:<A> - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC ), - // Now: A:<A>, B:<empty>, C:<B>, D:<A> - array( 'op' => 'move', 'src' => $fileD, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileA, 'overwrite' => 1 ), - // Now: A:<B>, B:<empty>, C:<empty>, D:<empty> - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC ), - // Now: A:<B>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'move', 'src' => $fileA, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Now: A:<empty>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'null' ), - // Does nothing - ) ); - - $this->assertGoodStatus( $status, "Operation batch succeeded" ); - $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" ); - $this->assertEquals( 14, count( $status->success ), - "Operation batch has correct success array" ); - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileA ) ), - "File does not exist at $fileA" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileB ) ), - "File does not exist at $fileB" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileD ) ), - "File does not exist at $fileD" ); - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileC ) ), - "File exists at $fileC" ); - $this->assertEquals( $fileBContents, - $this->backend->getFileContents( array( 'src' => $fileC ) ), - "Correct file contents of $fileC" ); - $this->assertEquals( strlen( $fileBContents ), - $this->backend->getFileSize( array( 'src' => $fileC ) ), - "Correct file size of $fileC" ); - $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ), - $this->backend->getFileSha1Base36( array( 'src' => $fileC ) ), - "Correct file SHA-1 of $fileC" ); - } - - /** - * @covers FileBackend::doOperations - */ - public function testDoOperationsPipeline() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsPipeline(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsPipeline(); - $this->tearDownFiles(); - } - - // concurrency orientated - private function doTestDoOperationsPipeline() { - $base = self::baseStorePath(); - - $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - - $tmpNameA = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - file_put_contents( $tmpNameA, $fileAContents ); - $tmpNameB = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - file_put_contents( $tmpNameB, $fileBContents ); - $tmpNameC = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - file_put_contents( $tmpNameC, $fileCContents ); - - $this->filesToPrune[] = $tmpNameA; # avoid file leaking - $this->filesToPrune[] = $tmpNameB; # avoid file leaking - $this->filesToPrune[] = $tmpNameC; # avoid file leaking - - $fileA = "$base/unittest-cont1/e/a/b/fileA.txt"; - $fileB = "$base/unittest-cont1/e/a/b/fileB.txt"; - $fileC = "$base/unittest-cont1/e/a/b/fileC.txt"; - $fileD = "$base/unittest-cont1/e/a/b/fileD.txt"; - - $this->prepare( array( 'dir' => dirname( $fileA ) ) ); - $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); - $this->prepare( array( 'dir' => dirname( $fileB ) ) ); - $this->prepare( array( 'dir' => dirname( $fileC ) ) ); - $this->prepare( array( 'dir' => dirname( $fileD ) ) ); - - $status = $this->backend->doOperations( array( - array( 'op' => 'store', 'src' => $tmpNameA, 'dst' => $fileA, 'overwriteSame' => 1 ), - array( 'op' => 'store', 'src' => $tmpNameB, 'dst' => $fileB, 'overwrite' => 1 ), - array( 'op' => 'store', 'src' => $tmpNameC, 'dst' => $fileC, 'overwrite' => 1 ), - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (file:<orginal contents>) - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<empty>, D:<A> - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC ), - // Now: A:<A>, B:<empty>, C:<B>, D:<A> - array( 'op' => 'move', 'src' => $fileD, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileA, 'overwrite' => 1 ), - // Now: A:<B>, B:<empty>, C:<empty>, D:<empty> - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC ), - // Now: A:<B>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'move', 'src' => $fileA, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Now: A:<empty>, B:<empty>, C:<B>, D:<empty> - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'null' ), - // Does nothing - ) ); - - $this->assertGoodStatus( $status, "Operation batch succeeded" ); - $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" ); - $this->assertEquals( 16, count( $status->success ), - "Operation batch has correct success array" ); - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileA ) ), - "File does not exist at $fileA" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileB ) ), - "File does not exist at $fileB" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileD ) ), - "File does not exist at $fileD" ); - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileC ) ), - "File exists at $fileC" ); - $this->assertEquals( $fileBContents, - $this->backend->getFileContents( array( 'src' => $fileC ) ), - "Correct file contents of $fileC" ); - $this->assertEquals( strlen( $fileBContents ), - $this->backend->getFileSize( array( 'src' => $fileC ) ), - "Correct file size of $fileC" ); - $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ), - $this->backend->getFileSha1Base36( array( 'src' => $fileC ) ), - "Correct file SHA-1 of $fileC" ); - } - - /** - * @covers FileBackend::doOperations - */ - public function testDoOperationsFailing() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsFailing(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsFailing(); - $this->tearDownFiles(); - } - - private function doTestDoOperationsFailing() { - $base = self::baseStorePath(); - - $fileA = "$base/unittest-cont2/a/b/fileA.txt"; - $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileB = "$base/unittest-cont2/a/b/fileB.txt"; - $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileC = "$base/unittest-cont2/a/b/fileC.txt"; - $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - $fileD = "$base/unittest-cont2/a/b/fileD.txt"; - - $this->prepare( array( 'dir' => dirname( $fileA ) ) ); - $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); - $this->prepare( array( 'dir' => dirname( $fileB ) ) ); - $this->create( array( 'dst' => $fileB, 'content' => $fileBContents ) ); - $this->prepare( array( 'dir' => dirname( $fileC ) ) ); - $this->create( array( 'dst' => $fileC, 'content' => $fileCContents ) ); - - $status = $this->backend->doOperations( array( - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (file:<orginal contents>) - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> - array( 'op' => 'copy', 'src' => $fileB, 'dst' => $fileD, 'overwrite' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<B> - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (failed) - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Now: A:<A>, B:<B>, C:<A>, D:<empty> (failed) - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileA, 'overwrite' => 1 ), - // Now: A:<B>, B:<empty>, C:<A>, D:<empty> - array( 'op' => 'delete', 'src' => $fileD ), - // Now: A:<B>, B:<empty>, C:<A>, D:<empty> - array( 'op' => 'null' ), - // Does nothing - ), array( 'force' => 1 ) ); - - $this->assertNotEquals( array(), $status->errors, "Operation had warnings" ); - $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" ); - $this->assertEquals( 8, count( $status->success ), - "Operation batch has correct success array" ); - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileB ) ), - "File does not exist at $fileB" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileD ) ), - "File does not exist at $fileD" ); - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileA ) ), - "File does not exist at $fileA" ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileC ) ), - "File exists at $fileC" ); - $this->assertEquals( $fileBContents, - $this->backend->getFileContents( array( 'src' => $fileA ) ), - "Correct file contents of $fileA" ); - $this->assertEquals( strlen( $fileBContents ), - $this->backend->getFileSize( array( 'src' => $fileA ) ), - "Correct file size of $fileA" ); - $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ), - $this->backend->getFileSha1Base36( array( 'src' => $fileA ) ), - "Correct file SHA-1 of $fileA" ); - } - - /** - * @covers FileBackend::getFileList - */ - public function testGetFileList() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileList(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileList(); - $this->tearDownFiles(); - } - - private function doTestGetFileList() { - $backendName = $this->backendClass(); - $base = self::baseStorePath(); - - // Should have no errors - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont-notexists" ) ); - - $files = array( - "$base/unittest-cont1/e/test1.txt", - "$base/unittest-cont1/e/test2.txt", - "$base/unittest-cont1/e/test3.txt", - "$base/unittest-cont1/e/subdir1/test1.txt", - "$base/unittest-cont1/e/subdir1/test2.txt", - "$base/unittest-cont1/e/subdir2/test3.txt", - "$base/unittest-cont1/e/subdir2/test4.txt", - "$base/unittest-cont1/e/subdir2/subdir/test1.txt", - "$base/unittest-cont1/e/subdir2/subdir/test2.txt", - "$base/unittest-cont1/e/subdir2/subdir/test3.txt", - "$base/unittest-cont1/e/subdir2/subdir/test4.txt", - "$base/unittest-cont1/e/subdir2/subdir/test5.txt", - "$base/unittest-cont1/e/subdir2/subdir/sub/test0.txt", - "$base/unittest-cont1/e/subdir2/subdir/sub/120-px-file.txt", - ); - - // Add the files - $ops = array(); - foreach ( $files as $file ) { - $this->prepare( array( 'dir' => dirname( $file ) ) ); - $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file ); - } - $status = $this->backend->doQuickOperations( $ops ); - $this->assertGoodStatus( $status, - "Creation of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of files succeeded with OK status ($backendName)." ); - - // Expected listing at root - $expected = array( - "e/test1.txt", - "e/test2.txt", - "e/test3.txt", - "e/subdir1/test1.txt", - "e/subdir1/test2.txt", - "e/subdir2/test3.txt", - "e/subdir2/test4.txt", - "e/subdir2/subdir/test1.txt", - "e/subdir2/subdir/test2.txt", - "e/subdir2/subdir/test3.txt", - "e/subdir2/subdir/test4.txt", - "e/subdir2/subdir/test5.txt", - "e/subdir2/subdir/sub/test0.txt", - "e/subdir2/subdir/sub/120-px-file.txt", - ); - sort( $expected ); - - // Actual listing (no trailing slash) at root - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1" ) ); - $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) 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 at subdir - $expected = array( - "test1.txt", - "test2.txt", - "test3.txt", - "test4.txt", - "test5.txt", - "sub/test0.txt", - "sub/120-px-file.txt", - ); - sort( $expected ); - - // Actual listing (no trailing slash) at subdir - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - $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) 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 = $this->listToArray( $iter ); - sort( $list ); - $this->assertEquals( $expected, $list, "Correct file listing ($backendName), second iteration." ); - - // 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", - "test3.txt", - "test4.txt", - "test5.txt" - ); - sort( $expected ); - - // Actual listing (top files only) at subdir - $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - $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 - $this->backend->doOperation( array( 'op' => 'delete', 'src' => $file ) ); - } - - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - foreach ( $iter as $iter ) { - // no errors - } - } - - /** - * @covers FileBackend::getTopDirectoryList - * @covers FileBackend::getDirectoryList - */ - public function testGetDirectoryList() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetDirectoryList(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetDirectoryList(); - $this->tearDownFiles(); - } - - private function doTestGetDirectoryList() { - $backendName = $this->backendClass(); - - $base = self::baseStorePath(); - $files = array( - "$base/unittest-cont1/e/test1.txt", - "$base/unittest-cont1/e/test2.txt", - "$base/unittest-cont1/e/test3.txt", - "$base/unittest-cont1/e/subdir1/test1.txt", - "$base/unittest-cont1/e/subdir1/test2.txt", - "$base/unittest-cont1/e/subdir2/test3.txt", - "$base/unittest-cont1/e/subdir2/test4.txt", - "$base/unittest-cont1/e/subdir2/subdir/test1.txt", - "$base/unittest-cont1/e/subdir3/subdir/test2.txt", - "$base/unittest-cont1/e/subdir4/subdir/test3.txt", - "$base/unittest-cont1/e/subdir4/subdir/test4.txt", - "$base/unittest-cont1/e/subdir4/subdir/test5.txt", - "$base/unittest-cont1/e/subdir4/subdir/sub/test0.txt", - "$base/unittest-cont1/e/subdir4/subdir/sub/120-px-file.txt", - ); - - // Add the files - $ops = array(); - foreach ( $files as $file ) { - $this->prepare( array( 'dir' => dirname( $file ) ) ); - $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file ); - } - $status = $this->backend->doQuickOperations( $ops ); - $this->assertGoodStatus( $status, - "Creation of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of files succeeded with OK status ($backendName)." ); - - $this->assertEquals( true, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir1" ) ), - "Directory exists in ($backendName)." ); - $this->assertEquals( true, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ), - "Directory exists in ($backendName)." ); - $this->assertEquals( false, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir2/test1.txt" ) ), - "Directory does not exists in ($backendName)." ); - - // Expected listing - $expected = array( - "e", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Expected listing - $expected = array( - "subdir1", - "subdir2", - "subdir3", - "subdir4", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Actual listing (with trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Expected listing - $expected = array( - "subdir", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir2" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Actual listing (with trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir2/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Actual listing (using iterator second time) - $list = array(); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName), second iteration." ); - - // Expected listing (recursive) - $expected = array( - "e", - "e/subdir1", - "e/subdir2", - "e/subdir3", - "e/subdir4", - "e/subdir2/subdir", - "e/subdir3/subdir", - "e/subdir4/subdir", - "e/subdir4/subdir/sub", - ); - sort( $expected ); - - // Actual listing (recursive) - $list = array(); - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); - - // Expected listing (recursive) - $expected = array( - "subdir", - "subdir/sub", - ); - sort( $expected ); - - // Actual listing (recursive) - $list = array(); - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir4" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); - - // Actual listing (recursive, second time) - $list = array(); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); - - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir1" ) ); - $items = $this->listToArray( $iter ); - $this->assertEquals( array(), $items, "Directory listing is empty." ); - - foreach ( $files as $file ) { // clean up - $this->backend->doOperation( array( 'op' => 'delete', 'src' => $file ) ); - } - - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - 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 = $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(); - } - - private function doTestLockCalls() { - $backendName = $this->backendClass(); - - $paths = array( - "test1.txt", - "test2.txt", - "test3.txt", - "subdir1", - "subdir1", // duplicate - "subdir1/test1.txt", - "subdir1/test2.txt", - "subdir2", - "subdir2", // duplicate - "subdir2/test3.txt", - "subdir2/test4.txt", - "subdir2/subdir", - "subdir2/subdir/test1.txt", - "subdir2/subdir/test2.txt", - "subdir2/subdir/test3.txt", - "subdir2/subdir/test4.txt", - "subdir2/subdir/test5.txt", - "subdir2/subdir/sub", - "subdir2/subdir/sub/test0.txt", - "subdir2/subdir/sub/120-px-file.txt", - ); - - 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)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->lockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName) ($i)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName) ($i)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_EX ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName). ($i)" ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - ## Flip the acquire/release ordering around ## - - $status = $this->backend->lockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName) ($i)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($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)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_EX ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName). ($i)" ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( print_r( array(), true ), print_r( $status->errors, true ), - "Locking of files succeeded ($backendName) ($i)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName) ($i)." ); - } - - $status = Status::newGood(); - $sl = $this->backend->getScopedFileLocks( $paths, LockManager::LOCK_EX, $status ); - $this->assertType( 'ScopedLock', $sl, - "Scoped locking of files succeeded ($backendName)." ); - $this->assertEquals( array(), $status->errors, - "Scoped locking of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Scoped locking of files succeeded with OK status ($backendName)." ); - - ScopedLock::release( $sl ); - $this->assertEquals( null, $sl, - "Scoped unlocking of files succeeded ($backendName)." ); - $this->assertEquals( array(), $status->errors, - "Scoped unlocking of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "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 ); - } - - // 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 ) { - if ( is_file( $file ) ) { - unlink( $file ); - } - } - $containers = array( 'unittest-cont1', 'unittest-cont2' ); - foreach ( $containers as $container ) { - $this->deleteFiles( $container ); - } - $this->filesToPrune = array(); - } - - private function deleteFiles( $container ) { - $base = self::baseStorePath(); - $iter = $this->backend->getFileList( array( 'dir' => "$base/$container" ) ); - if ( $iter ) { - foreach ( $iter as $file ) { - $this->backend->quickDelete( array( 'src' => "$base/$container/$file" ) ); - } - // free the directory, to avoid Permission denied under windows on rmdir - unset( $iter ); - } - $this->backend->clean( array( 'dir' => "$base/$container", 'recursive' => 1 ) ); - } - - function assertBackendPathsConsistent( array $paths ) { - if ( $this->backend instanceof FileBackendMultiWrite ) { - $status = $this->backend->consistencyCheck( $paths ); - $this->assertGoodStatus( $status, "Files synced: " . implode( ',', $paths ) ); - } - } - - function assertGoodStatus( $status, $msg ) { - $this->assertEquals( print_r( array(), 1 ), print_r( $status->errors, 1 ), $msg ); - } -} diff --git a/tests/phpunit/includes/filerepo/FileRepoTest.php b/tests/phpunit/includes/filerepo/FileRepoTest.php deleted file mode 100644 index e3a75567..00000000 --- a/tests/phpunit/includes/filerepo/FileRepoTest.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php - -class FileRepoTest extends MediaWikiTestCase { - - /** - * @expectedException MWException - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionOptionCanNotBeNull() { - new FileRepo(); - } - - /** - * @expectedException MWException - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionOptionCanNotBeAnEmptyArray() { - new FileRepo( array() ); - } - - /** - * @expectedException MWException - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionOptionNeedNameKey() { - new FileRepo( array( - 'backend' => 'foobar' - ) ); - } - - /** - * @expectedException MWException - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionOptionNeedBackendKey() { - new FileRepo( array( - 'name' => 'foobar' - ) ); - } - - /** - * @covers FileRepo::__construct - */ - public function testFileRepoConstructionWithRequiredOptions() { - $f = new FileRepo( array( - 'name' => 'FileRepoTestRepository', - 'backend' => new FSFileBackend( array( - 'name' => 'local-testing', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array() - ) ) - ) ); - $this->assertInstanceOf( 'FileRepo', $f ); - } -} diff --git a/tests/phpunit/includes/filerepo/StoreBatchTest.php b/tests/phpunit/includes/filerepo/StoreBatchTest.php deleted file mode 100644 index b33c1bbb..00000000 --- a/tests/phpunit/includes/filerepo/StoreBatchTest.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php - -/** - * @group FileRepo - * @group medium - */ -class StoreBatchTest extends MediaWikiTestCase { - - protected $createdFiles; - protected $date; - /** @var FileRepo */ - protected $repo; - - protected function setUp() { - global $wgFileBackends; - parent::setUp(); - - # Forge a FSRepo object to not have to rely on local wiki settings - $tmpPrefix = wfTempDir() . '/storebatch-test-' . time() . '-' . mt_rand(); - if ( $this->getCliArg( 'use-filebackend=' ) ) { - $name = $this->getCliArg( 'use-filebackend=' ); - $useConfig = array(); - foreach ( $wgFileBackends as $conf ) { - if ( $conf['name'] == $name ) { - $useConfig = $conf; - } - } - $useConfig['name'] = 'local-testing'; // swap name - $class = $useConfig['class']; - $backend = new $class( $useConfig ); - } else { - $backend = new FSFileBackend( array( - 'name' => 'local-testing', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( - 'unittests-public' => "{$tmpPrefix}-public", - 'unittests-thumb' => "{$tmpPrefix}-thumb", - 'unittests-temp' => "{$tmpPrefix}-temp", - 'unittests-deleted' => "{$tmpPrefix}-deleted", - ) - ) ); - } - $this->repo = new FileRepo( array( - 'name' => 'unittests', - 'backend' => $backend - ) ); - - $this->date = gmdate( "YmdHis" ); - $this->createdFiles = array(); - } - - protected function tearDown() { - $this->repo->cleanupBatch( $this->createdFiles ); // delete files - foreach ( $this->createdFiles as $tmp ) { // delete dirs - $tmp = $this->repo->resolveVirtualUrl( $tmp ); - while ( $tmp = FileBackend::parentStoragePath( $tmp ) ) { - $this->repo->getBackend()->clean( array( 'dir' => $tmp ) ); - } - } - parent::tearDown(); - } - - /** - * Store a file or virtual URL source into a media file name. - * - * @param $originalName string The title of the image - * @param $srcPath string The filepath or virtual URL - * @param $flags integer Flags to pass into repo::store(). - * @return FileRepoStatus - */ - private function storeit( $originalName, $srcPath, $flags ) { - $hashPath = $this->repo->getHashPath( $originalName ); - $dstRel = "$hashPath{$this->date}!$originalName"; - $dstUrlRel = $hashPath . $this->date . '!' . rawurlencode( $originalName ); - - $result = $this->repo->store( $srcPath, 'temp', $dstRel, $flags ); - $result->value = $this->repo->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel; - $this->createdFiles[] = $result->value; - - return $result; - } - - /** - * Test storing a file using different flags. - * - * @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 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 ); - $this->assertTrue( $f->isOK(), 'failed to store a new file' ); - $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - if ( $fromrepo ) { - $f = $this->storeit( "Other-$fn", $infn, FileRepo::OVERWRITE ); - $infn = $f->value; - } - // This should work because we're allowed to overwrite - $f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE ); - $this->assertTrue( $f->isOK(), 'We should be allowed to overwrite' ); - $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - // This should fail because we're overwriting. - $f = $this->storeit( $fn, $infn, 0 ); - $this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite' ); - $this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - // This should succeed because we're overwriting the same content. - $f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE_SAME ); - $this->assertTrue( $f->isOK(), 'We should be able to overwrite the same content' ); - $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - // This should fail because we're overwriting different content. - if ( $fromrepo ) { - $f = $this->storeit( "Other-$fn", $otherfn, FileRepo::OVERWRITE ); - $otherfn = $f->value; - } - $f = $this->storeit( $fn, $otherfn, FileRepo::OVERWRITE_SAME ); - $this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite different content' ); - $this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - $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 ); - $this->storecohort( "Test2.png", "$IP/skins/monobook/wiki.png", "$IP/skins/monobook/video.png", true ); - } -} diff --git a/tests/phpunit/includes/installer/InstallDocFormatterTest.php b/tests/phpunit/includes/installer/InstallDocFormatterTest.php deleted file mode 100644 index 0e5f2671..00000000 --- a/tests/phpunit/includes/installer/InstallDocFormatterTest.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - -class InstallDocFormatterTest extends MediaWikiTestCase { - /** - * @covers InstallDocFormatter::format - * @dataProvider provideDocFormattingTests - */ - public function testFormat( $expected, $unformattedText, $message = '' ) { - $this->assertEquals( - $expected, - InstallDocFormatter::format( $unformattedText ), - $message - ); - } - - /** - * Provider for testFormat() - */ - public static function provideDocFormattingTests() { - # Format: (expected string, unformattedText string, optional message) - return array( - # Escape some wikitext - array( 'Install <tag>', 'Install <tag>', 'Escaping <' ), - array( 'Install {{template}}', 'Install {{template}}', 'Escaping [[' ), - array( 'Install [[page]]', 'Install [[page]]', 'Escaping {{' ), - array( 'Install __TOC__', 'Install __TOC__', 'Escaping __' ), - array( 'Install ', "Install \r", 'Removing \r' ), - - # Transform \t{1,2} into :{1,2} - array( ':One indentation', "\tOne indentation", 'Replacing a single \t' ), - array( '::Two indentations', "\t\tTwo indentations", 'Replacing 2 x \t' ), - - # Transform 'bug 123' links - array( - '<span class="config-plainlink">[https://bugzilla.wikimedia.org/123 bug 123]</span>', - 'bug 123', 'Testing bug 123 links' ), - array( - '(<span class="config-plainlink">[https://bugzilla.wikimedia.org/987654 bug 987654]</span>)', - '(bug 987654)', 'Testing (bug 987654) links' ), - - # "bug abc" shouldn't work - array( 'bug foobar', 'bug foobar', "Don't match bug followed by non-digits" ), - array( 'bug !!fakefake!!', 'bug !!fakefake!!', "Don't match bug followed by non-digits" ), - - # Transform '$wgFooBar' links - array( - '<span class="config-plainlink">[http://www.mediawiki.org/wiki/Manual:$wgFooBar $wgFooBar]</span>', - '$wgFooBar', 'Testing basic $wgFooBar' ), - array( - '<span class="config-plainlink">[http://www.mediawiki.org/wiki/Manual:$wgFooBar45 $wgFooBar45]</span>', - '$wgFooBar45', 'Testing $wgFooBar45 (with numbers)' ), - array( - '<span class="config-plainlink">[http://www.mediawiki.org/wiki/Manual:$wgFoo_Bar $wgFoo_Bar]</span>', - '$wgFoo_Bar', 'Testing $wgFoo_Bar (with underscore)' ), - - # Icky variables that shouldn't link - array( '$myAwesomeVariable', '$myAwesomeVariable', 'Testing $myAwesomeVariable (not starting with $wg)' ), - array( '$()not!a&Var', '$()not!a&Var', 'Testing $()not!a&Var (obviously not a variable)' ), - ); - } -} diff --git a/tests/phpunit/includes/installer/OracleInstallerTest.php b/tests/phpunit/includes/installer/OracleInstallerTest.php deleted file mode 100644 index 66e65592..00000000 --- a/tests/phpunit/includes/installer/OracleInstallerTest.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -/** - * Tests for OracleInstaller - * - * @group Database - * @group Installer - */ - -class OracleInstallerTest extends MediaWikiTestCase { - - /** - * @dataProvider provideOracleConnectStrings - * @covers OracleInstaller::checkConnectStringFormat - */ - public function testCheckConnectStringFormat( $expected, $connectString, $msg = '' ) { - $validity = $expected ? 'should be valid' : 'should NOT be valid'; - $msg = "'$connectString' ($msg) $validity."; - $this->assertEquals( $expected, - OracleInstaller::checkConnectStringFormat( $connectString ), - $msg - ); - } - - /** - * Provider to test OracleInstaller::checkConnectStringFormat() - */ - function provideOracleConnectStrings() { - // expected result, connectString[, message] - return array( - array( true, 'simple_01', 'Simple TNS name' ), - array( true, 'simple_01.world', 'TNS name with domain' ), - array( true, 'simple_01.domain.net', 'TNS name with domain' ), - array( true, 'host123', 'Host only' ), - array( true, 'host123.domain.net', 'FQDN only' ), - array( true, '//host123.domain.net', 'FQDN URL only' ), - array( true, '123.223.213.132', 'Host IP only' ), - array( true, 'host:1521', 'Host and port' ), - array( true, 'host:1521/service', 'Host, port and service' ), - array( true, 'host:1521/service:shared', 'Host, port, service and shared server type' ), - array( true, 'host:1521/service:dedicated', 'Host, port, service and dedicated server type' ), - array( true, 'host:1521/service:pooled', 'Host, port, service and pooled server type' ), - array( true, 'host:1521/service:shared/instance1', 'Host, port, service, server type and instance' ), - array( true, 'host:1521//instance1', 'Host, port and instance' ), - ); - } - -} diff --git a/tests/phpunit/includes/jobqueue/JobQueueTest.php b/tests/phpunit/includes/jobqueue/JobQueueTest.php deleted file mode 100644 index 4e51c4fc..00000000 --- a/tests/phpunit/includes/jobqueue/JobQueueTest.php +++ /dev/null @@ -1,329 +0,0 @@ -<?php - -/** - * @group JobQueue - * @group medium - * @group Database - */ -class JobQueueTest extends MediaWikiTestCase { - protected $key; - protected $queueRand, $queueRandTTL, $queueFifo, $queueFifoTTL; - - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - - $this->tablesUsed[] = 'job'; - } - - protected function setUp() { - global $wgJobTypeConf; - parent::setUp(); - - $this->setMwGlobals( 'wgMemc', new HashBagOStuff() ); - - if ( $this->getCliArg( 'use-jobqueue=' ) ) { - $name = $this->getCliArg( 'use-jobqueue=' ); - if ( !isset( $wgJobTypeConf[$name] ) ) { - throw new MWException( "No \$wgJobTypeConf entry for '$name'." ); - } - $baseConfig = $wgJobTypeConf[$name]; - } else { - $baseConfig = array( 'class' => 'JobQueueDB' ); - } - $baseConfig['type'] = 'null'; - $baseConfig['wiki'] = wfWikiID(); - $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() { - parent::tearDown(); - foreach ( - array( - 'queueRand', 'queueRandTTL', 'queueTimestamp', 'queueTimestampTTL', - 'queueFifo', 'queueFifoTTL' - ) as $q - ) { - if ( $this->$q ) { - $this->$q->delete(); - } - $this->$q = null; - } - } - - /** - * @dataProvider provider_queueLists - */ - 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)" ); - } - - /** - * @dataProvider provider_queueLists - */ - public function testBasicOperations( $queue, $recycles, $desc ) { - $queue = $this->$queue; - if ( !$queue ) { - $this->markTestSkipped( $desc ); - } - - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" ); - - $this->assertTrue( $queue->push( $this->newJob() ), "Push worked ($desc)" ); - $this->assertTrue( $queue->batchPush( array( $this->newJob() ) ), "Push worked ($desc)" ); - - $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); - - $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)" ); - - $queue->flushCaches(); - $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" ); - - $queue->flushCaches(); - if ( $recycles ) { - $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } else { - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - $job2 = $queue->pop(); - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - if ( $recycles ) { - $this->assertEquals( 2, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } else { - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - $queue->ack( $job1 ); - - $queue->flushCaches(); - if ( $recycles ) { - $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } else { - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - $queue->ack( $job2 ); - - $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 - */ - public function testBasicDeduplication( $queue, $recycles, $desc ) { - $queue = $this->$queue; - if ( !$queue ) { - $this->markTestSkipped( $desc ); - } - - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $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() ) - ), - "Push worked ($desc)" ); - - $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); - - $queue->flushCaches(); - $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->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); - - $job1 = $queue->pop(); - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - if ( $recycles ) { - $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } else { - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - $queue->ack( $job1 ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" ); - } - - /** - * @dataProvider provider_queueLists - */ - public function testRootDeduplication( $queue, $recycles, $desc ) { - $queue = $this->$queue; - if ( !$queue ) { - $this->markTestSkipped( $desc ); - } - - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" ); - - $id = wfRandomString( 32 ); - $root1 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp - for ( $i = 0; $i < 5; ++$i ) { - $this->assertTrue( $queue->push( $this->newJob( 0, $root1 ) ), "Push worked ($desc)" ); - } - $queue->deduplicateRootJob( $this->newJob( 0, $root1 ) ); - sleep( 1 ); // roo job timestamp will increase - $root2 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp - $this->assertNotEquals( $root1['rootJobTimestamp'], $root2['rootJobTimestamp'], - "Root job signatures have different timestamps." ); - for ( $i = 0; $i < 5; ++$i ) { - $this->assertTrue( $queue->push( $this->newJob( 0, $root2 ) ), "Push worked ($desc)" ); - } - $queue->deduplicateRootJob( $this->newJob( 0, $root2 ) ); - - $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 10, $queue->getSize(), "Queue size is correct ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); - - $dupcount = 0; - $jobs = array(); - do { - $job = $queue->pop(); - if ( $job ) { - $jobs[] = $job; - $queue->ack( $job ); - } - if ( $job instanceof DuplicateJob ) { - ++$dupcount; - } - } while ( $job ); - - $this->assertEquals( 10, count( $jobs ), "Correct number of jobs popped ($desc)" ); - $this->assertEquals( 5, $dupcount, "Correct number of duplicate jobs popped ($desc)" ); - } - - /** - * @dataProvider provider_fifoQueueLists - */ - public function testJobOrder( $queue, $recycles, $desc ) { - $queue = $this->$queue; - if ( !$queue ) { - $this->markTestSkipped( $desc ); - } - - $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" ); - - for ( $i = 0; $i < 10; ++$i ) { - $this->assertTrue( $queue->push( $this->newJob( $i ) ), "Push worked ($desc)" ); - } - - for ( $i = 0; $i < 10; ++$i ) { - $job = $queue->pop(); - $this->assertTrue( $job instanceof Job, "Jobs popped from queue ($desc)" ); - $params = $job->getParams(); - $this->assertEquals( $i, $params['i'], "Job popped from queue is FIFO ($desc)" ); - $queue->ack( $job ); - } - - $this->assertFalse( $queue->pop(), "Queue is not empty ($desc)" ); - - $queue->flushCaches(); - $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" ); - $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" ); - } - - public static function provider_queueLists() { - return array( - 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()' ) - ); - } - - public static function provider_fifoQueueLists() { - return array( - array( 'queueFifo', false, 'Ordered queue without ack()' ), - array( 'queueFifoTTL', true, 'Ordered queue with ack()' ) - ); - } - - function newJob( $i = 0, $rootJob = array() ) { - return new NullJob( Title::newMainPage(), - array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 0, 'i' => $i ) + $rootJob ); - } - - function newDedupedJob( $i = 0, $rootJob = array() ) { - return new NullJob( Title::newMainPage(), - array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 1, 'i' => $i ) + $rootJob ); - } -} diff --git a/tests/phpunit/includes/json/FormatJsonTest.php b/tests/phpunit/includes/json/FormatJsonTest.php deleted file mode 100644 index 149be05b..00000000 --- a/tests/phpunit/includes/json/FormatJsonTest.php +++ /dev/null @@ -1,161 +0,0 @@ -<?php - -class FormatJsonTest extends MediaWikiTestCase { - - public function testEncoderPrettyPrinting() { - $obj = array( - 'emptyObject' => new stdClass, - 'emptyArray' => array(), - 'string' => 'foobar\\', - 'filledArray' => array( - array( - 123, - 456, - ), - // Nested json works without problems - '"7":["8",{"9":"10"}]', - // Whitespace clean up doesn't touch strings that look alike - "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}", - ), - ); - - // 4 space indent, no trailing whitespace, no trailing linefeed - $json = '{ - "emptyObject": {}, - "emptyArray": [], - "string": "foobar\\\\", - "filledArray": [ - [ - 123, - 456 - ], - "\"7\":[\"8\",{\"9\":\"10\"}]", - "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}" - ] -}'; - - $json = str_replace( "\r", '', $json ); // Windows compat - $this->assertSame( $json, FormatJson::encode( $obj, true ) ); - } - - public static function provideEncodeDefault() { - return self::getEncodeTestCases( array() ); - } - - /** - * @dataProvider provideEncodeDefault - */ - public function testEncodeDefault( $from, $to ) { - $this->assertSame( $to, FormatJson::encode( $from ) ); - } - - public static function provideEncodeUtf8() { - return self::getEncodeTestCases( array( 'unicode' ) ); - } - - /** - * @dataProvider provideEncodeUtf8 - */ - public function testEncodeUtf8( $from, $to ) { - $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::UTF8_OK ) ); - } - - public static function provideEncodeXmlMeta() { - return self::getEncodeTestCases( array( 'xmlmeta' ) ); - } - - /** - * @dataProvider provideEncodeXmlMeta - */ - public function testEncodeXmlMeta( $from, $to ) { - $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::XMLMETA_OK ) ); - } - - public static function provideEncodeAllOk() { - return self::getEncodeTestCases( array( 'unicode', 'xmlmeta' ) ); - } - - /** - * @dataProvider provideEncodeAllOk - */ - public function testEncodeAllOk( $from, $to ) { - $this->assertSame( $to, FormatJson::encode( $from, false, FormatJson::ALL_OK ) ); - } - - public function testEncodePhpBug46944() { - $this->assertNotEquals( - '\ud840\udc00', - strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ), - 'Test encoding an broken json_encode character (U+20000)' - ); - } - - public function testDecodeReturnType() { - $this->assertInternalType( - 'object', - FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ), - 'Default to object' - ); - - $this->assertInternalType( - 'array', - FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ), - 'Optional array' - ); - } - - /** - * Generate a set of test cases for a particular combination of encoder options. - * - * @param array $unescapedGroups List of character groups to leave unescaped - * @return array: Arrays of unencoded strings and corresponding encoded strings - */ - private static function getEncodeTestCases( array $unescapedGroups ) { - $groups = array( - 'always' => array( - // Forward slash (always unescaped) - '/' => '/', - - // Control characters - "\0" => '\u0000', - "\x08" => '\b', - "\t" => '\t', - "\n" => '\n', - "\r" => '\r', - "\f" => '\f', - "\x1f" => '\u001f', // representative example - - // Double quotes - '"' => '\"', - - // Backslashes - '\\' => '\\\\', - '\\\\' => '\\\\\\\\', - '\\u00e9' => '\\\u00e9', // security check for Unicode unescaping - - // Line terminators - "\xe2\x80\xa8" => '\u2028', - "\xe2\x80\xa9" => '\u2029', - ), - 'unicode' => array( - "\xc3\xa9" => '\u00e9', - "\xf0\x9d\x92\x9e" => '\ud835\udc9e', // U+1D49E, outside the BMP - ), - 'xmlmeta' => array( - '<' => '\u003C', // JSON_HEX_TAG uses uppercase hex digits - '>' => '\u003E', - '&' => '\u0026', - ), - ); - - $cases = array(); - foreach ( $groups as $name => $rules ) { - $leaveUnescaped = in_array( $name, $unescapedGroups ); - foreach ( $rules as $from => $to ) { - $cases[] = array( $from, '"' . ( $leaveUnescaped ? $from : $to ) . '"' ); - } - } - - return $cases; - } -} diff --git a/tests/phpunit/includes/libs/CSSJanusTest.php b/tests/phpunit/includes/libs/CSSJanusTest.php deleted file mode 100644 index 5a3c1619..00000000 --- a/tests/phpunit/includes/libs/CSSJanusTest.php +++ /dev/null @@ -1,606 +0,0 @@ -<?php -/** - * Based on the test suite of the original Python - * 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 - */ - public function testTransform( $cssA, $cssB = null ) { - - if ( $cssB ) { - $transformedA = CSSJanus::transform( $cssA ); - $this->assertEquals( $transformedA, $cssB, 'Test A-B transformation' ); - - $transformedB = CSSJanus::transform( $cssB ); - $this->assertEquals( $transformedB, $cssA, 'Test B-A transformation' ); - } else { - // If no B version is provided, it means - // the output should equal the input. - $transformedA = CSSJanus::transform( $cssA ); - $this->assertEquals( $transformedA, $cssA, 'Nothing was flipped' ); - } - } - - /** - * @dataProvider provideTransformAdvancedCases - */ - public function testTransformAdvanced( $code, $expectedOutput, $options = array() ) { - $swapLtrRtlInURL = isset( $options['swapLtrRtlInURL'] ) ? $options['swapLtrRtlInURL'] : false; - $swapLeftRightInURL = isset( $options['swapLeftRightInURL'] ) ? $options['swapLeftRightInURL'] : false; - - $flipped = CSSJanus::transform( $code, $swapLtrRtlInURL, $swapLeftRightInURL ); - - $this->assertEquals( $expectedOutput, $flipped, - 'Test flipping, options: url-ltr-rtl=' . ( $swapLtrRtlInURL ? 'true' : 'false' ) - . ' url-left-right=' . ( $swapLeftRightInURL ? 'true' : 'false' ) - ); - } - - /** - * @dataProvider provideTransformBrokenCases - * @group Broken - */ - public function testTransformBroken( $code, $expectedOutput ) { - $flipped = CSSJanus::transform( $code ); - - $this->assertEquals( $expectedOutput, $flipped, 'Test flipping' ); - } - - /** - * These transform cases are tested *in both directions* - * No need to declare a principle twice in both directions here. - */ - public static function provideTransformCases() { - return array( - // Property keys - array( - '.foo { left: 0; }', - '.foo { right: 0; }' - ), - // Guard against partial keys - // (CSS currently doesn't have flippable properties - // that contain the direction as part of the key without - // dash separation) - array( - '.foo { alright: 0; }' - ), - array( - '.foo { balleft: 0; }' - ), - - // Dashed property keys - array( - '.foo { padding-left: 0; }', - '.foo { padding-right: 0; }' - ), - array( - '.foo { margin-left: 0; }', - '.foo { margin-right: 0; }' - ), - array( - '.foo { border-left: 0; }', - '.foo { border-right: 0; }' - ), - - // Double-dashed property keys - array( - '.foo { border-left-color: red; }', - '.foo { border-right-color: red; }' - ), - array( - // Includes unknown properties? - '.foo { x-left-y: 0; }', - '.foo { x-right-y: 0; }' - ), - - // Multi-value properties - array( - '.foo { padding: 0; }' - ), - array( - '.foo { padding: 0 1px; }' - ), - array( - '.foo { padding: 0 1px 2px; }' - ), - array( - '.foo { padding: 0 1px 2px 3px; }', - '.foo { padding: 0 3px 2px 1px; }' - ), - - // Shorthand / Four notation - array( - '.foo { padding: .25em 15px 0pt 0ex; }', - '.foo { padding: .25em 0ex 0pt 15px; }' - ), - array( - '.foo { margin: 1px -4px 3px 2px; }', - '.foo { margin: 1px 2px 3px -4px; }' - ), - array( - '.foo { padding: 0 15px .25em 0; }', - '.foo { padding: 0 0 .25em 15px; }' - ), - array( - '.foo { padding: 1px 4.1grad 3px 2%; }', - '.foo { padding: 1px 2% 3px 4.1grad; }' - ), - array( - '.foo { padding: 1px 2px 3px auto; }', - '.foo { padding: 1px auto 3px 2px; }' - ), - array( - '.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: 15px .25em 0ex 0pt; }' - ), - array( - '.foo { border-radius: 0px 0px 5px 5px; }', - ), - // Ensure the rule doesn't break other stuff - array( - '.foo { x-unknown: a b c d; }' - ), - array( - '.foo barpx 0 2% { opacity: 0; }' - ), - array( - '#settings td p strong' - ), - array( - // 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( - // 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 - array( - '.foo { margin: 1em 0 .25em; }' - ), - array( - '.foo { margin:-1.5em 0 -.75em; }' - ), - - // Shorthand / Two notation - array( - '.foo { padding: 1px 2px; }' - ), - - // Shorthand / One notation - array( - '.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. - array( - '.foo { direction: ltr; }', - '.foo { direction: rtl; }' - ), - array( - '.foo { direction: rtl; }', - '.foo { direction: ltr; }' - ), - array( - 'input { direction: ltr; }', - 'input { direction: rtl; }' - ), - array( - 'input { direction: rtl; }', - 'input { direction: ltr; }' - ), - array( - 'body { direction: ltr; }', - 'body { direction: rtl; }' - ), - array( - '.foo, body, input { direction: ltr; }', - '.foo, body, input { direction: rtl; }' - ), - array( - 'body { padding: 10px; direction: ltr; }', - 'body { padding: 10px; direction: rtl; }' - ), - array( - 'body { direction: ltr } .myClass { direction: ltr }', - 'body { direction: rtl } .myClass { direction: rtl }' - ), - - // Left/right values - array( - '.foo { float: left; }', - '.foo { float: right; }' - ), - array( - '.foo { text-align: left; }', - '.foo { text-align: right; }' - ), - array( - '.foo { -x-unknown: left; }', - '.foo { -x-unknown: right; }' - ), - // Guard against selectors that look flippable - array( - '.column-left { width: 0; }' - ), - array( - 'a.left { width: 0; }' - ), - array( - 'a.leftification { width: 0; }' - ), - array( - 'a.ltr { width: 0; }' - ), - array( - # <div class="a-ltr png"> - '.a-ltr.png { width: 0; }' - ), - array( - # <foo-ltr attr="x"> - 'foo-ltr[attr="x"] { width: 0; }' - ), - array( - 'div.left > span.right+span.left { width: 0; }' - ), - array( - '.thisclass .left .myclass { width: 0; }' - ), - array( - '.thisclass .left .myclass #myid { width: 0; }' - ), - - // Cursor values (east/west) - array( - '.foo { cursor: e-resize; }', - '.foo { cursor: w-resize; }' - ), - array( - '.foo { cursor: se-resize; }', - '.foo { cursor: sw-resize; }' - ), - array( - '.foo { cursor: ne-resize; }', - '.foo { cursor: nw-resize; }' - ), - - // Background - array( - '.foo { background-position: top left; }', - '.foo { background-position: top right; }' - ), - array( - '.foo { background: url(/foo/bar.png) top left; }', - '.foo { background: url(/foo/bar.png) top right; }' - ), - array( - '.foo { background: url(/foo/bar.png) top left no-repeat; }', - '.foo { background: url(/foo/bar.png) top right no-repeat; }' - ), - array( - '.foo { background: url(/foo/bar.png) no-repeat top left; }', - '.foo { background: url(/foo/bar.png) no-repeat top right; }' - ), - array( - '.foo { background: #fff url(/foo/bar.png) no-repeat top left; }', - '.foo { background: #fff url(/foo/bar.png) no-repeat top right; }' - ), - array( - '.foo { background-position: 100% 40%; }', - '.foo { background-position: 0% 40%; }' - ), - array( - '.foo { background-position: 23% 0; }', - '.foo { background-position: 77% 0; }' - ), - array( - '.foo { background-position: 23% auto; }', - '.foo { background-position: 77% auto; }' - ), - array( - '.foo { background-position-x: 23%; }', - '.foo { background-position-x: 77%; }' - ), - array( - '.foo { background-position-y: 23%; }', - '.foo { background-position-y: 23%; }' - ), - array( - '.foo { background:url(../foo.png) no-repeat 75% 50%; }', - '.foo { background:url(../foo.png) no-repeat 25% 50%; }' - ), - array( - '.foo { background: 10% 20% } .bar { background: 40% 30% }', - '.foo { background: 90% 20% } .bar { background: 60% 30% }' - ), - - // Multiple rules - array( - 'body { direction: rtl; float: right; } .foo { direction: ltr; float: right; }', - 'body { direction: ltr; float: left; } .foo { direction: rtl; float: left; }', - ), - - // Duplicate properties - array( - '.foo { float: left; float: right; float: left; }', - '.foo { float: right; float: left; float: right; }', - ), - - // Preserve comments - array( - '/* left /* right */left: 10px', - '/* left /* right */right: 10px' - ), - array( - '/*left*//*left*/left: 10px', - '/*left*//*left*/right: 10px' - ), - array( - '/* Going right is cool */ .foo { width: 0 }', - ), - array( - "/* padding-right 1 2 3 4 */\n#test { width: 0}\n/*right*/" - ), - array( - "/** Two line comment\n * left\n \*/\n#test {width: 0}" - ), - - // @noflip annotation - array( - // before selector (single) - '/* @noflip */ div { float: left; }' - ), - array( - // before selector (multiple) - '/* @noflip */ div, .notme { float: left; }' - ), - array( - // inside selector - 'div, /* @noflip */ .foo { float: left; }' - ), - array( - // after selector - 'div, .notme /* @noflip */ { float: left; }' - ), - array( - // before multiple rules - '/* @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; }', - '.foo { float: right; } /* @noflip */ div { float: left; }' - ), - array( - // before multiple properties - 'div { /* @noflip */ float: left; text-align: left; }', - 'div { /* @noflip */ float: left; text-align: right; }' - ), - array( - // after multiple properties - 'div { float: left; /* @noflip */ text-align: left; }', - 'div { float: right; /* @noflip */ text-align: left; }' - ), - - // Guard against css3 stuff - array( - 'background-image: -moz-linear-gradient(#326cc1, #234e8c);' - ), - array( - 'background-image: -webkit-gradient(linear, 100% 0%, 0% 0%, from(#666666), to(#ffffff));' - ), - - // CSS syntax / white-space variations - // spaces, no spaces, tabs, new lines, omitting semi-colons - array( - ".foo { left: 0; }", - ".foo { right: 0; }" - ), - array( - ".foo{ left: 0; }", - ".foo{ right: 0; }" - ), - array( - ".foo{ left: 0 }", - ".foo{ right: 0 }" - ), - array( - ".foo{left:0 }", - ".foo{right:0 }" - ), - array( - ".foo{left:0}", - ".foo{right:0}" - ), - array( - ".foo { left : 0 ; }", - ".foo { right : 0 ; }" - ), - array( - ".foo\n { left : 0 ; }", - ".foo\n { right : 0 ; }" - ), - array( - ".foo\n { \nleft : 0 ; }", - ".foo\n { \nright : 0 ; }" - ), - array( - ".foo\n { \n left : 0 ; }", - ".foo\n { \n right : 0 ; }" - ), - array( - ".foo\n { \n left\n : 0; }", - ".foo\n { \n right\n : 0; }" - ), - array( - ".foo \n { \n left\n : 0; }", - ".foo \n { \n right\n : 0; }" - ), - array( - ".foo\n{\nleft\n:\n0;}", - ".foo\n{\nright\n:\n0;}" - ), - array( - ".foo\n.bar {\n\tleft: 0;\n}", - ".foo\n.bar {\n\tright: 0;\n}" - ), - array( - ".foo\t{\tleft\t:\t0;}", - ".foo\t{\tright\t:\t0;}" - ), - - // Guard against partial keys - array( - '.foo { leftxx: 0; }', - '.foo { leftxx: 0; }' - ), - array( - '.foo { rightxx: 0; }', - '.foo { rightxx: 0; }' - ), - ); - } - - /** - * These cases are tested in one way only (format: actual, expected, msg). - * If both ways can be tested, either put both versions in here or move - * it to provideTransformCases(). - */ - public static function provideTransformAdvancedCases() { - $bgPairs = array( - # [ - _ . ] <-> [ left right ltr rtl ] - 'foo.jpg' => 'foo.jpg', - 'left.jpg' => 'right.jpg', - 'ltr.jpg' => 'rtl.jpg', - - 'foo-left.png' => 'foo-right.png', - 'foo_left.png' => 'foo_right.png', - 'foo.left.png' => 'foo.right.png', - - 'foo-ltr.png' => 'foo-rtl.png', - 'foo_ltr.png' => 'foo_rtl.png', - 'foo.ltr.png' => 'foo.rtl.png', - - 'left-foo.png' => 'right-foo.png', - 'left_foo.png' => 'right_foo.png', - 'left.foo.png' => 'right.foo.png', - - 'ltr-foo.png' => 'rtl-foo.png', - 'ltr_foo.png' => 'rtl_foo.png', - 'ltr.foo.png' => 'rtl.foo.png', - - 'foo-ltr-left.gif' => 'foo-rtl-right.gif', - 'foo_ltr_left.gif' => 'foo_rtl_right.gif', - 'foo.ltr.left.gif' => 'foo.rtl.right.gif', - 'foo-ltr_left.gif' => 'foo-rtl_right.gif', - 'foo_ltr.left.gif' => 'foo_rtl.right.gif', - ); - $provider = array(); - foreach ( $bgPairs as $left => $right ) { - # By default '-rtl' and '-left' etc. are not touched, - # Only when the appropiate parameter is set. - $provider[] = array( - ".foo { background: url(images/$left); }", - ".foo { background: url(images/$left); }" - ); - $provider[] = array( - ".foo { background: url(images/$right); }", - ".foo { background: url(images/$right); }" - ); - $provider[] = array( - ".foo { background: url(images/$left); }", - ".foo { background: url(images/$right); }", - array( - 'swapLtrRtlInURL' => true, - 'swapLeftRightInURL' => true, - ) - ); - $provider[] = array( - ".foo { background: url(images/$right); }", - ".foo { background: url(images/$left); }", - array( - 'swapLtrRtlInURL' => true, - 'swapLeftRightInURL' => true, - ) - ); - } - - return $provider; - } - - /** - * Cases that are currently failing, but - * should be looked at in the future as enhancements and/or bug fix - */ - public static function provideTransformBrokenCases() { - return array( - // Guard against selectors that look flippable - array( - # <foo-left-x attr="x"> - 'foo-left-x[attr="x"] { width: 0; }', - 'foo-left-x[attr="x"] { width: 0; }' - ), - array( - # <div class="foo" data-left="x"> - '.foo[data-left="x"] { width: 0; }', - '.foo[data-left="x"] { width: 0; }' - ), - ); - } -} diff --git a/tests/phpunit/includes/libs/CSSMinTest.php b/tests/phpunit/includes/libs/CSSMinTest.php deleted file mode 100644 index 951dd7b9..00000000 --- a/tests/phpunit/includes/libs/CSSMinTest.php +++ /dev/null @@ -1,133 +0,0 @@ -<?php -/** - * This file test the CSSMin library shipped with Mediawiki. - * - * @author Timo Tijhof - */ - -class CSSMinTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $server = 'http://doc.example.org'; - - $this->setMwGlobals( array( - 'wgServer' => $server, - 'wgCanonicalServer' => $server, - ) ); - } - - /** - * @dataProvider provideMinifyCases - */ - public function testMinify( $code, $expectedOutput ) { - $minified = CSSMin::minify( $code ); - - $this->assertEquals( $expectedOutput, $minified, 'Minified output should be in the form expected.' ); - } - - public static function provideMinifyCases() { - return array( - // Whitespace - array( "\r\t\f \v\n\r", "" ), - array( "foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - - // Loose comments - array( "/* foo */", "" ), - array( "/*******\n foo\n *******/", "" ), - array( "/*!\n foo\n */", "" ), - - // Inline comments in various different places - array( "/* comment */foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo/* comment */, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo,/* comment */ bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar/* comment */ {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar {\n\t/* comment */prop: value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar {\n\tprop: /* comment */value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar {\n\tprop: value /* comment */;\n}", "foo,bar{prop:value }" ), - array( "foo, bar {\n\tprop: value; /* comment */\n}", "foo,bar{prop:value; }" ), - - // Keep track of things that aren't as minified as much as they - // could be (bug 35493) - array( 'foo { prop: value ;}', 'foo{prop:value }' ), - array( 'foo { prop : value; }', 'foo{prop :value}' ), - array( 'foo { prop: value ; }', 'foo{prop:value }' ), - array( 'foo { font-family: "foo" , "bar"; }', 'foo{font-family:"foo" ,"bar"}' ), - array( "foo { src:\n\turl('foo') ,\n\turl('bar') ; }", "foo{src:url('foo') ,url('bar') }" ), - - // Interesting cases with string values - // - Double quotes, single quotes - array( 'foo { content: ""; }', 'foo{content:""}' ), - array( "foo { content: ''; }", "foo{content:''}" ), - array( 'foo { content: "\'"; }', 'foo{content:"\'"}' ), - array( "foo { content: '\"'; }", "foo{content:'\"'}" ), - // - Whitespace in string values - array( 'foo { content: " "; }', 'foo{content:" "}' ), - ); - } - - /** - * @dataProvider provideRemapCases - */ - 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 ); - } - - public static function provideRemapCases() { - // Parameter signature: - // CSSMin::remap( $code, $local, $remote, $embedData = true ) - return array( - array( - 'Simple case', - array( 'foo { prop: url(bar.png); }', false, 'http://example.org', false ), - 'foo { prop: url(http://example.org/bar.png); }', - ), - array( - 'Without trailing slash', - array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux', false ), - 'foo { prop: url(http://example.org/quux/../bar.png); }', - ), - array( - 'With trailing slash on remote (bug 27052)', - array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux/', false ), - 'foo { prop: url(http://example.org/quux/../bar.png); }', - ), - array( - 'Guard against stripping double slashes from query', - array( 'foo { prop: url(bar.png?corge=//grault); }', false, 'http://example.org/quux/', false ), - 'foo { prop: url(http://example.org/quux/bar.png?corge=//grault); }', - ), - array( - 'Expand absolute paths', - array( 'foo { prop: url(/w/skin/images/bar.png); }', false, 'http://example.org/quux', false ), - 'foo { prop: url(http://doc.example.org/w/skin/images/bar.png); }', - ), - ); - } - - /** - * Seperated because they are currently broken (bug 35492) - * - * @group Broken - * @dataProvider provideStringCases - */ - public function testMinifyWithCSSStringValues( $code, $expectedOutput ) { - $this->testMinifyOutput( $code, $expectedOutput ); - } - - public static function provideStringCases() { - return array( - // String values should be respected - // - More than one space in a string value - array( 'foo { content: " "; }', 'foo{content:" "}' ), - // - Using a tab in a string value (turns into a space) - array( "foo { content: '\t'; }", "foo{content:'\t'}" ), - // - Using css-like syntax in string values - array( 'foo::after { content: "{;}"; position: absolute; }', 'foo::after{content:"{;}";position:absolute}' ), - ); - } -} diff --git a/tests/phpunit/includes/libs/GenericArrayObjectTest.php b/tests/phpunit/includes/libs/GenericArrayObjectTest.php deleted file mode 100644 index 7436c43c..00000000 --- a/tests/phpunit/includes/libs/GenericArrayObjectTest.php +++ /dev/null @@ -1,263 +0,0 @@ -<?php - -/** - * Tests for the GenericArrayObject and deriving classes. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @since 1.20 - * - * @ingroup Test - * @group GenericArrayObject - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -abstract class GenericArrayObjectTest extends MediaWikiTestCase { - - /** - * Returns objects that can serve as elements in the concrete GenericArrayObject deriving class being tested. - * - * @since 1.20 - * - * @return array - */ - abstract public function elementInstancesProvider(); - - /** - * Returns the name of the concrete class being tested. - * - * @since 1.20 - * - * @return string - */ - abstract public function getInstanceClass(); - - /** - * Provides instances of the concrete class being tested. - * - * @since 1.20 - * - * @return array - */ - public function instanceProvider() { - $instances = array(); - - foreach ( $this->elementInstancesProvider() as $elementInstances ) { - $instances[] = $this->getNew( $elementInstances[0] ); - } - - return $this->arrayWrap( $instances ); - } - - /** - * @since 1.20 - * - * @param array $elements - * - * @return GenericArrayObject - */ - protected function getNew( array $elements = array() ) { - $class = $this->getInstanceClass(); - - return new $class( $elements ); - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testConstructor( array $elements ) { - $arrayObject = $this->getNew( $elements ); - - $this->assertEquals( count( $elements ), $arrayObject->count() ); - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testIsEmpty( array $elements ) { - $arrayObject = $this->getNew( $elements ); - - $this->assertEquals( $elements === array(), $arrayObject->isEmpty() ); - } - - /** - * @dataProvider instanceProvider - * - * @since 1.20 - * - * @param GenericArrayObject $list - */ - public function testUnset( GenericArrayObject $list ) { - if ( $list->isEmpty() ) { - $this->assertTrue( true ); // We cannot test unset if there are no elements - } else { - $offset = $list->getIterator()->key(); - $count = $list->count(); - $list->offsetUnset( $offset ); - $this->assertEquals( $count - 1, $list->count() ); - } - - if ( !$list->isEmpty() ) { - $offset = $list->getIterator()->key(); - $count = $list->count(); - unset( $list[$offset] ); - $this->assertEquals( $count - 1, $list->count() ); - } - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testAppend( array $elements ) { - $list = $this->getNew(); - - $listSize = count( $elements ); - - foreach ( $elements as $element ) { - $list->append( $element ); - } - - $this->assertEquals( $listSize, $list->count() ); - - $list = $this->getNew(); - - foreach ( $elements as $element ) { - $list[] = $element; - } - - $this->assertEquals( $listSize, $list->count() ); - - $this->checkTypeChecks( function ( GenericArrayObject $list, $element ) { - $list->append( $element ); - } ); - } - - /** - * @since 1.20 - * - * @param callback $function - */ - protected function checkTypeChecks( $function ) { - $excption = null; - $list = $this->getNew(); - - $elementClass = $list->getObjectType(); - - foreach ( array( 42, 'foo', array(), new stdClass(), 4.2 ) as $element ) { - $validValid = $element instanceof $elementClass; - - try { - call_user_func( $function, $list, $element ); - $valid = true; - } catch ( InvalidArgumentException $exception ) { - $valid = false; - } - - $this->assertEquals( - $validValid, - $valid, - 'Object of invalid type got successfully added to a GenericArrayObject' - ); - } - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testOffsetSet( array $elements ) { - if ( $elements === array() ) { - $this->assertTrue( true ); - - return; - } - - $list = $this->getNew(); - - $element = reset( $elements ); - $list->offsetSet( 42, $element ); - $this->assertEquals( $element, $list->offsetGet( 42 ) ); - - $list = $this->getNew(); - - $element = reset( $elements ); - $list['oHai'] = $element; - $this->assertEquals( $element, $list['oHai'] ); - - $list = $this->getNew(); - - $element = reset( $elements ); - $list->offsetSet( 9001, $element ); - $this->assertEquals( $element, $list[9001] ); - - $list = $this->getNew(); - - $element = reset( $elements ); - $list->offsetSet( null, $element ); - $this->assertEquals( $element, $list[0] ); - - $list = $this->getNew(); - $offset = 0; - - foreach ( $elements as $element ) { - $list->offsetSet( null, $element ); - $this->assertEquals( $element, $list[$offset++] ); - } - - $this->assertEquals( count( $elements ), $list->count() ); - - $this->checkTypeChecks( function ( GenericArrayObject $list, $element ) { - $list->offsetSet( mt_rand(), $element ); - } ); - } - - /** - * @dataProvider instanceProvider - * - * @since 1.21 - * - * @param GenericArrayObject $list - */ - public function testSerialization( GenericArrayObject $list ) { - $serialization = serialize( $list ); - $copy = unserialize( $serialization ); - - $this->assertEquals( $serialization, serialize( $copy ) ); - $this->assertEquals( count( $list ), count( $copy ) ); - - $list = $list->getArrayCopy(); - $copy = $copy->getArrayCopy(); - - $this->assertArrayEquals( $list, $copy, true, true ); - } -} diff --git a/tests/phpunit/includes/libs/IEUrlExtensionTest.php b/tests/phpunit/includes/libs/IEUrlExtensionTest.php deleted file mode 100644 index 66fe915a..00000000 --- a/tests/phpunit/includes/libs/IEUrlExtensionTest.php +++ /dev/null @@ -1,126 +0,0 @@ -<?php - -/** - * Tests for IEUrlExtension::findIE6Extension - */ -class IEUrlExtensionTest extends MediaWikiTestCase { - public function testSimple() { - $this->assertEquals( - 'y', - IEUrlExtension::findIE6Extension( 'x.y' ), - 'Simple extension' - ); - } - - public function testSimpleNoExt() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( 'x' ), - 'No extension' - ); - } - - public function testEmpty() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '' ), - 'Empty string' - ); - } - - public function testQuestionMark() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '?' ), - 'Question mark only' - ); - } - - public function testExtQuestionMark() { - $this->assertEquals( - 'x', - IEUrlExtension::findIE6Extension( '.x?' ), - 'Extension then question mark' - ); - } - - public function testQuestionMarkExt() { - $this->assertEquals( - 'x', - IEUrlExtension::findIE6Extension( '?.x' ), - 'Question mark then extension' - ); - } - - public function testInvalidChar() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '.x*' ), - 'Extension with invalid character' - ); - } - - public function testInvalidCharThenExtension() { - $this->assertEquals( - 'x', - IEUrlExtension::findIE6Extension( '*.x' ), - 'Invalid character followed by an extension' - ); - } - - public function testMultipleQuestionMarks() { - $this->assertEquals( - 'c', - IEUrlExtension::findIE6Extension( 'a?b?.c?.d?e?f' ), - 'Multiple question marks' - ); - } - - public function testExeException() { - $this->assertEquals( - 'd', - IEUrlExtension::findIE6Extension( 'a?b?.exe?.d?.e' ), - '.exe exception' - ); - } - - public function testExeException2() { - $this->assertEquals( - 'exe', - IEUrlExtension::findIE6Extension( 'a?b?.exe' ), - '.exe exception 2' - ); - } - - public function testHash() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( 'a#b.c' ), - 'Hash character preceding extension' - ); - } - - public function testHash2() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( 'a?#b.c' ), - 'Hash character preceding extension 2' - ); - } - - public function testDotAtEnd() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '.' ), - 'Dot at end of string' - ); - } - - public function testTwoDots() { - $this->assertEquals( - 'z', - IEUrlExtension::findIE6Extension( 'x.y.z' ), - 'Two dots' - ); - } -} diff --git a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php b/tests/phpunit/includes/libs/JavaScriptMinifierTest.php deleted file mode 100644 index ab72e361..00000000 --- a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php +++ /dev/null @@ -1,170 +0,0 @@ -<?php - -class JavaScriptMinifierTest extends MediaWikiTestCase { - - public static function provideCases() { - return array( - - // Basic whitespace and comments that should be stripped entirely - array( "\r\t\f \v\n\r", "" ), - array( "/* Foo *\n*bar\n*/", "" ), - - /** - * Slashes used inside block comments (bug 26931). - * At some point there was a bug that caused this comment to be ended at '* /', - * causing /M... to be left as the beginning of a regex. - */ - array( "/**\n * Foo\n * {\n * 'bar' : {\n * //Multiple rules with configurable operators\n * 'baz' : false\n * }\n */", "" ), - - /** - * ' Foo \' bar \ - * baz \' quox ' . - */ - array( "' Foo \\' bar \\\n baz \\' quox ' .length", "' Foo \\' bar \\\n baz \\' quox '.length" ), - array( "\" Foo \\\" bar \\\n baz \\\" quox \" .length", "\" Foo \\\" bar \\\n baz \\\" quox \".length" ), - array( "// Foo b/ar baz", "" ), - array( "/ Foo \\/ bar [ / \\] / ] baz / .length", "/ Foo \\/ bar [ / \\] / ] baz /.length" ), - - // HTML comments - array( "<!-- Foo bar", "" ), - array( "<!-- Foo --> bar", "" ), - array( "--> Foo", "" ), - array( "x --> y", "x-->y" ), - - // Semicolon insertion - array( "(function(){return\nx;})", "(function(){return\nx;})" ), - array( "throw\nx;", "throw\nx;" ), - array( "while(p){continue\nx;}", "while(p){continue\nx;}" ), - array( "while(p){break\nx;}", "while(p){break\nx;}" ), - array( "var\nx;", "var x;" ), - array( "x\ny;", "x\ny;" ), - array( "x\n++y;", "x\n++y;" ), - array( "x\n!y;", "x\n!y;" ), - array( "x\n{y}", "x\n{y}" ), - array( "x\n+y;", "x+y;" ), - array( "x\n(y);", "x(y);" ), - array( "5.\nx;", "5.\nx;" ), - array( "0xFF.\nx;", "0xFF.x;" ), - array( "5.3.\nx;", "5.3.x;" ), - - // Semicolon insertion between an expression having an inline - // comment after it, and a statement on the next line (bug 27046). - array( "var a = this //foo bar \n for ( b = 0; c < d; b++ ) {}", "var a=this\nfor(b=0;c<d;b++){}" ), - - // Token separation - array( "x in y", "x in y" ), - array( "/x/g in y", "/x/g in y" ), - array( "x in 30", "x in 30" ), - array( "x + ++ y", "x+ ++y" ), - array( "x ++ + y", "x++ +y" ), - array( "x / /y/.exec(z)", "x/ /y/.exec(z)" ), - - // State machine - array( "/ x/g", "/ x/g" ), - array( "(function(){return/ x/g})", "(function(){return/ x/g})" ), - array( "+/ x/g", "+/ x/g" ), - array( "++/ x/g", "++/ x/g" ), - array( "x/ x/g", "x/x/g" ), - array( "(/ x/g)", "(/ x/g)" ), - array( "if(/ x/g);", "if(/ x/g);" ), - array( "(x/ x/g)", "(x/x/g)" ), - array( "([/ x/g])", "([/ x/g])" ), - array( "+x/ x/g", "+x/x/g" ), - array( "{}/ x/g", "{}/ x/g" ), - array( "+{}/ x/g", "+{}/x/g" ), - array( "(x)/ x/g", "(x)/x/g" ), - array( "if(x)/ x/g", "if(x)/ x/g" ), - array( "for(x;x;{}/ x/g);", "for(x;x;{}/x/g);" ), - array( "x;x;{}/ x/g", "x;x;{}/ x/g" ), - array( "x:{}/ x/g", "x:{}/ x/g" ), - array( "switch(x){case y?z:{}/ x/g:{}/ x/g;}", "switch(x){case y?z:{}/x/g:{}/ x/g;}" ), - array( "function x(){}/ x/g", "function x(){}/ x/g" ), - array( "+function x(){}/ x/g", "+function x(){}/x/g" ), - - // Multiline quoted string - array( "var foo=\"\\\nblah\\\n\";", "var foo=\"\\\nblah\\\n\";" ), - - // Multiline quoted string followed by string with spaces - array( "var foo=\"\\\nblah\\\n\";\nvar baz = \" foo \";\n", "var foo=\"\\\nblah\\\n\";var baz=\" foo \";" ), - - // URL in quoted string ( // is not a comment) - array( "aNode.setAttribute('href','http://foo.bar.org/baz');", "aNode.setAttribute('href','http://foo.bar.org/baz');" ), - - // URL in quoted string after multiline quoted string - array( "var foo=\"\\\nblah\\\n\";\naNode.setAttribute('href','http://foo.bar.org/baz');", "var foo=\"\\\nblah\\\n\";aNode.setAttribute('href','http://foo.bar.org/baz');" ), - - // Division vs. regex nastiness - array( "alert( (10+10) / '/'.charCodeAt( 0 ) + '//' );", "alert((10+10)/'/'.charCodeAt(0)+'//');" ), - array( "if(1)/a /g.exec('Pa ss');", "if(1)/a /g.exec('Pa ss');" ), - - // newline insertion after 1000 chars: break after the "++", not before - array( str_repeat( ';', 996 ) . "if(x++);", str_repeat( ';', 996 ) . "if(x++\n);" ), - - // Unicode letter characters should pass through ok in identifiers (bug 31187) - array( "var KaŝSkatolVal = {}", 'var KaŝSkatolVal={}' ), - - // Per spec unicode char escape values should work in identifiers, - // as long as it's a valid char. In future it might get normalized. - array( "var Ka\\u015dSkatolVal = {}", 'var Ka\\u015dSkatolVal={}' ), - - // Some structures that might look invalid at first sight - array( "var a = 5.;", "var a=5.;" ), - array( "5.0.toString();", "5.0.toString();" ), - array( "5..toString();", "5..toString();" ), - array( "5...toString();", false ), - array( "5.\n.toString();", '5..toString();' ), - ); - } - - /** - * @dataProvider provideCases - */ - public function testJavaScriptMinifierOutput( $code, $expectedOutput ) { - $minified = JavaScriptMinifier::minify( $code ); - - // JSMin+'s parser will throw an exception if output is not valid JS. - // suppression of warnings needed for stupid crap - wfSuppressWarnings(); - $parser = new JSParser(); - wfRestoreWarnings(); - $parser->parse( $minified, 'minify-test.js', 1 ); - - $this->assertEquals( $expectedOutput, $minified, "Minified output should be in the form expected." ); - } - - public static function provideBug32548() { - return array( - array( - // This one gets interpreted all together by the prior code; - // no break at the 'E' happens. - '1.23456789E55', - ), - array( - // This one breaks under the bad code; splits between 'E' and '+' - '1.23456789E+5', - ), - array( - // This one breaks under the bad code; splits between 'E' and '-' - '1.23456789E-5', - ), - ); - } - - /** - * @dataProvider provideBug32548 - */ - 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. - $prefix = 'var longVarName' . str_repeat( '_', 973 ) . '='; - $suffix = ',shortVarName=0;'; - - $input = $prefix . $num . $suffix; - $expected = $prefix . "\n" . $num . $suffix; - - $minified = JavaScriptMinifier::minify( $input ); - - $this->assertEquals( $expected, $minified, "Line breaks must not occur in middle of exponent" ); - } -} diff --git a/tests/phpunit/includes/logging/LogFormatterTest.php b/tests/phpunit/includes/logging/LogFormatterTest.php deleted file mode 100644 index e8ccf433..00000000 --- a/tests/phpunit/includes/logging/LogFormatterTest.php +++ /dev/null @@ -1,207 +0,0 @@ -<?php -/** - * @group Database - */ -class LogFormatterTest extends MediaWikiLangTestCase { - - /** - * @var User - */ - protected $user; - - /** - * @var Title - */ - protected $title; - - /** - * @var RequestContext - */ - protected $context; - - protected function setUp() { - parent::setUp(); - - global $wgLang; - - $this->setMwGlobals( array( - 'wgLogTypes' => array( 'phpunit' ), - 'wgLogActionsHandlers' => array( 'phpunit/test' => 'LogFormatter', - 'phpunit/param' => 'LogFormatter' ), - 'wgUser' => User::newFromName( 'Testuser' ), - 'wgExtensionMessagesFiles' => array( 'LogTests' => __DIR__ . '/LogTests.i18n.php' ), - ) ); - - $wgLang->getLocalisationCache()->recache( $wgLang->getCode() ); - - $this->user = User::newFromName( 'Testuser' ); - $this->title = Title::newMainPage(); - - $this->context = new RequestContext(); - $this->context->setUser( $this->user ); - $this->context->setTitle( $this->title ); - $this->context->setLanguage( $wgLang ); - } - - protected function tearDown() { - parent::tearDown(); - - global $wgLang; - $wgLang->getLocalisationCache()->recache( $wgLang->getCode() ); - } - - public function newLogEntry( $action, $params ) { - $logEntry = new ManualLogEntry( 'phpunit', $action ); - $logEntry->setPerformer( $this->user ); - $logEntry->setTarget( $this->title ); - $logEntry->setComment( 'A very good reason' ); - - $logEntry->setParameters( $params ); - - return $logEntry; - } - - public function testNormalLogParams() { - $entry = $this->newLogEntry( 'test', array() ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $formatter->setShowUserToolLinks( false ); - $paramsWithoutTools = $formatter->getMessageParametersForTesting(); - unset( $formatter->parsedParameters ); - - $formatter->setShowUserToolLinks( true ); - $paramsWithTools = $formatter->getMessageParametersForTesting(); - - $userLink = Linker::userLink( - $this->user->getId(), - $this->user->getName() - ); - - $userTools = Linker::userToolLinksRedContribs( - $this->user->getId(), - $this->user->getName(), - $this->user->getEditCount() - ); - - $titleLink = Linker::link( $this->title, null, array(), array() ); - - // $paramsWithoutTools and $paramsWithTools should be only different - // in index 0 - $this->assertEquals( $paramsWithoutTools[1], $paramsWithTools[1] ); - $this->assertEquals( $paramsWithoutTools[2], $paramsWithTools[2] ); - - $this->assertEquals( $userLink, $paramsWithoutTools[0]['raw'] ); - $this->assertEquals( $userLink . $userTools, $paramsWithTools[0]['raw'] ); - - $this->assertEquals( $this->user->getName(), $paramsWithoutTools[1] ); - - $this->assertEquals( $titleLink, $paramsWithoutTools[2]['raw'] ); - } - - public function testLogParamsTypeRaw() { - $params = array( '4:raw:raw' => Linker::link( $this->title, null, array(), array() ) ); - $expected = Linker::link( $this->title, null, array(), array() ); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeMsg() { - $params = array( '4:msg:msg' => 'log-description-phpunit' ); - $expected = wfMessage( 'log-description-phpunit' )->text(); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeMsgContent() { - $params = array( '4:msg-content:msgContent' => 'log-description-phpunit' ); - $expected = wfMessage( 'log-description-phpunit' )->inContentLanguage()->text(); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeNumber() { - global $wgLang; - - $params = array( '4:number:number' => 123456789 ); - $expected = $wgLang->formatNum( 123456789 ); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeUserLink() { - $params = array( '4:user-link:userLink' => $this->user->getName() ); - $expected = Linker::userLink( - $this->user->getId(), - $this->user->getName() - ); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypeTitleLink() { - $params = array( '4:title-link:titleLink' => $this->title->getText() ); - $expected = Linker::link( $this->title, null, array(), array() ); - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogParamsTypePlain() { - $params = array( '4:plain:plain' => 'Some plain text' ); - $expected = 'Some plain text'; - - $entry = $this->newLogEntry( 'param', $params ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $logParam = $formatter->getActionText(); - - $this->assertEquals( $expected, $logParam ); - } - - public function testLogComment() { - $entry = $this->newLogEntry( 'test', array() ); - $formatter = LogFormatter::newFromEntry( $entry ); - $formatter->setContext( $this->context ); - - $comment = ltrim( Linker::commentBlock( $entry->getComment() ) ); - - $this->assertEquals( $comment, $formatter->getComment() ); - } -} diff --git a/tests/phpunit/includes/logging/LogTests.i18n.php b/tests/phpunit/includes/logging/LogTests.i18n.php deleted file mode 100644 index 78787ba1..00000000 --- a/tests/phpunit/includes/logging/LogTests.i18n.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -/** - * Internationalisation file for log tests. - * - * @file - */ - -$messages = array(); - -$messages['en'] = array( - 'log-name-phpunit' => 'PHPUnit-log', - 'log-description-phpunit' => 'Log for PHPUnit-tests', - 'logentry-phpunit-test' => '$1 {{GENDER:$2|tests}} with page $3', - 'logentry-phpunit-param' => '$4', -); diff --git a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php b/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php deleted file mode 100644 index a0e63a8a..00000000 --- a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php +++ /dev/null @@ -1,167 +0,0 @@ -<?php -class BitmapMetadataHandlerTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( 'wgShowEXIF', false ); - - $this->filePath = __DIR__ . '/../../data/media/'; - } - - /** - * Test if having conflicting metadata values from different - * types of metadata, that the right one takes precedence. - * - * 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() { - if ( !extension_loaded( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - if ( !extension_loaded( 'xml' ) ) { - $this->markTestSkipped( "This test needs the xml extension." ); - } - - $this->setMwGlobals( 'wgShowEXIF', true ); - - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - '/Xmp-exif-multilingual_test.jpg' ); - - $expected = array( - 'x-default' => 'right(iptc)', - 'en' => 'right translation', - '_type' => 'lang' - ); - - $this->assertArrayHasKey( 'ImageDescription', $meta, - 'Did not extract any ImageDescription info?!' ); - - $this->assertEquals( $expected, $meta['ImageDescription'] ); - } - - /** - * Test for jpeg comments are being handled by - * BitmapMetadataHandler correctly. - * - * There's more extensive tests of comment extraction in - * JpegMetadataExtractorTests.php - * @covers BitmapMetadataHandler::Jpeg - */ - public function testJpegComment() { - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - 'jpeg-comment-utf.jpg' ); - - $this->assertEquals( 'UTF-8 JPEG Comment — ¼', - $meta['JPEGFileComment'][0] ); - } - - /** - * 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 . - 'iptc-invalid-psir.jpg' ); - $this->assertEquals( 'Created with GIMP', $meta['JPEGFileComment'][0] ); - } - - /** - * @covers BitmapMetadataHandler::Jpeg - */ - public function testIPTCDates() { - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - 'iptc-timetest.jpg' ); - - $this->assertEquals( '2020:07:14 01:36:05', $meta['DateTimeDigitized'] ); - $this->assertEquals( '1997:03:02 00:01:02', $meta['DateTimeOriginal'] ); - } - - /** - * 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 . - 'iptc-timetest-invalid.jpg' ); - - $this->assertEquals( '1845:03:02 00:01:02', $meta['DateTimeOriginal'] ); - $this->assertFalse( isset( $meta['DateTimeDigitized'] ) ); - } - - /** - * 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(); - $merger->addMetadata( array( 'foo' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'bar' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'baz' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'fred' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'foo' => 'iptc (hash)' ), 'iptc-good-hash' ); - $merger->addMetadata( array( 'bar' => 'iptc (bad hash)' ), 'iptc-bad-hash' ); - $merger->addMetadata( array( 'baz' => 'iptc (bad hash)' ), 'iptc-bad-hash' ); - $merger->addMetadata( array( 'fred' => 'iptc (no hash)' ), 'iptc-no-hash' ); - $merger->addMetadata( array( 'baz' => 'exif' ), 'exif' ); - - $actual = $merger->getMetadataArray(); - $expected = array( - 'foo' => 'xmp', - 'bar' => 'iptc (bad hash)', - 'baz' => 'exif', - 'fred' => 'xmp', - ); - $this->assertEquals( $expected, $actual ); - } - - /** - * @covers BitmapMetadataHandler::png - */ - public function testPNGXMP() { - if ( !extension_loaded( 'xml' ) ) { - $this->markTestSkipped( "This test needs the xml extension." ); - } - $handler = new BitmapMetadataHandler(); - $result = $handler->png( $this->filePath . 'xmp.png' ); - $expected = array( - 'frameCount' => 0, - 'loopCount' => 1, - 'duration' => 0, - 'bitDepth' => 1, - 'colorType' => 'index-coloured', - 'metadata' => array( - 'SerialNumber' => '123456789', - '_MW_PNG_VERSION' => 1, - ), - ); - $this->assertEquals( $expected, $result ); - } - - /** - * @covers BitmapMetadataHandler::png - */ - public function testPNGNative() { - $handler = new BitmapMetadataHandler(); - $result = $handler->png( $this->filePath . 'Png-native-test.png' ); - $expected = 'http://example.com/url'; - $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 deleted file mode 100644 index 9395b660..00000000 --- a/tests/phpunit/includes/media/BitmapScalingTest.php +++ /dev/null @@ -1,137 +0,0 @@ -<?php - -class BitmapScalingTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgMaxImageArea' => 1.25e7, // 3500x3500 - 'wgCustomConvertCommand' => 'dummy', // Set so that we don't get client side rendering - ) ); - } - - /** - * @dataProvider provideNormaliseParams - * @covers BitmapHandler::normaliseParams - */ - public function testNormaliseParams( $fileDimensions, $expectedParams, $params, $msg ) { - $file = new FakeDimensionFile( $fileDimensions ); - $handler = new BitmapHandler; - $valid = $handler->normaliseParams( $file, $params ); - $this->assertTrue( $valid ); - $this->assertEquals( $expectedParams, $params, $msg ); - } - - public static function provideNormaliseParams() { - return array( - /* Regular resize operations */ - array( - array( 1024, 768 ), - array( - 'width' => 512, 'height' => 384, - 'physicalWidth' => 512, 'physicalHeight' => 384, - 'page' => 1, - ), - array( 'width' => 512 ), - 'Resizing with width set', - ), - array( - array( 1024, 768 ), - array( - 'width' => 512, 'height' => 384, - 'physicalWidth' => 512, 'physicalHeight' => 384, - 'page' => 1, - ), - array( 'width' => 512, 'height' => 768 ), - 'Resizing with height set too high', - ), - array( - array( 1024, 768 ), - array( - 'width' => 512, 'height' => 384, - 'physicalWidth' => 512, 'physicalHeight' => 384, - 'page' => 1, - ), - array( 'width' => 1024, 'height' => 384 ), - 'Resizing with height set', - ), - - /* Very tall images */ - array( - array( 1000, 100 ), - array( - 'width' => 5, 'height' => 1, - 'physicalWidth' => 5, 'physicalHeight' => 1, - 'page' => 1, - ), - array( 'width' => 5 ), - 'Very wide image', - ), - - array( - array( 100, 1000 ), - array( - 'width' => 1, 'height' => 10, - 'physicalWidth' => 1, 'physicalHeight' => 10, - 'page' => 1, - ), - array( 'width' => 1 ), - 'Very high image', - ), - array( - array( 100, 1000 ), - array( - 'width' => 1, 'height' => 5, - 'physicalWidth' => 1, 'physicalHeight' => 10, - 'page' => 1, - ), - array( 'width' => 10, 'height' => 5 ), - 'Very high image with height set', - ), - /* Max image area */ - array( - array( 4000, 4000 ), - array( - 'width' => 5000, 'height' => 5000, - 'physicalWidth' => 4000, 'physicalHeight' => 4000, - 'page' => 1, - ), - array( 'width' => 5000 ), - 'Bigger than max image size but doesn\'t need scaling', - ), - ); - } - - /** - * @covers BitmapHandler::doTransform - */ - public function testTooBigImage() { - $file = new FakeDimensionFile( array( 4000, 4000 ) ); - $handler = new BitmapHandler; - $params = array( 'width' => '3700' ); // Still bigger than max size. - $this->assertEquals( 'TransformParameterError', - get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); - } - - /** - * @covers BitmapHandler::doTransform - */ - public function testTooBigMustRenderImage() { - $file = new FakeDimensionFile( array( 4000, 4000 ) ); - $file->mustRender = true; - $handler = new BitmapHandler; - $params = array( 'width' => '5000' ); // Still bigger than max size. - $this->assertEquals( 'TransformParameterError', - get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); - } - - /** - * @covers BitmapHandler::getImageArea - */ - public function testImageArea() { - $file = new FakeDimensionFile( array( 7, 9 ) ); - $handler = new BitmapHandler; - $this->assertEquals( 63, $handler->getImageArea( $file ) ); - } -} diff --git a/tests/phpunit/includes/media/ExifBitmapTest.php b/tests/phpunit/includes/media/ExifBitmapTest.php deleted file mode 100644 index a2e0eb62..00000000 --- a/tests/phpunit/includes/media/ExifBitmapTest.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php - -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; - - } - - /** - * @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. - * @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 ); - } - - /** - * @covers ExifBitmapHandler::convertMetadataVersion - */ - public function testConvertMetadataLatest() { - $metadata = array( - 'foo' => array( 'First', 'Second', '_type' => 'ol' ), - 'MEDIAWIKI_EXIF_VERSION' => 2 - ); - $res = $this->handler->convertMetadataVersion( $metadata, 2 ); - $this->assertEquals( $metadata, $res ); - } - - /** - * @covers ExifBitmapHandler::convertMetadataVersion - */ - public function testConvertMetadataToOld() { - $metadata = array( - 'foo' => array( 'First', 'Second', '_type' => 'ol' ), - 'bar' => array( 'First', 'Second', '_type' => 'ul' ), - 'baz' => array( 'First', 'Second' ), - 'fred' => 'Single', - 'MEDIAWIKI_EXIF_VERSION' => 2, - ); - $expected = array( - 'foo' => "\n#First\n#Second", - 'bar' => "\n*First\n*Second", - 'baz' => "\n*First\n*Second", - 'fred' => 'Single', - 'MEDIAWIKI_EXIF_VERSION' => 1, - ); - $res = $this->handler->convertMetadataVersion( $metadata, 1 ); - $this->assertEquals( $expected, $res ); - } - - /** - * @covers ExifBitmapHandler::convertMetadataVersion - */ - public function testConvertMetadataSoftware() { - $metadata = array( - 'Software' => array( array( 'GIMP', '1.1' ) ), - 'MEDIAWIKI_EXIF_VERSION' => 2, - ); - $expected = array( - 'Software' => 'GIMP (Version 1.1)', - 'MEDIAWIKI_EXIF_VERSION' => 1, - ); - $res = $this->handler->convertMetadataVersion( $metadata, 1 ); - $this->assertEquals( $expected, $res ); - } - - /** - * @covers ExifBitmapHandler::convertMetadataVersion - */ - public function testConvertMetadataSoftwareNormal() { - $metadata = array( - 'Software' => array( "GIMP 1.2", "vim" ), - 'MEDIAWIKI_EXIF_VERSION' => 2, - ); - $expected = array( - 'Software' => "\n*GIMP 1.2\n*vim", - 'MEDIAWIKI_EXIF_VERSION' => 1, - ); - $res = $this->handler->convertMetadataVersion( $metadata, 1 ); - $this->assertEquals( $expected, $res ); - } -} diff --git a/tests/phpunit/includes/media/ExifRotationTest.php b/tests/phpunit/includes/media/ExifRotationTest.php deleted file mode 100644 index 64276d92..00000000 --- a/tests/phpunit/includes/media/ExifRotationTest.php +++ /dev/null @@ -1,248 +0,0 @@ -<?php -/** - * 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'; - - $tmpDir = $this->getNewTempDirectory(); - - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'temp-thumb' => $tmpDir, 'data' => $filePath ) - ) ) - ) ); - - $this->setMwGlobals( array( - 'wgShowEXIF' => true, - 'wgEnableAutoRotation' => true, - ) ); - } - - /** - * @dataProvider provideFiles - */ - public function testMetadata( $name, $type, $info ) { - if ( !BitmapHandler::canRotate() ) { - $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); - } - $file = $this->dataFile( $name, $type ); - $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); - $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); - } - - /** - * - * @dataProvider provideFiles - */ - public function testRotationRendering( $name, $type, $info, $thumbs ) { - if ( !BitmapHandler::canRotate() ) { - $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); - } - foreach ( $thumbs as $size => $out ) { - if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - ); - } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - 'height' => $matches[2] - ); - } else { - throw new MWException( 'bogus test data format ' . $size ); - } - - $file = $this->dataFile( $name, $type ); - $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE ); - - $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); - $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); - - $gis = getimagesize( $thumb->getLocalCopyPath() ); - if ( $out[0] > $info['width'] ) { - // Physical image won't be scaled bigger than the original. - $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" ); - $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" ); - } else { - $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" ); - $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" ); - } - } - } - - /* Utility function */ - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } - - public static function provideFiles() { - return array( - array( - 'landscape-plain.jpg', - 'image/jpeg', - array( - 'width' => 1024, - 'height' => 768, - ), - array( - '800x600px' => array( 800, 600 ), - '9999x800px' => array( 1067, 800 ), - '800px' => array( 800, 600 ), - '600px' => array( 600, 450 ), - ) - ), - array( - 'portrait-rotated.jpg', - 'image/jpeg', - array( - 'width' => 768, // as rotated - 'height' => 1024, // as rotated - ), - array( - '800x600px' => array( 450, 600 ), - '9999x800px' => array( 600, 800 ), - '800px' => array( 800, 1067 ), - '600px' => array( 600, 800 ), - ) - ) - ); - } - - /** - * Same as before, but with auto-rotation disabled. - * @dataProvider provideFilesNoAutoRotate - */ - 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" ); - } - - /** - * - * @dataProvider provideFilesNoAutoRotate - */ - public function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) { - $this->setMwGlobals( 'wgEnableAutoRotation', false ); - - foreach ( $thumbs as $size => $out ) { - if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - ); - } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - 'height' => $matches[2] - ); - } else { - throw new MWException( 'bogus test data format ' . $size ); - } - - $file = $this->dataFile( $name, $type ); - $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE ); - - $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); - $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); - - $gis = getimagesize( $thumb->getLocalCopyPath() ); - if ( $out[0] > $info['width'] ) { - // Physical image won't be scaled bigger than the original. - $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" ); - $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" ); - } else { - $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" ); - $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" ); - } - } - } - - public static function provideFilesNoAutoRotate() { - return array( - array( - 'landscape-plain.jpg', - 'image/jpeg', - array( - 'width' => 1024, - 'height' => 768, - ), - array( - '800x600px' => array( 800, 600 ), - '9999x800px' => array( 1067, 800 ), - '800px' => array( 800, 600 ), - '600px' => array( 600, 450 ), - ) - ), - array( - 'portrait-rotated.jpg', - 'image/jpeg', - array( - 'width' => 1024, // since not rotated - 'height' => 768, // since not rotated - ), - array( - '800x600px' => array( 800, 600 ), - '9999x800px' => array( 1067, 800 ), - '800px' => array( 800, 600 ), - '600px' => array( 600, 450 ), - ) - ) - ); - } - - - const TEST_WIDTH = 100; - const TEST_HEIGHT = 200; - - /** - * @dataProvider provideBitmapExtractPreRotationDimensions - */ - public function testBitmapExtractPreRotationDimensions( $rotation, $expected ) { - $result = $this->handler->extractPreRotationDimensions( array( - 'physicalWidth' => self::TEST_WIDTH, - 'physicalHeight' => self::TEST_HEIGHT, - ), $rotation ); - $this->assertEquals( $expected, $result ); - } - - public static function provideBitmapExtractPreRotationDimensions() { - return array( - array( - 0, - array( self::TEST_WIDTH, self::TEST_HEIGHT ) - ), - array( - 90, - array( self::TEST_HEIGHT, self::TEST_WIDTH ) - ), - array( - 180, - array( self::TEST_WIDTH, self::TEST_HEIGHT ) - ), - array( - 270, - array( self::TEST_HEIGHT, self::TEST_WIDTH ) - ), - ); - } -} diff --git a/tests/phpunit/includes/media/ExifTest.php b/tests/phpunit/includes/media/ExifTest.php deleted file mode 100644 index dea36b03..00000000 --- a/tests/phpunit/includes/media/ExifTest.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -class ExifTest extends MediaWikiTestCase { - - /** @var string */ - protected $mediaPath; - - protected function setUp() { - parent::setUp(); - if ( !extension_loaded( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - - $this->mediaPath = __DIR__ . '/../../data/media/'; - - - - $this->setMwGlobals( 'wgShowEXIF', true ); - } - - public function testGPSExtraction() { - $filename = $this->mediaPath . 'exif-gps.jpg'; - $seg = JpegMetadataExtractor::segmentSplitter( $filename ); - $exif = new Exif( $filename, $seg['byteOrder'] ); - $data = $exif->getFilteredData(); - $expected = array( - 'GPSLatitude' => 88.5180555556, - 'GPSLongitude' => -21.12357, - 'GPSAltitude' => -3.141592653, - 'GPSDOP' => '5/1', - 'GPSVersionID' => '2.2.0.0', - ); - $this->assertEquals( $expected, $data, '', 0.0000000001 ); - } - - public function testUnicodeUserComment() { - $filename = $this->mediaPath . 'exif-user-comment.jpg'; - $seg = JpegMetadataExtractor::segmentSplitter( $filename ); - $exif = new Exif( $filename, $seg['byteOrder'] ); - $data = $exif->getFilteredData(); - - $expected = array( - 'UserComment' => 'test⁔comment' - ); - $this->assertEquals( $expected, $data ); - } -} diff --git a/tests/phpunit/includes/media/FakeDimensionFile.php b/tests/phpunit/includes/media/FakeDimensionFile.php deleted file mode 100644 index 7926000b..00000000 --- a/tests/phpunit/includes/media/FakeDimensionFile.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -class FakeDimensionFile extends File { - public $mustRender = false; - - public function __construct( $dimensions ) { - parent::__construct( Title::makeTitle( NS_FILE, 'Test' ), - new NullRepo( null ) ); - - $this->dimensions = $dimensions; - } - - public function getWidth( $page = 1 ) { - return $this->dimensions[0]; - } - - public function getHeight( $page = 1 ) { - return $this->dimensions[1]; - } - - public function mustRender() { - return $this->mustRender; - } - - public function getPath() { - return ''; - } -}
\ No newline at end of file diff --git a/tests/phpunit/includes/media/FormatMetadataTest.php b/tests/phpunit/includes/media/FormatMetadataTest.php deleted file mode 100644 index a073e4ca..00000000 --- a/tests/phpunit/includes/media/FormatMetadataTest.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -/** - * @todo covers tags - */ -class FormatMetadataTest extends MediaWikiTestCase { - - /** @var FSFileBackend */ - protected $backend; - /** @var FSRepo */ - protected $repo; - - protected function setUp() { - parent::setUp(); - - if ( !extension_loaded( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - $filePath = __DIR__ . '/../../data/media'; - $this->backend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'data' => $filePath ) - ) ); - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => $this->backend - ) ); - - $this->setMwGlobals( 'wgShowEXIF', true ); - } - - public function testInvalidDate() { - $file = $this->dataFile( 'broken_exif_date.jpg', 'image/jpeg' ); - - // Throws an error if bug hit - $meta = $file->formatMetadata(); - $this->assertNotEquals( false, $meta, 'Valid metadata extracted' ); - - // Find date exif entry - $this->assertArrayHasKey( 'visible', $meta ); - $dateIndex = null; - foreach ( $meta['visible'] as $i => $data ) { - if ( $data['id'] == 'exif-datetimeoriginal' ) { - $dateIndex = $i; - } - } - $this->assertNotNull( $dateIndex, 'Date entry exists in metadata' ); - $this->assertEquals( '0000:01:00 00:02:27', - $meta['visible'][$dateIndex]['value'], - 'File with invalid date metadata (bug 29471)' ); - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } -} diff --git a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php b/tests/phpunit/includes/media/GIFMetadataExtractorTest.php deleted file mode 100644 index 9e3f9244..00000000 --- a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -class GIFMetadataExtractorTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - - $this->mediaPath = __DIR__ . '/../../data/media/'; - } - - /** - * Put in a file, and see if the metadata coming out is as expected. - * @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 ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideGetMetadata() { - - $xmpNugget = <<<EOF -<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> -<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 7.30'> -<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'> - - <rdf:Description rdf:about='' - xmlns:Iptc4xmpCore='http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/'> - <Iptc4xmpCore:Location>The interwebs</Iptc4xmpCore:Location> - </rdf:Description> - - <rdf:Description rdf:about='' - xmlns:tiff='http://ns.adobe.com/tiff/1.0/'> - <tiff:Artist>Bawolff</tiff:Artist> - <tiff:ImageDescription> - <rdf:Alt> - <rdf:li xml:lang='x-default'>A file to test GIF</rdf:li> - </rdf:Alt> - </tiff:ImageDescription> - </rdf:Description> -</rdf:RDF> -</x:xmpmeta> - - - - - - - - - - - - - - - - - - - - - - - - -<?xpacket end='w'?> -EOF; - $xmpNugget = str_replace( "\r", '', $xmpNugget ); // Windows compat - - return array( - array( - 'nonanimated.gif', - array( - 'comment' => array( 'GIF test file ⁕ Created with GIMP' ), - 'duration' => 0.1, - 'frameCount' => 1, - 'looped' => false, - 'xmp' => '', - ) - ), - array( - 'animated.gif', - array( - 'comment' => array( 'GIF test file . Created with GIMP' ), - 'duration' => 2.4, - 'frameCount' => 4, - 'looped' => true, - 'xmp' => '', - ) - ), - - array( - 'animated-xmp.gif', - array( - 'xmp' => $xmpNugget, - 'duration' => 2.4, - 'frameCount' => 4, - 'looped' => true, - 'comment' => array( 'GIƒ·test·file' ), - ) - ), - ); - } -} diff --git a/tests/phpunit/includes/media/GIFTest.php b/tests/phpunit/includes/media/GIFTest.php deleted file mode 100644 index c8e729c8..00000000 --- a/tests/phpunit/includes/media/GIFTest.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php -class GIFHandlerTest extends MediaWikiTestCase { - - /** @var FSFileBackend */ - protected $backend; - /** @var GIFHandler */ - protected $handler; - /** @var FSRepo */ - protected $repo; - /** @var string */ - protected $filePath; - - protected function setUp() { - parent::setUp(); - - $this->filePath = __DIR__ . '/../../data/media'; - $this->backend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'data' => $this->filePath ) - ) ); - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => $this->backend - ) ); - $this->handler = new GIFHandler(); - } - - /** - * @covers GIFHandler::getMetadata - */ - public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); - $this->assertEquals( GIFHandler::BROKEN_FILE, $res ); - } - - /** - * @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' ); - $actual = $this->handler->isAnimatedImage( $file ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideIsAnimated() { - return array( - array( 'animated.gif', true ), - array( 'nonanimated.gif', false ), - ); - } - - /** - * @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' ); - $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideGetImageArea() { - return array( - array( 'animated.gif', 5400 ), - array( 'nonanimated.gif', 1350 ), - ); - } - - /** - * @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 ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideIsMetadataValid() { - return array( - array( GIFHandler::BROKEN_FILE, GIFHandler::METADATA_GOOD ), - array( '', GIFHandler::METADATA_BAD ), - array( null, GIFHandler::METADATA_BAD ), - array( 'Something invalid!', GIFHandler::METADATA_BAD ), - array( 'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}', GIFHandler::METADATA_GOOD ), - ); - } - - /** - * @param $filename String - * @param $expected String Serialized array - * @dataProvider provideGetMetadata - * @covers GIFHandler::getMetadata - */ - public function testGetMetadata( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/gif' ); - $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); - $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); - } - - public static function provideGetMetadata() { - return array( - array( 'nonanimated.gif', 'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}' ), - array( 'animated-xmp.gif', 'a:4:{s:10:"frameCount";i:4;s:6:"looped";b:1;s:8:"duration";d:2.399999999999999911182158029987476766109466552734375;s:8:"metadata";a:5:{s:6:"Artist";s:7:"Bawolff";s:16:"ImageDescription";a:2:{s:9:"x-default";s:18:"A file to test GIF";s:5:"_type";s:4:"lang";}s:15:"SublocationDest";s:13:"The interwebs";s:14:"GIFFileComment";a:1:{i:0;s:16:"GIƒ·test·file";}s:15:"_MW_GIF_VERSION";i:1;}}' ), - ); - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } -} diff --git a/tests/phpunit/includes/media/IPTCTest.php b/tests/phpunit/includes/media/IPTCTest.php deleted file mode 100644 index 81c1d287..00000000 --- a/tests/phpunit/includes/media/IPTCTest.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php - -class IPTCTest extends MediaWikiTestCase { - - /** - * @covers IPTC::getCharset - */ - public function testRecognizeUtf8() { - // utf-8 is the only one used in practise. - $res = IPTC::getCharset( "\x1b%G" ); - $this->assertEquals( 'UTF-8', $res ); - } - - /** - * @covers IPTC::Parse - */ - public function testIPTCParseNoCharset88591() { - // basically IPTC for keyword with value of 0xBC which is 1/4 in iso-8859-1 - // This data doesn't specify a charset. We're supposed to guess - // (which basically means utf-8 if valid, windows 1252 (iso 8859-1) if not) - $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x06\x1c\x02\x19\x00\x01\xBC"; - $res = IPTC::Parse( $iptcData ); - $this->assertEquals( array( '¼' ), $res['Keywords'] ); - } - - /** - * @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. - * 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" - . "\x1c\x01\x5A\x00\x03\x1B\x25\x47"; - $res = IPTC::Parse( $iptcData ); - $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 - * @covers IPTC::Parse - */ - public function testIPTCParseMulti() { - $iptcData = /* identifier */ "Photoshop 3.0\08BIM\4\4" - /* length */ . "\0\0\0\0\0\x0D" - . "\x1c\x02\x19" . "\x00\x01" . "\xBC" - . "\x1c\x02\x19" . "\x00\x02" . "\xBC\xBD"; - $res = IPTC::Parse( $iptcData ); - $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 deleted file mode 100644 index eafc8a2e..00000000 --- a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php -/** - * @todo Could use a test of extended XMP segments. Hard to find programs that - * create example files, and creating my own in vim propbably wouldn't - * 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(); - - $this->filePath = __DIR__ . '/../../data/media/'; - } - - /** - * We also use this test to test padding bytes don't - * screw stuff up - * - * @param string $file filename - * - * @dataProvider provideUtf8Comment - */ - public function testUtf8Comment( $file ) { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . $file ); - $this->assertEquals( array( 'UTF-8 JPEG Comment — ¼' ), $res['COM'] ); - } - - public static function provideUtf8Comment() { - return array( - array( 'jpeg-comment-utf.jpg' ), - array( 'jpeg-padding-even.jpg' ), - array( 'jpeg-padding-odd.jpg' ), - ); - } - - /** The file is iso-8859-1, but it should get auto converted */ - public function testIso88591Comment() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-iso8859-1.jpg' ); - $this->assertEquals( array( 'ISO-8859-1 JPEG Comment - ¼' ), $res['COM'] ); - } - - /** Comment values that are non-textual (random binary junk) should not be shown. - * The example test file has a comment with a 0x5 byte in it which is a control character - * and considered binary junk for our purposes. - */ - public function testBinaryCommentStripped() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-binary.jpg' ); - $this->assertEmpty( $res['COM'] ); - } - - /* Very rarely a file can have multiple comments. - * Order of comments is based on order inside the file. - */ - public function testMultipleComment() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-multiple.jpg' ); - $this->assertEquals( array( 'foo', 'bar' ), $res['COM'] ); - } - - public function testXMPExtraction() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' ); - $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' ); - $this->assertEquals( $expected, $res['XMP'] ); - } - - public function testPSIRExtraction() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' ); - $expected = '50686f746f73686f7020332e30003842494d04040000000000181c02190004746573741c02190003666f6f1c020000020004'; - $this->assertEquals( $expected, bin2hex( $res['PSIR'][0] ) ); - } - - public function testXMPExtractionAltAppId() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-alt.jpg' ); - $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' ); - $this->assertEquals( $expected, $res['XMP'] ); - } - - - public function testIPTCHashComparisionNoHash() { - $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' ); - $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] ); - - $this->assertEquals( 'iptc-no-hash', $res ); - } - - public function testIPTCHashComparisionBadHash() { - $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-bad-hash.jpg' ); - $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] ); - - $this->assertEquals( 'iptc-bad-hash', $res ); - } - - public function testIPTCHashComparisionGoodHash() { - $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-good-hash.jpg' ); - $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] ); - - $this->assertEquals( 'iptc-good-hash', $res ); - } - - public function testExifByteOrder() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'exif-user-comment.jpg' ); - $expected = 'BE'; - $this->assertEquals( $expected, $res['byteOrder'] ); - } -} diff --git a/tests/phpunit/includes/media/JpegTest.php b/tests/phpunit/includes/media/JpegTest.php deleted file mode 100644 index 9af4f1e1..00000000 --- a/tests/phpunit/includes/media/JpegTest.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * @todo covers tags - */ -class JpegTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - if ( !extension_loaded( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - - $this->filePath = __DIR__ . '/../../data/media/'; - - - $this->setMwGlobals( 'wgShowEXIF', true ); - } - - public function testInvalidFile() { - $jpeg = new JpegHandler; - $res = $jpeg->getMetadata( null, $this->filePath . 'README' ); - $this->assertEquals( ExifBitmapHandler::BROKEN_FILE, $res ); - } - - public function testJpegMetadataExtraction() { - $h = new JpegHandler; - $res = $h->getMetadata( null, $this->filePath . 'test.jpg' ); - $expected = 'a:7:{s:16:"ImageDescription";s:9:"Test file";s:11:"XResolution";s:4:"72/1";s:11:"YResolution";s:4:"72/1";s:14:"ResolutionUnit";i:2;s:16:"YCbCrPositioning";i:1;s:15:"JPEGFileComment";a:1:{i:0;s:17:"Created with GIMP";}s:22:"MEDIAWIKI_EXIF_VERSION";i:2;}'; - - // Unserialize in case serialization format ever changes. - $this->assertEquals( unserialize( $expected ), unserialize( $res ) ); - } -} diff --git a/tests/phpunit/includes/media/MediaHandlerTest.php b/tests/phpunit/includes/media/MediaHandlerTest.php deleted file mode 100644 index c28898bb..00000000 --- a/tests/phpunit/includes/media/MediaHandlerTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -class MediaHandlerTest extends MediaWikiTestCase { - - /** - * @covers MediaHandler::fitBoxWidth - * @todo split into a dataprovider and test method - */ - public function testFitBoxWidth() { - $vals = array( - array( - 'width' => 50, - 'height' => 50, - 'tests' => array( - 50 => 50, - 17 => 17, - 18 => 18 ) ), - array( - 'width' => 366, - 'height' => 300, - 'tests' => array( - 50 => 61, - 17 => 21, - 18 => 22 ) ), - array( - 'width' => 300, - 'height' => 366, - 'tests' => array( - 50 => 41, - 17 => 14, - 18 => 15 ) ), - array( - 'width' => 100, - 'height' => 400, - 'tests' => array( - 50 => 12, - 17 => 4, - 18 => 4 ) ) ); - foreach ( $vals as $row ) { - $tests = $row['tests']; - $height = $row['height']; - $width = $row['width']; - foreach ( $tests as $max => $expected ) { - $y = round( $expected * $height / $width ); - $result = MediaHandler::fitBoxWidth( $width, $height, $max ); - $y2 = round( $result * $height / $width ); - $this->assertEquals( $expected, - $result, - "($width, $height, $max) wanted: {$expected}x$y, got: {$result}x$y2" ); - } - } - } -} diff --git a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php b/tests/phpunit/includes/media/PNGMetadataExtractorTest.php deleted file mode 100644 index 939f2cfc..00000000 --- a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php +++ /dev/null @@ -1,155 +0,0 @@ -<?php - -/** - * @todo covers tags - */ -class PNGMetadataExtractorTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - $this->filePath = __DIR__ . '/../../data/media/'; - } - - /** - * Tests zTXt tag (compressed textual metadata) - */ - public function testPngNativetZtxt() { - $this->checkPHPExtension( 'zlib' ); - - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - $expected = "foo bar baz foo foo foo foof foo foo foo foo"; - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - $this->assertArrayHasKey( 'Make', $meta ); - $this->assertArrayHasKey( 'x-default', $meta['Make'] ); - - $this->assertEquals( $expected, $meta['Make']['x-default'] ); - } - - /** - * Test tEXt tag (Uncompressed textual metadata) - */ - public function testPngNativeText() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - $expected = "Some long image desc"; - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - $this->assertArrayHasKey( 'ImageDescription', $meta ); - $this->assertArrayHasKey( 'x-default', $meta['ImageDescription'] ); - $this->assertArrayHasKey( '_type', $meta['ImageDescription'] ); - - $this->assertEquals( $expected, $meta['ImageDescription']['x-default'] ); - } - - /** - * tEXt tags must be encoded iso-8859-1 (vs iTXt which are utf-8) - * Make sure non-ascii characters get converted properly - */ - public function testPngNativeTextNonAscii() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - // Note the Copyright symbol here is a utf-8 one - // (aka \xC2\xA9) where in the file its iso-8859-1 - // encoded as just \xA9. - $expected = "© 2010 Bawolff"; - - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - $this->assertArrayHasKey( 'Copyright', $meta ); - $this->assertArrayHasKey( 'x-default', $meta['Copyright'] ); - - $this->assertEquals( $expected, $meta['Copyright']['x-default'] ); - } - - /** - * Test extraction of pHYs tags, which can tell what the - * actual resolution of the image is (aka in dots per meter). - */ - /* - public function testPngPhysTag() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - - $this->assertEquals( '2835/100', $meta['XResolution'] ); - $this->assertEquals( '2835/100', $meta['YResolution'] ); - $this->assertEquals( 3, $meta['ResolutionUnit'] ); // 3 = cm - } - */ - - /** - * Given a normal static PNG, check the animation metadata returned. - */ - public function testStaticPngAnimationMetadata() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertEquals( 0, $meta['frameCount'] ); - $this->assertEquals( 1, $meta['loopCount'] ); - $this->assertEquals( 0, $meta['duration'] ); - } - - /** - * Given an animated APNG image file - * check it gets animated metadata right. - */ - public function testApngAnimationMetadata() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Animated_PNG_example_bouncing_beach_ball.png' ); - - $this->assertEquals( 20, $meta['frameCount'] ); - // Note loop count of 0 = infinity - $this->assertEquals( 0, $meta['loopCount'] ); - $this->assertEquals( 1.5, $meta['duration'], '', 0.00001 ); - } - - public function testPngBitDepth8() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertEquals( 8, $meta['bitDepth'] ); - } - - public function testPngBitDepth1() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - '1bit-png.png' ); - $this->assertEquals( 1, $meta['bitDepth'] ); - } - - - public function testPngIndexColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertEquals( 'index-coloured', $meta['colorType'] ); - } - - public function testPngRgbColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'rgb-png.png' ); - $this->assertEquals( 'truecolour-alpha', $meta['colorType'] ); - } - - public function testPngRgbNoAlphaColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'rgb-na-png.png' ); - $this->assertEquals( 'truecolour', $meta['colorType'] ); - } - - public function testPngGreyscaleColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'greyscale-png.png' ); - $this->assertEquals( 'greyscale-alpha', $meta['colorType'] ); - } - - 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 deleted file mode 100644 index ad4c2493..00000000 --- a/tests/phpunit/includes/media/PNGTest.php +++ /dev/null @@ -1,123 +0,0 @@ -<?php -class PNGHandlerTest extends MediaWikiTestCase { - - /** @var PNGHandler */ - protected $handler; - /** @var FSRepo */ - protected $repo; - /** @var FSFileBackend */ - protected $backend; - /** @var string */ - protected $filePath; - - protected function setUp() { - parent::setUp(); - - $this->filePath = __DIR__ . '/../../data/media'; - $this->backend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'data' => $this->filePath ) - ) ); - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => $this->backend - ) ); - $this->handler = new PNGHandler(); - } - - /** - * @covers PNGHandler::getMetadata - */ - public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); - $this->assertEquals( PNGHandler::BROKEN_FILE, $res ); - } - - /** - * @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' ); - $actual = $this->handler->isAnimatedImage( $file ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideIsAnimated() { - return array( - array( 'Animated_PNG_example_bouncing_beach_ball.png', true ), - array( '1bit-png.png', false ), - ); - } - - /** - * @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' ); - $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideGetImageArea() { - return array( - array( '1bit-png.png', 2500 ), - array( 'greyscale-png.png', 2500 ), - array( 'Png-native-test.png', 126000 ), - array( 'Animated_PNG_example_bouncing_beach_ball.png', 10000 ), - ); - } - - /** - * @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 ); - $this->assertEquals( $expected, $actual ); - } - - public static function provideIsMetadataValid() { - return array( - array( PNGHandler::BROKEN_FILE, PNGHandler::METADATA_GOOD ), - array( '', PNGHandler::METADATA_BAD ), - array( null, PNGHandler::METADATA_BAD ), - array( 'Something invalid!', PNGHandler::METADATA_BAD ), - array( 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}', PNGHandler::METADATA_GOOD ), - ); - } - - /** - * @param $filename String - * @param $expected String Serialized array - * @dataProvider provideGetMetadata - * @covers PNGHandler::getMetadata - */ - public function testGetMetadata( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/png' ); - $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); -// $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); - $this->assertEquals( ( $expected ), ( $actual ) ); - } - - public static function provideGetMetadata() { - return array( - array( 'rgb-na-png.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}' ), - array( 'xmp.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}' ), - ); - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } -} diff --git a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php deleted file mode 100644 index 257009b0..00000000 --- a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php +++ /dev/null @@ -1,112 +0,0 @@ -<?php - -/** - * @todo covers tags - */ -class SVGMetadataExtractorTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - AutoLoader::loadClass( 'SVGMetadataExtractorTest' ); - } - - /** - * @dataProvider provideSvgFiles - */ - public function testGetMetadata( $infile, $expected ) { - $this->assertMetadata( $infile, $expected ); - } - - /** - * @dataProvider provideSvgFilesWithXMLMetadata - */ - 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 ); - } - - function assertMetadata( $infile, $expected ) { - try { - $data = SVGMetadataExtractor::getMetadata( $infile ); - $this->assertEquals( $expected, $data, 'SVG metadata extraction test' ); - } catch ( MWException $e ) { - if ( $expected === false ) { - $this->assertTrue( true, 'SVG metadata extracted test (expected failure)' ); - } else { - throw $e; - } - } - } - - public static function provideSvgFiles() { - $base = __DIR__ . '/../../data/media'; - - return array( - array( - "$base/Wikimedia-logo.svg", - array( - 'width' => 1024, - 'height' => 1024, - 'originalWidth' => '1024', - 'originalHeight' => '1024', - ) - ), - array( - "$base/QA_icon.svg", - array( - 'width' => 60, - 'height' => 60, - 'originalWidth' => '60', - 'originalHeight' => '60', - ) - ), - array( - "$base/Gtk-media-play-ltr.svg", - array( - 'width' => 60, - 'height' => 60, - 'originalWidth' => '60.0000000', - 'originalHeight' => '60.0000000', - ) - ), - array( - "$base/Toll_Texas_1.svg", - // This file triggered bug 31719, needs entity expansion in the xmlns checks - array( - 'width' => 385, - 'height' => 385, - 'originalWidth' => '385', - 'originalHeight' => '385.0004883', - ) - ) - ); - } - - public static function provideSvgFilesWithXMLMetadata() { - $base = __DIR__ . '/../../data/media'; - $metadata = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> - <ns4:Work xmlns:ns4="http://creativecommons.org/ns#" rdf:about=""> - <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format> - <ns5:type xmlns:ns5="http://purl.org/dc/elements/1.1/" rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> - </ns4:Work> - </rdf:RDF>'; - $metadata = str_replace( "\r", '', $metadata ); // Windows compat - return array( - array( - "$base/US_states_by_total_state_tax_revenue.svg", - array( - 'height' => 593, - 'metadata' => $metadata, - 'width' => 959, - 'originalWidth' => '958.69', - 'originalHeight' => '592.78998', - ) - ), - ); - } -} diff --git a/tests/phpunit/includes/media/TiffTest.php b/tests/phpunit/includes/media/TiffTest.php deleted file mode 100644 index 8d74b98d..00000000 --- a/tests/phpunit/includes/media/TiffTest.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -class TiffTest extends MediaWikiTestCase { - - /** @var TiffHandler */ - protected $handler; - /** @var string */ - protected $filePath; - - protected function setUp() { - parent::setUp(); - if ( !extension_loaded( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - - $this->setMwGlobals( 'wgShowEXIF', true ); - - $this->filePath = __DIR__ . '/../../data/media/'; - $this->handler = new TiffHandler; - } - - /** - * @covers TiffHandler::getMetadata - */ - public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . 'README' ); - $this->assertEquals( ExifBitmapHandler::BROKEN_FILE, $res ); - } - - /** - * @covers TiffHandler::getMetadata - */ - public function testTiffMetadataExtraction() { - $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 - // of php serialize stuff. - $this->assertEquals( unserialize( $expected ), unserialize( $res ) ); - } -} diff --git a/tests/phpunit/includes/media/XMPTest.php b/tests/phpunit/includes/media/XMPTest.php deleted file mode 100644 index d12e9b00..00000000 --- a/tests/phpunit/includes/media/XMPTest.php +++ /dev/null @@ -1,166 +0,0 @@ -<?php - -/** - * @todo covers tags - */ -class XMPTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - if ( !extension_loaded( 'xml' ) ) { - $this->markTestSkipped( 'Requires libxml to do XMP parsing' ); - } - } - - /** - * Put XMP in, compare what comes out... - * - * @param $xmp String the actual xml data. - * @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 ) { - if ( !is_string( $xmp ) || !is_array( $expected ) ) { - throw new Exception( "Invalid data provided to " . __METHOD__ ); - } - $reader = new XMPReader; - $reader->parse( $xmp ); - $this->assertEquals( $expected, $reader->getResults(), $info, 0.0000000001 ); - } - - public static function provideXMPParse() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $data = array(); - - // $xmpFiles format: array of arrays with first arg file base name, - // with the actual file having .xmp on the end for the xmp - // and .result.php on the end for a php file containing the result - // array. Second argument is some info on what's being tested. - $xmpFiles = array( - array( '1', 'parseType=Resource test' ), - array( '2', 'Structure with mixed attribute and element props' ), - array( '3', 'Extra qualifiers (that should be ignored)' ), - array( '3-invalid', 'Test ignoring qualifiers that look like normal props' ), - array( '4', 'Flash as qualifier' ), - array( '5', 'Flash as qualifier 2' ), - array( '6', 'Multiple rdf:Description' ), - array( '7', 'Generic test of several property types' ), - array( 'flash', 'Test of Flash property' ), - array( 'invalid-child-not-struct', 'Test child props not in struct or ignored' ), - array( 'no-recognized-props', 'Test namespace and no recognized props' ), - array( 'no-namespace', 'Test non-namespaced attributes are ignored' ), - array( 'bag-for-seq', "Allow bag's instead of seq's. (bug 27105)" ), - array( 'utf16BE', 'UTF-16BE encoding' ), - array( 'utf16LE', 'UTF-16LE encoding' ), - array( 'utf32BE', 'UTF-32BE encoding' ), - array( 'utf32LE', 'UTF-32LE encoding' ), - array( 'xmpExt', 'Extended XMP missing second part' ), - array( 'gps', 'Handling of exif GPS parameters in XMP' ), - ); - - foreach ( $xmpFiles as $file ) { - $xmp = file_get_contents( $xmpPath . $file[0] . '.xmp' ); - // I'm not sure if this is the best way to handle getting the - // result array, but it seems kind of big to put directly in the test - // file. - $result = null; - include $xmpPath . $file[0] . '.result.php'; - $data[] = array( $xmp, $result, '[' . $file[0] . '.xmp] ' . $file[1] ); - } - - return $data; - } - - /** Test ExtendedXMP block support. (Used when the XMP has to be split - * over multiple jpeg segments, due to 64k size limit on jpeg segments. - * - * @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. - */ - public function testExtendedXMP() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); - $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); - - $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp - $length = pack( 'N', strlen( $extendedXMP ) ); - $offset = pack( 'N', 0 ); - $extendedPacket = $md5sum . $length . $offset . $extendedXMP; - - $reader = new XMPReader(); - $reader->parse( $standardXMP ); - $reader->parseExtended( $extendedPacket ); - $actual = $reader->getResults(); - - $expected = array( - 'xmp-exif' => array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => 9, - 'FNumber' => '2/10', - ) - ); - - $this->assertEquals( $expected, $actual ); - } - - /** - * This test has an extended XMP block with a wrong guid (md5sum) - * and thus should only return the StandardXMP, not the ExtendedXMP. - */ - public function testExtendedXMPWithWrongGUID() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); - $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); - - $md5sum = '28C74E0AC2D796886759006FBE2E57B9'; // Note last digit. - $length = pack( 'N', strlen( $extendedXMP ) ); - $offset = pack( 'N', 0 ); - $extendedPacket = $md5sum . $length . $offset . $extendedXMP; - - $reader = new XMPReader(); - $reader->parse( $standardXMP ); - $reader->parseExtended( $extendedPacket ); - $actual = $reader->getResults(); - - $expected = array( - 'xmp-exif' => array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => 9, - ) - ); - - $this->assertEquals( $expected, $actual ); - } - - /** - * Have a high offset to simulate a missing packet, - * which should cause it to ignore the ExtendedXMP packet. - */ - public function testExtendedXMPMissingPacket() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); - $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); - - $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp - $length = pack( 'N', strlen( $extendedXMP ) ); - $offset = pack( 'N', 2048 ); - $extendedPacket = $md5sum . $length . $offset . $extendedXMP; - - $reader = new XMPReader(); - $reader->parse( $standardXMP ); - $reader->parseExtended( $extendedPacket ); - $actual = $reader->getResults(); - - $expected = array( - 'xmp-exif' => array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => 9, - ) - ); - - $this->assertEquals( $expected, $actual ); - } -} diff --git a/tests/phpunit/includes/media/XMPValidateTest.php b/tests/phpunit/includes/media/XMPValidateTest.php deleted file mode 100644 index 96bf5e47..00000000 --- a/tests/phpunit/includes/media/XMPValidateTest.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -class XMPValidateTest extends MediaWikiTestCase { - - /** - * @dataProvider provideDates - * @covers XMPValidate::validateDate - */ - public function testValidateDate( $value, $expected ) { - // The method should modify $value. - XMPValidate::validateDate( array(), $value, true ); - $this->assertEquals( $expected, $value ); - } - - public static function provideDates() { - /* For reference valid date formats are: - * YYYY - * YYYY-MM - * YYYY-MM-DD - * YYYY-MM-DDThh:mmTZD - * YYYY-MM-DDThh:mm:ssTZD - * YYYY-MM-DDThh:mm:ss.sTZD - * (Time zone is optional) - */ - return array( - array( '1992', '1992' ), - array( '1992-04', '1992:04' ), - array( '1992-02-01', '1992:02:01' ), - array( '2011-09-29', '2011:09:29' ), - array( '1982-12-15T20:12', '1982:12:15 20:12' ), - array( '1982-12-15T20:12Z', '1982:12:15 20:12' ), - array( '1982-12-15T20:12+02:30', '1982:12:15 22:42' ), - array( '1982-12-15T01:12-02:30', '1982:12:14 22:42' ), - array( '1982-12-15T20:12:11', '1982:12:15 20:12:11' ), - array( '1982-12-15T20:12:11Z', '1982:12:15 20:12:11' ), - array( '1982-12-15T20:12:11+01:10', '1982:12:15 21:22:11' ), - array( '2045-12-15T20:12:11', '2045:12:15 20:12:11' ), - array( '1867-06-01T15:00:00', '1867:06:01 15:00:00' ), - /* some invalid ones */ - array( '2001--12', null ), - array( '2001-5-12', null ), - array( '2001-5-12TZ', null ), - 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 deleted file mode 100644 index 52dd2ef5..00000000 --- a/tests/phpunit/includes/normal/CleanUpTest.php +++ /dev/null @@ -1,409 +0,0 @@ -<?php -/** - * Tests for UtfNormal::cleanUp() function. - * - * Copyright © 2004 Brion Vibber <brion@pobox.com> - * http://www.mediawiki.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -/** - * Additional tests for UtfNormal::cleanUp() function, inclusion - * regression checks for known problems. - * Requires PHPUnit. - * - * @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 */ - public function testAscii() { - $text = 'This is plain ASCII text.'; - $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); - } - - /** @todo document */ - public function testNull() { - $text = "a \x00 null"; - $expect = "a \xef\xbf\xbd null"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testLatin() { - $text = "L'\xc3\xa9cole"; - $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); - } - - /** @todo document */ - public function testLatinNormal() { - $text = "L'e\xcc\x81cole"; - $expect = "L'\xc3\xa9cole"; - $this->assertEquals( $expect, UtfNormal::cleanUp( $text ) ); - } - - /** - * This test is *very* expensive! - * @todo document - */ - function XtestAllChars() { - $rep = UTF8_REPLACEMENT; - for ( $i = 0x0; $i < UNICODE_MAX; $i++ ) { - $char = codepointToUtf8( $i ); - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%04X", $i ); - - if ( $i % 0x1000 == 0 ) { - echo "U+$x\n"; - } - - if ( $i == 0x0009 || - $i == 0x000a || - $i == 0x000d || - ( $i > 0x001f && $i < UNICODE_SURROGATE_FIRST ) || - ( $i > UNICODE_SURROGATE_LAST && $i < 0xfffe ) || - ( $i > 0xffff && $i <= UNICODE_MAX ) - ) { - if ( isset( UtfNormal::$utfCanonicalComp[$char] ) || isset( UtfNormal::$utfCanonicalDecomp[$char] ) ) { - $comp = UtfNormal::NFC( $char ); - $this->assertEquals( - bin2hex( $comp ), - bin2hex( $clean ), - "U+$x should be decomposed" ); - } else { - $this->assertEquals( - bin2hex( $char ), - bin2hex( $clean ), - "U+$x should be intact" ); - } - } else { - $this->assertEquals( bin2hex( $rep ), bin2hex( $clean ), $x ); - } - } - } - - /** @todo document */ - public function testAllBytes() { - $this->doTestBytes( '', '' ); - $this->doTestBytes( 'x', '' ); - $this->doTestBytes( '', 'x' ); - $this->doTestBytes( 'x', 'x' ); - } - - /** @todo document */ - function doTestBytes( $head, $tail ) { - for ( $i = 0x0; $i < 256; $i++ ) { - $char = $head . chr( $i ) . $tail; - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%02X", $i ); - - if ( $i == 0x0009 || - $i == 0x000a || - $i == 0x000d || - ( $i > 0x001f && $i < 0x80 ) - ) { - $this->assertEquals( - bin2hex( $char ), - bin2hex( $clean ), - "ASCII byte $x should be intact" ); - if ( $char != $clean ) { - return; - } - } else { - $norm = $head . UTF8_REPLACEMENT . $tail; - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Forbidden byte $x should be rejected" ); - if ( $norm != $clean ) { - return; - } - } - } - } - - /** @todo document */ - public function testDoubleBytes() { - $this->doTestDoubleBytes( '', '' ); - $this->doTestDoubleBytes( 'x', '' ); - $this->doTestDoubleBytes( '', 'x' ); - $this->doTestDoubleBytes( 'x', 'x' ); - } - - /** - * @todo document - */ - function doTestDoubleBytes( $head, $tail ) { - for ( $first = 0xc0; $first < 0x100; $first += 2 ) { - for ( $second = 0x80; $second < 0x100; $second += 2 ) { - $char = $head . chr( $first ) . chr( $second ) . $tail; - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%02X,%02X", $first, $second ); - if ( $first > 0xc1 && - $first < 0xe0 && - $second < 0xc0 - ) { - $norm = UtfNormal::NFC( $char ); - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Pair $x should be intact" ); - if ( $norm != $clean ) { - return; - } - } elseif ( $first > 0xfd || $second > 0xbf ) { - # fe and ff are not legal head bytes -- expect two replacement chars - $norm = $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail; - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Forbidden pair $x should be rejected" ); - if ( $norm != $clean ) { - return; - } - } else { - $norm = $head . UTF8_REPLACEMENT . $tail; - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Forbidden pair $x should be rejected" ); - if ( $norm != $clean ) { - return; - } - } - } - } - } - - /** @todo document */ - public function testTripleBytes() { - $this->doTestTripleBytes( '', '' ); - $this->doTestTripleBytes( 'x', '' ); - $this->doTestTripleBytes( '', 'x' ); - $this->doTestTripleBytes( 'x', 'x' ); - } - - /** @todo document */ - function doTestTripleBytes( $head, $tail ) { - for ( $first = 0xc0; $first < 0x100; $first += 2 ) { - for ( $second = 0x80; $second < 0x100; $second += 2 ) { - #for( $third = 0x80; $third < 0x100; $third++ ) { - for ( $third = 0x80; $third < 0x81; $third++ ) { - $char = $head . chr( $first ) . chr( $second ) . chr( $third ) . $tail; - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%02X,%02X,%02X", $first, $second, $third ); - - if ( $first >= 0xe0 && - $first < 0xf0 && - $second < 0xc0 && - $third < 0xc0 - ) { - if ( $first == 0xe0 && $second < 0xa0 ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Overlong triplet $x should be rejected" ); - } elseif ( $first == 0xed && - ( chr( $first ) . chr( $second ) . chr( $third ) ) >= UTF8_SURROGATE_FIRST - ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Surrogate triplet $x should be rejected" ); - } else { - $this->assertEquals( - bin2hex( UtfNormal::NFC( $char ) ), - bin2hex( $clean ), - "Triplet $x should be intact" ); - } - } elseif ( $first > 0xc1 && $first < 0xe0 && $second < 0xc0 ) { - $this->assertEquals( - bin2hex( UtfNormal::NFC( $head . chr( $first ) . chr( $second ) ) . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Valid 2-byte $x + broken tail" ); - } elseif ( $second > 0xc1 && $second < 0xe0 && $third < 0xc0 ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . UtfNormal::NFC( chr( $second ) . chr( $third ) . $tail ) ), - bin2hex( $clean ), - "Broken head + valid 2-byte $x" ); - } elseif ( ( $first > 0xfd || $second > 0xfd ) && - ( ( $second > 0xbf && $third > 0xbf ) || - ( $second < 0xc0 && $third < 0xc0 ) || - ( $second > 0xfd ) || - ( $third > 0xfd ) ) - ) { - # fe and ff are not legal head bytes -- expect three replacement chars - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Forbidden triplet $x should be rejected" ); - } elseif ( $first > 0xc2 && $second < 0xc0 && $third < 0xc0 ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Forbidden triplet $x should be rejected" ); - } else { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Forbidden triplet $x should be rejected" ); - } - } - } - } - } - - /** @todo document */ - public function testChunkRegression() { - # Check for regression against a chunking bug - $text = "\x46\x55\xb8" . - "\xdc\x96" . - "\xee" . - "\xe7" . - "\x44" . - "\xaa" . - "\x2f\x25"; - $expect = "\x46\x55\xef\xbf\xbd" . - "\xdc\x96" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x44" . - "\xef\xbf\xbd" . - "\x2f\x25"; - - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testInterposeRegression() { - $text = "\x4e\x30" . - "\xb1" . # bad tail - "\x3a" . - "\x92" . # bad tail - "\x62\x3a" . - "\x84" . # bad tail - "\x43" . - "\xc6" . # bad head - "\x3f" . - "\x92" . # bad tail - "\xad" . # bad tail - "\x7d" . - "\xd9\x95"; - - $expect = "\x4e\x30" . - "\xef\xbf\xbd" . - "\x3a" . - "\xef\xbf\xbd" . - "\x62\x3a" . - "\xef\xbf\xbd" . - "\x43" . - "\xef\xbf\xbd" . - "\x3f" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x7d" . - "\xd9\x95"; - - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testOverlongRegression() { - $text = "\x67" . - "\x1a" . # forbidden ascii - "\xea" . # bad head - "\xc1\xa6" . # overlong sequence - "\xad" . # bad tail - "\x1c" . # forbidden ascii - "\xb0" . # bad tail - "\x3c" . - "\x9e"; # bad tail - $expect = "\x67" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x3c" . - "\xef\xbf\xbd"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testSurrogateRegression() { - $text = "\xed\xb4\x96" . # surrogate 0xDD16 - "\x83" . # bad tail - "\xb4" . # bad tail - "\xac"; # bad head - $expect = "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testBomRegression() { - $text = "\xef\xbf\xbe" . # U+FFFE, illegal char - "\xb2" . # bad tail - "\xef" . # bad head - "\x59"; - $expect = "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x59"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testForbiddenRegression() { - $text = "\xef\xbf\xbf"; # U+FFFF, illegal char - $expect = "\xef\xbf\xbd"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - public function testHangulRegression() { - $text = "\xed\x9c\xaf" . # Hangul char - "\xe1\x87\x81"; # followed by another final jamo - $expect = $text; # Should *not* change. - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } -} diff --git a/tests/phpunit/includes/objectcache/BagOStuffTest.php b/tests/phpunit/includes/objectcache/BagOStuffTest.php deleted file mode 100644 index aa783943..00000000 --- a/tests/phpunit/includes/objectcache/BagOStuffTest.php +++ /dev/null @@ -1,149 +0,0 @@ -<?php -/** - * This class will test BagOStuff. - * - * @author Matthias Mullie <mmullie@wikimedia.org> - */ -class BagOStuffTest extends MediaWikiTestCase { - private $cache; - - protected function setUp() { - parent::setUp(); - - // type defined through parameter - if ( $this->getCliArg( 'use-bagostuff=' ) ) { - $name = $this->getCliArg( 'use-bagostuff=' ); - - $this->cache = ObjectCache::newFromId( $name ); - } else { - // no type defined - use simple hash - $this->cache = new HashBagOStuff; - } - - $this->cache->delete( wfMemcKey( 'test' ) ); - } - - protected function tearDown() { - } - - public function testMerge() { - $key = wfMemcKey( 'test' ); - - $usleep = 0; - - /** - * Callback method: append "merged" to whatever is in cache. - * - * @param BagOStuff $cache - * @param string $key - * @param int $existingValue - * @use int $usleep - * @return int - */ - $callback = function ( BagOStuff $cache, $key, $existingValue ) use ( &$usleep ) { - // let's pretend this is an expensive callback to test concurrent merge attempts - usleep( $usleep ); - - if ( $existingValue === false ) { - return 'merged'; - } - - return $existingValue . 'merged'; - }; - - // merge on non-existing value - $merged = $this->cache->merge( $key, $callback, 0 ); - $this->assertTrue( $merged ); - $this->assertEquals( $this->cache->get( $key ), 'merged' ); - - // merge on existing value - $merged = $this->cache->merge( $key, $callback, 0 ); - $this->assertTrue( $merged ); - $this->assertEquals( $this->cache->get( $key ), 'mergedmerged' ); - - /* - * Test concurrent merges by forking this process, if: - * - not manually called with --use-bagostuff - * - pcntl_fork is supported by the system - * - cache type will correctly support calls over forks - */ - $fork = (bool)$this->getCliArg( 'use-bagostuff=' ); - $fork &= function_exists( 'pcntl_fork' ); - $fork &= !$this->cache instanceof HashBagOStuff; - $fork &= !$this->cache instanceof EmptyBagOStuff; - $fork &= !$this->cache instanceof MultiWriteBagOStuff; - if ( $fork ) { - // callback should take awhile now so that we can test concurrent merge attempts - $usleep = 5000; - - $pid = pcntl_fork(); - if ( $pid == -1 ) { - // can't fork, ignore this test... - } elseif ( $pid ) { - // wait a little, making sure that the child process is calling merge - usleep( 3000 ); - - // attempt a merge - this should fail - $merged = $this->cache->merge( $key, $callback, 0, 1 ); - - // merge has failed because child process was merging (and we only attempted once) - $this->assertFalse( $merged ); - - // make sure the child's merge is completed and verify - usleep( 3000 ); - $this->assertEquals( $this->cache->get( $key ), 'mergedmergedmerged' ); - } else { - $this->cache->merge( $key, $callback, 0, 1 ); - - // Note: I'm not even going to check if the merge worked, I'll - // compare values in the parent process to test if this merge worked. - // I'm just going to exit this child process, since I don't want the - // child to output any test results (would be rather confusing to - // have test output twice) - exit; - } - } - } - - public function testAdd() { - $key = wfMemcKey( 'test' ); - $this->assertTrue( $this->cache->add( $key, 'test' ) ); - } - - public function testGet() { - $value = array( 'this' => 'is', 'a' => 'test' ); - - $key = wfMemcKey( 'test' ); - $this->cache->add( $key, $value ); - $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' ); - - $key1 = wfMemcKey( 'test1' ); - $key2 = wfMemcKey( 'test2' ); - - $this->cache->add( $key1, $value1 ); - $this->cache->add( $key2, $value2 ); - - $this->assertEquals( $this->cache->getMulti( array( $key1, $key2 ) ), array( $key1 => $value1, $key2 => $value2 ) ); - - // cleanup - $this->cache->delete( $key1 ); - $this->cache->delete( $key2 ); - } -} diff --git a/tests/phpunit/includes/parser/MagicVariableTest.php b/tests/phpunit/includes/parser/MagicVariableTest.php deleted file mode 100644 index c2c97c01..00000000 --- a/tests/phpunit/includes/parser/MagicVariableTest.php +++ /dev/null @@ -1,242 +0,0 @@ -<?php -/** - * This file is intended to test magic variables in the parser - * It was inspired by Raymond & Matěj Grabovský commenting about r66200 - * - * As of february 2011, it only tests some revisions and date related - * magic variables. - * - * @author Antoine Musso - * @copyright Copyright © 2011, Antoine Musso - * @file - * @todo covers tags - */ - -class MagicVariableTest extends MediaWikiTestCase { - /** - * @var Parser - */ - private $testParser = null; - - /** - * An array of magicword returned as type integer by the parser - * They are usually returned as a string for i18n since we support - * persan numbers for example, but some magic explicitly return - * them as integer. - * @see MagicVariableTest::assertMagic() - */ - private $expectedAsInteger = array( - 'revisionday', - 'revisionmonth1', - ); - - /** setup a basic parser object */ - protected function setUp() { - parent::setUp(); - - $contLang = Language::factory( 'en' ); - $this->setMwGlobals( array( - 'wgLanguageCode' => 'en', - 'wgContLang' => $contLang, - ) ); - - $this->testParser = new Parser(); - $this->testParser->Options( ParserOptions::newFromUserAndLang( new User, $contLang ) ); - - # initialize parser output - $this->testParser->clearState(); - - # Needs a title to do magic word stuff - $title = Title::newFromText( 'Tests' ); - $title->mRedirect = false; # Else it needs a db connection just to check if it's a redirect (when deciding the page language) - - $this->testParser->setTitle( $title ); - } - - /** - * @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 ); - } - - /** - * @return array of days numbers (as an integer) - */ - public static function provideDays() { - return self::createProviderUpTo( 31 ); - } - - ############### TESTS ############################################# - # @todo FIXME: - # - those got copy pasted, we can probably make them cleaner - # - tests are lacking useful messages - - # day - - /** @dataProvider provideDays */ - public function testCurrentdayIsUnPadded( $day ) { - $this->assertUnPadded( 'currentday', $day ); - } - - /** @dataProvider provideDays */ - public function testCurrentdaytwoIsZeroPadded( $day ) { - $this->assertZeroPadded( 'currentday2', $day ); - } - - /** @dataProvider provideDays */ - public function testLocaldayIsUnPadded( $day ) { - $this->assertUnPadded( 'localday', $day ); - } - - /** @dataProvider provideDays */ - public function testLocaldaytwoIsZeroPadded( $day ) { - $this->assertZeroPadded( 'localday2', $day ); - } - - # month - - /** @dataProvider provideMonths */ - public function testCurrentmonthIsZeroPadded( $month ) { - $this->assertZeroPadded( 'currentmonth', $month ); - } - - /** @dataProvider provideMonths */ - public function testCurrentmonthoneIsUnPadded( $month ) { - $this->assertUnPadded( 'currentmonth1', $month ); - } - - /** @dataProvider provideMonths */ - public function testLocalmonthIsZeroPadded( $month ) { - $this->assertZeroPadded( 'localmonth', $month ); - } - - /** @dataProvider provideMonths */ - public function testLocalmonthoneIsUnPadded( $month ) { - $this->assertUnPadded( 'localmonth1', $month ); - } - - # revision day - - /** @dataProvider provideDays */ - public function testRevisiondayIsUnPadded( $day ) { - $this->assertUnPadded( 'revisionday', $day ); - } - - /** @dataProvider provideDays */ - public function testRevisiondaytwoIsZeroPadded( $day ) { - $this->assertZeroPadded( 'revisionday2', $day ); - } - - # revision month - - /** @dataProvider provideMonths */ - public function testRevisionmonthIsZeroPadded( $month ) { - $this->assertZeroPadded( 'revisionmonth', $month ); - } - - /** @dataProvider provideMonths */ - public function testRevisionmonthoneIsUnPadded( $month ) { - $this->assertUnPadded( 'revisionmonth1', $month ); - } - - /** - * Rough tests for {{SERVERNAME}} magic word - * Bug 31176 - * @group Database - * @dataProvider provideDataServernameFromDifferentProtocols - */ - public function testServernameFromDifferentProtocols( $server ) { - $this->setMwGlobals( 'wgServer', $server ); - - $this->assertMagic( 'localhost', 'servername' ); - } - - 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 ) { - $this->assertMagicPadding( $magic, $value, '%02d' ); - } - - /** assertion helper expecting a magic output which is unpadded */ - public function assertUnPadded( $magic, $value ) { - $this->assertMagicPadding( $magic, $value, '%d' ); - } - - /** - * Main assertion helper for magic variables padding - * @param $magic string Magic variable name - * @param $value mixed Month or day - * @param $format string sprintf format for $value - */ - private function assertMagicPadding( $magic, $value, $format ) { - # Initialize parser timestamp as year 2010 at 12h34 56s. - # month and day are given by the caller ($value). Month < 12! - if ( $value > 12 ) { - $month = $value % 12; - } else { - $month = $value; - } - - $this->setParserTS( - sprintf( '2010%02d%02d123456', $month, $value ) - ); - - # please keep the following commented line of code. It helps debugging. - //print "\nDEBUG (value $value):" . sprintf( '2010%02d%02d123456', $value, $value ) . "\n"; - - # format expectation and test it - $expected = sprintf( $format, $value ); - $this->assertMagic( $expected, $magic ); - } - - /** helper to set the parser timestamp and revision timestamp */ - private function setParserTS( $ts ) { - $this->testParser->Options()->setTimestamp( $ts ); - $this->testParser->mRevisionTimestamp = $ts; - } - - /** - * Assertion helper to test a magic variable output - */ - private function assertMagic( $expected, $magic ) { - if ( in_array( $magic, $this->expectedAsInteger ) ) { - $expected = (int)$expected; - } - - # Generate a message for the assertion - $msg = sprintf( "Magic %s should be <%s:%s>", - $magic, - $expected, - gettype( $expected ) - ); - - $this->assertSame( - $expected, - $this->testParser->getVariableValue( $magic ), - $msg - ); - } -} diff --git a/tests/phpunit/includes/parser/MediaWikiParserTest.php b/tests/phpunit/includes/parser/MediaWikiParserTest.php deleted file mode 100644 index c120ca34..00000000 --- a/tests/phpunit/includes/parser/MediaWikiParserTest.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php -require_once __DIR__ . '/NewParserTest.php'; - -/** - * The UnitTest must be either a class that inherits from MediaWikiTestCase - * or a class that provides a public static suite() method which returns - * an PHPUnit_Framework_Test object - * - * @group Parser - * @group Database - */ -class MediaWikiParserTest { - - /** - * @defgroup filtering_constants Filtering constants - * - * Limit inclusion of parser tests files coming from MediaWiki core - * @{ - */ - - /** Include files shipped with MediaWiki core */ - const CORE_ONLY = 1; - /** Include non core files as set in $wgParserTestFiles */ - const NO_CORE = 2; - /** Include anything set via $wgParserTestFiles */ - const WITH_ALL = 3; # CORE_ONLY | NO_CORE - - /** @} */ - - /** - * Get a PHPUnit test suite of parser tests. Optionally filtered with - * $flags. - * - * @par Examples: - * Get a suite of parser tests shipped by MediaWiki core: - * @code - * MediaWikiParserTest::suite( MediaWikiParserTest::CORE_ONLY ); - * @endcode - * Get a suite of various parser tests, like extensions: - * @code - * MediaWikiParserTest::suite( MediaWikiParserTest::NO_CORE ); - * @endcode - * Get any test defined via $wgParserTestFiles: - * @code - * MediaWikiParserTest::suite( MediaWikiParserTest::WITH_ALL ); - * @endcode - * - * @param $flags bitwise flag to filter out the $wgParserTestFiles that - * will be included. Default: MediaWikiParserTest::CORE_ONLY - * - * @return PHPUnit_Framework_TestSuite - */ - public static function suite( $flags = self::CORE_ONLY ) { - if ( is_string( $flags ) ) { - $flags = self::CORE_ONLY; - } - global $wgParserTestFiles, $IP; - - $mwTestDir = $IP . '/tests/'; - - # Human friendly helpers - $wantsCore = ( $flags & self::CORE_ONLY ); - $wantsRest = ( $flags & self::NO_CORE ); - - # Will hold the .txt parser test files we will include - $filesToTest = array(); - - # Filter out .txt files - foreach ( $wgParserTestFiles as $parserTestFile ) { - $isCore = ( 0 === strpos( $parserTestFile, $mwTestDir ) ); - - if ( $isCore && $wantsCore ) { - self::debug( "included core parser tests: $parserTestFile" ); - $filesToTest[] = $parserTestFile; - } elseif ( !$isCore && $wantsRest ) { - self::debug( "included non core parser tests: $parserTestFile" ); - $filesToTest[] = $parserTestFile; - } else { - self::debug( "skipped parser tests: $parserTestFile" ); - } - } - self::debug( 'parser tests files: ' - . implode( ' ', $filesToTest ) ); - - $suite = new PHPUnit_Framework_TestSuite; - foreach ( $filesToTest as $fileName ) { - $testsName = basename( $fileName, '.txt' ); - $escapedFileName = strtr( $fileName, array( "'" => "\\'", '\\' => '\\\\' ) ); - /* This used to be ucfirst( basename( dirname( $filename ) ) ) - * and then was ucfirst( basename( $filename, '.txt' ) - * but that didn't work with names like foo.tests.txt - */ - $parserTestClassName = str_replace( '.', '_', ucfirst( $testsName ) ); - $parserTestClassDefinition = <<<EOT -/** - * @group Database - * @group Parser - * @group ParserTests - * @group ParserTests_$parserTestClassName - */ -class $parserTestClassName extends NewParserTest { - protected \$file = '$escapedFileName'; -} -EOT; - - 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 deleted file mode 100644 index eac4de5c..00000000 --- a/tests/phpunit/includes/parser/NewParserTest.php +++ /dev/null @@ -1,969 +0,0 @@ -<?php - -/** - * Although marked as a stub, can work independently. - * - * @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 - /* The data provider is run on a different instance than the test, so it must be static - * When running tests from several files, all tests will see all articles. - */ - static protected $backendToUse; - - public $keepUploads = false; - public $runDisabled = false; - public $runParsoid = false; - public $regex = ''; - public $showProgress = true; - public $savedWeirdGlobals = array(); - public $savedGlobals = array(); - public $hooks = array(); - public $functionHooks = array(); - - //Fuzz test - public $maxFuzzTestLength = 300; - public $fuzzSeed = 0; - public $memoryLimit = 50; - - protected $file = false; - - public static function setUpBeforeClass() { - // Inject ParserTest well-known interwikis - ParserTest::setupInterwikis(); - } - - protected function setUp() { - global $wgNamespaceAliases, $wgContLang; - global $wgHooks, $IP; - - parent::setUp(); - - //Setup CLI arguments - if ( $this->getCliArg( 'regex=' ) ) { - $this->regex = $this->getCliArg( 'regex=' ); - } else { - # Matches anything - $this->regex = ''; - } - - $this->keepUploads = $this->getCliArg( 'keep-uploads' ); - - $tmpGlobals = array(); - - $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['wgActionPaths'] = array(); - $tmpGlobals['wgVariantArticlePath'] = false; - $tmpGlobals['wgExtensionAssetsPath'] = '/extensions'; - $tmpGlobals['wgStylePath'] = '/skins'; - $tmpGlobals['wgEnableUploads'] = true; - $tmpGlobals['wgThumbnailScriptPath'] = false; - $tmpGlobals['wgLocalFileRepo'] = array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => 'local-backend' - ); - $tmpGlobals['wgForeignFileRepos'] = array(); - $tmpGlobals['wgDefaultExternalStore'] = array(); - $tmpGlobals['wgEnableParserCache'] = false; - $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['wgGroupPermissions'] = array( - '*' => array( - 'createaccount' => true, - 'read' => true, - 'edit' => true, - 'createpage' => true, - 'createtalk' => true, - ) ); - $tmpGlobals['wgNamespaceProtection'] = array( NS_MEDIAWIKI => 'editinterface' ); - - $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'; - - $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' ); - - $this->setMwGlobals( $tmpGlobals ); - - $this->savedWeirdGlobals['image_alias'] = $wgNamespaceAliases['Image']; - $this->savedWeirdGlobals['image_talk_alias'] = $wgNamespaceAliases['Image_talk']; - - $wgNamespaceAliases['Image'] = NS_FILE; - $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - - MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache - $wgContLang->resetNamespaces(); # reset namespace cache - } - - protected function tearDown() { - global $wgNamespaceAliases, $wgContLang; - - $wgNamespaceAliases['Image'] = $this->savedWeirdGlobals['image_alias']; - $wgNamespaceAliases['Image_talk'] = $this->savedWeirdGlobals['image_talk_alias']; - - // Restore backends - 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'; - # disabled for performance - #$this->tablesUsed[] = 'image'; - - # Update certain things in site_stats - $this->db->insert( 'site_stats', - array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ), - __METHOD__ - ); - - $user = User::newFromId( 0 ); - LinkCache::singleton()->clear(); # Avoids the odd failure at creating the nullRevision - - # Upload DB table entries for files. - # 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( - '', // archive name - 'Upload of some lame file', - 'Some lame file', - array( - 'size' => 7881, - 'width' => 1941, - 'height' => 220, - 'bits' => 8, - 'media_type' => MEDIATYPE_BITMAP, - 'mime' => 'image/jpeg', - 'metadata' => serialize( array() ), - '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() ) ) ) { - $image->recordUpload2( - '', // archive name - 'zomgnotcensored', - 'Borderline image', - array( - 'size' => 12345, - 'width' => 320, - 'height' => 240, - 'bits' => 24, - 'media_type' => MEDIATYPE_BITMAP, - 'mime' => 'image/jpeg', - 'metadata' => serialize( array() ), - '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 - - /** - * Set up the global variables for a consistent environment for each test. - * Ideally this should replace the global configuration entirely. - */ - protected function setupGlobals( $opts = array(), $config = '' ) { - global $wgFileBackends; - # Find out values for some special options. - $lang = - self::getOptionValue( 'language', $opts, 'en' ); - $variant = - self::getOptionValue( 'variant', $opts, false ); - $maxtoclevel = - self::getOptionValue( 'wgMaxTocLevel', $opts, 999 ); - $linkHolderBatchSize = - self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 ); - - $uploadDir = $this->getUploadDir(); - if ( $this->getCliArg( 'use-filebackend=' ) ) { - if ( self::$backendToUse ) { - $backend = self::$backendToUse; - } else { - $name = $this->getCliArg( 'use-filebackend=' ); - $useConfig = array(); - foreach ( $wgFileBackends as $conf ) { - if ( $conf['name'] == $name ) { - $useConfig = $conf; - } - } - $useConfig['name'] = 'local-backend'; // swap name - $class = $conf['class']; - self::$backendToUse = new $class( $useConfig ); - $backend = self::$backendToUse; - } - } else { - # 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( - 'local-public' => "$uploadDir", - 'local-thumb' => "$uploadDir/thumb", - ) - ) ); - } - - $settings = array( - 'wgLocalFileRepo' => array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => $backend - ), - 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ), - 'wgLanguageCode' => $lang, - 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'unittest_' : 'ut_', - 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ), - 'wgNamespacesWithSubpages' => array( NS_MAIN => isset( $opts['subpage'] ) ), - 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ), - 'wgMaxTocLevel' => $maxtoclevel, - 'wgUseTeX' => isset( $opts['math'] ) || isset( $opts['texvc'] ), - 'wgMathDirectory' => $uploadDir . '/math', - 'wgDefaultLanguageVariant' => $variant, - 'wgLinkHolderBatchSize' => $linkHolderBatchSize, - ); - - if ( $config ) { - $configLines = explode( "\n", $config ); - - foreach ( $configLines as $line ) { - list( $var, $value ) = explode( '=', $line, 2 ); - - $settings[$var] = eval( "return $value;" ); //??? - } - } - - $this->savedGlobals = array(); - - /** @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]; - } - - $GLOBALS[$var] = $val; - } - - MagicWord::clearCache(); - - # The entries saved into RepoGroup cache with previous globals will be wrong. - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - - # Create dummy files in storage - $this->setupUploads(); - - # Publish the articles after we have the final language set - $this->publishTestArticles(); - - MessageCache::destroyInstance(); - - return $context; - } - - /** - * Get an FS upload directory (only applies to FSFileBackend) - * - * @return String: the directory - */ - protected function getUploadDir() { - if ( $this->keepUploads ) { - $dir = wfTempDir() . '/mwParser-images'; - - if ( is_dir( $dir ) ) { - return $dir; - } - } else { - $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; - } - - // wfDebug( "Creating upload directory $dir\n" ); - if ( file_exists( $dir ) ) { - wfDebug( "Already exists!\n" ); - - return $dir; - } - - return $dir; - } - - /** - * Create a dummy uploads directory which will contain a couple - * of files in order to pass existence tests. - * - * @return String: the directory - */ - protected function setupUploads() { - global $IP; - - $base = $this->getBaseDir(); - $backend = RepoGroup::singleton()->getLocalRepo()->getBackend(); - $backend->prepare( array( 'dir' => "$base/local-public/3/3a" ) ); - $backend->store( array( - 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/3/3a/Foobar.jpg" - ) ); - $backend->prepare( array( 'dir' => "$base/local-public/e/ea" ) ); - $backend->store( array( - 'src' => "$IP/skins/monobook/wiki.png", 'dst' => "$base/local-public/e/ea/Thumb.png" - ) ); - $backend->prepare( array( 'dir' => "$base/local-public/0/09" ) ); - $backend->store( array( - 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/0/09/Bad.jpg" - ) ); - - // No helpful SVG file to copy, so make one ourselves - $tmpDir = wfTempDir(); - $tempFsFile = new TempFSFile( "$tmpDir/Foobar.svg" ); - $tempFsFile->autocollect(); // destroy file when $tempFsFile leaves scope - file_put_contents( "$tmpDir/Foobar.svg", - '<?xml version="1.0" encoding="utf-8"?>' . - '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><text>Foo</text></svg>' ); - - $backend->prepare( array( 'dir' => "$base/local-public/f/ff" ) ); - $backend->quickStore( array( - 'src' => "$tmpDir/Foobar.svg", 'dst' => "$base/local-public/f/ff/Foobar.svg" - ) ); - } - - /** - * Restore default values and perform any necessary clean-up - * after each test runs. - */ - protected function teardownGlobals() { - $this->teardownUploads(); - - foreach ( $this->savedGlobals as $var => $val ) { - $GLOBALS[$var] = $val; - } - } - - /** - * Remove the dummy uploads directory - */ - private function teardownUploads() { - if ( $this->keepUploads ) { - 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( - array( - "$base/local-public/3/3a/Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/20px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/270px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/300px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/30px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/360px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/400px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/40px-Foobar.jpg", - "$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-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", - ) - ); - } - - /** - * Delete the specified files, if they exist. - * @param $files Array: full paths to files to delete. - */ - private static function deleteFiles( $files ) { - $backend = RepoGroup::singleton()->getLocalRepo()->getBackend(); - foreach ( $files as $file ) { - $backend->delete( array( 'src' => $file ), array( 'force' => 1 ) ); - } - foreach ( $files as $file ) { - $tmp = $file; - while ( $tmp = FileBackend::parentStoragePath( $tmp ) ) { - if ( !$backend->clean( array( 'dir' => $tmp ) )->isOK() ) { - break; - } - } - } - } - - protected function getBaseDir() { - return 'mwstore://local-backend'; - } - - public function parserTestProvider() { - if ( $this->file === false ) { - global $wgParserTestFiles; - $this->file = $wgParserTestFiles[0]; - } - - return new TestFileIterator( $this->file, $this ); - } - - /** - * Set the file from whose tests will be run by this instance - */ - public function setParserTestFile( $filename ) { - $this->file = $filename; - } - - /** - * @group medium - * @dataProvider parserTestProvider - */ - public function testParserTest( $desc, $input, $result, $opts, $config ) { - if ( $this->regex != '' && !preg_match( '/' . $this->regex . '/', $desc ) ) { - $this->assertTrue( true ); // XXX: don't flood output with "test made no assertions" - //$this->markTestSkipped( 'Filtered out by the user' ); - return; - } - - 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 - // $wgtContentModelUseDB is false. - $this->markTestSkipped( "Main namespace does not support wikitext," - . "skipping parser test: $desc" ); - } - - wfDebug( "Running parser test: $desc\n" ); - - $opts = $this->parseOptions( $opts ); - $context = $this->setupGlobals( $opts, $config ); - - $user = $context->getUser(); - $options = ParserOptions::newFromContext( $context ); - - if ( isset( $opts['title'] ) ) { - $titleText = $opts['title']; - } else { - $titleText = 'Parser test'; - } - - $local = isset( $opts['local'] ); - $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null; - $parser = $this->getParser( $preprocessor ); - - $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'] ) ) { - $out = $parser->transformMsg( $input, $options, $title ); - } elseif ( isset( $opts['section'] ) ) { - $section = $opts['section']; - $out = $parser->getSection( $input, $section ); - } elseif ( isset( $opts['replace'] ) ) { - $section = $opts['replace'][0]; - $replace = $opts['replace'][1]; - $out = $parser->replaceSection( $input, $section, $replace ); - } elseif ( isset( $opts['comment'] ) ) { - $out = Linker::formatComment( $input, $title, $local ); - } elseif ( isset( $opts['preload'] ) ) { - $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'] ) ) { - if ( $output->getTitleText() ) { - $title = $output->getTitleText(); - } - - $out = "$title\n$out"; - } - - if ( isset( $opts['ill'] ) ) { - $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) ); - } elseif ( isset( $opts['cat'] ) ) { - $outputPage = $context->getOutput(); - $outputPage->addCategoryLinks( $output->getCategories() ); - $cats = $outputPage->getCategoryLinks(); - - if ( isset( $cats['normal'] ) ) { - $out = $this->tidy( implode( ' ', $cats['normal'] ) ); - } else { - $out = ''; - } - } - $parser->mPreprocessor = null; - - $result = $this->tidy( $result ); - } - - $this->teardownGlobals(); - - $this->assertEquals( $result, $out, $desc ); - } - - /** - * Run a fuzz test series - * Draw input from a set of test files - * - * @todo fixme Needs some work to not eat memory until the world explodes - * - * @group ParserFuzz - */ - public function testFuzzTests() { - global $wgParserTestFiles; - - $files = $wgParserTestFiles; - - if ( $this->getCliArg( 'file=' ) ) { - $files = array( $this->getCliArg( 'file=' ) ); - } - - $dict = $this->getFuzzInput( $files ); - $dictSize = strlen( $dict ); - $logMaxLength = log( $this->maxFuzzTestLength ); - - ini_set( 'memory_limit', $this->memoryLimit * 1048576 ); - - $user = new User; - $opts = ParserOptions::newFromUser( $user ); - $title = Title::makeTitle( NS_MAIN, 'Parser_test' ); - - $id = 1; - - while ( true ) { - - // Generate test input - mt_srand( ++$this->fuzzSeed ); - $totalLength = mt_rand( 1, $this->maxFuzzTestLength ); - $input = ''; - - while ( strlen( $input ) < $totalLength ) { - $logHairLength = mt_rand( 0, 1000000 ) / 1000000 * $logMaxLength; - $hairLength = min( intval( exp( $logHairLength ) ), $dictSize ); - $offset = mt_rand( 0, $dictSize - $hairLength ); - $input .= substr( $dict, $offset, $hairLength ); - } - - $this->setupGlobals(); - $parser = $this->getParser(); - - // Run the test - try { - $parser->parse( $input, $title, $opts ); - $this->assertTrue( true, "Test $id, fuzz seed {$this->fuzzSeed}" ); - } catch ( Exception $exception ) { - $input_dump = sprintf( "string(%d) \"%s\"\n", strlen( $input ), $input ); - - $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(); - $parser->__destruct(); - - if ( $id % 100 == 0 ) { - $usage = intval( memory_get_usage( true ) / $this->memoryLimit / 1048576 * 100 ); - //echo "{$this->fuzzSeed}: $numSuccess/$numTotal (mem: $usage%)\n"; - if ( $usage > 90 ) { - $ret = "Out of memory:\n"; - $memStats = $this->getMemoryBreakdown(); - - foreach ( $memStats as $name => $usage ) { - $ret .= "$name: $usage\n"; - } - - throw new MWException( $ret ); - } - } - - $id++; - } - } - - //Various getter functions - - /** - * Get an input dictionary from a set of parser test files - */ - function getFuzzInput( $filenames ) { - $dict = ''; - - foreach ( $filenames as $filename ) { - $contents = file_get_contents( $filename ); - preg_match_all( '/!!\s*input\n(.*?)\n!!\s*result/s', $contents, $matches ); - - foreach ( $matches[1] as $match ) { - $dict .= $match . "\n"; - } - } - - return $dict; - } - - /** - * Get a memory usage breakdown - */ - function getMemoryBreakdown() { - $memStats = array(); - - foreach ( $GLOBALS as $name => $value ) { - $memStats['$' . $name] = strlen( serialize( $value ) ); - } - - $classes = get_declared_classes(); - - foreach ( $classes as $class ) { - $rc = new ReflectionClass( $class ); - $props = $rc->getStaticProperties(); - $memStats[$class] = strlen( serialize( $props ) ); - $methods = $rc->getMethods(); - - foreach ( $methods as $method ) { - $memStats[$class] += strlen( serialize( $method->getStaticVariables() ) ); - } - } - - $functions = get_defined_functions(); - - foreach ( $functions['user'] as $function ) { - $rf = new ReflectionFunction( $function ); - $memStats["$function()"] = strlen( serialize( $rf->getStaticVariables() ) ); - } - - asort( $memStats ); - - return $memStats; - } - - /** - * Get a Parser object - */ - function getParser( $preprocessor = null ) { - global $wgParserConf; - - $class = $wgParserConf['class']; - $parser = new $class( array( 'preprocessorClass' => $preprocessor ) + $wgParserConf ); - - wfRunHooks( 'ParserTestParser', array( &$parser ) ); - - return $parser; - } - - //Various action functions - - public function addArticle( $name, $text, $line ) { - self::$articles[$name] = array( $text, $line ); - } - - public function publishTestArticles() { - if ( empty( self::$articles ) ) { - return; - } - - foreach ( self::$articles as $name => $info ) { - list( $text, $line ) = $info; - ParserTest::addArticle( $name, $text, $line, 'ignoreduplicate' ); - } - } - - /** - * Steal a callback function from the primary parser, save it for - * application to our scary parser. If the hook is not installed, - * abort processing of this file. - * - * @param $name String - * @return Bool true if tag hook is present - */ - public function requireHook( $name ) { - global $wgParser; - $wgParser->firstCallInit(); // make sure hooks are loaded. - return isset( $wgParser->mTagHooks[$name] ); - } - - public function requireFunctionHook( $name ) { - global $wgParser; - $wgParser->firstCallInit(); // make sure hooks are loaded. - return isset( $wgParser->mFunctionHooks[$name] ); - } - - //Various "cleanup" functions - - /** - * Run the "tidy" command on text if the $wgUseTidy - * global is true - * - * @param $text String: the text to tidy - * @return String - */ - protected function tidy( $text ) { - global $wgUseTidy; - - if ( $wgUseTidy ) { - $text = MWTidy::tidy( $text ); - } - - return $text; - } - - /** - * Remove last character if it is a newline - */ - public function removeEndingNewline( $s ) { - if ( substr( $s, -1 ) === "\n" ) { - return substr( $s, 0, -1 ); - } else { - return $s; - } - } - - //Test options parser functions - - protected function parseOptions( $instring ) { - $opts = array(); - // foo - // foo=bar - // foo="bar baz" - // foo=[[bar baz]] - // foo=bar,"baz quux" - $regex = '/\b - ([\w-]+) # Key - \b - (?:\s* - = # First sub-value - \s* - ( - " - [^"]* # Quoted val - " - | - \[\[ - [^]]* # Link target - \]\] - | - [\w-]+ # Plain word - ) - (?:\s* - , # Sub-vals 1..N - \s* - ( - "[^"]*" # Quoted val - | - \[\[[^]]*\]\] # Link target - | - [\w-]+ # Plain word - ) - )* - )? - /x'; - - if ( preg_match_all( $regex, $instring, $matches, PREG_SET_ORDER ) ) { - foreach ( $matches as $bits ) { - array_shift( $bits ); - $key = strtolower( array_shift( $bits ) ); - if ( count( $bits ) == 0 ) { - $opts[$key] = true; - } elseif ( count( $bits ) == 1 ) { - $opts[$key] = $this->cleanupOption( array_shift( $bits ) ); - } else { - // Array! - $opts[$key] = array_map( array( $this, 'cleanupOption' ), $bits ); - } - } - } - - return $opts; - } - - protected function cleanupOption( $opt ) { - if ( substr( $opt, 0, 1 ) == '"' ) { - return substr( $opt, 1, -1 ); - } - - if ( substr( $opt, 0, 2 ) == '[[' ) { - return substr( $opt, 2, -2 ); - } - - return $opt; - } - - /** - * Use a regex to find out the value of an option - * @param $key String: name of option val to retrieve - * @param $opts Options array to look in - * @param $default Mixed: default value returned if not found - */ - protected static function getOptionValue( $key, $opts, $default ) { - $key = strtolower( $key ); - - if ( isset( $opts[$key] ) ) { - return $opts[$key]; - } else { - return $default; - } - } -} diff --git a/tests/phpunit/includes/parser/ParserMethodsTest.php b/tests/phpunit/includes/parser/ParserMethodsTest.php deleted file mode 100644 index e5c5cb21..00000000 --- a/tests/phpunit/includes/parser/ParserMethodsTest.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php - -class ParserMethodsTest extends MediaWikiLangTestCase { - - public static function providePreSaveTransform() { - return array( - array( 'hello this is ~~~', - "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]", - ), - array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - 'hello \'\'this\'\' is <nowiki>~~~</nowiki>', - ), - ); - } - - /** - * @dataProvider providePreSaveTransform - * @covers Parser::preSaveTransform - */ - public function testPreSaveTransform( $text, $expected ) { - global $wgParser; - - $title = Title::newFromText( str_replace( '::', '__', __METHOD__ ) ); - $user = new User(); - $user->setName( "127.0.0.1" ); - $popts = ParserOptions::newFromUser( $user ); - $text = $wgParser->preSaveTransform( $text, $title, $user, $popts ); - - $this->assertEquals( $expected, $text ); - } - - /** - * @covers Parser::callParserFunction - */ - public function testCallParserFunction() { - global $wgParser; - - // Normal parses test passing PPNodes. Test passing an array. - $title = Title::newFromText( str_replace( '::', '__', __METHOD__ ) ); - $wgParser->startExternalParse( $title, new ParserOptions(), Parser::OT_HTML ); - $frame = $wgParser->getPreprocessor()->newFrame(); - $ret = $wgParser->callParserFunction( $frame, '#tag', - array( 'pre', 'foo', 'style' => 'margin-left: 1.6em' ) - ); - $ret['text'] = $wgParser->mStripState->unstripBoth( $ret['text'] ); - $this->assertSame( array( - 'found' => true, - 'text' => '<pre style="margin-left: 1.6em">foo</pre>', - ), $ret, 'callParserFunction works for {{#tag:pre|foo|style=margin-left: 1.6em}}' ); - } - - /** - * @covers Parser::parse - * @covers ParserOutput::getSections - */ - public function testGetSections() { - global $wgParser; - - $title = Title::newFromText( str_replace( '::', '__', __METHOD__ ) ); - $out = $wgParser->parse( "==foo==\n<h2>bar</h2>\n==baz==\n", $title, new ParserOptions() ); - $this->assertSame( array( - array( - 'toclevel' => 1, - 'level' => '2', - 'line' => 'foo', - 'number' => '1', - 'index' => '1', - 'fromtitle' => $title->getPrefixedDBkey(), - 'byteoffset' => 0, - 'anchor' => 'foo', - ), - array( - 'toclevel' => 1, - 'level' => '2', - 'line' => 'bar', - 'number' => '2', - 'index' => '', - 'fromtitle' => false, - 'byteoffset' => null, - 'anchor' => 'bar', - ), - array( - 'toclevel' => 1, - 'level' => '2', - 'line' => 'baz', - 'number' => '3', - 'index' => '2', - 'fromtitle' => $title->getPrefixedDBkey(), - 'byteoffset' => 21, - 'anchor' => 'baz', - ), - ), $out->getSections(), 'getSections() with proper value when <h2> is used' ); - } - //@Todo Add tests for cleanSig() / cleanSigInSig(), getSection(), replaceSection(), getPreloadText() -} diff --git a/tests/phpunit/includes/parser/ParserOutputTest.php b/tests/phpunit/includes/parser/ParserOutputTest.php deleted file mode 100644 index c73666da..00000000 --- a/tests/phpunit/includes/parser/ParserOutputTest.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -class ParserOutputTest extends MediaWikiTestCase { - - public static function provideIsLinkInternal() { - return array( - // Different domains - array( false, 'http://example.org', 'http://mediawiki.org' ), - // Same domains - array( true, 'http://example.org', 'http://example.org' ), - array( true, 'https://example.org', 'https://example.org' ), - array( true, '//example.org', '//example.org' ), - // Same domain different cases - array( true, 'http://example.org', 'http://EXAMPLE.ORG' ), - // Paths, queries, and fragments are not relevant - array( true, 'http://example.org', 'http://example.org/wiki/Main_Page' ), - array( true, 'http://example.org', 'http://example.org?my=query' ), - array( true, 'http://example.org', 'http://example.org#its-a-fragment' ), - // Different protocols - array( false, 'http://example.org', 'https://example.org' ), - array( false, 'https://example.org', 'http://example.org' ), - // Protocol relative servers always match http and https links - array( true, '//example.org', 'http://example.org' ), - array( true, '//example.org', 'https://example.org' ), - // But they don't match strange things like this - array( false, '//example.org', 'irc://example.org' ), - ); - } - - /** - * Test to make sure ParserOutput::isLinkInternal behaves properly - * @dataProvider provideIsLinkInternal - * @covers ParserOutput::isLinkInternal - */ - 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(); - - $po->setExtensionData( "one", "Foo" ); - - $this->assertEquals( "Foo", $po->getExtensionData( "one" ) ); - $this->assertNull( $po->getExtensionData( "spam" ) ); - - $po->setExtensionData( "two", "Bar" ); - $this->assertEquals( "Foo", $po->getExtensionData( "one" ) ); - $this->assertEquals( "Bar", $po->getExtensionData( "two" ) ); - - $po->setExtensionData( "one", null ); - $this->assertNull( $po->getExtensionData( "one" ) ); - $this->assertEquals( "Bar", $po->getExtensionData( "two" ) ); - } -} diff --git a/tests/phpunit/includes/parser/ParserPreloadTest.php b/tests/phpunit/includes/parser/ParserPreloadTest.php deleted file mode 100644 index d12fee36..00000000 --- a/tests/phpunit/includes/parser/ParserPreloadTest.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php -/** - * Basic tests for Parser::getPreloadText - * @author Antoine Musso - */ -class ParserPreloadTest extends MediaWikiTestCase { - /** - * @var Parser - */ - private $testParser; - /** - * @var ParserOptions - */ - private $testParserOptions; - /** - * @var Title - */ - private $title; - - protected function setUp() { - global $wgContLang; - - parent::setUp(); - $this->testParserOptions = ParserOptions::newFromUserAndLang( new User, $wgContLang ); - - $this->testParser = new Parser(); - $this->testParser->Options( $this->testParserOptions ); - $this->testParser->clearState(); - - $this->title = Title::newFromText( 'Preload Test' ); - } - - protected function tearDown() { - parent::tearDown(); - - unset( $this->testParser ); - unset( $this->title ); - } - - /** - * @covers Parser::getPreloadText - */ - public function testPreloadSimpleText() { - $this->assertPreloaded( 'simple', 'simple' ); - } - - /** - * @covers Parser::getPreloadText - */ - public function testPreloadedPreIsUnstripped() { - $this->assertPreloaded( - '<pre>monospaced</pre>', - '<pre>monospaced</pre>', - '<pre> in preloaded text must be unstripped (bug 27467)' - ); - } - - /** - * @covers Parser::getPreloadText - */ - public function testPreloadedNowikiIsUnstripped() { - $this->assertPreloaded( - '<nowiki>[[Dummy title]]</nowiki>', - '<nowiki>[[Dummy title]]</nowiki>', - '<nowiki> in preloaded text must be unstripped (bug 27467)' - ); - } - - protected function assertPreloaded( $expected, $text, $msg = '' ) { - $this->assertEquals( - $expected, - $this->testParser->getPreloadText( - $text, - $this->title, - $this->testParserOptions - ), - $msg - ); - } -} diff --git a/tests/phpunit/includes/parser/PreprocessorTest.php b/tests/phpunit/includes/parser/PreprocessorTest.php deleted file mode 100644 index 8aee937c..00000000 --- a/tests/phpunit/includes/parser/PreprocessorTest.php +++ /dev/null @@ -1,239 +0,0 @@ -<?php - -class PreprocessorTest extends MediaWikiTestCase { - protected $mTitle = 'Page title'; - protected $mPPNodeCount = 0; - /** - * @var ParserOptions - */ - protected $mOptions; - /** - * @var Preprocessor - */ - protected $mPreprocessor; - - protected function setUp() { - global $wgParserConf, $wgContLang; - parent::setUp(); - $this->mOptions = ParserOptions::newFromUserAndLang( new User, $wgContLang ); - $name = isset( $wgParserConf['preprocessorClass'] ) ? $wgParserConf['preprocessorClass'] : 'Preprocessor_DOM'; - - $this->mPreprocessor = new $name( $this ); - } - - function getStripList() { - return array( 'gallery', 'display map' /* Used by Maps, see r80025 CR */, '/foo' ); - } - - public static function provideCases() { - return array( - array( "Foo", "<root>Foo</root>" ), - array( "<!-- Foo -->", "<root><comment><!-- Foo --></comment></root>" ), - array( "<!-- Foo --><!-- Bar -->", "<root><comment><!-- Foo --></comment><comment><!-- Bar --></comment></root>" ), - array( "<!-- Foo --> <!-- Bar -->", "<root><comment><!-- Foo --></comment> <comment><!-- Bar --></comment></root>" ), - array( "<!-- Foo --> \n <!-- Bar -->", "<root><comment><!-- Foo --></comment> \n <comment><!-- Bar --></comment></root>" ), - array( "<!-- Foo --> \n <!-- Bar -->\n", "<root><comment><!-- Foo --></comment> \n<comment> <!-- Bar -->\n</comment></root>" ), - array( "<!-- Foo --> <!-- Bar -->\n", "<root><comment><!-- Foo --></comment> <comment><!-- Bar --></comment>\n</root>" ), - array( "<!-->Bar", "<root><comment><!-->Bar</comment></root>" ), - array( "<!-- Comment -- comment", "<root><comment><!-- Comment -- comment</comment></root>" ), - array( "== Foo ==\n <!-- Bar -->\n== Baz ==\n", "<root><h level=\"2\" i=\"1\">== Foo ==</h>\n<comment> <!-- Bar -->\n</comment><h level=\"2\" i=\"2\">== Baz ==</h>\n</root>" ), - array( "<gallery/>", "<root><ext><name>gallery</name><attr></attr></ext></root>" ), - array( "Foo <gallery/> Bar", "<root>Foo <ext><name>gallery</name><attr></attr></ext> Bar</root>" ), - array( "<gallery></gallery>", "<root><ext><name>gallery</name><attr></attr><inner></inner><close></gallery></close></ext></root>" ), - array( "<foo> <gallery></gallery>", "<root><foo> <ext><name>gallery</name><attr></attr><inner></inner><close></gallery></close></ext></root>" ), - array( "<foo> <gallery><gallery></gallery>", "<root><foo> <ext><name>gallery</name><attr></attr><inner><gallery></inner><close></gallery></close></ext></root>" ), - array( "<noinclude> Foo bar </noinclude>", "<root><ignore><noinclude></ignore> Foo bar <ignore></noinclude></ignore></root>" ), - array( "<noinclude>\n{{Foo}}\n</noinclude>", "<root><ignore><noinclude></ignore>\n<template lineStart=\"1\"><title>Foo</title></template>\n<ignore></noinclude></ignore></root>" ), - array( "<noinclude>\n{{Foo}}\n</noinclude>\n", "<root><ignore><noinclude></ignore>\n<template lineStart=\"1\"><title>Foo</title></template>\n<ignore></noinclude></ignore>\n</root>" ), - array( "<gallery>foo bar", "<root><ext><name>gallery</name><attr></attr><inner>foo bar</inner></ext></root>" ), - array( "<{{foo}}>", "<root><<template><title>foo</title></template>></root>" ), - array( "<{{{foo}}}>", "<root><<tplarg><title>foo</title></tplarg>></root>" ), - array( "<gallery></gallery</gallery>", "<root><ext><name>gallery</name><attr></attr><inner></gallery</inner><close></gallery></close></ext></root>" ), - array( "=== Foo === ", "<root><h level=\"3\" i=\"1\">=== Foo === </h></root>" ), - array( "==<!-- -->= Foo === ", "<root><h level=\"2\" i=\"1\">==<comment><!-- --></comment>= Foo === </h></root>" ), - array( "=== Foo ==<!-- -->= ", "<root><h level=\"1\" i=\"1\">=== Foo ==<comment><!-- --></comment>= </h></root>" ), - array( "=== Foo ===<!-- -->\n", "<root><h level=\"3\" i=\"1\">=== Foo ===<comment><!-- --></comment></h>\n</root>" ), - array( "=== Foo ===<!-- --> <!-- -->\n", "<root><h level=\"3\" i=\"1\">=== Foo ===<comment><!-- --></comment> <comment><!-- --></comment></h>\n</root>" ), - array( "== Foo ==\n== Bar == \n", "<root><h level=\"2\" i=\"1\">== Foo ==</h>\n<h level=\"2\" i=\"2\">== Bar == </h>\n</root>" ), - array( "===========", "<root><h level=\"5\" i=\"1\">===========</h></root>" ), - array( "Foo\n=\n==\n=\n", "<root>Foo\n=\n==\n=\n</root>" ), - array( "{{Foo}}", "<root><template><title>Foo</title></template></root>" ), - array( "\n{{Foo}}", "<root>\n<template lineStart=\"1\"><title>Foo</title></template></root>" ), - array( "{{Foo|bar}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template></root>" ), - array( "{{Foo|bar}}a", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template>a</root>" ), - array( "{{Foo|bar|baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></template></root>" ), - array( "{{Foo|1=bar}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part></template></root>" ), - array( "{{Foo|=bar}}", "<root><template><title>Foo</title><part><name></name>=<value>bar</value></part></template></root>" ), - array( "{{Foo|bar=baz}}", "<root><template><title>Foo</title><part><name>bar</name>=<value>baz</value></part></template></root>" ), - array( "{{Foo|{{bar}}=baz}}", "<root><template><title>Foo</title><part><name><template><title>bar</title></template></name>=<value>baz</value></part></template></root>" ), - array( "{{Foo|1=bar|baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name index=\"1\" /><value>baz</value></part></template></root>" ), - array( "{{Foo|1=bar|2=baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name>2</name>=<value>baz</value></part></template></root>" ), - array( "{{Foo|bar|foo=baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name>foo</name>=<value>baz</value></part></template></root>" ), - array( "{{{1}}}", "<root><tplarg><title>1</title></tplarg></root>" ), - array( "{{{1|}}}", "<root><tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ), - array( "{{{Foo}}}", "<root><tplarg><title>Foo</title></tplarg></root>" ), - array( "{{{Foo|}}}", "<root><tplarg><title>Foo</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ), - array( "{{{Foo|bar|baz}}}", "<root><tplarg><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></tplarg></root>" ), - array( "{<!-- -->{Foo}}", "<root>{<comment><!-- --></comment>{Foo}}</root>" ), - array( "{{{{Foobar}}}}", "<root>{<tplarg><title>Foobar</title></tplarg>}</root>" ), - array( "{{{ {{Foo}} }}}", "<root><tplarg><title> <template><title>Foo</title></template> </title></tplarg></root>" ), - array( "{{ {{{Foo}}} }}", "<root><template><title> <tplarg><title>Foo</title></tplarg> </title></template></root>" ), - array( "{{{{{Foo}}}}}", "<root><template><title><tplarg><title>Foo</title></tplarg></title></template></root>" ), - array( "{{{{{Foo}} }}}", "<root><tplarg><title><template><title>Foo</title></template> </title></tplarg></root>" ), - array( "{{{{{{Foo}}}}}}", "<root><tplarg><title><tplarg><title>Foo</title></tplarg></title></tplarg></root>" ), - array( "{{{{{{Foo}}}}}", "<root>{<template><title><tplarg><title>Foo</title></tplarg></title></template></root>" ), - array( "[[[Foo]]", "<root>[[[Foo]]</root>" ), - array( "{{Foo|[[[[bar]]|baz]]}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>[[[[bar]]|baz]]</value></part></template></root>" ), // This test is important, since it means the difference between having the [[ rule stacked or not - array( "{{Foo|[[[[bar]|baz]]}}", "<root>{{Foo|[[[[bar]|baz]]}}</root>" ), - array( "{{Foo|Foo [[[[bar]|baz]]}}", "<root>{{Foo|Foo [[[[bar]|baz]]}}</root>" ), - array( "Foo <display map>Bar</display map >Baz", "<root>Foo <ext><name>display map</name><attr></attr><inner>Bar</inner><close></display map ></close></ext>Baz</root>" ), - array( "Foo <display map foo>Bar</display map >Baz", "<root>Foo <ext><name>display map</name><attr> foo</attr><inner>Bar</inner><close></display map ></close></ext>Baz</root>" ), - array( "Foo <gallery bar=\"baz\" />", "<root>Foo <ext><name>gallery</name><attr> bar="baz" </attr></ext></root>" ), - array( "Foo <gallery bar=\"1\" baz=2 />", "<root>Foo <ext><name>gallery</name><attr> bar="1" baz=2 </attr></ext></root>" ), - array( "</foo>Foo<//foo>", "<root><ext><name>/foo</name><attr></attr><inner>Foo</inner><close><//foo></close></ext></root>" ), # Worth blacklisting IMHO - array( "{{#ifexpr: ({{{1|1}}} = 2) | Foo | Bar }}", "<root><template><title>#ifexpr: (<tplarg><title>1</title><part><name index=\"1\" /><value>1</value></part></tplarg> = 2) </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>" ), - array( "{{#if: {{{1|}}} | Foo | {{Bar}} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> <template><title>Bar</title></template> </value></part></template></root>" ), - array( "{{#if: {{{1|}}} | Foo | [[Bar]] }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> [[Bar]] </value></part></template></root>" ), - array( "{{#if: {{{1|}}} | [[Foo]] | Bar }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> [[Foo]] </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>" ), - array( "{{#if: {{{1|}}} | 1 | {{#if: {{{1|}}} | 2 | 3 }} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 1 </value></part><part><name index=\"2\" /><value> <template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 2 </value></part><part><name index=\"2\" /><value> 3 </value></part></template> </value></part></template></root>" ), - array( "{{ {{Foo}}", "<root>{{ <template><title>Foo</title></template></root>" ), - array( "{{Foobar {{Foo}} {{Bar}} {{Baz}} ", "<root>{{Foobar <template><title>Foo</title></template> <template><title>Bar</title></template> <template><title>Baz</title></template> </root>" ), - array( "[[Foo]] |", "<root>[[Foo]] |</root>" ), - array( "{{Foo|Bar|", "<root>{{Foo|Bar|</root>" ), - array( "[[Foo]", "<root>[[Foo]</root>" ), - array( "[[Foo|Bar]", "<root>[[Foo|Bar]</root>" ), - array( "{{Foo| [[Bar] }}", "<root>{{Foo| [[Bar] }}</root>" ), - array( "{{Foo| [[Bar|Baz] }}", "<root>{{Foo| [[Bar|Baz] }}</root>" ), - array( "{{Foo|bar=[[baz]}}", "<root>{{Foo|bar=[[baz]}}</root>" ), - array( "{{foo|", "<root>{{foo|</root>" ), - array( "{{foo|}", "<root>{{foo|}</root>" ), - array( "{{foo|} }}", "<root><template><title>foo</title><part><name index=\"1\" /><value>} </value></part></template></root>" ), - array( "{{foo|bar=|}", "<root>{{foo|bar=|}</root>" ), - array( "{{Foo|} Bar=", "<root>{{Foo|} Bar=</root>" ), - array( "{{Foo|} Bar=}}", "<root><template><title>Foo</title><part><name>} Bar</name>=<value></value></part></template></root>" ), - /* array( file_get_contents( __DIR__ . '/QuoteQuran.txt' ), file_get_contents( __DIR__ . '/QuoteQuranExpanded.txt' ) ), */ - ); - } - - /** - * Get XML preprocessor tree from the preprocessor (which may not be the - * native XML-based one). - * - * @param string $wikiText - * @return string - */ - protected function preprocessToXml( $wikiText ) { - if ( method_exists( $this->mPreprocessor, 'preprocessToXml' ) ) { - return $this->normalizeXml( $this->mPreprocessor->preprocessToXml( $wikiText ) ); - } - - $dom = $this->mPreprocessor->preprocessToObj( $wikiText ); - if ( is_callable( array( $dom, 'saveXML' ) ) ) { - return $dom->saveXML(); - } else { - return $this->normalizeXml( $dom->__toString() ); - } - } - - /** - * Normalize XML string to the form that a DOMDocument saves out. - * - * @param string $xml - * @return string - */ - protected function normalizeXml( $xml ) { - return preg_replace( '!<([a-z]+)/>!', '<$1></$1>', str_replace( ' />', '/>', $xml ) ); - } - - /** - * @dataProvider provideCases - * @covers Preprocessor_DOM::preprocessToXml - */ - public function testPreprocessorOutput( $wikiText, $expectedXml ) { - $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) ); - } - - /** - * These are more complex test cases taken out of wiki articles. - */ - 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 - array( "All_system_messages" ), # http://tl.wiktionary.org/w/index.php?title=Suleras:All_system_messages&oldid=2765 GPL text generated by MediaWiki - array( "Fundraising" ), # http://tl.wiktionary.org/w/index.php?title=MediaWiki:Sitenotice&oldid=5716 GFDL + CC-BY-SA, copied there by Sky Harbor. - array( "NestedTemplates" ), # bug 27936 - ); - } - - /** - * @dataProvider provideFiles - * @covers Preprocessor_DOM::preprocessToXml - */ - public function testPreprocessorOutputFiles( $filename ) { - $folder = __DIR__ . "/../../../parser/preprocess"; - $wikiText = file_get_contents( "$folder/$filename.txt" ); - $output = $this->preprocessToXml( $wikiText ); - - $expectedFilename = "$folder/$filename.expected"; - if ( file_exists( $expectedFilename ) ) { - $expectedXml = $this->normalizeXml( file_get_contents( $expectedFilename ) ); - $this->assertEquals( $expectedXml, $output ); - } else { - $tempFilename = tempnam( $folder, "$filename." ); - file_put_contents( $tempFilename, $output ); - $this->markTestIncomplete( "File $expectedFilename missing. Output stored as $tempFilename" ); - } - } - - /** - * Tests from Bug 28642 · https://bugzilla.wikimedia.org/28642 - */ - public static function provideHeadings() { - return array( /* These should become headings: */ - array( "== h ==<!--c1-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment></h></root>" ), - array( "== h == <!--c1-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment></h></root>" ), - array( "== h ==<!--c1--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> </h></root>" ), - array( "== h == <!--c1--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> </h></root>" ), - array( "== h ==<!--c1--><!--c2-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment><comment><!--c2--></comment></h></root>" ), - array( "== h == <!--c1--><!--c2-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment><comment><!--c2--></comment></h></root>" ), - array( "== h ==<!--c1--><!--c2--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment><comment><!--c2--></comment> </h></root>" ), - array( "== h == <!--c1--><!--c2--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment><comment><!--c2--></comment> </h></root>" ), - array( "== h == <!--c1--> <!--c2-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment></h></root>" ), - array( "== h ==<!--c1--> <!--c2--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment> </h></root>" ), - array( "== h == <!--c1--> <!--c2--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment> </h></root>" ), - array( "== h ==<!--c1--><!--c2--><!--c3-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment></h></root>" ), - array( "== h ==<!--c1--> <!--c2--><!--c3-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment><comment><!--c3--></comment></h></root>" ), - array( "== h ==<!--c1--><!--c2--> <!--c3-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment><comment><!--c2--></comment> <comment><!--c3--></comment></h></root>" ), - array( "== h ==<!--c1--> <!--c2--> <!--c3-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment> <comment><!--c3--></comment></h></root>" ), - array( "== h == <!--c1--><!--c2--><!--c3-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment></h></root>" ), - array( "== h == <!--c1--> <!--c2--><!--c3-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment><comment><!--c3--></comment></h></root>" ), - array( "== h == <!--c1--><!--c2--> <!--c3-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment><comment><!--c2--></comment> <comment><!--c3--></comment></h></root>" ), - array( "== h == <!--c1--> <!--c2--> <!--c3-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment> <comment><!--c3--></comment></h></root>" ), - array( "== h ==<!--c1--><!--c2--><!--c3--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment> </h></root>" ), - array( "== h ==<!--c1--> <!--c2--><!--c3--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment><comment><!--c3--></comment> </h></root>" ), - array( "== h ==<!--c1--><!--c2--> <!--c3--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment><comment><!--c2--></comment> <comment><!--c3--></comment> </h></root>" ), - array( "== h ==<!--c1--> <!--c2--> <!--c3--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment> <comment><!--c3--></comment> </h></root>" ), - array( "== h == <!--c1--><!--c2--><!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment> </h></root>" ), - array( "== h == <!--c1--> <!--c2--><!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment><comment><!--c3--></comment> </h></root>" ), - array( "== h == <!--c1--><!--c2--> <!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment><comment><!--c2--></comment> <comment><!--c3--></comment> </h></root>" ), - array( "== h == <!--c1--> <!--c2--> <!--c3--> ", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment> <comment><!--c3--></comment> </h></root>" ), - array( "== h ==<!--c1--> <!--c2-->", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment></h></root>" ), - array( "== h == <!--c1--> <!--c2-->", "<root><h level=\"2\" i=\"1\">== h == <comment><!--c1--></comment> <comment><!--c2--></comment></h></root>" ), - array( "== h ==<!--c1--> <!--c2--> ", "<root><h level=\"2\" i=\"1\">== h ==<comment><!--c1--></comment> <comment><!--c2--></comment> </h></root>" ), - - /* These are not working: */ - array( "== h == x <!--c1--><!--c2--><!--c3--> ", "<root>== h == x <comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment> </root>" ), - array( "== h ==<!--c1--> x <!--c2--><!--c3--> ", "<root>== h ==<comment><!--c1--></comment> x <comment><!--c2--></comment><comment><!--c3--></comment> </root>" ), - array( "== h ==<!--c1--><!--c2--><!--c3--> x ", "<root>== h ==<comment><!--c1--></comment><comment><!--c2--></comment><comment><!--c3--></comment> x </root>" ), - ); - } - - /** - * @dataProvider provideHeadings - * @covers Preprocessor_DOM::preprocessToXml - */ - 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 deleted file mode 100644 index 61cbe45d..00000000 --- a/tests/phpunit/includes/parser/TagHooksTest.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php - -/** - * @group Parser - */ -class TagHookTest extends MediaWikiTestCase { - public static function provideValidNames() { - return array( array( 'foo' ), array( 'foo-bar' ), array( 'foo_bar' ), array( 'FOO-BAR' ), array( 'foo bar' ) ); - } - - public static function provideBadNames() { - return array( array( "foo<bar" ), array( "foo>bar" ), array( "foo\nbar" ), array( "foo\rbar" ) ); - } - - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( 'wgAlwaysUseTidy', false ); - } - - /** - * @dataProvider provideValidNames - */ - public function testTagHooks( $tag ) { - global $wgParserConf, $wgContLang; - $parser = new Parser( $wgParserConf ); - - $parser->setHook( $tag, array( $this, 'tagCallback' ) ); - $parserOutput = $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) ); - $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() ); - - $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle - } - - /** - * @dataProvider provideBadNames - * @expectedException MWException - */ - public function testBadTagHooks( $tag ) { - global $wgParserConf, $wgContLang; - $parser = new Parser( $wgParserConf ); - - $parser->setHook( $tag, array( $this, 'tagCallback' ) ); - $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) ); - $this->fail( 'Exception not thrown.' ); - } - - /** - * @dataProvider provideValidNames - */ - public function testFunctionTagHooks( $tag ) { - global $wgParserConf, $wgContLang; - $parser = new Parser( $wgParserConf ); - - $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), 0 ); - $parserOutput = $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) ); - $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() ); - - $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle - } - - /** - * @dataProvider provideBadNames - * @expectedException MWException - */ - public function testBadFunctionTagHooks( $tag ) { - global $wgParserConf, $wgContLang; - $parser = new Parser( $wgParserConf ); - - $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), SFH_OBJECT_ARGS ); - $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) ); - $this->fail( 'Exception not thrown.' ); - } - - function tagCallback( $text, $params, $parser ) { - return str_rot13( $text ); - } - - function functionTagCallback( &$parser, $frame, $code, $attribs ) { - return str_rot13( $code ); - } -} diff --git a/tests/phpunit/includes/parser/TidyTest.php b/tests/phpunit/includes/parser/TidyTest.php deleted file mode 100644 index 57a88b9d..00000000 --- a/tests/phpunit/includes/parser/TidyTest.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -/** - * @group Parser - */ -class TidyTest extends MediaWikiTestCase { - public function setUp() { - parent::setUp(); - $check = MWTidy::tidy( '' ); - if ( strpos( $check, '<!--' ) !== false ) { - $this->markTestSkipped( 'Tidy not found' ); - } - } - - /** - * @dataProvider provideTestWrapping - */ - public function testTidyWrapping( $expected, $text, $msg = '' ) { - $text = MWTidy::tidy( $text ); - // We don't care about where Tidy wants to stick is <p>s - $text = trim( preg_replace( '#</?p>#', '', $text ) ); - // Windows, we love you! - $text = str_replace( "\r", '', $text ); - $this->assertEquals( $expected, $text, $msg ); - } - - public function provideTestWrapping() { - return array( - array( - '<mw:editsection page="foo" section="bar">foo</mw:editsection>', - '<mw:editsection page="foo" section="bar">foo</mw:editsection>', - '<mw:editsection> should survive tidy' - ), - array( - '<editsection page="foo" section="bar">foo</editsection>', - '<editsection page="foo" section="bar">foo</editsection>', - '<editsection> should survive tidy' - ), - array( '<mw:toc>foo</mw:toc>', '<mw:toc>foo</mw:toc>', '<mw:toc> should survive tidy' ), - array( "<link foo=\"bar\" />\nfoo", '<link foo="bar"/>foo', '<link> should survive tidy' ), - array( "<meta foo=\"bar\" />\nfoo", '<meta foo="bar"/>foo', '<meta> should survive tidy' ), - ); - } -}
\ No newline at end of file diff --git a/tests/phpunit/includes/search/SearchEngineTest.php b/tests/phpunit/includes/search/SearchEngineTest.php deleted file mode 100644 index 87067038..00000000 --- a/tests/phpunit/includes/search/SearchEngineTest.php +++ /dev/null @@ -1,176 +0,0 @@ -<?php - -/** - * @group Search - * @group Database - */ -class SearchEngineTest extends MediaWikiLangTestCase { - protected $search, $pageList; - - /** - * Checks for database type & version. - * Will skip current test if DB does not support search. - */ - protected function setUp() { - parent::setUp(); - - // Search tests require MySQL or SQLite with FTS - # Get database type and version - $dbType = $this->db->getType(); - $dbSupported = - ( $dbType === 'mysql' ) - || ( $dbType === 'sqlite' && $this->db->getFulltextSearchModule() == 'FTS3' ); - - if ( !$dbSupported ) { - $this->markTestSkipped( "MySQL or SQLite with FTS3 only" ); - } - - $searchType = $this->db->getSearchEngine(); - $this->search = new $searchType( $this->db ); - } - - protected function tearDown() { - unset( $this->search ); - - parent::tearDown(); - } - - function pageExists( $title ) { - return false; - } - - function addDBData() { - if ( $this->pageExists( 'Not_Main_Page' ) ) { - return; - } - - if ( !$this->isWikitextNS( NS_MAIN ) ) { - // @todo cover the case of non-wikitext content in the main namespace - return; - } - - $this->insertPage( "Not_Main_Page", "This is not a main page", 0 ); - $this->insertPage( 'Talk:Not_Main_Page', 'This is not a talk page to the main page, see [[smithee]]', 1 ); - $this->insertPage( 'Smithee', 'A smithee is one who smiths. See also [[Alan Smithee]]', 0 ); - $this->insertPage( 'Talk:Smithee', 'This article sucks.', 1 ); - $this->insertPage( 'Unrelated_page', 'Nothing in this page is about the S word.', 0 ); - $this->insertPage( 'Another_page', 'This page also is unrelated.', 0 ); - $this->insertPage( 'Help:Help', 'Help me!', 4 ); - $this->insertPage( 'Thppt', 'Blah blah', 0 ); - $this->insertPage( 'Alan_Smithee', 'yum', 0 ); - $this->insertPage( 'Pages', 'are\'food', 0 ); - $this->insertPage( 'HalfOneUp', 'AZ', 0 ); - $this->insertPage( 'FullOneUp', 'AZ', 0 ); - $this->insertPage( 'HalfTwoLow', 'az', 0 ); - $this->insertPage( 'FullTwoLow', 'az', 0 ); - $this->insertPage( 'HalfNumbers', '1234567890', 0 ); - $this->insertPage( 'FullNumbers', '1234567890', 0 ); - $this->insertPage( 'DomainName', 'example.com', 0 ); - } - - function fetchIds( $results ) { - if ( !$this->isWikitextNS( NS_MAIN ) ) { - $this->markTestIncomplete( __CLASS__ . " does no yet support non-wikitext content " - . "in the main namespace" ); - } - - $this->assertTrue( is_object( $results ) ); - - $matches = array(); - $row = $results->next(); - while ( $row ) { - $matches[] = $row->getTitle()->getPrefixedText(); - $row = $results->next(); - } - $results->free(); - # Search is not guaranteed to return results in a certain order; - # sort them numerically so we will compare simply that we received - # the expected matches. - sort( $matches ); - - return $matches; - } - - /** - * Insert a new page - * - * @param $pageName String: page name - * @param $text String: page's content - * @param $n Integer: unused - */ - function insertPage( $pageName, $text, $ns ) { - $title = Title::newFromText( $pageName, $ns ); - - $user = User::newFromName( 'WikiSysop' ); - $comment = 'Search Test'; - - // avoid memory leak...? - LinkCache::singleton()->clear(); - - $page = WikiPage::factory( $title ); - $page->doEditContent( ContentHandler::makeContent( $text, $title ), $comment, 0, false, $user ); - - $this->pageList[] = array( $title, $page->getId() ); - - return true; - } - - public function testFullWidth() { - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'AZ' ) ), - "Search for normalized from Half-width Upper" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'az' ) ), - "Search for normalized from Half-width Lower" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'AZ' ) ), - "Search for normalized from Full-width Upper" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'az' ) ), - "Search for normalized from Full-width Lower" ); - } - - public function testTextSearch() { - $this->assertEquals( - array( 'Smithee' ), - $this->fetchIds( $this->search->searchText( 'smithee' ) ), - "Plain search failed" ); - } - - public function testTextPowerSearch() { - $this->search->setNamespaces( array( 0, 1, 4 ) ); - $this->assertEquals( - array( - 'Smithee', - 'Talk:Not Main Page', - ), - $this->fetchIds( $this->search->searchText( 'smithee' ) ), - "Power search failed" ); - } - - public function testTitleSearch() { - $this->assertEquals( - array( - 'Alan Smithee', - 'Smithee', - ), - $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), - "Title search failed" ); - } - - public function testTextTitlePowerSearch() { - $this->search->setNamespaces( array( 0, 1, 4 ) ); - $this->assertEquals( - array( - 'Alan Smithee', - 'Smithee', - 'Talk:Smithee', - ), - $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 deleted file mode 100644 index 2f4fd501..00000000 --- a/tests/phpunit/includes/search/SearchUpdateTest.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -class MockSearch extends SearchEngine { - public static $id; - public static $title; - public static $text; - - public function __construct( $db ) { - } - - public function update( $id, $title, $text ) { - self::$id = $id; - self::$title = $title; - self::$text = $text; - } -} - -/** - * @group Search - * @group Database - */ -class SearchUpdateTest extends MediaWikiTestCase { - - protected function setUp() { - parent::setUp(); - $this->setMwGlobals( 'wgSearchType', 'MockSearch' ); - } - - function updateText( $text ) { - return trim( SearchUpdate::updateText( $text ) ); - } - - public function testUpdateText() { - $this->assertEquals( - 'test', - $this->updateText( '<div>TeSt</div>' ), - 'HTML stripped, text lowercased' - ); - - $this->assertEquals( - 'foo bar boz quux', - $this->updateText( <<<EOT -<table style="color:red; font-size:100px"> - <tr class="scary"><td><div>foo</div></td><tr>bar</td></tr> - <tr><td>boz</td><tr>quux</td></tr> -</table> -EOT - ), 'Stripping HTML tables' ); - - $this->assertEquals( - 'a b', - $this->updateText( 'a > b' ), - 'Handle unclosed tags' - ); - - $text = str_pad( "foo <barbarbar \n", 10000, 'x' ); - - $this->assertNotEquals( - '', - $this->updateText( $text ), - 'Bug 18609' - ); - } - - public function testBug32712() { - $text = "text „http://example.com“ text"; - $result = $this->updateText( $text ); - $processed = preg_replace( '/Q/u', 'Q', $result ); - $this->assertTrue( - $processed != '', - 'Link surrounded by unicode quotes should not fail UTF-8 validation' - ); - } -} diff --git a/tests/phpunit/includes/site/MediaWikiSiteTest.php b/tests/phpunit/includes/site/MediaWikiSiteTest.php deleted file mode 100644 index c5d52d33..00000000 --- a/tests/phpunit/includes/site/MediaWikiSiteTest.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php - -/** - * Tests for the MediaWikiSite class. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class MediaWikiSiteTest extends SiteTest { - - public function testNormalizePageTitle() { - $site = new MediaWikiSite(); - $site->setGlobalId( 'enwiki' ); - - //NOTE: this does not actually call out to the enwiki site to perform the normalization, - // but uses a local Title object to do so. This is hardcoded on SiteLink::normalizePageTitle - // for the case that MW_PHPUNIT_TEST is set. - $this->assertEquals( 'Foo', $site->normalizePageName( ' foo ' ) ); - } - - public function fileUrlProvider() { - return array( - // url, filepath, path arg, expected - array( 'https://en.wikipedia.org', '/w/$1', 'api.php', 'https://en.wikipedia.org/w/api.php' ), - array( 'https://en.wikipedia.org', '/w/', 'api.php', 'https://en.wikipedia.org/w/' ), - array( 'https://en.wikipedia.org', '/foo/page.php?name=$1', 'api.php', 'https://en.wikipedia.org/foo/page.php?name=api.php' ), - array( 'https://en.wikipedia.org', '/w/$1', '', 'https://en.wikipedia.org/w/' ), - array( 'https://en.wikipedia.org', '/w/$1', 'foo/bar/api.php', 'https://en.wikipedia.org/w/foo/bar/api.php' ), - ); - } - - /** - * @dataProvider fileUrlProvider - * @covers MediaWikiSite::getFileUrl - */ - public function testGetFileUrl( $url, $filePath, $pathArgument, $expected ) { - $site = new MediaWikiSite(); - $site->setFilePath( $url . $filePath ); - - $this->assertEquals( $expected, $site->getFileUrl( $pathArgument ) ); - } - - public static function provideGetPageUrl() { - return array( - // path, page, expected substring - array( 'http://acme.test/wiki/$1', 'Berlin', '/wiki/Berlin' ), - array( 'http://acme.test/wiki/', 'Berlin', '/wiki/' ), - array( 'http://acme.test/w/index.php?title=$1', 'Berlin', '/w/index.php?title=Berlin' ), - array( 'http://acme.test/wiki/$1', '', '/wiki/' ), - array( 'http://acme.test/wiki/$1', 'Berlin/sub page', '/wiki/Berlin/sub_page' ), - array( 'http://acme.test/wiki/$1', 'Cork (city) ', '/Cork_(city)' ), - array( 'http://acme.test/wiki/$1', 'M&M', '/wiki/M%26M' ), - ); - } - - /** - * @dataProvider provideGetPageUrl - * @covers MediaWikiSite::getPageUrl - */ - public function testGetPageUrl( $path, $page, $expected ) { - $site = new MediaWikiSite(); - $site->setLinkPath( $path ); - - $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 deleted file mode 100644 index 8af2fc1b..00000000 --- a/tests/phpunit/includes/site/SiteListTest.php +++ /dev/null @@ -1,197 +0,0 @@ -<?php - -/** - * Tests for the SiteList class. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class SiteListTest extends MediaWikiTestCase { - - /** - * Returns instances of SiteList implementing objects. - * @return array - */ - public function siteListProvider() { - $sitesArrays = $this->siteArrayProvider(); - - $listInstances = array(); - - foreach ( $sitesArrays as $sitesArray ) { - $listInstances[] = new SiteList( $sitesArray[0] ); - } - - return $this->arrayWrap( $listInstances ); - } - - /** - * Returns arrays with instances of Site implementing objects. - * @return array - */ - public function siteArrayProvider() { - $sites = TestSites::getSites(); - - $siteArrays = array(); - - $siteArrays[] = $sites; - - $siteArrays[] = array( array_shift( $sites ) ); - - $siteArrays[] = array( array_shift( $sites ), array_shift( $sites ) ); - - return $this->arrayWrap( $siteArrays ); - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::isEmpty - */ - public function testIsEmpty( SiteList $sites ) { - $this->assertEquals( count( $sites ) === 0, $sites->isEmpty() ); - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::getSite - */ - public function testGetSiteByGlobalId( SiteList $sites ) { - if ( $sites->isEmpty() ) { - $this->assertTrue( true ); - } else { - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - $this->assertEquals( $site, $sites->getSite( $site->getGlobalId() ) ); - } - } - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::getSiteByInternalId - */ - public function testGetSiteByInternalId( $sites ) { - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - if ( is_integer( $site->getInternalId() ) ) { - $this->assertEquals( $site, $sites->getSiteByInternalId( $site->getInternalId() ) ); - } - } - - $this->assertTrue( true ); - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::hasSite - */ - public function testHasGlobalId( $sites ) { - $this->assertFalse( $sites->hasSite( 'non-existing-global-id' ) ); - $this->assertFalse( $sites->hasInternalId( 720101010 ) ); - - if ( !$sites->isEmpty() ) { - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - $this->assertTrue( $sites->hasSite( $site->getGlobalId() ) ); - } - } - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::hasInternalId - */ - public function testHasInternallId( $sites ) { - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - if ( is_integer( $site->getInternalId() ) ) { - $this->assertTrue( $site, $sites->hasInternalId( $site->getInternalId() ) ); - } - } - - $this->assertFalse( $sites->hasInternalId( -1 ) ); - } - - /** - * @dataProvider siteListProvider - * @param SiteList $sites - * @covers SiteList::getGlobalIdentifiers - */ - public function testGetGlobalIdentifiers( SiteList $sites ) { - $identifiers = $sites->getGlobalIdentifiers(); - - $this->assertTrue( is_array( $identifiers ) ); - - $expected = array(); - - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - $expected[] = $site->getGlobalId(); - } - - $this->assertArrayEquals( $expected, $identifiers ); - } - - /** - * @dataProvider siteListProvider - * - * @since 1.21 - * - * @param SiteList $list - * @covers SiteList::getSerializationData - * @covers SiteList::unserialize - */ - public function testSerialization( SiteList $list ) { - $serialization = serialize( $list ); - /** - * @var SiteArray $copy - */ - $copy = unserialize( $serialization ); - - $this->assertArrayEquals( $list->getGlobalIdentifiers(), $copy->getGlobalIdentifiers() ); - - /** - * @var Site $site - */ - foreach ( $list as $site ) { - $this->assertTrue( $copy->hasInternalId( $site->getInternalId() ) ); - } - } -} diff --git a/tests/phpunit/includes/site/SiteSQLStoreTest.php b/tests/phpunit/includes/site/SiteSQLStoreTest.php deleted file mode 100644 index 6002c1a1..00000000 --- a/tests/phpunit/includes/site/SiteSQLStoreTest.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php - -/** - * Tests for the SiteSQLStore class. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * @group Database - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class SiteSQLStoreTest extends MediaWikiTestCase { - - /** - * @covers SiteSQLStore::getSites - */ - public function testGetSites() { - $expectedSites = TestSites::getSites(); - TestSites::insertIntoDb(); - - $store = SiteSQLStore::newInstance(); - - $sites = $store->getSites(); - - $this->assertInstanceOf( 'SiteList', $sites ); - - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - $this->assertInstanceOf( 'Site', $site ); - } - - foreach ( $expectedSites as $site ) { - if ( $site->getGlobalId() !== null ) { - $this->assertTrue( $sites->hasSite( $site->getGlobalId() ) ); - } - } - } - - /** - * @covers SiteSQLStore::saveSites - */ - public function testSaveSites() { - $store = SiteSQLStore::newInstance(); - - $sites = array(); - - $site = new Site(); - $site->setGlobalId( 'ertrywuutr' ); - $site->setLanguageCode( 'en' ); - $sites[] = $site; - - $site = new MediaWikiSite(); - $site->setGlobalId( 'sdfhxujgkfpth' ); - $site->setLanguageCode( 'nl' ); - $sites[] = $site; - - $this->assertTrue( $store->saveSites( $sites ) ); - - $site = $store->getSite( 'ertrywuutr' ); - $this->assertInstanceOf( 'Site', $site ); - $this->assertEquals( 'en', $site->getLanguageCode() ); - $this->assertTrue( is_integer( $site->getInternalId() ) ); - $this->assertTrue( $site->getInternalId() >= 0 ); - - $site = $store->getSite( 'sdfhxujgkfpth' ); - $this->assertInstanceOf( 'Site', $site ); - $this->assertEquals( 'nl', $site->getLanguageCode() ); - $this->assertTrue( is_integer( $site->getInternalId() ) ); - $this->assertTrue( $site->getInternalId() >= 0 ); - } - - /** - * @covers SiteSQLStore::reset - */ - public function testReset() { - $store1 = SiteSQLStore::newInstance(); - $store2 = SiteSQLStore::newInstance(); - - // initialize internal cache - $this->assertGreaterThan( 0, $store1->getSites()->count() ); - $this->assertGreaterThan( 0, $store2->getSites()->count() ); - - // Clear actual data. Will purge the external cache and reset the internal - // cache in $store1, but not the internal cache in store2. - $this->assertTrue( $store1->clear() ); - - // sanity check: $store2 should have a stale cache now - $this->assertNotNull( $store2->getSite( 'enwiki' ) ); - - // purge cache - $store2->reset(); - - // ...now the internal cache of $store2 should be updated and thus empty. - $site = $store2->getSite( 'enwiki' ); - $this->assertNull( $site ); - } - - /** - * @covers SiteSQLStore::clear - */ - public function testClear() { - $store = SiteSQLStore::newInstance(); - $this->assertTrue( $store->clear() ); - - $site = $store->getSite( 'enwiki' ); - $this->assertNull( $site ); - - $sites = $store->getSites(); - $this->assertEquals( 0, $sites->count() ); - } -} diff --git a/tests/phpunit/includes/site/SiteTest.php b/tests/phpunit/includes/site/SiteTest.php deleted file mode 100644 index 29c1ff33..00000000 --- a/tests/phpunit/includes/site/SiteTest.php +++ /dev/null @@ -1,296 +0,0 @@ -<?php - -/** - * Tests for the Site class. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class SiteTest extends MediaWikiTestCase { - - public function instanceProvider() { - return $this->arrayWrap( TestSites::getSites() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getInterwikiIds - */ - public function testGetInterwikiIds( Site $site ) { - $this->assertInternalType( 'array', $site->getInterwikiIds() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getNavigationIds - */ - public function testGetNavigationIds( Site $site ) { - $this->assertInternalType( 'array', $site->getNavigationIds() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::addNavigationId - */ - public function testAddNavigationId( Site $site ) { - $site->addNavigationId( 'foobar' ); - $this->assertTrue( in_array( 'foobar', $site->getNavigationIds(), true ) ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::addInterwikiId - */ - public function testAddInterwikiId( Site $site ) { - $site->addInterwikiId( 'foobar' ); - $this->assertTrue( in_array( 'foobar', $site->getInterwikiIds(), true ) ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getLanguageCode - */ - public function testGetLanguageCode( Site $site ) { - $this->assertTypeOrValue( 'string', $site->getLanguageCode(), null ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::setLanguageCode - */ - public function testSetLanguageCode( Site $site ) { - $site->setLanguageCode( 'en' ); - $this->assertEquals( 'en', $site->getLanguageCode() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::normalizePageName - */ - public function testNormalizePageName( Site $site ) { - $this->assertInternalType( 'string', $site->normalizePageName( 'Foobar' ) ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getGlobalId - */ - public function testGetGlobalId( Site $site ) { - $this->assertTypeOrValue( 'string', $site->getGlobalId(), null ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::setGlobalId - */ - public function testSetGlobalId( Site $site ) { - $site->setGlobalId( 'foobar' ); - $this->assertEquals( 'foobar', $site->getGlobalId() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getType - */ - public function testGetType( Site $site ) { - $this->assertInternalType( 'string', $site->getType() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getPath - */ - public function testGetPath( Site $site ) { - $this->assertTypeOrValue( 'string', $site->getPath( 'page_path' ), null ); - $this->assertTypeOrValue( 'string', $site->getPath( 'file_path' ), null ); - $this->assertTypeOrValue( 'string', $site->getPath( 'foobar' ), null ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::getAllPaths - */ - public function testGetAllPaths( Site $site ) { - $this->assertInternalType( 'array', $site->getAllPaths() ); - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::setPath - * @covers Site::removePath - */ - public function testSetAndRemovePath( Site $site ) { - $count = count( $site->getAllPaths() ); - - $site->setPath( 'spam', 'http://www.wikidata.org/$1' ); - $site->setPath( 'spam', 'http://www.wikidata.org/foo/$1' ); - $site->setPath( 'foobar', 'http://www.wikidata.org/bar/$1' ); - - $this->assertEquals( $count + 2, count( $site->getAllPaths() ) ); - - $this->assertInternalType( 'string', $site->getPath( 'foobar' ) ); - $this->assertEquals( 'http://www.wikidata.org/foo/$1', $site->getPath( 'spam' ) ); - - $site->removePath( 'spam' ); - $site->removePath( 'foobar' ); - - $this->assertEquals( $count, count( $site->getAllPaths() ) ); - - $this->assertNull( $site->getPath( 'foobar' ) ); - $this->assertNull( $site->getPath( 'spam' ) ); - } - - /** - * @covers Site::setLinkPath - */ - public function testSetLinkPath() { - $site = new Site(); - $path = "TestPath/$1"; - - $site->setLinkPath( $path ); - $this->assertEquals( $path, $site->getLinkPath() ); - } - - /** - * @covers Site::getLinkPathType - */ - public function testGetLinkPathType() { - $site = new Site(); - - $path = 'TestPath/$1'; - $site->setLinkPath( $path ); - $this->assertEquals( $path, $site->getPath( $site->getLinkPathType() ) ); - - $path = 'AnotherPath/$1'; - $site->setPath( $site->getLinkPathType(), $path ); - $this->assertEquals( $path, $site->getLinkPath() ); - } - - /** - * @covers Site::setPath - */ - public function testSetPath() { - $site = new Site(); - - $path = 'TestPath/$1'; - $site->setPath( 'foo', $path ); - - $this->assertEquals( $path, $site->getPath( 'foo' ) ); - } - - /** - * @covers Site::setPath - * @covers Site::getProtocol - */ - public function testProtocolRelativePath() { - $site = new Site(); - - $type = $site->getLinkPathType(); - $path = '//acme.com/'; // protocol-relative URL - $site->setPath( $type, $path ); - - $this->assertEquals( '', $site->getProtocol() ); - } - - 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. - // Subclasses need to override this provider appropriately. - - return array( - array( #0 - 'http://acme.test/TestPath/$1', - 'Foo', - '/TestPath/Foo', - ), - array( #1 - 'http://acme.test/TestScript?x=$1&y=bla', - 'Foo', - 'TestScript?x=Foo&y=bla', - ), - array( #2 - 'http://acme.test/TestPath/$1', - 'foo & bar/xyzzy (quux-shmoox?)', - '/TestPath/foo%20%26%20bar%2Fxyzzy%20%28quux-shmoox%3F%29', - ), - ); - } - - /** - * @dataProvider provideGetPageUrl - * @covers Site::getPageUrl - */ - public function testGetPageUrl( $path, $page, $expected ) { - $site = new Site(); - - //NOTE: the assumption that getPageUrl is based on getLinkPath - // is true for Site but not guaranteed for subclasses. - // Subclasses need to override this test case appropriately. - $site->setLinkPath( $path ); - $this->assertContains( $path, $site->getPageUrl() ); - - $this->assertContains( $expected, $site->getPageUrl( $page ) ); - } - - protected function assertTypeOrFalse( $type, $value ) { - if ( $value === false ) { - $this->assertTrue( true ); - } else { - $this->assertInternalType( $type, $value ); - } - } - - /** - * @dataProvider instanceProvider - * @param Site $site - * @covers Site::serialize - * @covers Site::unserialize - */ - public function testSerialization( Site $site ) { - $this->assertInstanceOf( 'Serializable', $site ); - - $serialization = serialize( $site ); - $newInstance = unserialize( $serialization ); - - $this->assertInstanceOf( 'Site', $newInstance ); - - $this->assertEquals( $serialization, serialize( $newInstance ) ); - } -} diff --git a/tests/phpunit/includes/site/TestSites.php b/tests/phpunit/includes/site/TestSites.php deleted file mode 100644 index f224b7d7..00000000 --- a/tests/phpunit/includes/site/TestSites.php +++ /dev/null @@ -1,100 +0,0 @@ -<?php - -/** - * Holds sites for testing purposes. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @since 1.21 - * - * @ingroup Site - * @ingroup Test - * - * @group Site - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroendedauw@gmail.com > - */ -class TestSites { - - /** - * @since 1.21 - * - * @return array - */ - public static function getSites() { - $sites = array(); - - $site = new Site(); - $site->setGlobalId( 'foobar' ); - $sites[] = $site; - - $site = new MediaWikiSite(); - $site->setGlobalId( 'enwiktionary' ); - $site->setGroup( 'wiktionary' ); - $site->setLanguageCode( 'en' ); - $site->addNavigationId( 'enwiktionary' ); - $site->setPath( MediaWikiSite::PATH_PAGE, "https://en.wiktionary.org/wiki/$1" ); - $site->setPath( MediaWikiSite::PATH_FILE, "https://en.wiktionary.org/w/$1" ); - $sites[] = $site; - - $site = new MediaWikiSite(); - $site->setGlobalId( 'dewiktionary' ); - $site->setGroup( 'wiktionary' ); - $site->setLanguageCode( 'de' ); - $site->addInterwikiId( 'dewiktionary' ); - $site->addInterwikiId( 'wiktionaryde' ); - $site->setPath( MediaWikiSite::PATH_PAGE, "https://de.wiktionary.org/wiki/$1" ); - $site->setPath( MediaWikiSite::PATH_FILE, "https://de.wiktionary.org/w/$1" ); - $sites[] = $site; - - $site = new Site(); - $site->setGlobalId( 'spam' ); - $site->setGroup( 'spam' ); - $site->setLanguageCode( 'en' ); - $site->addNavigationId( 'spam' ); - $site->addNavigationId( 'spamz' ); - $site->addInterwikiId( 'spamzz' ); - $site->setLinkPath( "http://spamzz.test/testing/" ); - $sites[] = $site; - - foreach ( array( 'en', 'de', 'nl', 'sv', 'sr', 'no', 'nn' ) as $langCode ) { - $site = new MediaWikiSite(); - $site->setGlobalId( $langCode . 'wiki' ); - $site->setGroup( 'wikipedia' ); - $site->setLanguageCode( $langCode ); - $site->addInterwikiId( $langCode ); - $site->addNavigationId( $langCode ); - $site->setPath( MediaWikiSite::PATH_PAGE, "https://$langCode.wikipedia.org/wiki/$1" ); - $site->setPath( MediaWikiSite::PATH_FILE, "https://$langCode.wikipedia.org/w/$1" ); - $sites[] = $site; - } - - return $sites; - } - - /** - * Inserts sites into the database for the unit tests that need them. - * - * @since 0.1 - */ - public static function insertIntoDb() { - $sitesTable = SiteSQLStore::newInstance(); - $sitesTable->clear(); - $sitesTable->saveSites( TestSites::getSites() ); - } -} diff --git a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php b/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php deleted file mode 100644 index a806b4ac..00000000 --- a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php -/** - * Test class to run the query of most of all our special pages - * - * Copyright © 2011, Antoine Musso - * - * @author Antoine Musso - * @group Database - */ - -if ( !defined( 'MEDIAWIKI' ) ) { - die( 1 ); -} - -global $IP; -require_once "$IP/includes/QueryPage.php"; // Needed to populate $wgQueryPages - -class QueryAllSpecialPagesTest extends MediaWikiTestCase { - - /** List query pages that can not be tested automatically */ - protected $manualTest = array( - 'LinkSearchPage' - ); - - /** - * Pages whose query use the same DB table more than once. - * This is used to skip testing those pages when run against a MySQL backend - * which does not support reopening a temporary table. See upstream bug: - * http://bugs.mysql.com/bug.php?id=10327 - */ - protected $reopensTempTable = array( - 'BrokenRedirects', - ); - - /** - * Initialize all query page objects - */ - function __construct() { - parent::__construct(); - - global $wgQueryPages; - foreach ( $wgQueryPages as $page ) { - $class = $page[0]; - if ( !in_array( $class, $this->manualTest ) ) { - $this->queryPages[$class] = new $class; - } - } - } - - /** - * Test SQL for each of our QueryPages objects - * @group Database - */ - public function testQuerypageSqlQuery() { - global $wgDBtype; - - foreach ( $this->queryPages as $page ) { - - // With MySQL, skips special pages reopening a temporary table - // See http://bugs.mysql.com/bug.php?id=10327 - if ( - $wgDBtype === 'mysql' - && in_array( $page->getName(), $this->reopensTempTable ) - ) { - $this->markTestSkipped( "SQL query for page {$page->getName()} can not be tested on MySQL backend (it reopens a temporary table)" ); - continue; - } - - $msg = "SQL query for page {$page->getName()} should give a result wrapper object"; - - $result = $page->reallyDoQuery( 50 ); - if ( $result instanceof ResultWrapper ) { - $this->assertTrue( true, $msg ); - } else { - $this->assertFalse( false, $msg ); - } - } - } -} diff --git a/tests/phpunit/includes/specials/SpecialPreferencesTest.php b/tests/phpunit/includes/specials/SpecialPreferencesTest.php deleted file mode 100644 index 6c637c65..00000000 --- a/tests/phpunit/includes/specials/SpecialPreferencesTest.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** - * Test class for SpecialPreferences class. - * - * Copyright © 2013, Antoine Musso - * Copyright © 2013, Wikimedia Foundation Inc. - * - */ - -class SpecialPreferencesTest extends MediaWikiTestCase { - - /** - * Make sure a nickname which is longer than $wgMaxSigChars - * is not throwing a fatal error. - * - * Test specifications by Alexandre "ialex" Emsenhuber. - */ - public function testBug41337() { - - // Set a low limit - $this->setMwGlobals( 'wgMaxSigChars', 2 ); - - $user = $this->getMock( 'User' ); - $user->expects( $this->any() ) - ->method( 'isAnon' ) - ->will( $this->returnValue( false ) ); - - # Yeah foreach requires an array, not NULL =( - $user->expects( $this->any() ) - ->method( 'getEffectiveGroups' ) - ->will( $this->returnValue( array() ) ); - - # The mocked user has a long nickname - $user->expects( $this->any() ) - ->method( 'getOption' ) - ->will( $this->returnValueMap( array( - array( 'nickname', null, false, 'superlongnickname' ), - ) - ) ); - - # Validate the mock (FIXME should probably be removed) - $this->assertFalse( $user->isAnon() ); - $this->assertEquals( array(), - $user->getEffectiveGroups() ); - $this->assertEquals( 'superlongnickname', - $user->getOption( 'nickname' ) ); - - # Forge a request to call the special page - $context = new RequestContext(); - $context->setRequest( new FauxRequest() ); - $context->setUser( $user ); - $context->setTitle( Title::newFromText( 'Test' ) ); - - # Do the call, should not spurt a fatal error. - $special = new SpecialPreferences(); - $special->setContext( $context ); - $special->execute( array() ); - } - -} diff --git a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php b/tests/phpunit/includes/specials/SpecialRecentchangesTest.php deleted file mode 100644 index 436eb2e2..00000000 --- a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php +++ /dev/null @@ -1,125 +0,0 @@ -<?php -/** - * Test class for SpecialRecentchanges class - * - * Copyright © 2011, Antoine Musso - * - * @author Antoine Musso - * @group Database - */ -class SpecialRecentchangesTest extends MediaWikiTestCase { - - /** - * @var SpecialRecentChanges - */ - protected $rc; - - /** helper to test SpecialRecentchanges::buildMainQueryConds() */ - private function assertConditions( $expected, $requestOptions = null, $message = '' ) { - $context = new RequestContext; - $context->setRequest( new FauxRequest( $requestOptions ) ); - - # setup the rc object - $this->rc = new SpecialRecentChanges(); - $this->rc->setContext( $context ); - $formOptions = $this->rc->setup( null ); - - # Filter out rc_timestamp conditions which depends on the test runtime - # This condition is not needed as of march 2, 2011 -- hashar - # @todo FIXME: Find a way to generate the correct rc_timestamp - $queryConditions = array_filter( - $this->rc->buildMainQueryConds( $formOptions ), - 'SpecialRecentchangesTest::filterOutRcTimestampCondition' - ); - - $this->assertEquals( - $expected, - $queryConditions, - $message - ); - } - - /** return false if condition begin with 'rc_timestamp ' */ - private static function filterOutRcTimestampCondition( $var ) { - return ( false === strpos( $var, 'rc_timestamp ' ) ); - } - - public function testRcNsFilter() { - $this->assertConditions( - array( # expected - 'rc_bot' => 0, - #0 => "rc_timestamp >= '20110223000000'", - 1 => "rc_namespace = '0'", - ), - array( - 'namespace' => NS_MAIN, - ), - "rc conditions with no options (aka default setting)" - ); - } - - public function testRcNsFilterInversion() { - $this->assertConditions( - array( # expected - #0 => "rc_timestamp >= '20110223000000'", - 'rc_bot' => 0, - 1 => sprintf( "rc_namespace != '%s'", NS_MAIN ), - ), - array( - 'namespace' => NS_MAIN, - 'invert' => 1, - ), - "rc conditions with namespace inverted" - ); - } - - /** - * @bug 2429 - * @dataProvider provideNamespacesAssociations - */ - public function testRcNsFilterAssociation( $ns1, $ns2 ) { - $this->assertConditions( - array( # expected - #0 => "rc_timestamp >= '20110223000000'", - 'rc_bot' => 0, - 1 => sprintf( "(rc_namespace = '%s' OR rc_namespace = '%s')", $ns1, $ns2 ), - ), - array( - 'namespace' => $ns1, - 'associated' => 1, - ), - "rc conditions with namespace inverted" - ); - } - - /** - * @bug 2429 - * @dataProvider provideNamespacesAssociations - */ - public function testRcNsFilterAssociationWithInversion( $ns1, $ns2 ) { - $this->assertConditions( - array( # expected - #0 => "rc_timestamp >= '20110223000000'", - 'rc_bot' => 0, - 1 => sprintf( "(rc_namespace != '%s' AND rc_namespace != '%s')", $ns1, $ns2 ), - ), - array( - 'namespace' => $ns1, - 'associated' => 1, - 'invert' => 1, - ), - "rc conditions with namespace inverted" - ); - } - - /** - * Provides associated namespaces to test recent changes - * namespaces association filtering. - */ - public static function provideNamespacesAssociations() { - return array( # (NS => Associated_NS) - array( NS_MAIN, NS_TALK ), - array( NS_TALK, NS_MAIN ), - ); - } -} diff --git a/tests/phpunit/includes/specials/SpecialSearchTest.php b/tests/phpunit/includes/specials/SpecialSearchTest.php deleted file mode 100644 index 17e883fd..00000000 --- a/tests/phpunit/includes/specials/SpecialSearchTest.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php -/** - * Test class for SpecialSearch class - * Copyright © 2012, Antoine Musso - * - * @author Antoine Musso - * @group Database - */ - -class SpecialSearchTest extends MediaWikiTestCase { - private $search; - - /** - * @covers SpecialSearch::load - * @dataProvider provideSearchOptionsTests - * @param $requested Array Request parameters. For example array( 'ns5' => true, 'ns6' => true). NULL to use default options. - * @param $userOptions Array User options to test with. For example array('searchNs5' => 1 );. NULL to use default options. - * @param $expectedProfile An expected search profile name - * @param $expectedNs Array Expected namespaces - */ - public function testProfileAndNamespaceLoading( - $requested, $userOptions, $expectedProfile, $expectedNS, - $message = 'Profile name and namespaces mismatches!' - ) { - $context = new RequestContext; - $context->setUser( - $this->newUserWithSearchNS( $userOptions ) - ); - /* - $context->setRequest( new FauxRequest( array( - 'ns5'=>true, - 'ns6'=>true, - ) )); - */ - $context->setRequest( new FauxRequest( $requested ) ); - $search = new SpecialSearch(); - $search->setContext( $context ); - $search->load(); - - /** - * Verify profile name and namespace in the same assertion to make - * sure we will be able to fully compare the above code. PHPUnit stop - * after an assertion fail. - */ - $this->assertEquals( - array( /** Expected: */ - 'ProfileName' => $expectedProfile, - 'Namespaces' => $expectedNS, - ) - , array( /** Actual: */ - 'ProfileName' => $search->getProfile(), - 'Namespaces' => $search->getNamespaces(), - ) - , $message - ); - } - - public static function provideSearchOptionsTests() { - $defaultNS = SearchEngine::defaultNamespaces(); - $EMPTY_REQUEST = array(); - $NO_USER_PREF = null; - - return array( - /** - * Parameters: - * <Web Request>, <User options> - * Followed by expected values: - * <ProfileName>, <NSList> - * Then an optional message. - */ - array( - $EMPTY_REQUEST, $NO_USER_PREF, - 'default', $defaultNS, - 'Bug 33270: No request nor user preferences should give default profile' - ), - array( - array( 'ns5' => 1 ), $NO_USER_PREF, - 'advanced', array( 5 ), - 'Web request with specific NS should override user preference' - ), - array( - $EMPTY_REQUEST, array( - 'searchNs2' => 1, - 'searchNs14' => 1, - ) + array_fill_keys( array_map( function ( $ns ) { - return "searchNs$ns"; - }, $defaultNS ), 0 ), - 'advanced', array( 2, 14 ), - 'Bug 33583: search with no option should honor User search preferences' - . ' and have all other namespace disabled' - ), - ); - } - - /** - * Helper to create a new User object with given options - * User remains anonymous though - */ - function newUserWithSearchNS( $opt = null ) { - $u = User::newFromId( 0 ); - if ( $opt === null ) { - return $u; - } - foreach ( $opt as $name => $value ) { - $u->setOption( $name, $value ); - } - - return $u; - } - - /** - * Verify we do not expand search term in <title> on search result page - * https://gerrit.wikimedia.org/r/4841 - */ - public function testSearchTermIsNotExpanded() { - - # Initialize [[Special::Search]] - $search = new SpecialSearch(); - $search->getContext()->setTitle( Title::newFromText( 'Special:Search' ) ); - $search->load(); - - # Simulate a user searching for a given term - $term = '{{SITENAME}}'; - $search->showResults( $term ); - - # Lookup the HTML page title set for that page - $pageTitle = $search - ->getContext() - ->getOutput() - ->getHTMLTitle(); - - # Compare :-] - $this->assertRegExp( - '/' . preg_quote( $term ) . '/', - $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 deleted file mode 100644 index 982b46b2..00000000 --- a/tests/phpunit/includes/upload/UploadBaseTest.php +++ /dev/null @@ -1,147 +0,0 @@ -<?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 deleted file mode 100644 index a75fba69..00000000 --- a/tests/phpunit/includes/upload/UploadFromUrlTest.php +++ /dev/null @@ -1,350 +0,0 @@ -<?php - -/** - * @group Broken - * @group Upload - * @group Database - */ -class UploadFromUrlTest extends ApiTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( array( - 'wgEnableUploads' => true, - 'wgAllowCopyUploads' => true, - 'wgAllowAsyncCopyUploads' => true, - ) ); - wfSetupSession(); - - if ( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ) { - $this->deleteFile( 'UploadFromUrlTest.png' ); - } - } - - protected function doApiRequest( array $params, array $unused = null, $appendModule = false, User $user = null ) { - $sessionId = session_id(); - session_write_close(); - - $req = new FauxRequest( $params, true, $_SESSION ); - $module = new ApiMain( $req, true ); - $module->execute(); - - wfSetupSession( $sessionId ); - - return array( $module->getResultData(), $req ); - } - - /** - * Ensure that the job queue is empty before continuing - */ - public function testClearQueue() { - $job = JobQueueGroup::singleton()->pop(); - while ( $job ) { - $job = JobQueueGroup::singleton()->pop(); - } - $this->assertFalse( $job ); - } - - /** - * @todo Document why we test login, since the $wgUser hack used doesn't - * require login - */ - public function testLogin() { - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => $this->user->userName, - 'lgpassword' => $this->user->passWord ) ); - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( array( - 'action' => 'login', - "lgtoken" => $token, - 'lgname' => $this->user->userName, - 'lgpassword' => $this->user->passWord ) ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "Success", $data[0]['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testSetupUrlDownload( $data ) { - $token = $this->user->getEditToken(); - $exception = false; - - try { - $this->doApiRequest( array( - 'action' => 'upload', - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The token parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "One of the parameters sessionkey, file, url, statuskey is required", - $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://www.example.com/test.png', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The filename parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $this->user->removeGroup( 'sysop' ); - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://www.example.com/test.png', - 'filename' => 'UploadFromUrlTest.png', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "Permission denied", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $this->user->addGroup( 'sysop' ); - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'filename' => 'UploadFromUrlTest.png', - 'token' => $token, - ), $data ); - - $this->assertEquals( $data[0]['upload']['result'], 'Queued', 'Queued upload' ); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertThat( $job, $this->isInstanceOf( 'UploadFromUrlJob' ), 'Queued upload inserted' ); - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testAsyncUpload( $data ) { - $token = $this->user->getEditToken(); - - $this->user->addGroup( 'users' ); - - $data = $this->doAsyncUpload( $token, true ); - $this->assertEquals( $data[0]['upload']['result'], 'Success' ); - $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); - $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testAsyncUploadWarning( $data ) { - $token = $this->user->getEditToken(); - - $this->user->addGroup( 'users' ); - - $data = $this->doAsyncUpload( $token ); - - $this->assertEquals( $data[0]['upload']['result'], 'Warning' ); - $this->assertTrue( isset( $data[0]['upload']['sessionkey'] ) ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'sessionkey' => $data[0]['upload']['sessionkey'], - 'filename' => 'UploadFromUrlTest.png', - 'ignorewarnings' => 1, - 'token' => $token, - ) ); - $this->assertEquals( $data[0]['upload']['result'], 'Success' ); - $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); - $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testSyncDownload( $data ) { - $token = $this->user->getEditToken(); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertFalse( $job, 'Starting with an empty jobqueue' ); - - $this->user->addGroup( 'users' ); - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'ignorewarnings' => true, - 'token' => $token, - ), $data ); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertFalse( $job ); - - $this->assertEquals( 'Success', $data[0]['upload']['result'] ); - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - public function testLeaveMessage() { - $token = $this->user->user->getEditToken(); - - $talk = $this->user->user->getTalkPage(); - if ( $talk->exists() ) { - $page = WikiPage::factory( $talk ); - $page->doDeleteArticle( '' ); - } - - $this->assertFalse( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk does not exist' ); - - $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - 'leavemessage' => 1, - 'ignorewarnings' => 1, - ) ); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) ); - $job->run(); - - $this->assertTrue( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); - $this->assertTrue( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk exists' ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - $talkRev = Revision::newFromTitle( $talk ); - $talkSize = $talkRev->getSize(); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - 'leavemessage' => 1, - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( 'Using leavemessage without ignorewarnings is not supported', $e->getMessage() ); - } - $this->assertTrue( $exception ); - - $job = JobQueueGroup::singleton()->pop(); - $this->assertFalse( $job ); - - return; - /* - // Broken until using leavemessage with ignorewarnings is supported - $job->run(); - - $this->assertFalse( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); - - $talkRev = Revision::newFromTitle( $talk ); - $this->assertTrue( $talkRev->getSize() > $talkSize, 'New message left' ); - */ - } - - /** - * Helper function to perform an async upload, execute the job and fetch - * the status - * - * @return array The result of action=upload&statuskey=key - */ - private function doAsyncUpload( $token, $ignoreWarnings = false, $leaveMessage = false ) { - $params = array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - ); - if ( $ignoreWarnings ) { - $params['ignorewarnings'] = 1; - } - if ( $leaveMessage ) { - $params['leavemessage'] = 1; - } - - $data = $this->doApiRequest( $params ); - $this->assertEquals( $data[0]['upload']['result'], 'Queued' ); - $this->assertTrue( isset( $data[0]['upload']['statuskey'] ) ); - $statusKey = $data[0]['upload']['statuskey']; - - $job = JobQueueGroup::singleton()->pop(); - $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) ); - - $status = $job->run(); - $this->assertTrue( $status ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'statuskey' => $statusKey, - 'token' => $token, - ) ); - - return $data; - } - - /** - * - */ - protected function deleteFile( $name ) { - $t = Title::newFromText( $name, NS_FILE ); - $this->assertTrue( $t->exists(), "File '$name' exists" ); - - if ( $t->exists() ) { - $file = wfFindFile( $name, array( 'ignoreRedirect' => true ) ); - $empty = ""; - FileDeleteForm::doDelete( $t, $file, $empty, "none", true ); - $page = WikiPage::factory( $t ); - $page->doDeleteArticle( "testing" ); - } - $t = Title::newFromText( $name, NS_FILE ); - - $this->assertFalse( $t->exists(), "File '$name' was deleted" ); - } -} diff --git a/tests/phpunit/includes/upload/UploadStashTest.php b/tests/phpunit/includes/upload/UploadStashTest.php deleted file mode 100644 index 7a0fea48..00000000 --- a/tests/phpunit/includes/upload/UploadStashTest.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php -/** - * @group Database - */ -class UploadStashTest extends MediaWikiTestCase { - /** - * @var Array of UploadStashTestUser - */ - public static $users; - - protected function setUp() { - parent::setUp(); - - // Setup a file for bug 29408 - $this->bug29408File = __DIR__ . '/bug29408'; - file_put_contents( $this->bug29408File, "\x00" ); - - self::$users = array( - 'sysop' => new TestUser( - 'Uploadstashtestsysop', - 'Upload Stash Test Sysop', - 'upload_stash_test_sysop@example.com', - array( 'sysop' ) - ), - 'uploader' => new TestUser( - 'Uploadstashtestuser', - 'Upload Stash Test User', - 'upload_stash_test_user@example.com', - array() - ) - ); - } - - protected function tearDown() { - if ( file_exists( $this->bug29408File . "." ) ) { - unlink( $this->bug29408File . "." ); - } - - if ( file_exists( $this->bug29408File ) ) { - unlink( $this->bug29408File ); - } - - parent::tearDown(); - } - - public function testBug29408() { - $this->setMwGlobals( 'wgUser', self::$users['uploader']->user ); - - $repo = RepoGroup::singleton()->getLocalRepo(); - $stash = new UploadStash( $repo ); - - // Throws exception caught by PHPUnit on failure - $file = $stash->stashFile( $this->bug29408File ); - // We'll never reach this point if we hit bug 29408 - $this->assertTrue( true, 'Unrecognized file without extension' ); - - $stash->removeFile( $file->getFileKey() ); - } - - public function testValidRequest() { - $request = new FauxRequest( array( 'wpFileKey' => 'foo' ) ); - $this->assertFalse( UploadFromStash::isValidRequest( $request ), 'Check failure on bad wpFileKey' ); - - $request = new FauxRequest( array( 'wpSessionKey' => 'foo' ) ); - $this->assertFalse( UploadFromStash::isValidRequest( $request ), 'Check failure on bad wpSessionKey' ); - - $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) ); - $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check good wpFileKey' ); - - $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) ); - $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check good wpSessionKey' ); - - $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test', 'wpSessionKey' => 'foo' ) ); - $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check key precedence' ); - } -} |